LLVM 23.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()
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.
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);
211 // Preserve entry count for the merged function. Branch weights for blocks
212 // are automatically preserved via splice() which moves the basic blocks.
213 if (auto EC = MergedFunc->getEntryCount())
214 NewFunction->setEntryCount(*EC);
216
218 NewFunction->addFnAttr(Attribute::NoInline);
219
220 // Add the new function before the root function.
221 M->getFunctionList().insert(MergedFunc->getIterator(), NewFunction);
222
223 // Move the body of MergedFunc into the NewFunction.
224 NewFunction->splice(NewFunction->begin(), MergedFunc);
225
226 // Update the original args by the new args.
227 auto NewArgIter = NewFunction->arg_begin();
228 for (Argument &OrigArg : MergedFunc->args()) {
229 Argument &NewArg = *NewArgIter++;
230 OrigArg.replaceAllUsesWith(&NewArg);
231 }
232
233 // Replace the original Constants by the new args.
234 unsigned NumOrigArgs = MergedFunc->arg_size();
235 for (unsigned ParamIdx = 0; ParamIdx < ParamLocsVec.size(); ++ParamIdx) {
236 Argument *NewArg = NewFunction->getArg(NumOrigArgs + ParamIdx);
237 for (auto [InstIndex, OpndIndex] : ParamLocsVec[ParamIdx]) {
238 auto *Inst = FI.IndexInstruction->lookup(InstIndex);
239 auto *OrigC = Inst->getOperand(OpndIndex);
240 if (OrigC->getType() != NewArg->getType()) {
241 IRBuilder<> Builder(Inst->getParent(), Inst->getIterator());
242 Inst->setOperand(OpndIndex,
243 Builder.CreateAggregateCast(NewArg, OrigC->getType()));
244 } else {
245 Inst->setOperand(OpndIndex, NewArg);
246 }
247 }
248 }
249
250 return NewFunction;
251}
252
253// Given the original function (Thunk) and the merged function (ToFunc), create
254// a thunk to the merged function.
256 Function *ToFunc) {
257 auto *Thunk = FI.F;
258
259 assert(Thunk->arg_size() + Params.size() ==
260 ToFunc->getFunctionType()->getNumParams());
261
262 // Save entry count before dropping references (which clears metadata).
263 auto EC = Thunk->getEntryCount();
264
265 Thunk->dropAllReferences();
266
267 BasicBlock *BB = BasicBlock::Create(Thunk->getContext(), "", Thunk);
268 IRBuilder<> Builder(BB);
269
271 unsigned ParamIdx = 0;
272 FunctionType *ToFuncTy = ToFunc->getFunctionType();
273
274 // Add arguments which are passed through Thunk.
275 for (Argument &AI : Thunk->args()) {
276 Args.push_back(
277 Builder.CreateAggregateCast(&AI, ToFuncTy->getParamType(ParamIdx)));
278 ++ParamIdx;
279 }
280
281 // Add new arguments defined by Params.
282 for (auto *Param : Params) {
283 assert(ParamIdx < ToFuncTy->getNumParams());
284 Args.push_back(
285 Builder.CreateAggregateCast(Param, ToFuncTy->getParamType(ParamIdx)));
286 ++ParamIdx;
287 }
288
289 CallInst *CI = Builder.CreateCall(ToFunc, Args);
290 bool isSwiftTailCall = ToFunc->getCallingConv() == CallingConv::SwiftTail &&
291 Thunk->getCallingConv() == CallingConv::SwiftTail;
294 CI->setCallingConv(ToFunc->getCallingConv());
295 CI->setAttributes(ToFunc->getAttributes());
296 if (Thunk->getReturnType()->isVoidTy())
297 Builder.CreateRetVoid();
298 else
299 Builder.CreateRet(Builder.CreateAggregateCast(CI, Thunk->getReturnType()));
300
301 // Restore the thunk's original entry count.
302 if (EC)
303 Thunk->setEntryCount(*EC);
304}
305
306// Check if the old merged/optimized IndexOperandHashMap is compatible with
307// the current IndexOperandHashMap. An operand hash may not be stable across
308// different builds due to varying modules combined. To address this, we relax
309// the hash check condition by comparing Const hash patterns instead of absolute
310// hash values. For example, let's assume we have three Consts located at idx1,
311// idx3, and idx6, where their corresponding hashes are hash1, hash2, and hash1
312// in the old merged map below:
313// Old (Merged): [(idx1, hash1), (idx3, hash2), (idx6, hash1)]
314// Current: [(idx1, hash1'), (idx3, hash2'), (idx6, hash1')]
315// If the current function also has three Consts in the same locations,
316// with hash sequences hash1', hash2', and hash1' where the first and third
317// are the same as the old hash sequences, we consider them matched.
319 const DenseMap<IndexPair, stable_hash> &OldInstOpndIndexToConstHash,
320 const DenseMap<IndexPair, stable_hash> &CurrInstOpndIndexToConstHash) {
321
322 DenseMap<stable_hash, stable_hash> OldHashToCurrHash;
323 for (const auto &[Index, OldHash] : OldInstOpndIndexToConstHash) {
324 auto It = CurrInstOpndIndexToConstHash.find(Index);
325 if (It == CurrInstOpndIndexToConstHash.end())
326 return false;
327
328 auto CurrHash = It->second;
329 auto J = OldHashToCurrHash.find(OldHash);
330 if (J == OldHashToCurrHash.end())
331 OldHashToCurrHash.insert({OldHash, CurrHash});
332 else if (J->second != CurrHash)
333 return false;
334 }
335
336 return true;
337}
338
339// Validate the locations pointed by a param has the same hash and Constant.
340static bool
342 const IndexInstrMap &IndexInstruction,
343 const ParamLocsVecTy &ParamLocsVec) {
344 for (auto &ParamLocs : ParamLocsVec) {
345 std::optional<stable_hash> OldHash;
346 std::optional<Constant *> OldConst;
347 for (auto &Loc : ParamLocs) {
348 assert(SF.IndexOperandHashMap->count(Loc));
349 auto CurrHash = SF.IndexOperandHashMap->at(Loc);
350 auto [InstIndex, OpndIndex] = Loc;
351 assert(InstIndex < IndexInstruction.size());
352 const auto *Inst = IndexInstruction.lookup(InstIndex);
353 auto *CurrConst = cast<Constant>(Inst->getOperand(OpndIndex));
354 if (!OldHash) {
355 OldHash = CurrHash;
356 OldConst = CurrConst;
357 } else if (CurrConst != *OldConst || CurrHash != *OldHash) {
358 return false;
359 }
360 }
361 }
362 return true;
363}
364
365static ParamLocsVecTy
367 std::map<std::vector<stable_hash>, ParamLocs> HashSeqToLocs;
368 auto &RSF = *SFS[0];
369 unsigned StableFunctionCount = SFS.size();
370
371 for (auto &[IndexPair, Hash] : *RSF.IndexOperandHashMap) {
372 // Const hash sequence across stable functions.
373 // We will allocate a parameter per unique hash squence.
374 // can't use SmallVector as key
375 std::vector<stable_hash> ConstHashSeq;
376 ConstHashSeq.push_back(Hash);
377 bool Identical = true;
378 for (unsigned J = 1; J < StableFunctionCount; ++J) {
379 auto &SF = SFS[J];
380 auto SHash = SF->IndexOperandHashMap->at(IndexPair);
381 if (Hash != SHash)
382 Identical = false;
383 ConstHashSeq.push_back(SHash);
384 }
385
386 if (Identical)
387 continue;
388
389 // For each unique Const hash sequence (parameter), add the locations.
390 HashSeqToLocs[ConstHashSeq].push_back(IndexPair);
391 }
392
393 ParamLocsVecTy ParamLocsVec;
394 for (auto &[HashSeq, Locs] : HashSeqToLocs)
395 ParamLocsVec.push_back(std::move(Locs));
396
397 llvm::sort(ParamLocsVec, [&](const ParamLocs &L, const ParamLocs &R) {
398 return L[0] < R[0];
399 });
400
401 return ParamLocsVec;
402}
403
404bool GlobalMergeFunc::merge(Module &M, const StableFunctionMap *FunctionMap) {
405 bool Changed = false;
406
407 // Collect stable functions related to the current module.
409 HashToFuncs;
410 for (auto &F : M) {
411 if (!isEligibleFunction(&F))
412 continue;
414 if (FunctionMap->contains(FI.FunctionHash))
415 HashToFuncs[FI.FunctionHash].emplace_back(&F, std::move(FI));
416 }
417
418 for (auto &[Hash, Funcs] : HashToFuncs) {
419 std::optional<ParamLocsVecTy> ParamLocsVec;
420 SmallVector<FuncMergeInfo> FuncMergeInfos;
421 auto &SFS = FunctionMap->at(Hash);
422 assert(!SFS.empty());
423 auto &RFS = SFS[0];
424
425 // Iterate functions with the same hash.
426 for (auto &[F, FI] : Funcs) {
427 // Check if the function is compatible with any stable function
428 // in terms of the number of instructions and ignored operands.
429 if (RFS->InstCount != FI.IndexInstruction->size())
430 continue;
431
432 auto hasValidSharedConst = [&](StableFunctionMap::StableFunctionEntry *SF,
433 FunctionHashInfo &FHI) {
434 for (auto &[Index, Hash] : *SF->IndexOperandHashMap) {
435 auto [InstIndex, OpndIndex] = Index;
436 assert(InstIndex < FHI.IndexInstruction->size());
437 auto *Inst = FHI.IndexInstruction->lookup(InstIndex);
438 if (!ignoreOp(Inst, OpndIndex))
439 return false;
440 }
441 return true;
442 };
443 if (!hasValidSharedConst(RFS.get(), FI))
444 continue;
445
446 for (auto &SF : SFS) {
447 assert(SF->InstCount == FI.IndexInstruction->size());
448 assert(hasValidSharedConst(SF.get(), FI));
449 // Check if there is any stable function that is compatiable with the
450 // current one.
452 *FI.IndexOperandHashMap))
453 continue;
454 if (!ParamLocsVec.has_value()) {
455 ParamLocsVec = computeParamInfo(SFS);
456 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging hash: " << Hash
457 << " with Params " << ParamLocsVec->size() << "\n");
458 }
459 if (!checkConstLocationCompatible(*SF, *FI.IndexInstruction,
460 *ParamLocsVec))
461 continue;
462
463 // If a stable function matching the current one is found,
464 // create a candidate for merging and proceed to the next function.
465 FuncMergeInfos.emplace_back(SF.get(), F, FI.IndexInstruction.get());
466 break;
467 }
468 }
469 unsigned FuncMergeInfoSize = FuncMergeInfos.size();
470 if (FuncMergeInfoSize == 0)
471 continue;
472
473 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging function count "
474 << FuncMergeInfoSize << " for hash: " << Hash << "\n");
475
476 for (auto &FMI : FuncMergeInfos) {
477 Changed = true;
478
479 // We've already validated all locations of constant operands pointed by
480 // the parameters. Populate parameters pointing to the original constants.
482 SmallVector<Type *> ParamTypes;
483 for (auto &ParamLocs : *ParamLocsVec) {
484 assert(!ParamLocs.empty());
485 auto &[InstIndex, OpndIndex] = ParamLocs[0];
486 auto *Inst = FMI.IndexInstruction->lookup(InstIndex);
487 auto *Opnd = cast<Constant>(Inst->getOperand(OpndIndex));
488 Params.push_back(Opnd);
489 ParamTypes.push_back(Opnd->getType());
490 }
491
492 // Create a merged function derived from the current function.
493 Function *MergedFunc =
494 createMergedFunction(FMI, ParamTypes, *ParamLocsVec);
495
496 LLVM_DEBUG({
497 dbgs() << "[GlobalMergeFunc] Merged function (hash:" << FMI.SF->Hash
498 << ") " << MergedFunc->getName() << " generated from "
499 << FMI.F->getName() << ":\n";
500 MergedFunc->dump();
501 });
502
503 // Transform the current function into a thunk that calls the merged
504 // function.
505 createThunk(FMI, Params, MergedFunc);
506 LLVM_DEBUG({
507 dbgs() << "[GlobalMergeFunc] Thunk generated: \n";
508 FMI.F->dump();
509 });
510 ++NumMergedFunctions;
511 }
512 }
513
514 return Changed;
515}
516
518 // Initialize the local function map regardless of the merger mode.
519 LocalFunctionMap = std::make_unique<StableFunctionMap>();
520
521 // Disable codegen data for merging. The local merge is still enabled.
523 return;
524
525 // (Full)LTO module does not have functions added to the index.
526 // In this case, we run a local merger without using codegen data.
527 if (Index && !Index->hasExportedFunctions(M))
528 return;
529
530 if (cgdata::emitCGData())
534}
535
537 LLVM_DEBUG(dbgs() << "Emit function map. Size: " << LocalFunctionMap->size()
538 << "\n");
539 // No need to emit the function map if it is empty.
540 if (LocalFunctionMap->empty())
541 return;
543 raw_svector_ostream OS(Buf);
544
545 std::vector<CGDataPatchItem> PatchItems;
546 StableFunctionMapRecord::serialize(OS, LocalFunctionMap.get(), PatchItems);
547 CGDataOStream COS(OS);
548 COS.patch(PatchItems);
549
550 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(
551 OS.str(), "in-memory stable function map", false);
552
553 Triple TT(M.getTargetTriple());
554 embedBufferInModule(M, *Buffer,
555 getCodeGenDataSectionName(CG_merge, TT.getObjectFormat()),
556 Align(4));
557}
558
561
562 const StableFunctionMap *FuncMap;
563 if (MergerMode == HashFunctionMode::UsingHashFunction) {
564 // Use the prior CG data to optimistically create global merge candidates.
566 } else {
567 analyze(M);
568 // Emit the local function map to the custom section, __llvm_merge before
569 // finalizing it.
572 LocalFunctionMap->finalize();
573 FuncMap = LocalFunctionMap.get();
574 }
575
576 return merge(M, FuncMap);
577}
578
579namespace {
580
581class GlobalMergeFuncPassWrapper : public ModulePass {
582
583public:
584 static char ID;
585
586 GlobalMergeFuncPassWrapper() : ModulePass(ID) {}
587
588 void getAnalysisUsage(AnalysisUsage &AU) const override {
590 AU.setPreservesAll();
592 }
593
594 StringRef getPassName() const override { return "Global Merge Functions"; }
595
596 bool runOnModule(Module &M) override;
597};
598
599} // namespace
600
601char GlobalMergeFuncPassWrapper::ID = 0;
602INITIALIZE_PASS(GlobalMergeFuncPassWrapper, "global-merge-func",
603 "Global merge function pass", false, false)
604
606 return new GlobalMergeFuncPassWrapper();
607}
608
609bool GlobalMergeFuncPassWrapper::runOnModule(Module &M) {
610 const ModuleSummaryIndex *Index = nullptr;
611 if (auto *IndexWrapperPass =
612 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>())
613 Index = IndexWrapperPass->getIndex();
614
615 return GlobalMergeFunc(Index).run(M);
616}
617
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool checkConstHashCompatible(const DenseMap< IndexPair, stable_hash > &OldInstOpndIndexToConstHash, const DenseMap< IndexPair, stable_hash > &CurrInstOpndIndexToConstHash)
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)
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.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This is the interface to build a ModuleSummaryIndex for a module.
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
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:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
A container for analyses that lazily runs them and caches their results.
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:40
iterator end() const
Definition ArrayRef.h:131
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
iterator begin() const
Definition ArrayRef.h:130
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...
bool isInlineAsm() const
Check if this call is an inline asm statement.
void setCallingConv(CallingConv::ID CC)
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.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Value * getCalledOperand() const
const Use & getCalledOperandUse() const
void setAttributes(AttributeList A)
Set the attributes for this call.
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:178
iterator end()
Definition DenseMap.h:81
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:241
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
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:639
void setSubprogram(DISubprogram *SP)
Set the attached subprogram.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:168
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:211
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Definition Function.h:272
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:354
iterator begin()
Definition Function.h:853
arg_iterator arg_begin()
Definition Function.h:868
Argument * getArg(unsigned i) const
Definition Function.h:886
void setEntryCount(ProfileCount Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Definition Function.cpp:844
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 char MergingInstanceSuffix[]
The suffix used to identify the merged function that parameterizes the constant values.
void setDLLStorageClass(DLLStorageClassTypes C)
void setLinkage(LinkageTypes LT)
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2787
Legacy wrapper pass to provide the ModuleSummaryIndex object.
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:108
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...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition Pass.cpp:112
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
reference emplace_back(ArgTypes &&... Args)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::string str() const
str - Get the contents as an std::string.
Definition StringRef.h:222
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
const Use & getOperandUse(unsigned i) const
Definition User.h:220
Value * getOperand(unsigned i) const
Definition User.h:207
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:553
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:708
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()
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
Changed
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()
bool emitCGData()
const StableFunctionMap * getStableFunctionMap()
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
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:1669
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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...
MapVector< unsigned, Instruction * > IndexInstrMap
A map from an instruction index to an instruction pointer.
LLVM_ABI ModulePass * createGlobalMergeFuncPass()
This pass performs merging similar functions globally.
SmallVector< IndexPairHash > IndexOperandHashVecType
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
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)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
SmallVector< IndexPair, 4 > ParamLocs
std::pair< unsigned, unsigned > IndexPair
The pair of an instruction index and a operand index.
SmallVector< ParamLocs, 8 > ParamLocsVecTy
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:1917
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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:870
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.
SmallVector< std::unique_ptr< StableFunctionEntry > > StableFunctionEntries
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...