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 // Check if the module can be promoted, otherwise just disable importing from 124 // it by not emitting any summary. 125 // FIXME: we could still import *into* it most of the time. 126 if (!moduleCanBeRenamedForThinLTO(*M)) 127 return; 128 129 // Compute summaries for all functions defined in module, and save in the 130 // index. 131 for (auto &F : *M) { 132 if (F.isDeclaration()) 133 continue; 134 135 BlockFrequencyInfo *BFI = nullptr; 136 std::unique_ptr<BlockFrequencyInfo> BFIPtr; 137 if (Ftor) 138 BFI = Ftor(F); 139 else if (F.getEntryCount().hasValue()) { 140 LoopInfo LI{DominatorTree(const_cast<Function &>(F))}; 141 BranchProbabilityInfo BPI{F, LI}; 142 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI); 143 BFI = BFIPtr.get(); 144 } 145 146 computeFunctionSummary(F, BFI); 147 } 148 149 // Compute summaries for all variables defined in module, and save in the 150 // index. 151 for (const GlobalVariable &G : M->globals()) { 152 if (G.isDeclaration()) 153 continue; 154 computeVariableSummary(G); 155 } 156 } 157 158 char ModuleSummaryIndexWrapperPass::ID = 0; 159 INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 160 "Module Summary Analysis", false, true) 161 INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) 162 INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 163 "Module Summary Analysis", false, true) 164 165 ModulePass *llvm::createModuleSummaryIndexWrapperPass() { 166 return new ModuleSummaryIndexWrapperPass(); 167 } 168 169 ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass() 170 : ModulePass(ID) { 171 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry()); 172 } 173 174 bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { 175 IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>( 176 &M, [this](const Function &F) { 177 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>( 178 *const_cast<Function *>(&F)) 179 .getBFI()); 180 }); 181 return false; 182 } 183 184 bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) { 185 IndexBuilder.reset(); 186 return false; 187 } 188 189 void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { 190 AU.setPreservesAll(); 191 AU.addRequired<BlockFrequencyInfoWrapperPass>(); 192 } 193 194 bool llvm::moduleCanBeRenamedForThinLTO(const Module &M) { 195 // We cannot currently promote or rename anything used in inline assembly, 196 // which are not visible to the compiler. Detect a possible case by looking 197 // for a llvm.used local value, in conjunction with an inline assembly call 198 // in the module. Prevent importing of any modules containing these uses by 199 // suppressing generation of the index. This also prevents importing 200 // into this module, which is also necessary to avoid needing to rename 201 // in case of a name clash between a local in this module and an imported 202 // global. 203 // FIXME: If we find we need a finer-grained approach of preventing promotion 204 // and renaming of just the functions using inline assembly we will need to: 205 // - Add flag in the function summaries to identify those with inline asm. 206 // - Prevent importing of any functions with flag set. 207 // - Prevent importing of any global function with the same name as a 208 // function in current module that has the flag set. 209 // - For any llvm.used value that is exported and promoted, add a private 210 // alias to the original name in the current module (even if we don't 211 // export the function using those values in inline asm, another function 212 // with a reference could be exported). 213 SmallPtrSet<GlobalValue *, 8> Used; 214 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 215 bool LocalIsUsed = 216 llvm::any_of(Used, [](GlobalValue *V) { return V->hasLocalLinkage(); }); 217 if (!LocalIsUsed) 218 return true; 219 220 // Walk all the instructions in the module and find if one is inline ASM 221 auto HasInlineAsm = llvm::any_of(M, [](const Function &F) { 222 return llvm::any_of(instructions(F), [](const Instruction &I) { 223 const CallInst *CallI = dyn_cast<CallInst>(&I); 224 if (!CallI) 225 return false; 226 return CallI->isInlineAsm(); 227 }); 228 }); 229 return !HasInlineAsm; 230 } 231