LLVM 22.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"
18#include "llvm/CodeGen/Passes.h"
19#include "llvm/IR/IRBuilder.h"
24
25#define DEBUG_TYPE "global-merge-func"
26
27using namespace llvm;
28using namespace llvm::support;
29
31 "disable-cgdata-for-merging", cl::Hidden,
32 cl::desc("Disable codegen data for function merging. Local "
33 "merging is still enabled within a module."),
34 cl::init(false));
35
36STATISTIC(NumMergedFunctions,
37 "Number of functions that are actually merged using function hash");
38STATISTIC(NumAnalyzedModues, "Number of modules that are analyzed");
39STATISTIC(NumAnalyzedFunctions, "Number of functions that are analyzed");
40STATISTIC(NumEligibleFunctions, "Number of functions that are eligible");
41
42/// Returns true if the \OpIdx operand of \p CI is the callee operand.
43static bool isCalleeOperand(const CallBase *CI, unsigned OpIdx) {
44 return &CI->getCalledOperandUse() == &CI->getOperandUse(OpIdx);
45}
46
47static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx) {
48 if (CI->isInlineAsm())
49 return false;
50 Function *Callee = CI->getCalledOperand()
51 ? dyn_cast_or_null<Function>(
53 : nullptr;
54 if (Callee) {
55 if (Callee->isIntrinsic())
56 return false;
57 auto Name = Callee->getName();
58 // objc_msgSend stubs must be called, and can't have their address taken.
59 if (Name.starts_with("objc_msgSend$"))
60 return false;
61 // Calls to dtrace probes must generate unique patchpoints.
62 if (Name.starts_with("__dtrace"))
63 return false;
64 }
65 if (isCalleeOperand(CI, OpIdx)) {
66 // The operand is the callee and it has already been signed. Ignore this
67 // because we cannot add another ptrauth bundle to the call instruction.
68 if (CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value())
69 return false;
70 } else {
71 // The target of the arc-attached call must be a constant and cannot be
72 // parameterized.
74 OpIdx))
75 return false;
76 }
77 return true;
78}
79
80/// Returns true if function \p F is eligible for merging.
82 if (F->isDeclaration())
83 return false;
84
85 if (F->hasFnAttribute(llvm::Attribute::NoMerge) ||
86 F->hasFnAttribute(llvm::Attribute::AlwaysInline))
87 return false;
88
89 if (F->hasAvailableExternallyLinkage())
90 return false;
91
92 if (F->getFunctionType()->isVarArg())
93 return false;
94
95 if (F->getCallingConv() == CallingConv::SwiftTail)
96 return false;
97
98 // Unnamed functions are skipped for simplicity.
99 if (!F->hasName())
100 return false;
101
102 // If function contains callsites with musttail, if we merge
103 // it, the merged function will have the musttail callsite, but
104 // the number of parameters can change, thus the parameter count
105 // of the callsite will mismatch with the function itself.
106 for (const BasicBlock &BB : *F) {
107 for (const Instruction &I : BB) {
108 const auto *CB = dyn_cast<CallBase>(&I);
109 if (CB && CB->isMustTailCall())
110 return false;
111 }
112 }
113
114 return true;
115}
116
118 switch (I->getOpcode()) {
119 case Instruction::Load:
120 case Instruction::Store:
121 case Instruction::Call:
122 case Instruction::Invoke:
123 return true;
124 default:
125 return false;
126 }
127}
128
129// This function takes an instruction, \p I, and an operand index, \p OpIdx.
130// It returns true if the operand should be ignored in the hash computation.
131// If \p OpIdx is out of range based on the other instruction context, it cannot
132// be ignored.
133static bool ignoreOp(const Instruction *I, unsigned OpIdx) {
134 if (OpIdx >= I->getNumOperands())
135 return false;
136
138 return false;
139
140 if (!isa<Constant>(I->getOperand(OpIdx)))
141 return false;
142
143 if (const auto *CI = dyn_cast<CallBase>(I))
145
146 return true;
147}
148
150 ++NumAnalyzedModues;
151 for (Function &Func : M) {
152 ++NumAnalyzedFunctions;
153 if (isEligibleFunction(&Func)) {
154 ++NumEligibleFunctions;
155
157
158 // Convert the operand map to a vector for a serialization-friendly
159 // format.
160 IndexOperandHashVecType IndexOperandHashes;
161 for (auto &Pair : *FI.IndexOperandHashMap)
162 IndexOperandHashes.emplace_back(Pair);
163
164 StableFunction SF(FI.FunctionHash, get_stable_name(Func.getName()).str(),
165 M.getModuleIdentifier(), FI.IndexInstruction->size(),
166 std::move(IndexOperandHashes));
167
168 LocalFunctionMap->insert(SF);
169 }
170 }
171}
172
173/// Tuple to hold function info to process merging.
179 IndexInstrMap *IndexInstruction)
180 : SF(SF), F(F), IndexInstruction(std::move(IndexInstruction)) {}
181};
182
183// Given the func info, and the parameterized locations, create and return
184// a new merged function by replacing the original constants with the new
185// parameters.
187 ArrayRef<Type *> ConstParamTypes,
188 const ParamLocsVecTy &ParamLocsVec) {
189 // Synthesize a new merged function name by appending ".Tgm" to the root
190 // function's name.
191 auto *MergedFunc = FI.F;
192 std::string NewFunctionName =
194 auto *M = MergedFunc->getParent();
195 assert(!M->getFunction(NewFunctionName));
196
197 FunctionType *OrigTy = MergedFunc->getFunctionType();
198 // Get the original params' types.
199 SmallVector<Type *> ParamTypes(OrigTy->param_begin(), OrigTy->param_end());
200 // Append const parameter types that are passed in.
201 ParamTypes.append(ConstParamTypes.begin(), ConstParamTypes.end());
202 FunctionType *FuncType = FunctionType::get(OrigTy->getReturnType(),
203 ParamTypes, /*isVarArg=*/false);
204
205 // Declare a new function
206 Function *NewFunction =
207 Function::Create(FuncType, MergedFunc->getLinkage(), NewFunctionName);
208 if (auto *SP = MergedFunc->getSubprogram())
209 NewFunction->setSubprogram(SP);
210 NewFunction->copyAttributesFrom(MergedFunc);
212
214 NewFunction->addFnAttr(Attribute::NoInline);
215
216 // Add the new function before the root function.
217 M->getFunctionList().insert(MergedFunc->getIterator(), NewFunction);
218
219 // Move the body of MergedFunc into the NewFunction.
220 NewFunction->splice(NewFunction->begin(), MergedFunc);
221
222 // Update the original args by the new args.
223 auto NewArgIter = NewFunction->arg_begin();
224 for (Argument &OrigArg : MergedFunc->args()) {
225 Argument &NewArg = *NewArgIter++;
226 OrigArg.replaceAllUsesWith(&NewArg);
227 }
228
229 // Replace the original Constants by the new args.
230 unsigned NumOrigArgs = MergedFunc->arg_size();
231 for (unsigned ParamIdx = 0; ParamIdx < ParamLocsVec.size(); ++ParamIdx) {
232 Argument *NewArg = NewFunction->getArg(NumOrigArgs + ParamIdx);
233 for (auto [InstIndex, OpndIndex] : ParamLocsVec[ParamIdx]) {
234 auto *Inst = FI.IndexInstruction->lookup(InstIndex);
235 auto *OrigC = Inst->getOperand(OpndIndex);
236 if (OrigC->getType() != NewArg->getType()) {
237 IRBuilder<> Builder(Inst->getParent(), Inst->getIterator());
238 Inst->setOperand(OpndIndex,
239 Builder.CreateAggregateCast(NewArg, OrigC->getType()));
240 } else {
241 Inst->setOperand(OpndIndex, NewArg);
242 }
243 }
244 }
245
246 return NewFunction;
247}
248
249// Given the original function (Thunk) and the merged function (ToFunc), create
250// a thunk to the merged function.
252 Function *ToFunc) {
253 auto *Thunk = FI.F;
254
255 assert(Thunk->arg_size() + Params.size() ==
256 ToFunc->getFunctionType()->getNumParams());
257 Thunk->dropAllReferences();
258
259 BasicBlock *BB = BasicBlock::Create(Thunk->getContext(), "", Thunk);
260 IRBuilder<> Builder(BB);
261
263 unsigned ParamIdx = 0;
264 FunctionType *ToFuncTy = ToFunc->getFunctionType();
265
266 // Add arguments which are passed through Thunk.
267 for (Argument &AI : Thunk->args()) {
268 Args.push_back(
269 Builder.CreateAggregateCast(&AI, ToFuncTy->getParamType(ParamIdx)));
270 ++ParamIdx;
271 }
272
273 // Add new arguments defined by Params.
274 for (auto *Param : Params) {
275 assert(ParamIdx < ToFuncTy->getNumParams());
276 Args.push_back(
277 Builder.CreateAggregateCast(Param, ToFuncTy->getParamType(ParamIdx)));
278 ++ParamIdx;
279 }
280
281 CallInst *CI = Builder.CreateCall(ToFunc, Args);
282 bool isSwiftTailCall = ToFunc->getCallingConv() == CallingConv::SwiftTail &&
283 Thunk->getCallingConv() == CallingConv::SwiftTail;
286 CI->setCallingConv(ToFunc->getCallingConv());
287 CI->setAttributes(ToFunc->getAttributes());
288 if (Thunk->getReturnType()->isVoidTy())
289 Builder.CreateRetVoid();
290 else
291 Builder.CreateRet(Builder.CreateAggregateCast(CI, Thunk->getReturnType()));
292}
293
294// Check if the old merged/optimized IndexOperandHashMap is compatible with
295// the current IndexOperandHashMap. An operand hash may not be stable across
296// different builds due to varying modules combined. To address this, we relax
297// the hash check condition by comparing Const hash patterns instead of absolute
298// hash values. For example, let's assume we have three Consts located at idx1,
299// idx3, and idx6, where their corresponding hashes are hash1, hash2, and hash1
300// in the old merged map below:
301// Old (Merged): [(idx1, hash1), (idx3, hash2), (idx6, hash1)]
302// Current: [(idx1, hash1'), (idx3, hash2'), (idx6, hash1')]
303// If the current function also has three Consts in the same locations,
304// with hash sequences hash1', hash2', and hash1' where the first and third
305// are the same as the old hash sequences, we consider them matched.
307 const DenseMap<IndexPair, stable_hash> &OldInstOpndIndexToConstHash,
308 const DenseMap<IndexPair, stable_hash> &CurrInstOpndIndexToConstHash) {
309
310 DenseMap<stable_hash, stable_hash> OldHashToCurrHash;
311 for (const auto &[Index, OldHash] : OldInstOpndIndexToConstHash) {
312 auto It = CurrInstOpndIndexToConstHash.find(Index);
313 if (It == CurrInstOpndIndexToConstHash.end())
314 return false;
315
316 auto CurrHash = It->second;
317 auto J = OldHashToCurrHash.find(OldHash);
318 if (J == OldHashToCurrHash.end())
319 OldHashToCurrHash.insert({OldHash, CurrHash});
320 else if (J->second != CurrHash)
321 return false;
322 }
323
324 return true;
325}
326
327// Validate the locations pointed by a param has the same hash and Constant.
328static bool
330 const IndexInstrMap &IndexInstruction,
331 const ParamLocsVecTy &ParamLocsVec) {
332 for (auto &ParamLocs : ParamLocsVec) {
333 std::optional<stable_hash> OldHash;
334 std::optional<Constant *> OldConst;
335 for (auto &Loc : ParamLocs) {
336 assert(SF.IndexOperandHashMap->count(Loc));
337 auto CurrHash = SF.IndexOperandHashMap->at(Loc);
338 auto [InstIndex, OpndIndex] = Loc;
339 assert(InstIndex < IndexInstruction.size());
340 const auto *Inst = IndexInstruction.lookup(InstIndex);
341 auto *CurrConst = cast<Constant>(Inst->getOperand(OpndIndex));
342 if (!OldHash) {
343 OldHash = CurrHash;
344 OldConst = CurrConst;
345 } else if (CurrConst != *OldConst || CurrHash != *OldHash) {
346 return false;
347 }
348 }
349 }
350 return true;
351}
352
353static ParamLocsVecTy
355 std::map<std::vector<stable_hash>, ParamLocs> HashSeqToLocs;
356 auto &RSF = *SFS[0];
357 unsigned StableFunctionCount = SFS.size();
358
359 for (auto &[IndexPair, Hash] : *RSF.IndexOperandHashMap) {
360 // Const hash sequence across stable functions.
361 // We will allocate a parameter per unique hash squence.
362 // can't use SmallVector as key
363 std::vector<stable_hash> ConstHashSeq;
364 ConstHashSeq.push_back(Hash);
365 bool Identical = true;
366 for (unsigned J = 1; J < StableFunctionCount; ++J) {
367 auto &SF = SFS[J];
368 auto SHash = SF->IndexOperandHashMap->at(IndexPair);
369 if (Hash != SHash)
370 Identical = false;
371 ConstHashSeq.push_back(SHash);
372 }
373
374 if (Identical)
375 continue;
376
377 // For each unique Const hash sequence (parameter), add the locations.
378 HashSeqToLocs[ConstHashSeq].push_back(IndexPair);
379 }
380
381 ParamLocsVecTy ParamLocsVec;
382 for (auto &[HashSeq, Locs] : HashSeqToLocs)
383 ParamLocsVec.push_back(std::move(Locs));
384
385 llvm::sort(ParamLocsVec, [&](const ParamLocs &L, const ParamLocs &R) {
386 return L[0] < R[0];
387 });
388
389 return ParamLocsVec;
390}
391
392bool GlobalMergeFunc::merge(Module &M, const StableFunctionMap *FunctionMap) {
393 bool Changed = false;
394
395 // Collect stable functions related to the current module.
397 HashToFuncs;
398 for (auto &F : M) {
399 if (!isEligibleFunction(&F))
400 continue;
402 if (FunctionMap->contains(FI.FunctionHash))
403 HashToFuncs[FI.FunctionHash].emplace_back(&F, std::move(FI));
404 }
405
406 for (auto &[Hash, Funcs] : HashToFuncs) {
407 std::optional<ParamLocsVecTy> ParamLocsVec;
408 SmallVector<FuncMergeInfo> FuncMergeInfos;
409 auto &SFS = FunctionMap->at(Hash);
410 assert(!SFS.empty());
411 auto &RFS = SFS[0];
412
413 // Iterate functions with the same hash.
414 for (auto &[F, FI] : Funcs) {
415 // Check if the function is compatible with any stable function
416 // in terms of the number of instructions and ignored operands.
417 if (RFS->InstCount != FI.IndexInstruction->size())
418 continue;
419
420 auto hasValidSharedConst = [&](StableFunctionMap::StableFunctionEntry *SF,
421 FunctionHashInfo &FHI) {
422 for (auto &[Index, Hash] : *SF->IndexOperandHashMap) {
423 auto [InstIndex, OpndIndex] = Index;
424 assert(InstIndex < FHI.IndexInstruction->size());
425 auto *Inst = FHI.IndexInstruction->lookup(InstIndex);
426 if (!ignoreOp(Inst, OpndIndex))
427 return false;
428 }
429 return true;
430 };
431 if (!hasValidSharedConst(RFS.get(), FI))
432 continue;
433
434 for (auto &SF : SFS) {
435 assert(SF->InstCount == FI.IndexInstruction->size());
436 assert(hasValidSharedConst(SF.get(), FI));
437 // Check if there is any stable function that is compatiable with the
438 // current one.
440 *FI.IndexOperandHashMap))
441 continue;
442 if (!ParamLocsVec.has_value()) {
443 ParamLocsVec = computeParamInfo(SFS);
444 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging hash: " << Hash
445 << " with Params " << ParamLocsVec->size() << "\n");
446 }
447 if (!checkConstLocationCompatible(*SF, *FI.IndexInstruction,
448 *ParamLocsVec))
449 continue;
450
451 // If a stable function matching the current one is found,
452 // create a candidate for merging and proceed to the next function.
453 FuncMergeInfos.emplace_back(SF.get(), F, FI.IndexInstruction.get());
454 break;
455 }
456 }
457 unsigned FuncMergeInfoSize = FuncMergeInfos.size();
458 if (FuncMergeInfoSize == 0)
459 continue;
460
461 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging function count "
462 << FuncMergeInfoSize << " for hash: " << Hash << "\n");
463
464 for (auto &FMI : FuncMergeInfos) {
465 Changed = true;
466
467 // We've already validated all locations of constant operands pointed by
468 // the parameters. Populate parameters pointing to the original constants.
470 SmallVector<Type *> ParamTypes;
471 for (auto &ParamLocs : *ParamLocsVec) {
473 auto &[InstIndex, OpndIndex] = ParamLocs[0];
474 auto *Inst = FMI.IndexInstruction->lookup(InstIndex);
475 auto *Opnd = cast<Constant>(Inst->getOperand(OpndIndex));
476 Params.push_back(Opnd);
477 ParamTypes.push_back(Opnd->getType());
478 }
479
480 // Create a merged function derived from the current function.
481 Function *MergedFunc =
482 createMergedFunction(FMI, ParamTypes, *ParamLocsVec);
483
484 LLVM_DEBUG({
485 dbgs() << "[GlobalMergeFunc] Merged function (hash:" << FMI.SF->Hash
486 << ") " << MergedFunc->getName() << " generated from "
487 << FMI.F->getName() << ":\n";
488 MergedFunc->dump();
489 });
490
491 // Transform the current function into a thunk that calls the merged
492 // function.
493 createThunk(FMI, Params, MergedFunc);
494 LLVM_DEBUG({
495 dbgs() << "[GlobalMergeFunc] Thunk generated: \n";
496 FMI.F->dump();
497 });
498 ++NumMergedFunctions;
499 }
500 }
501
502 return Changed;
503}
504
506 // Initialize the local function map regardless of the merger mode.
507 LocalFunctionMap = std::make_unique<StableFunctionMap>();
508
509 // Disable codegen data for merging. The local merge is still enabled.
511 return;
512
513 // (Full)LTO module does not have functions added to the index.
514 // In this case, we run a local merger without using codegen data.
515 if (Index && !Index->hasExportedFunctions(M))
516 return;
517
518 if (cgdata::emitCGData())
519 MergerMode = HashFunctionMode::BuildingHashFuncion;
521 MergerMode = HashFunctionMode::UsingHashFunction;
522}
523
525 LLVM_DEBUG(dbgs() << "Emit function map. Size: " << LocalFunctionMap->size()
526 << "\n");
527 // No need to emit the function map if it is empty.
528 if (LocalFunctionMap->empty())
529 return;
532
533 std::vector<CGDataPatchItem> PatchItems;
534 StableFunctionMapRecord::serialize(OS, LocalFunctionMap.get(), PatchItems);
535 CGDataOStream COS(OS);
536 COS.patch(PatchItems);
537
538 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(
539 OS.str(), "in-memory stable function map", false);
540
541 Triple TT(M.getTargetTriple());
542 embedBufferInModule(M, *Buffer,
543 getCodeGenDataSectionName(CG_merge, TT.getObjectFormat()),
544 Align(4));
545}
546
549
550 const StableFunctionMap *FuncMap;
551 if (MergerMode == HashFunctionMode::UsingHashFunction) {
552 // Use the prior CG data to optimistically create global merge candidates.
554 } else {
555 analyze(M);
556 // Emit the local function map to the custom section, __llvm_merge before
557 // finalizing it.
558 if (MergerMode == HashFunctionMode::BuildingHashFuncion)
560 LocalFunctionMap->finalize();
561 FuncMap = LocalFunctionMap.get();
562 }
563
564 return merge(M, FuncMap);
565}
566
567namespace {
568
569class GlobalMergeFuncPassWrapper : public ModulePass {
570
571public:
572 static char ID;
573
574 GlobalMergeFuncPassWrapper();
575
576 void getAnalysisUsage(AnalysisUsage &AU) const override {
578 AU.setPreservesAll();
579 ModulePass::getAnalysisUsage(AU);
580 }
581
582 StringRef getPassName() const override { return "Global Merge Functions"; }
583
584 bool runOnModule(Module &M) override;
585};
586
587} // namespace
588
589char GlobalMergeFuncPassWrapper::ID = 0;
590INITIALIZE_PASS_BEGIN(GlobalMergeFuncPassWrapper, "global-merge-func",
591 "Global merge function pass", false, false)
592INITIALIZE_PASS_END(GlobalMergeFuncPassWrapper, "global-merge-func",
594
595namespace llvm {
597 return new GlobalMergeFuncPassWrapper();
598}
599} // namespace llvm
600
601GlobalMergeFuncPassWrapper::GlobalMergeFuncPassWrapper() : ModulePass(ID) {
604}
605
606bool GlobalMergeFuncPassWrapper::runOnModule(Module &M) {
607 const ModuleSummaryIndex *Index = nullptr;
608 if (auto *IndexWrapperPass =
609 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>())
610 Index = IndexWrapperPass->getIndex();
611
612 return GlobalMergeFunc(Index).run(M);
613}
614
617 bool Changed = GlobalMergeFunc(ImportSummary).run(M);
618 return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
619}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Performs the initial survey of the specified function
std::string Name
static bool checkConstHashCompatible(const DenseMap< IndexPair, stable_hash > &OldInstOpndIndexToConstHash, const DenseMap< IndexPair, stable_hash > &CurrInstOpndIndexToConstHash)
global merge func
static ParamLocsVecTy computeParamInfo(const StableFunctionMap::StableFunctionEntries &SFS)
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 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.
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:39
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:167
#define LLVM_DEBUG(...)
Definition: Debug.h:119
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
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:32
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:136
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
iterator begin() const
Definition: ArrayRef.h:135
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
A wrapper class to abstract writer stream with support of bytes back patching.
LLVM_ABI void patch(ArrayRef< CGDataPatchItem > P)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
bool isInlineAsm() const
Check if this call is an inline asm statement.
Definition: InstrTypes.h:1415
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1410
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:2023
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:2083
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
const Use & getCalledOperandUse() const
Definition: InstrTypes.h:1342
void setAttributes(AttributeList A)
Set the attributes for this call.
Definition: InstrTypes.h:1427
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:177
iterator end()
Definition: DenseMap.h:87
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
static LLVM_ABI 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:637
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
Definition: Metadata.cpp:1911
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:166
void splice(Function::iterator ToIt, Function *FromF)
Transfer all blocks from FromF to this function at ToIt.
Definition: Function.h:759
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:209
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition: Function.h:270
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition: Function.h:352
iterator begin()
Definition: Function.h:851
arg_iterator arg_begin()
Definition: Function.h:866
Argument * getArg(unsigned i) const
Definition: Function.h:884
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition: Function.cpp:856
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:286
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:539
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:60
LLVM_ABI Value * CreateAggregateCast(Value *V, Type *DestTy)
Cast between aggregate types that must have identical structure but may differ in their leaf types.
Definition: IRBuilder.cpp:71
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1172
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1167
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2508
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
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:99
size_type size() const
Definition: MapVector.h:56
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:255
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:67
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:118
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void push_back(const T &Elt)
Definition: SmallVector.h:414
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
const Use & getOperandUse(unsigned i) const
Definition: User.h:245
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:701
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
Definition: AsmWriter.cpp:5465
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:692
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
Definition: CallingConv.h:87
bool hasStableFunctionMap()
Definition: CodeGenData.h:176
bool emitCGData()
Definition: CodeGenData.h:188
const StableFunctionMap * getStableFunctionMap()
Definition: CodeGenData.h:184
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
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:1702
LLVM_ABI ModulePass * createGlobalMergeFuncPass()
This pass performs merging similar functions globally.
LLVM_ABI 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:1669
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
StringRef get_stable_name(StringRef Name)
Definition: StableHashing.h:55
@ Global
Append to llvm.global_dtors.
LLVM_ABI 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:1886
LLVM_ABI 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.
LLVM_ABI 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:856
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 LLVM_ABI void serialize(raw_ostream &OS, const StableFunctionMap *FunctionMap, std::vector< CGDataPatchItem > &PatchItems)
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 StableFunctionEntries & at(HashFuncsMapType::key_type FunctionHash) const
bool contains(HashFuncsMapType::key_type FunctionHash) const
A stable function is a function with a stable hash while tracking the locations of ignored operands a...