1 //===- ModuleSummaryAnalysis.cpp - Module summary index builder -----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass builds a ModuleSummaryIndex object for the module, to be written 11 // to bitcode or LLVM assembly. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Analysis/ModuleSummaryAnalysis.h" 16 #include "llvm/Analysis/BlockFrequencyInfo.h" 17 #include "llvm/Analysis/BlockFrequencyInfoImpl.h" 18 #include "llvm/Analysis/BranchProbabilityInfo.h" 19 #include "llvm/Analysis/LoopInfo.h" 20 #include "llvm/IR/CallSite.h" 21 #include "llvm/IR/Dominators.h" 22 #include "llvm/IR/InstIterator.h" 23 #include "llvm/IR/IntrinsicInst.h" 24 #include "llvm/IR/ValueSymbolTable.h" 25 #include "llvm/Pass.h" 26 using namespace llvm; 27 28 #define DEBUG_TYPE "module-summary-analysis" 29 30 // Walk through the operands of a given User via worklist iteration and populate 31 // the set of GlobalValue references encountered. Invoked either on an 32 // Instruction or a GlobalVariable (which walks its initializer). 33 static void findRefEdges(const User *CurUser, DenseSet<const Value *> &RefEdges, 34 SmallPtrSet<const User *, 8> &Visited) { 35 SmallVector<const User *, 32> Worklist; 36 Worklist.push_back(CurUser); 37 38 while (!Worklist.empty()) { 39 const User *U = Worklist.pop_back_val(); 40 41 if (!Visited.insert(U).second) 42 continue; 43 44 ImmutableCallSite CS(U); 45 46 for (const auto &OI : U->operands()) { 47 const User *Operand = dyn_cast<User>(OI); 48 if (!Operand) 49 continue; 50 if (isa<BlockAddress>(Operand)) 51 continue; 52 if (isa<GlobalValue>(Operand)) { 53 // We have a reference to a global value. This should be added to 54 // the reference set unless it is a callee. Callees are handled 55 // specially by WriteFunction and are added to a separate list. 56 if (!(CS && CS.isCallee(&OI))) 57 RefEdges.insert(Operand); 58 continue; 59 } 60 Worklist.push_back(Operand); 61 } 62 } 63 } 64 65 void ModuleSummaryIndexBuilder::computeFunctionSummary( 66 const Function &F, BlockFrequencyInfo *BFI) { 67 // Summary not currently supported for anonymous functions, they must 68 // be renamed. 69 if (!F.hasName()) 70 return; 71 72 unsigned NumInsts = 0; 73 // Map from callee ValueId to profile count. Used to accumulate profile 74 // counts for all static calls to a given callee. 75 DenseMap<const Value *, CalleeInfo> CallGraphEdges; 76 DenseSet<const Value *> RefEdges; 77 78 SmallPtrSet<const User *, 8> Visited; 79 for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) 80 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; 81 ++I) { 82 if (!isa<DbgInfoIntrinsic>(I)) 83 ++NumInsts; 84 85 if (auto CS = ImmutableCallSite(&*I)) { 86 auto *CalledFunction = CS.getCalledFunction(); 87 if (CalledFunction && CalledFunction->hasName() && 88 !CalledFunction->isIntrinsic()) { 89 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&*BB) : None; 90 auto *CalleeId = 91 M->getValueSymbolTable().lookup(CalledFunction->getName()); 92 CallGraphEdges[CalleeId] += 93 (ScaledCount ? ScaledCount.getValue() : 0); 94 } 95 } 96 findRefEdges(&*I, RefEdges, Visited); 97 } 98 99 GlobalValueSummary::GVFlags Flags(F); 100 std::unique_ptr<FunctionSummary> FuncSummary = 101 llvm::make_unique<FunctionSummary>(Flags, NumInsts); 102 FuncSummary->addCallGraphEdges(CallGraphEdges); 103 FuncSummary->addRefEdges(RefEdges); 104 Index->addGlobalValueSummary(F.getName(), std::move(FuncSummary)); 105 } 106 107 void ModuleSummaryIndexBuilder::computeVariableSummary( 108 const GlobalVariable &V) { 109 DenseSet<const Value *> RefEdges; 110 SmallPtrSet<const User *, 8> Visited; 111 findRefEdges(&V, RefEdges, Visited); 112 GlobalValueSummary::GVFlags Flags(V); 113 std::unique_ptr<GlobalVarSummary> GVarSummary = 114 llvm::make_unique<GlobalVarSummary>(Flags); 115 GVarSummary->addRefEdges(RefEdges); 116 Index->addGlobalValueSummary(V.getName(), std::move(GVarSummary)); 117 } 118 119 ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder( 120 const Module *M, 121 std::function<BlockFrequencyInfo *(const Function &F)> Ftor) 122 : Index(llvm::make_unique<ModuleSummaryIndex>()), M(M) { 123 // We cannot currently promote or rename anything used in inline assembly, 124 // which are not visible to the compiler. Detect a possible case by looking 125 // for a llvm.used local value, in conjunction with an inline assembly call 126 // in the module. Prevent importing of any modules containing these uses by 127 // suppressing generation of the index. This also prevents importing 128 // into this module, which is also necessary to avoid needing to rename 129 // in case of a name clash between a local in this module and an imported 130 // global. 131 // FIXME: If we find we need a finer-grained approach of preventing promotion 132 // and renaming of just the functions using inline assembly we will need to: 133 // - Add flag in the function summaries to identify those with inline asm. 134 // - Prevent importing of any functions with flag set. 135 // - Prevent importing of any global function with the same name as a 136 // function in current module that has the flag set. 137 // - For any llvm.used value that is exported and promoted, add a private 138 // alias to the original name in the current module (even if we don't 139 // export the function using those values in inline asm, another function 140 // with a reference could be exported). 141 SmallPtrSet<GlobalValue *, 8> Used; 142 collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false); 143 bool LocalIsUsed = false; 144 for (GlobalValue *V : Used) { 145 if ((LocalIsUsed |= V->hasLocalLinkage())) 146 break; 147 } 148 if (LocalIsUsed) 149 for (auto &F : *M) 150 for (auto &I : instructions(F)) 151 if (const CallInst *CallI = dyn_cast<CallInst>(&I)) 152 if (CallI->isInlineAsm()) 153 return; 154 155 // Compute summaries for all functions defined in module, and save in the 156 // index. 157 for (auto &F : *M) { 158 if (F.isDeclaration()) 159 continue; 160 161 BlockFrequencyInfo *BFI = nullptr; 162 std::unique_ptr<BlockFrequencyInfo> BFIPtr; 163 if (Ftor) 164 BFI = Ftor(F); 165 else if (F.getEntryCount().hasValue()) { 166 LoopInfo LI{DominatorTree(const_cast<Function &>(F))}; 167 BranchProbabilityInfo BPI{F, LI}; 168 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI); 169 BFI = BFIPtr.get(); 170 } 171 172 computeFunctionSummary(F, BFI); 173 } 174 175 // Compute summaries for all variables defined in module, and save in the 176 // index. 177 for (const GlobalVariable &G : M->globals()) { 178 if (G.isDeclaration()) 179 continue; 180 computeVariableSummary(G); 181 } 182 } 183 184 char ModuleSummaryIndexWrapperPass::ID = 0; 185 INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 186 "Module Summary Analysis", false, true) 187 INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) 188 INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 189 "Module Summary Analysis", false, true) 190 191 ModulePass *llvm::createModuleSummaryIndexWrapperPass() { 192 return new ModuleSummaryIndexWrapperPass(); 193 } 194 195 ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass() 196 : ModulePass(ID) { 197 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry()); 198 } 199 200 bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { 201 IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>( 202 &M, [this](const Function &F) { 203 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>( 204 *const_cast<Function *>(&F)) 205 .getBFI()); 206 }); 207 return false; 208 } 209 210 bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) { 211 IndexBuilder.reset(); 212 return false; 213 } 214 215 void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { 216 AU.setPreservesAll(); 217 AU.addRequired<BlockFrequencyInfoWrapperPass>(); 218 } 219