Movatterモバイル変換


[0]ホーム

URL:


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

Generated on Fri Jul 18 2025 10:37:37 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp