LLVM 20.0.0git
GlobalMergeFunctions.cpp
Go to the documentation of this file.
1//===---- GlobalMergeFunctions.cpp - Global merge functions -------*- C++ -===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass implements the global merge function pass.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/Statistic.h"
17#include "llvm/IR/IRBuilder.h"
22
23#define DEBUG_TYPE "global-merge-func"
24
25using namespace llvm;
26using namespace llvm::support;
27
29 "disable-cgdata-for-merging", cl::Hidden,
30 cl::desc("Disable codegen data for function merging. Local "
31 "merging is still enabled within a module."),
32 cl::init(false));
33
34STATISTIC(NumMergedFunctions,
35 "Number of functions that are actually merged using function hash");
36STATISTIC(NumAnalyzedModues, "Number of modules that are analyzed");
37STATISTIC(NumAnalyzedFunctions, "Number of functions that are analyzed");
38STATISTIC(NumEligibleFunctions, "Number of functions that are eligible");
39
40/// Returns true if the \OpIdx operand of \p CI is the callee operand.
41static bool isCalleeOperand(const CallBase *CI, unsigned OpIdx) {
42 return &CI->getCalledOperandUse() == &CI->getOperandUse(OpIdx);
43}
44
45static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx) {
46 if (CI->isInlineAsm())
47 return false;
48 Function *Callee = CI->getCalledOperand()
49 ? dyn_cast_or_null<Function>(
51 : nullptr;
52 if (Callee) {
53 if (Callee->isIntrinsic())
54 return false;
55 auto Name = Callee->getName();
56 // objc_msgSend stubs must be called, and can't have their address taken.
57 if (Name.starts_with("objc_msgSend$"))
58 return false;
59 // Calls to dtrace probes must generate unique patchpoints.
60 if (Name.starts_with("__dtrace"))
61 return false;
62 }
63 if (isCalleeOperand(CI, OpIdx) &&
65 // The operand is the callee and it has already been signed. Ignore this
66 // because we cannot add another ptrauth bundle to the call instruction.
67 return false;
68 }
69 return true;
70}
71
72/// Returns true if function \p F is eligible for merging.
74 if (F->isDeclaration())
75 return false;
76
77 if (F->hasFnAttribute(llvm::Attribute::NoMerge) ||
78 F->hasFnAttribute(llvm::Attribute::AlwaysInline))
79 return false;
80
81 if (F->hasAvailableExternallyLinkage())
82 return false;
83
84 if (F->getFunctionType()->isVarArg())
85 return false;
86
87 if (F->getCallingConv() == CallingConv::SwiftTail)
88 return false;
89
90 // If function contains callsites with musttail, if we merge
91 // it, the merged function will have the musttail callsite, but
92 // the number of parameters can change, thus the parameter count
93 // of the callsite will mismatch with the function itself.
94 for (const BasicBlock &BB : *F) {
95 for (const Instruction &I : BB) {
96 const auto *CB = dyn_cast<CallBase>(&I);
97 if (CB && CB->isMustTailCall())
98 return false;
99 }
100 }
101
102 return true;
103}
104
106 switch (I->getOpcode()) {
107 case Instruction::Load:
108 case Instruction::Store:
109 case Instruction::Call:
110 case Instruction::Invoke:
111 return true;
112 default:
113 return false;
114 }
115}
116
117// This function takes an instruction, \p I, and an operand index, \p OpIdx.
118// It returns true if the operand should be ignored in the hash computation.
119// If \p OpIdx is out of range based on the other instruction context, it cannot
120// be ignored.
121static bool ignoreOp(const Instruction *I, unsigned OpIdx) {
122 if (OpIdx >= I->getNumOperands())
123 return false;
124
126 return false;
127
128 if (!isa<Constant>(I->getOperand(OpIdx)))
129 return false;
130
131 if (const auto *CI = dyn_cast<CallBase>(I))
132 return canParameterizeCallOperand(CI, OpIdx);
133
134 return true;
135}
136
137static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) {
138 Type *SrcTy = V->getType();
139 if (SrcTy->isStructTy()) {
140 assert(DestTy->isStructTy());
141 assert(SrcTy->getStructNumElements() == DestTy->getStructNumElements());
142 Value *Result = PoisonValue::get(DestTy);
143 for (unsigned int I = 0, E = SrcTy->getStructNumElements(); I < E; ++I) {
144 Value *Element =
145 createCast(Builder, Builder.CreateExtractValue(V, ArrayRef(I)),
146 DestTy->getStructElementType(I));
147
148 Result = Builder.CreateInsertValue(Result, Element, ArrayRef(I));
149 }
150 return Result;
151 }
152 assert(!DestTy->isStructTy());
153 if (auto *SrcAT = dyn_cast<ArrayType>(SrcTy)) {
154 auto *DestAT = dyn_cast<ArrayType>(DestTy);
155 assert(DestAT);
156 assert(SrcAT->getNumElements() == DestAT->getNumElements());
157 Value *Result = PoisonValue::get(DestTy);
158 for (unsigned int I = 0, E = SrcAT->getNumElements(); I < E; ++I) {
159 Value *Element =
160 createCast(Builder, Builder.CreateExtractValue(V, ArrayRef(I)),
161 DestAT->getElementType());
162
163 Result = Builder.CreateInsertValue(Result, Element, ArrayRef(I));
164 }
165 return Result;
166 }
167 assert(!DestTy->isArrayTy());
168 if (SrcTy->isIntegerTy() && DestTy->isPointerTy())
169 return Builder.CreateIntToPtr(V, DestTy);
170 if (SrcTy->isPointerTy() && DestTy->isIntegerTy())
171 return Builder.CreatePtrToInt(V, DestTy);
172 return Builder.CreateBitCast(V, DestTy);
173}
174
176 ++NumAnalyzedModues;
177 for (Function &Func : M) {
178 ++NumAnalyzedFunctions;
179 if (isEligibleFunction(&Func)) {
180 ++NumEligibleFunctions;
181
183
184 // Convert the operand map to a vector for a serialization-friendly
185 // format.
186 IndexOperandHashVecType IndexOperandHashes;
187 for (auto &Pair : *FI.IndexOperandHashMap)
188 IndexOperandHashes.emplace_back(Pair);
189
190 StableFunction SF(FI.FunctionHash, get_stable_name(Func.getName()).str(),
191 M.getModuleIdentifier(), FI.IndexInstruction->size(),
192 std::move(IndexOperandHashes));
193
194 LocalFunctionMap->insert(SF);
195 }
196 }
197}
198
199/// Tuple to hold function info to process merging.
205 IndexInstrMap *IndexInstruction)
206 : SF(SF), F(F), IndexInstruction(std::move(IndexInstruction)) {}
207};
208
209// Given the func info, and the parameterized locations, create and return
210// a new merged function by replacing the original constants with the new
211// parameters.
213 ArrayRef<Type *> ConstParamTypes,
214 const ParamLocsVecTy &ParamLocsVec) {
215 // Synthesize a new merged function name by appending ".Tgm" to the root
216 // function's name.
217 auto *MergedFunc = FI.F;
218 std::string NewFunctionName =
220 auto *M = MergedFunc->getParent();
221 assert(!M->getFunction(NewFunctionName));
222
223 FunctionType *OrigTy = MergedFunc->getFunctionType();
224 // Get the original params' types.
225 SmallVector<Type *> ParamTypes(OrigTy->param_begin(), OrigTy->param_end());
226 // Append const parameter types that are passed in.
227 ParamTypes.append(ConstParamTypes.begin(), ConstParamTypes.end());
228 FunctionType *FuncType = FunctionType::get(OrigTy->getReturnType(),
229 ParamTypes, /*isVarArg=*/false);
230
231 // Declare a new function
232 Function *NewFunction =
233 Function::Create(FuncType, MergedFunc->getLinkage(), NewFunctionName);
234 if (auto *SP = MergedFunc->getSubprogram())
235 NewFunction->setSubprogram(SP);
236 NewFunction->copyAttributesFrom(MergedFunc);
238
240 NewFunction->addFnAttr(Attribute::NoInline);
241
242 // Add the new function before the root function.
243 M->getFunctionList().insert(MergedFunc->getIterator(), NewFunction);
244
245 // Move the body of MergedFunc into the NewFunction.
246 NewFunction->splice(NewFunction->begin(), MergedFunc);
247
248 // Update the original args by the new args.
249 auto NewArgIter = NewFunction->arg_begin();
250 for (Argument &OrigArg : MergedFunc->args()) {
251 Argument &NewArg = *NewArgIter++;
252 OrigArg.replaceAllUsesWith(&NewArg);
253 }
254
255 // Replace the original Constants by the new args.
256 unsigned NumOrigArgs = MergedFunc->arg_size();
257 for (unsigned ParamIdx = 0; ParamIdx < ParamLocsVec.size(); ++ParamIdx) {
258 Argument *NewArg = NewFunction->getArg(NumOrigArgs + ParamIdx);
259 for (auto [InstIndex, OpndIndex] : ParamLocsVec[ParamIdx]) {
260 auto *Inst = FI.IndexInstruction->lookup(InstIndex);
261 auto *OrigC = Inst->getOperand(OpndIndex);
262 if (OrigC->getType() != NewArg->getType()) {
263 IRBuilder<> Builder(Inst->getParent(), Inst->getIterator());
264 Inst->setOperand(OpndIndex,
265 createCast(Builder, NewArg, OrigC->getType()));
266 } else {
267 Inst->setOperand(OpndIndex, NewArg);
268 }
269 }
270 }
271
272 return NewFunction;
273}
274
275// Given the original function (Thunk) and the merged function (ToFunc), create
276// a thunk to the merged function.
278 Function *ToFunc) {
279 auto *Thunk = FI.F;
280
281 assert(Thunk->arg_size() + Params.size() ==
282 ToFunc->getFunctionType()->getNumParams());
283 Thunk->dropAllReferences();
284
285 BasicBlock *BB = BasicBlock::Create(Thunk->getContext(), "", Thunk);
286 IRBuilder<> Builder(BB);
287
289 unsigned ParamIdx = 0;
290 FunctionType *ToFuncTy = ToFunc->getFunctionType();
291
292 // Add arguments which are passed through Thunk.
293 for (Argument &AI : Thunk->args()) {
294 Args.push_back(createCast(Builder, &AI, ToFuncTy->getParamType(ParamIdx)));
295 ++ParamIdx;
296 }
297
298 // Add new arguments defined by Params.
299 for (auto *Param : Params) {
300 assert(ParamIdx < ToFuncTy->getNumParams());
301 Args.push_back(
302 createCast(Builder, Param, ToFuncTy->getParamType(ParamIdx)));
303 ++ParamIdx;
304 }
305
306 CallInst *CI = Builder.CreateCall(ToFunc, Args);
307 bool isSwiftTailCall = ToFunc->getCallingConv() == CallingConv::SwiftTail &&
308 Thunk->getCallingConv() == CallingConv::SwiftTail;
311 CI->setCallingConv(ToFunc->getCallingConv());
312 CI->setAttributes(ToFunc->getAttributes());
313 if (Thunk->getReturnType()->isVoidTy())
314 Builder.CreateRetVoid();
315 else
316 Builder.CreateRet(createCast(Builder, CI, Thunk->getReturnType()));
317}
318
319// Check if the old merged/optimized IndexOperandHashMap is compatible with
320// the current IndexOperandHashMap. An operand hash may not be stable across
321// different builds due to varying modules combined. To address this, we relax
322// the hash check condition by comparing Const hash patterns instead of absolute
323// hash values. For example, let's assume we have three Consts located at idx1,
324// idx3, and idx6, where their corresponding hashes are hash1, hash2, and hash1
325// in the old merged map below:
326// Old (Merged): [(idx1, hash1), (idx3, hash2), (idx6, hash1)]
327// Current: [(idx1, hash1'), (idx3, hash2'), (idx6, hash1')]
328// If the current function also has three Consts in the same locations,
329// with hash sequences hash1', hash2', and hash1' where the first and third
330// are the same as the old hash sequences, we consider them matched.
332 const DenseMap<IndexPair, stable_hash> &OldInstOpndIndexToConstHash,
333 const DenseMap<IndexPair, stable_hash> &CurrInstOpndIndexToConstHash) {
334
335 DenseMap<stable_hash, stable_hash> OldHashToCurrHash;
336 for (const auto &[Index, OldHash] : OldInstOpndIndexToConstHash) {
337 auto It = CurrInstOpndIndexToConstHash.find(Index);
338 if (It == CurrInstOpndIndexToConstHash.end())
339 return false;
340
341 auto CurrHash = It->second;
342 auto J = OldHashToCurrHash.find(OldHash);
343 if (J == OldHashToCurrHash.end())
344 OldHashToCurrHash.insert({OldHash, CurrHash});
345 else if (J->second != CurrHash)
346 return false;
347 }
348
349 return true;
350}
351
352// Validate the locations pointed by a param has the same hash and Constant.
353static bool
355 const IndexInstrMap &IndexInstruction,
356 const ParamLocsVecTy &ParamLocsVec) {
357 for (auto &ParamLocs : ParamLocsVec) {
358 std::optional<stable_hash> OldHash;
359 std::optional<Constant *> OldConst;
360 for (auto &Loc : ParamLocs) {
361 assert(SF.IndexOperandHashMap->count(Loc));
362 auto CurrHash = SF.IndexOperandHashMap.get()->at(Loc);
363 auto [InstIndex, OpndIndex] = Loc;
364 assert(InstIndex < IndexInstruction.size());
365 const auto *Inst = IndexInstruction.lookup(InstIndex);
366 auto *CurrConst = cast<Constant>(Inst->getOperand(OpndIndex));
367 if (!OldHash) {
368 OldHash = CurrHash;
369 OldConst = CurrConst;
370 } else if (CurrConst != *OldConst || CurrHash != *OldHash) {
371 return false;
372 }
373 }
374 }
375 return true;
376}
377
379 const SmallVector<std::unique_ptr<StableFunctionMap::StableFunctionEntry>>
380 &SFS) {
381 std::map<std::vector<stable_hash>, ParamLocs> HashSeqToLocs;
382 auto &RSF = *SFS[0];
383 unsigned StableFunctionCount = SFS.size();
384
385 for (auto &[IndexPair, Hash] : *RSF.IndexOperandHashMap) {
386 // Const hash sequence across stable functions.
387 // We will allocate a parameter per unique hash squence.
388 // can't use SmallVector as key
389 std::vector<stable_hash> ConstHashSeq;
390 ConstHashSeq.push_back(Hash);
391 bool Identical = true;
392 for (unsigned J = 1; J < StableFunctionCount; ++J) {
393 auto &SF = SFS[J];
394 auto SHash = SF->IndexOperandHashMap->at(IndexPair);
395 if (Hash != SHash)
396 Identical = false;
397 ConstHashSeq.push_back(SHash);
398 }
399
400 if (Identical)
401 continue;
402
403 // For each unique Const hash sequence (parameter), add the locations.
404 HashSeqToLocs[ConstHashSeq].push_back(IndexPair);
405 }
406
407 ParamLocsVecTy ParamLocsVec;
408 for (auto &[HashSeq, Locs] : HashSeqToLocs)
409 ParamLocsVec.push_back(std::move(Locs));
410
411 llvm::sort(ParamLocsVec, [&](const ParamLocs &L, const ParamLocs &R) {
412 return L[0] < R[0];
413 });
414
415 return ParamLocsVec;
416}
417
418bool GlobalMergeFunc::merge(Module &M, const StableFunctionMap *FunctionMap) {
419 bool Changed = false;
420
421 // Collect stable functions related to the current module.
423 HashToFuncs;
424 auto &Maps = FunctionMap->getFunctionMap();
425 for (auto &F : M) {
426 if (!isEligibleFunction(&F))
427 continue;
429 if (Maps.contains(FI.FunctionHash))
430 HashToFuncs[FI.FunctionHash].emplace_back(&F, std::move(FI));
431 }
432
433 for (auto &[Hash, Funcs] : HashToFuncs) {
434 std::optional<ParamLocsVecTy> ParamLocsVec;
435 SmallVector<FuncMergeInfo> FuncMergeInfos;
436 auto &SFS = Maps.at(Hash);
437 assert(!SFS.empty());
438 auto &RFS = SFS[0];
439
440 // Iterate functions with the same hash.
441 for (auto &[F, FI] : Funcs) {
442 // Check if the function is compatible with any stable function
443 // in terms of the number of instructions and ignored operands.
444 if (RFS->InstCount != FI.IndexInstruction->size())
445 continue;
446
447 auto hasValidSharedConst = [&](StableFunctionMap::StableFunctionEntry *SF,
448 FunctionHashInfo &FHI) {
449 for (auto &[Index, Hash] : *SF->IndexOperandHashMap) {
450 auto [InstIndex, OpndIndex] = Index;
451 assert(InstIndex < FHI.IndexInstruction->size());
452 auto *Inst = FHI.IndexInstruction->lookup(InstIndex);
453 if (!ignoreOp(Inst, OpndIndex))
454 return false;
455 }
456 return true;
457 };
458 if (!hasValidSharedConst(RFS.get(), FI))
459 continue;
460
461 for (auto &SF : SFS) {
462 assert(SF->InstCount == FI.IndexInstruction->size());
463 assert(hasValidSharedConst(SF.get(), FI));
464 // Check if there is any stable function that is compatiable with the
465 // current one.
467 *FI.IndexOperandHashMap))
468 continue;
469 if (!ParamLocsVec.has_value()) {
470 ParamLocsVec = computeParamInfo(SFS);
471 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging hash: " << Hash
472 << " with Params " << ParamLocsVec->size() << "\n");
473 }
474 if (!checkConstLocationCompatible(*SF, *FI.IndexInstruction,
475 *ParamLocsVec))
476 continue;
477
478 // If a stable function matching the current one is found,
479 // create a candidate for merging and proceed to the next function.
480 FuncMergeInfos.emplace_back(SF.get(), F, FI.IndexInstruction.get());
481 break;
482 }
483 }
484 unsigned FuncMergeInfoSize = FuncMergeInfos.size();
485 if (FuncMergeInfoSize == 0)
486 continue;
487
488 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging function count "
489 << FuncMergeInfoSize << " for hash: " << Hash << "\n");
490
491 for (auto &FMI : FuncMergeInfos) {
492 Changed = true;
493
494 // We've already validated all locations of constant operands pointed by
495 // the parameters. Populate parameters pointing to the original constants.
497 SmallVector<Type *> ParamTypes;
498 for (auto &ParamLocs : *ParamLocsVec) {
500 auto &[InstIndex, OpndIndex] = ParamLocs[0];
501 auto *Inst = FMI.IndexInstruction->lookup(InstIndex);
502 auto *Opnd = cast<Constant>(Inst->getOperand(OpndIndex));
503 Params.push_back(Opnd);
504 ParamTypes.push_back(Opnd->getType());
505 }
506
507 // Create a merged function derived from the current function.
508 Function *MergedFunc =
509 createMergedFunction(FMI, ParamTypes, *ParamLocsVec);
510
511 LLVM_DEBUG({
512 dbgs() << "[GlobalMergeFunc] Merged function (hash:" << FMI.SF->Hash
513 << ") " << MergedFunc->getName() << " generated from "
514 << FMI.F->getName() << ":\n";
515 MergedFunc->dump();
516 });
517
518 // Transform the current function into a thunk that calls the merged
519 // function.
520 createThunk(FMI, Params, MergedFunc);
521 LLVM_DEBUG({
522 dbgs() << "[GlobalMergeFunc] Thunk generated: \n";
523 FMI.F->dump();
524 });
525 ++NumMergedFunctions;
526 }
527 }
528
529 return Changed;
530}
531
533 // Initialize the local function map regardless of the merger mode.
534 LocalFunctionMap = std::make_unique<StableFunctionMap>();
535
536 // Disable codegen data for merging. The local merge is still enabled.
538 return;
539
540 // (Full)LTO module does not have functions added to the index.
541 // In this case, we run a local merger without using codegen data.
542 if (Index && !Index->hasExportedFunctions(M))
543 return;
544
545 if (cgdata::emitCGData())
546 MergerMode = HashFunctionMode::BuildingHashFuncion;
548 MergerMode = HashFunctionMode::UsingHashFunction;
549}
550
552 LLVM_DEBUG(dbgs() << "Emit function map. Size: " << LocalFunctionMap->size()
553 << "\n");
554 // No need to emit the function map if it is empty.
555 if (LocalFunctionMap->empty())
556 return;
559
560 StableFunctionMapRecord::serialize(OS, LocalFunctionMap.get());
561
562 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(
563 OS.str(), "in-memory stable function map", false);
564
565 Triple TT(M.getTargetTriple());
566 embedBufferInModule(M, *Buffer.get(),
567 getCodeGenDataSectionName(CG_merge, TT.getObjectFormat()),
568 Align(4));
569}
570
573
574 const StableFunctionMap *FuncMap;
575 if (MergerMode == HashFunctionMode::UsingHashFunction) {
576 // Use the prior CG data to optimistically create global merge candidates.
578 } else {
579 analyze(M);
580 // Emit the local function map to the custom section, __llvm_merge before
581 // finalizing it.
582 if (MergerMode == HashFunctionMode::BuildingHashFuncion)
584 LocalFunctionMap->finalize();
585 FuncMap = LocalFunctionMap.get();
586 }
587
588 return merge(M, FuncMap);
589}
590
591namespace {
592
593class GlobalMergeFuncPassWrapper : public ModulePass {
594
595public:
596 static char ID;
597
598 GlobalMergeFuncPassWrapper();
599
600 void getAnalysisUsage(AnalysisUsage &AU) const override {
602 AU.setPreservesAll();
603 ModulePass::getAnalysisUsage(AU);
604 }
605
606 StringRef getPassName() const override { return "Global Merge Functions"; }
607
608 bool runOnModule(Module &M) override;
609};
610
611} // namespace
612
613char GlobalMergeFuncPassWrapper::ID = 0;
614INITIALIZE_PASS_BEGIN(GlobalMergeFuncPassWrapper, "global-merge-func",
615 "Global merge function pass", false, false)
616INITIALIZE_PASS_END(GlobalMergeFuncPassWrapper, "global-merge-func",
618
619namespace llvm {
621 return new GlobalMergeFuncPassWrapper();
622}
623} // namespace llvm
624
625GlobalMergeFuncPassWrapper::GlobalMergeFuncPassWrapper() : ModulePass(ID) {
628}
629
630bool GlobalMergeFuncPassWrapper::runOnModule(Module &M) {
631 const ModuleSummaryIndex *Index = nullptr;
632 if (auto *IndexWrapperPass =
633 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>())
634 Index = IndexWrapperPass->getIndex();
635
636 return GlobalMergeFunc(Index).run(M);
637}
638
641 bool Changed = GlobalMergeFunc(ImportSummary).run(M);
642 return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
643}
Performs the initial survey of the specified function
#define LLVM_DEBUG(...)
Definition: Debug.h:106
std::string Name
static ParamLocsVecTy computeParamInfo(const SmallVector< std::unique_ptr< StableFunctionMap::StableFunctionEntry > > &SFS)
static bool checkConstHashCompatible(const DenseMap< IndexPair, stable_hash > &OldInstOpndIndexToConstHash, const DenseMap< IndexPair, stable_hash > &CurrInstOpndIndexToConstHash)
global merge func
static cl::opt< bool > DisableCGDataForMerging("disable-cgdata-for-merging", cl::Hidden, cl::desc("Disable codegen data for function merging. Local " "merging is still enabled within a module."), cl::init(false))
static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx)
static Function * createMergedFunction(FuncMergeInfo &FI, ArrayRef< Type * > ConstParamTypes, const ParamLocsVecTy &ParamLocsVec)
static void createThunk(FuncMergeInfo &FI, ArrayRef< Constant * > Params, Function *ToFunc)
global merge Global merge function pass
static Value * createCast(IRBuilder<> &Builder, Value *V, Type *DestTy)
static bool isEligibleInstructionForConstantSharing(const Instruction *I)
static bool ignoreOp(const Instruction *I, unsigned OpIdx)
bool isEligibleFunction(Function *F)
Returns true if function F is eligible for merging.
static bool checkConstLocationCompatible(const StableFunctionMap::StableFunctionEntry &SF, const IndexInstrMap &IndexInstruction, const ParamLocsVecTy &ParamLocsVec)
static bool isCalleeOperand(const CallBase *CI, unsigned OpIdx)
Returns true if the \OpIdx operand of CI is the callee operand.
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This is the interface to build a ModuleSummaryIndex for a module.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
Represent the analysis usage information of a pass.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:157
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:168
iterator begin() const
Definition: ArrayRef.h:156
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:212
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1120
bool isInlineAsm() const
Check if this call is an inline asm statement.
Definition: InstrTypes.h:1416
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1411
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:2051
Value * getCalledOperand() const
Definition: InstrTypes.h:1342
const Use & getCalledOperandUse() const
Definition: InstrTypes.h:1344
void setAttributes(AttributeList A)
Set the attributes for this call.
Definition: InstrTypes.h:1428
This class represents a function call, abstracting a target machine's calling convention.
void setTailCallKind(TailCallKind TCK)
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:211
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:641
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
Definition: Metadata.cpp:1870
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:173
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
Definition: Function.h:761
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:216
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:277
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:353
iterator begin()
Definition: Function.h:853
arg_iterator arg_begin()
Definition: Function.h:868
Argument * getArg(unsigned i) const
Definition: Function.h:886
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:860
GlobalMergeFunc is a ModulePass that implements a function merging mechanism using stable function ha...
void analyze(Module &M)
Analyze module to create stable function into LocalFunctionMap.
void initializeMergerMode(const Module &M)
bool merge(Module &M, const StableFunctionMap *FunctionMap)
Merge functions in the module using the given function map.
void emitFunctionMap(Module &M)
Emit LocalFunctionMap into __llvm_merge section.
static constexpr const char MergingInstanceSuffix[]
The suffix used to identify the merged function that parameterizes the constant values.
void setDLLStorageClass(DLLStorageClassTypes C)
Definition: GlobalValue.h:284
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:537
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2554
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2547
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2150
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1119
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2155
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1114
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2145
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2444
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2697
Legacy wrapper pass to provide the ModuleSummaryIndex object.
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
ValueT lookup(const KeyT &Key) const
Definition: MapVector.h:110
size_type size() const
Definition: MapVector.h:60
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
Class to hold module path string table and global value map, and encapsulate methods for operating on...
bool hasExportedFunctions(const Module &M) const
Check if the given Module has any functions available for exporting in the index.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1878
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void push_back(const T &Elt)
Definition: SmallVector.h:413
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Type * getStructElementType(unsigned N) const
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition: Type.h:261
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:264
unsigned getStructNumElements() const
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:258
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:237
const Use & getOperandUse(unsigned i) const
Definition: User.h:241
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:694
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
void dump() const
Support for debugging, callable in GDB: V->dump()
Definition: AsmWriter.cpp:5304
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition: CallingConv.h:87
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
bool hasStableFunctionMap()
Definition: CodeGenData.h:175
bool emitCGData()
Definition: CodeGenData.h:187
const StableFunctionMap * getStableFunctionMap()
Definition: CodeGenData.h:183
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1697
ModulePass * createGlobalMergeFuncPass()
This pass performs merging similar functions globally.
FunctionHashInfo StructuralHashWithDifferences(const Function &F, IgnoreOperandFunc IgnoreOp)
Computes a structural hash of a given function, considering the structure and content of the function...
std::pair< unsigned, unsigned > IndexPair
The pair of an instruction index and a operand index.
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1664
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
StringRef get_stable_name(StringRef Name)
Definition: StableHashing.h:55
@ Global
Append to llvm.global_dtors.
void initializeGlobalMergeFuncPassWrapperPass(PassRegistry &)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
void embedBufferInModule(Module &M, MemoryBufferRef Buf, StringRef SectionName, Align Alignment=Align(1))
Embed the memory buffer Buf into the module M as a global using the specified section name.
std::string getCodeGenDataSectionName(CGDataSectKind CGSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
Tuple to hold function info to process merging.
FuncMergeInfo(StableFunctionMap::StableFunctionEntry *SF, Function *F, IndexInstrMap *IndexInstruction)
StableFunctionMap::StableFunctionEntry * SF
IndexInstrMap * IndexInstruction
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
PreservedAnalyses run(Module &M, AnalysisManager< Module > &)
const ModuleSummaryIndex * ImportSummary
static void serialize(raw_ostream &OS, const StableFunctionMap *FunctionMap)
A static helper function to serialize the stable function map without owning the stable function map.
An efficient form of StableFunction for fast look-up.
std::unique_ptr< IndexOperandHashMapType > IndexOperandHashMap
A map from an IndexPair to a stable_hash which was skipped.
unsigned InstCount
The number of instructions.
const HashFuncsMapType & getFunctionMap() const
Get the HashToFuncs map for serialization.
A stable function is a function with a stable hash while tracking the locations of ignored operands a...