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 25 using namespace llvm; 26 using namespace llvm::support; 27 28 static cl::opt<bool> DisableCGDataForMerging( 29 "disable-cgdata-for-merging", cl::Hidden, 30 cl::desc("Disable codegen data for function merging. Local " 31 "merging is still enabled within a module."), 32 cl::init(false)); 33 34 STATISTIC(NumMergedFunctions, 35 "Number of functions that are actually merged using function hash"); 36 STATISTIC(NumAnalyzedModues, "Number of modules that are analyzed"); 37 STATISTIC(NumAnalyzedFunctions, "Number of functions that are analyzed"); 38 STATISTIC(NumEligibleFunctions, "Number of functions that are eligible"); 39 40 /// Returns true if the \OpIdx operand of \p CI is the callee operand. 41 static bool isCalleeOperand(const CallBase *CI, unsigned OpIdx) { 42 return &CI->getCalledOperandUse() == &CI->getOperandUse(OpIdx); 43 } 44 45 static bool canParameterizeCallOperand(const CallBase *CI, unsigned OpIdx) { 46 if (CI->isInlineAsm()) 47 return false; 48 Function *Callee = CI->getCalledOperand() 49 ? dyn_cast_or_null<Function>( 50 CI->getCalledOperand()->stripPointerCasts()) 51 : nullptr; 52 if (Callee) { 53 if (Callee->isIntrinsic()) 54 return false; 55 auto Name = Callee->getName(); 56 // objc_msgSend stubs must be called, and can't have their address taken. 57 if (Name.starts_with("objc_msgSend$")) 58 return false; 59 // Calls to dtrace probes must generate unique patchpoints. 60 if (Name.starts_with("__dtrace")) 61 return false; 62 } 63 if (isCalleeOperand(CI, OpIdx) && 64 CI->getOperandBundle(LLVMContext::OB_ptrauth).has_value()) { 65 // The operand is the callee and it has already been signed. Ignore this 66 // because we cannot add another ptrauth bundle to the call instruction. 67 return false; 68 } 69 return true; 70 } 71 72 /// Returns true if function \p F is eligible for merging. 73 bool isEligibleFunction(Function *F) { 74 if (F->isDeclaration()) 75 return false; 76 77 if (F->hasFnAttribute(llvm::Attribute::NoMerge) || 78 F->hasFnAttribute(llvm::Attribute::AlwaysInline)) 79 return false; 80 81 if (F->hasAvailableExternallyLinkage()) 82 return false; 83 84 if (F->getFunctionType()->isVarArg()) 85 return false; 86 87 if (F->getCallingConv() == CallingConv::SwiftTail) 88 return false; 89 90 // If function contains callsites with musttail, if we merge 91 // it, the merged function will have the musttail callsite, but 92 // the number of parameters can change, thus the parameter count 93 // of the callsite will mismatch with the function itself. 94 for (const BasicBlock &BB : *F) { 95 for (const Instruction &I : BB) { 96 const auto *CB = dyn_cast<CallBase>(&I); 97 if (CB && CB->isMustTailCall()) 98 return false; 99 } 100 } 101 102 return true; 103 } 104 105 static bool isEligibleInstructionForConstantSharing(const Instruction *I) { 106 switch (I->getOpcode()) { 107 case Instruction::Load: 108 case Instruction::Store: 109 case Instruction::Call: 110 case Instruction::Invoke: 111 return true; 112 default: 113 return false; 114 } 115 } 116 117 // This function takes an instruction, \p I, and an operand index, \p OpIdx. 118 // It returns true if the operand should be ignored in the hash computation. 119 // If \p OpIdx is out of range based on the other instruction context, it cannot 120 // be ignored. 121 static bool ignoreOp(const Instruction *I, unsigned OpIdx) { 122 if (OpIdx >= I->getNumOperands()) 123 return false; 124 125 if (!isEligibleInstructionForConstantSharing(I)) 126 return false; 127 128 if (!isa<Constant>(I->getOperand(OpIdx))) 129 return false; 130 131 if (const auto *CI = dyn_cast<CallBase>(I)) 132 return canParameterizeCallOperand(CI, OpIdx); 133 134 return true; 135 } 136 137 static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) { 138 Type *SrcTy = V->getType(); 139 if (SrcTy->isStructTy()) { 140 assert(DestTy->isStructTy()); 141 assert(SrcTy->getStructNumElements() == DestTy->getStructNumElements()); 142 Value *Result = PoisonValue::get(DestTy); 143 for (unsigned int I = 0, E = SrcTy->getStructNumElements(); I < E; ++I) { 144 Value *Element = 145 createCast(Builder, Builder.CreateExtractValue(V, ArrayRef(I)), 146 DestTy->getStructElementType(I)); 147 148 Result = Builder.CreateInsertValue(Result, Element, ArrayRef(I)); 149 } 150 return Result; 151 } 152 assert(!DestTy->isStructTy()); 153 if (auto *SrcAT = dyn_cast<ArrayType>(SrcTy)) { 154 auto *DestAT = dyn_cast<ArrayType>(DestTy); 155 assert(DestAT); 156 assert(SrcAT->getNumElements() == DestAT->getNumElements()); 157 Value *Result = UndefValue::get(DestTy); 158 for (unsigned int I = 0, E = SrcAT->getNumElements(); I < E; ++I) { 159 Value *Element = 160 createCast(Builder, Builder.CreateExtractValue(V, ArrayRef(I)), 161 DestAT->getElementType()); 162 163 Result = Builder.CreateInsertValue(Result, Element, ArrayRef(I)); 164 } 165 return Result; 166 } 167 assert(!DestTy->isArrayTy()); 168 if (SrcTy->isIntegerTy() && DestTy->isPointerTy()) 169 return Builder.CreateIntToPtr(V, DestTy); 170 if (SrcTy->isPointerTy() && DestTy->isIntegerTy()) 171 return Builder.CreatePtrToInt(V, DestTy); 172 return Builder.CreateBitCast(V, DestTy); 173 } 174 175 void GlobalMergeFunc::analyze(Module &M) { 176 ++NumAnalyzedModues; 177 for (Function &Func : M) { 178 ++NumAnalyzedFunctions; 179 if (isEligibleFunction(&Func)) { 180 ++NumEligibleFunctions; 181 182 auto FI = llvm::StructuralHashWithDifferences(Func, ignoreOp); 183 184 // Convert the operand map to a vector for a serialization-friendly 185 // format. 186 IndexOperandHashVecType IndexOperandHashes; 187 for (auto &Pair : *FI.IndexOperandHashMap) 188 IndexOperandHashes.emplace_back(Pair); 189 190 StableFunction SF(FI.FunctionHash, get_stable_name(Func.getName()).str(), 191 M.getModuleIdentifier(), FI.IndexInstruction->size(), 192 std::move(IndexOperandHashes)); 193 194 LocalFunctionMap->insert(SF); 195 } 196 } 197 } 198 199 /// Tuple to hold function info to process merging. 200 struct FuncMergeInfo { 201 StableFunctionMap::StableFunctionEntry *SF; 202 Function *F; 203 IndexInstrMap *IndexInstruction; 204 FuncMergeInfo(StableFunctionMap::StableFunctionEntry *SF, Function *F, 205 IndexInstrMap *IndexInstruction) 206 : SF(SF), F(F), IndexInstruction(std::move(IndexInstruction)) {} 207 }; 208 209 // Given the func info, and the parameterized locations, create and return 210 // a new merged function by replacing the original constants with the new 211 // parameters. 212 static Function *createMergedFunction(FuncMergeInfo &FI, 213 ArrayRef<Type *> ConstParamTypes, 214 const ParamLocsVecTy &ParamLocsVec) { 215 // Synthesize a new merged function name by appending ".Tgm" to the root 216 // function's name. 217 auto *MergedFunc = FI.F; 218 std::string NewFunctionName = 219 MergedFunc->getName().str() + GlobalMergeFunc::MergingInstanceSuffix; 220 auto *M = MergedFunc->getParent(); 221 assert(!M->getFunction(NewFunctionName)); 222 223 FunctionType *OrigTy = MergedFunc->getFunctionType(); 224 // Get the original params' types. 225 SmallVector<Type *> ParamTypes(OrigTy->param_begin(), OrigTy->param_end()); 226 // Append const parameter types that are passed in. 227 ParamTypes.append(ConstParamTypes.begin(), ConstParamTypes.end()); 228 FunctionType *FuncType = FunctionType::get(OrigTy->getReturnType(), 229 ParamTypes, /*isVarArg=*/false); 230 231 // Declare a new function 232 Function *NewFunction = 233 Function::Create(FuncType, MergedFunc->getLinkage(), NewFunctionName); 234 if (auto *SP = MergedFunc->getSubprogram()) 235 NewFunction->setSubprogram(SP); 236 NewFunction->copyAttributesFrom(MergedFunc); 237 NewFunction->setDLLStorageClass(GlobalValue::DefaultStorageClass); 238 239 NewFunction->setLinkage(GlobalValue::InternalLinkage); 240 NewFunction->addFnAttr(Attribute::NoInline); 241 242 // Add the new function before the root function. 243 M->getFunctionList().insert(MergedFunc->getIterator(), NewFunction); 244 245 // Move the body of MergedFunc into the NewFunction. 246 NewFunction->splice(NewFunction->begin(), MergedFunc); 247 248 // Update the original args by the new args. 249 auto NewArgIter = NewFunction->arg_begin(); 250 for (Argument &OrigArg : MergedFunc->args()) { 251 Argument &NewArg = *NewArgIter++; 252 OrigArg.replaceAllUsesWith(&NewArg); 253 } 254 255 // Replace the original Constants by the new args. 256 unsigned NumOrigArgs = MergedFunc->arg_size(); 257 for (unsigned ParamIdx = 0; ParamIdx < ParamLocsVec.size(); ++ParamIdx) { 258 Argument *NewArg = NewFunction->getArg(NumOrigArgs + ParamIdx); 259 for (auto [InstIndex, OpndIndex] : ParamLocsVec[ParamIdx]) { 260 auto *Inst = FI.IndexInstruction->lookup(InstIndex); 261 auto *OrigC = Inst->getOperand(OpndIndex); 262 if (OrigC->getType() != NewArg->getType()) { 263 IRBuilder<> Builder(Inst->getParent(), Inst->getIterator()); 264 Inst->setOperand(OpndIndex, 265 createCast(Builder, NewArg, OrigC->getType())); 266 } else { 267 Inst->setOperand(OpndIndex, NewArg); 268 } 269 } 270 } 271 272 return NewFunction; 273 } 274 275 // Given the original function (Thunk) and the merged function (ToFunc), create 276 // a thunk to the merged function. 277 static void createThunk(FuncMergeInfo &FI, ArrayRef<Constant *> Params, 278 Function *ToFunc) { 279 auto *Thunk = FI.F; 280 281 assert(Thunk->arg_size() + Params.size() == 282 ToFunc->getFunctionType()->getNumParams()); 283 Thunk->dropAllReferences(); 284 285 BasicBlock *BB = BasicBlock::Create(Thunk->getContext(), "", Thunk); 286 IRBuilder<> Builder(BB); 287 288 SmallVector<Value *> Args; 289 unsigned ParamIdx = 0; 290 FunctionType *ToFuncTy = ToFunc->getFunctionType(); 291 292 // Add arguments which are passed through Thunk. 293 for (Argument &AI : Thunk->args()) { 294 Args.push_back(createCast(Builder, &AI, ToFuncTy->getParamType(ParamIdx))); 295 ++ParamIdx; 296 } 297 298 // Add new arguments defined by Params. 299 for (auto *Param : Params) { 300 assert(ParamIdx < ToFuncTy->getNumParams()); 301 Args.push_back( 302 createCast(Builder, Param, ToFuncTy->getParamType(ParamIdx))); 303 ++ParamIdx; 304 } 305 306 CallInst *CI = Builder.CreateCall(ToFunc, Args); 307 bool isSwiftTailCall = ToFunc->getCallingConv() == CallingConv::SwiftTail && 308 Thunk->getCallingConv() == CallingConv::SwiftTail; 309 CI->setTailCallKind(isSwiftTailCall ? llvm::CallInst::TCK_MustTail 310 : llvm::CallInst::TCK_Tail); 311 CI->setCallingConv(ToFunc->getCallingConv()); 312 CI->setAttributes(ToFunc->getAttributes()); 313 if (Thunk->getReturnType()->isVoidTy()) 314 Builder.CreateRetVoid(); 315 else 316 Builder.CreateRet(createCast(Builder, CI, Thunk->getReturnType())); 317 } 318 319 // Check if the old merged/optimized IndexOperandHashMap is compatible with 320 // the current IndexOperandHashMap. An operand hash may not be stable across 321 // different builds due to varying modules combined. To address this, we relax 322 // the hash check condition by comparing Const hash patterns instead of absolute 323 // hash values. For example, let's assume we have three Consts located at idx1, 324 // idx3, and idx6, where their corresponding hashes are hash1, hash2, and hash1 325 // in the old merged map below: 326 // Old (Merged): [(idx1, hash1), (idx3, hash2), (idx6, hash1)] 327 // Current: [(idx1, hash1'), (idx3, hash2'), (idx6, hash1')] 328 // If the current function also has three Consts in the same locations, 329 // with hash sequences hash1', hash2', and hash1' where the first and third 330 // are the same as the old hash sequences, we consider them matched. 331 static bool checkConstHashCompatible( 332 const DenseMap<IndexPair, stable_hash> &OldInstOpndIndexToConstHash, 333 const DenseMap<IndexPair, stable_hash> &CurrInstOpndIndexToConstHash) { 334 335 DenseMap<stable_hash, stable_hash> OldHashToCurrHash; 336 for (const auto &[Index, OldHash] : OldInstOpndIndexToConstHash) { 337 auto It = CurrInstOpndIndexToConstHash.find(Index); 338 if (It == CurrInstOpndIndexToConstHash.end()) 339 return false; 340 341 auto CurrHash = It->second; 342 auto J = OldHashToCurrHash.find(OldHash); 343 if (J == OldHashToCurrHash.end()) 344 OldHashToCurrHash.insert({OldHash, CurrHash}); 345 else if (J->second != CurrHash) 346 return false; 347 } 348 349 return true; 350 } 351 352 // Validate the locations pointed by a param has the same hash and Constant. 353 static bool 354 checkConstLocationCompatible(const StableFunctionMap::StableFunctionEntry &SF, 355 const IndexInstrMap &IndexInstruction, 356 const ParamLocsVecTy &ParamLocsVec) { 357 for (auto &ParamLocs : ParamLocsVec) { 358 std::optional<stable_hash> OldHash; 359 std::optional<Constant *> OldConst; 360 for (auto &Loc : ParamLocs) { 361 assert(SF.IndexOperandHashMap->count(Loc)); 362 auto CurrHash = SF.IndexOperandHashMap.get()->at(Loc); 363 auto [InstIndex, OpndIndex] = Loc; 364 assert(InstIndex < IndexInstruction.size()); 365 const auto *Inst = IndexInstruction.lookup(InstIndex); 366 auto *CurrConst = cast<Constant>(Inst->getOperand(OpndIndex)); 367 if (!OldHash) { 368 OldHash = CurrHash; 369 OldConst = CurrConst; 370 } else if (CurrConst != *OldConst || CurrHash != *OldHash) { 371 return false; 372 } 373 } 374 } 375 return true; 376 } 377 378 static ParamLocsVecTy computeParamInfo( 379 const SmallVector<std::unique_ptr<StableFunctionMap::StableFunctionEntry>> 380 &SFS) { 381 std::map<std::vector<stable_hash>, ParamLocs> HashSeqToLocs; 382 auto &RSF = *SFS[0]; 383 unsigned StableFunctionCount = SFS.size(); 384 385 for (auto &[IndexPair, Hash] : *RSF.IndexOperandHashMap) { 386 // Const hash sequence across stable functions. 387 // We will allocate a parameter per unique hash squence. 388 // can't use SmallVector as key 389 std::vector<stable_hash> ConstHashSeq; 390 ConstHashSeq.push_back(Hash); 391 bool Identical = true; 392 for (unsigned J = 1; J < StableFunctionCount; ++J) { 393 auto &SF = SFS[J]; 394 auto SHash = SF->IndexOperandHashMap->at(IndexPair); 395 if (Hash != SHash) 396 Identical = false; 397 ConstHashSeq.push_back(SHash); 398 } 399 400 if (Identical) 401 continue; 402 403 // For each unique Const hash sequence (parameter), add the locations. 404 HashSeqToLocs[ConstHashSeq].push_back(IndexPair); 405 } 406 407 ParamLocsVecTy ParamLocsVec; 408 for (auto &[HashSeq, Locs] : HashSeqToLocs) { 409 ParamLocsVec.push_back(std::move(Locs)); 410 llvm::sort(ParamLocsVec, [&](const ParamLocs &L, const ParamLocs &R) { 411 return L[0] < R[0]; 412 }); 413 } 414 return ParamLocsVec; 415 } 416 417 bool GlobalMergeFunc::merge(Module &M, const StableFunctionMap *FunctionMap) { 418 bool Changed = false; 419 420 // Collect stable functions related to the current module. 421 DenseMap<stable_hash, SmallVector<std::pair<Function *, FunctionHashInfo>>> 422 HashToFuncs; 423 auto &Maps = FunctionMap->getFunctionMap(); 424 for (auto &F : M) { 425 if (!isEligibleFunction(&F)) 426 continue; 427 auto FI = llvm::StructuralHashWithDifferences(F, ignoreOp); 428 if (Maps.contains(FI.FunctionHash)) 429 HashToFuncs[FI.FunctionHash].emplace_back(&F, std::move(FI)); 430 } 431 432 for (auto &[Hash, Funcs] : HashToFuncs) { 433 std::optional<ParamLocsVecTy> ParamLocsVec; 434 SmallVector<FuncMergeInfo> FuncMergeInfos; 435 auto &SFS = Maps.at(Hash); 436 assert(!SFS.empty()); 437 auto &RFS = SFS[0]; 438 439 // Iterate functions with the same hash. 440 for (auto &[F, FI] : Funcs) { 441 // Check if the function is compatible with any stable function 442 // in terms of the number of instructions and ignored operands. 443 if (RFS->InstCount != FI.IndexInstruction->size()) 444 continue; 445 446 auto hasValidSharedConst = 447 [&](StableFunctionMap::StableFunctionEntry *SF) { 448 for (auto &[Index, Hash] : *SF->IndexOperandHashMap) { 449 auto [InstIndex, OpndIndex] = Index; 450 assert(InstIndex < FI.IndexInstruction->size()); 451 auto *Inst = FI.IndexInstruction->lookup(InstIndex); 452 if (!ignoreOp(Inst, OpndIndex)) 453 return false; 454 } 455 return true; 456 }; 457 if (!hasValidSharedConst(RFS.get())) 458 continue; 459 460 for (auto &SF : SFS) { 461 assert(SF->InstCount == FI.IndexInstruction->size()); 462 assert(hasValidSharedConst(SF.get())); 463 // Check if there is any stable function that is compatiable with the 464 // current one. 465 if (!checkConstHashCompatible(*SF->IndexOperandHashMap, 466 *FI.IndexOperandHashMap)) 467 continue; 468 if (!ParamLocsVec.has_value()) { 469 ParamLocsVec = computeParamInfo(SFS); 470 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging hash: " << Hash 471 << " with Params " << ParamLocsVec->size() << "\n"); 472 } 473 if (!checkConstLocationCompatible(*SF, *FI.IndexInstruction, 474 *ParamLocsVec)) 475 continue; 476 477 // If a stable function matching the current one is found, 478 // create a candidate for merging and proceed to the next function. 479 FuncMergeInfos.emplace_back(SF.get(), F, FI.IndexInstruction.get()); 480 break; 481 } 482 } 483 unsigned FuncMergeInfoSize = FuncMergeInfos.size(); 484 if (FuncMergeInfoSize == 0) 485 continue; 486 487 LLVM_DEBUG(dbgs() << "[GlobalMergeFunc] Merging function count " 488 << FuncMergeInfoSize << " for hash: " << Hash << "\n"); 489 490 for (auto &FMI : FuncMergeInfos) { 491 Changed = true; 492 493 // We've already validated all locations of constant operands pointed by 494 // the parameters. Populate parameters pointing to the original constants. 495 SmallVector<Constant *> Params; 496 SmallVector<Type *> ParamTypes; 497 for (auto &ParamLocs : *ParamLocsVec) { 498 assert(!ParamLocs.empty()); 499 auto &[InstIndex, OpndIndex] = ParamLocs[0]; 500 auto *Inst = FMI.IndexInstruction->lookup(InstIndex); 501 auto *Opnd = cast<Constant>(Inst->getOperand(OpndIndex)); 502 Params.push_back(Opnd); 503 ParamTypes.push_back(Opnd->getType()); 504 } 505 506 // Create a merged function derived from the current function. 507 Function *MergedFunc = 508 createMergedFunction(FMI, ParamTypes, *ParamLocsVec); 509 510 LLVM_DEBUG({ 511 dbgs() << "[GlobalMergeFunc] Merged function (hash:" << FMI.SF->Hash 512 << ") " << MergedFunc->getName() << " generated from " 513 << FMI.F->getName() << ":\n"; 514 MergedFunc->dump(); 515 }); 516 517 // Transform the current function into a thunk that calls the merged 518 // function. 519 createThunk(FMI, Params, MergedFunc); 520 LLVM_DEBUG({ 521 dbgs() << "[GlobalMergeFunc] Thunk generated: \n"; 522 FMI.F->dump(); 523 }); 524 ++NumMergedFunctions; 525 } 526 } 527 528 return Changed; 529 } 530 531 void GlobalMergeFunc::initializeMergerMode(const Module &M) { 532 // Initialize the local function map regardless of the merger mode. 533 LocalFunctionMap = std::make_unique<StableFunctionMap>(); 534 535 // Disable codegen data for merging. The local merge is still enabled. 536 if (DisableCGDataForMerging) 537 return; 538 539 // (Full)LTO module does not have functions added to the index. 540 // In this case, we run a local merger without using codegen data. 541 if (Index && !Index->hasExportedFunctions(M)) 542 return; 543 544 if (cgdata::emitCGData()) 545 MergerMode = HashFunctionMode::BuildingHashFuncion; 546 else if (cgdata::hasStableFunctionMap()) 547 MergerMode = HashFunctionMode::UsingHashFunction; 548 } 549 550 void GlobalMergeFunc::emitFunctionMap(Module &M) { 551 LLVM_DEBUG(dbgs() << "Emit function map. Size: " << LocalFunctionMap->size() 552 << "\n"); 553 // No need to emit the function map if it is empty. 554 if (LocalFunctionMap->empty()) 555 return; 556 SmallVector<char> Buf; 557 raw_svector_ostream OS(Buf); 558 559 StableFunctionMapRecord::serialize(OS, LocalFunctionMap.get()); 560 561 std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer( 562 OS.str(), "in-memory stable function map", false); 563 564 Triple TT(M.getTargetTriple()); 565 embedBufferInModule(M, *Buffer.get(), 566 getCodeGenDataSectionName(CG_merge, TT.getObjectFormat()), 567 Align(4)); 568 } 569 570 bool GlobalMergeFunc::run(Module &M) { 571 initializeMergerMode(M); 572 573 const StableFunctionMap *FuncMap; 574 if (MergerMode == HashFunctionMode::UsingHashFunction) { 575 // Use the prior CG data to optimistically create global merge candidates. 576 FuncMap = cgdata::getStableFunctionMap(); 577 } else { 578 analyze(M); 579 // Emit the local function map to the custom section, __llvm_merge before 580 // finalizing it. 581 if (MergerMode == HashFunctionMode::BuildingHashFuncion) 582 emitFunctionMap(M); 583 LocalFunctionMap->finalize(); 584 FuncMap = LocalFunctionMap.get(); 585 } 586 587 return merge(M, FuncMap); 588 } 589 590 namespace { 591 592 class GlobalMergeFuncPassWrapper : public ModulePass { 593 594 public: 595 static char ID; 596 597 GlobalMergeFuncPassWrapper(); 598 599 void getAnalysisUsage(AnalysisUsage &AU) const override { 600 AU.addUsedIfAvailable<ImmutableModuleSummaryIndexWrapperPass>(); 601 AU.setPreservesAll(); 602 ModulePass::getAnalysisUsage(AU); 603 } 604 605 StringRef getPassName() const override { return "Global Merge Functions"; } 606 607 bool runOnModule(Module &M) override; 608 }; 609 610 } // namespace 611 612 char GlobalMergeFuncPassWrapper::ID = 0; 613 INITIALIZE_PASS_BEGIN(GlobalMergeFuncPassWrapper, "global-merge-func", 614 "Global merge function pass", false, false) 615 INITIALIZE_PASS_END(GlobalMergeFuncPassWrapper, "global-merge-func", 616 "Global merge function pass", false, false) 617 618 namespace llvm { 619 ModulePass *createGlobalMergeFuncPass() { 620 return new GlobalMergeFuncPassWrapper(); 621 } 622 } // namespace llvm 623 624 GlobalMergeFuncPassWrapper::GlobalMergeFuncPassWrapper() : ModulePass(ID) { 625 initializeGlobalMergeFuncPassWrapperPass( 626 *llvm::PassRegistry::getPassRegistry()); 627 } 628 629 bool GlobalMergeFuncPassWrapper::runOnModule(Module &M) { 630 const ModuleSummaryIndex *Index = nullptr; 631 if (auto *IndexWrapperPass = 632 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>()) 633 Index = IndexWrapperPass->getIndex(); 634 635 return GlobalMergeFunc(Index).run(M); 636 } 637 638 PreservedAnalyses GlobalMergeFuncPass::run(Module &M, 639 AnalysisManager<Module> &AM) { 640 ModuleSummaryIndex *Index = &(AM.getResult<ModuleSummaryIndexAnalysis>(M)); 641 bool Changed = GlobalMergeFunc(Index).run(M); 642 return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); 643 } 644