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/IndirectCallPromotionAnalysis.h" 20 #include "llvm/Analysis/LoopInfo.h" 21 #include "llvm/Analysis/ProfileSummaryInfo.h" 22 #include "llvm/IR/CallSite.h" 23 #include "llvm/IR/Dominators.h" 24 #include "llvm/IR/InstIterator.h" 25 #include "llvm/IR/IntrinsicInst.h" 26 #include "llvm/IR/ValueSymbolTable.h" 27 #include "llvm/Pass.h" 28 using namespace llvm; 29 30 #define DEBUG_TYPE "module-summary-analysis" 31 32 // Walk through the operands of a given User via worklist iteration and populate 33 // the set of GlobalValue references encountered. Invoked either on an 34 // Instruction or a GlobalVariable (which walks its initializer). 35 static void findRefEdges(const User *CurUser, DenseSet<const Value *> &RefEdges, 36 SmallPtrSet<const User *, 8> &Visited) { 37 SmallVector<const User *, 32> Worklist; 38 Worklist.push_back(CurUser); 39 40 while (!Worklist.empty()) { 41 const User *U = Worklist.pop_back_val(); 42 43 if (!Visited.insert(U).second) 44 continue; 45 46 ImmutableCallSite CS(U); 47 48 for (const auto &OI : U->operands()) { 49 const User *Operand = dyn_cast<User>(OI); 50 if (!Operand) 51 continue; 52 if (isa<BlockAddress>(Operand)) 53 continue; 54 if (isa<GlobalValue>(Operand)) { 55 // We have a reference to a global value. This should be added to 56 // the reference set unless it is a callee. Callees are handled 57 // specially by WriteFunction and are added to a separate list. 58 if (!(CS && CS.isCallee(&OI))) 59 RefEdges.insert(Operand); 60 continue; 61 } 62 Worklist.push_back(Operand); 63 } 64 } 65 } 66 67 static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount, 68 ProfileSummaryInfo *PSI) { 69 if (!PSI) 70 return CalleeInfo::HotnessType::Unknown; 71 if (PSI->isHotCount(ProfileCount)) 72 return CalleeInfo::HotnessType::Hot; 73 if (PSI->isColdCount(ProfileCount)) 74 return CalleeInfo::HotnessType::Cold; 75 return CalleeInfo::HotnessType::None; 76 } 77 78 static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, 79 const Function &F, BlockFrequencyInfo *BFI, 80 ProfileSummaryInfo *PSI) { 81 // Summary not currently supported for anonymous functions, they must 82 // be renamed. 83 if (!F.hasName()) 84 return; 85 86 unsigned NumInsts = 0; 87 // Map from callee ValueId to profile count. Used to accumulate profile 88 // counts for all static calls to a given callee. 89 DenseMap<const Value *, CalleeInfo> CallGraphEdges; 90 DenseMap<GlobalValue::GUID, CalleeInfo> IndirectCallEdges; 91 DenseSet<const Value *> RefEdges; 92 ICallPromotionAnalysis ICallAnalysis; 93 94 SmallPtrSet<const User *, 8> Visited; 95 for (const BasicBlock &BB : F) 96 for (const Instruction &I : BB) { 97 if (isa<DbgInfoIntrinsic>(I)) 98 continue; 99 ++NumInsts; 100 findRefEdges(&I, RefEdges, Visited); 101 auto CS = ImmutableCallSite(&I); 102 if (!CS) 103 continue; 104 auto *CalledValue = CS.getCalledValue(); 105 auto *CalledFunction = CS.getCalledFunction(); 106 // Check if this is an alias to a function. If so, get the 107 // called aliasee for the checks below. 108 if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) { 109 assert(!CalledFunction && "Expected null called function in callsite for alias"); 110 CalledFunction = dyn_cast<Function>(GA->getBaseObject()); 111 } 112 // Check if this is a direct call to a known function. 113 if (CalledFunction) { 114 // Skip nameless and intrinsics. 115 if (!CalledFunction->hasName() || CalledFunction->isIntrinsic()) 116 continue; 117 auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None; 118 // Use the original CalledValue, in case it was an alias. We want 119 // to record the call edge to the alias in that case. Eventually 120 // an alias summary will be created to associate the alias and 121 // aliasee. 122 auto *CalleeId = 123 M.getValueSymbolTable().lookup(CalledValue->getName()); 124 125 auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI) 126 : CalleeInfo::HotnessType::Unknown; 127 CallGraphEdges[CalleeId].updateHotness(Hotness); 128 } else { 129 const auto *CI = dyn_cast<CallInst>(&I); 130 // Skip inline assembly calls. 131 if (CI && CI->isInlineAsm()) 132 continue; 133 // Skip direct calls. 134 if (!CS.getCalledValue() || isa<Constant>(CS.getCalledValue())) 135 continue; 136 137 uint32_t NumVals, NumCandidates; 138 uint64_t TotalCount; 139 auto CandidateProfileData = 140 ICallAnalysis.getPromotionCandidatesForInstruction( 141 &I, NumVals, TotalCount, NumCandidates); 142 for (auto &Candidate : CandidateProfileData) 143 IndirectCallEdges[Candidate.Value].updateHotness( 144 getHotness(Candidate.Count, PSI)); 145 } 146 } 147 148 GlobalValueSummary::GVFlags Flags(F); 149 std::unique_ptr<FunctionSummary> FuncSummary = 150 llvm::make_unique<FunctionSummary>(Flags, NumInsts); 151 FuncSummary->addCallGraphEdges(CallGraphEdges); 152 FuncSummary->addCallGraphEdges(IndirectCallEdges); 153 FuncSummary->addRefEdges(RefEdges); 154 Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary)); 155 } 156 157 static void computeVariableSummary(ModuleSummaryIndex &Index, 158 const GlobalVariable &V) { 159 DenseSet<const Value *> RefEdges; 160 SmallPtrSet<const User *, 8> Visited; 161 findRefEdges(&V, RefEdges, Visited); 162 GlobalValueSummary::GVFlags Flags(V); 163 std::unique_ptr<GlobalVarSummary> GVarSummary = 164 llvm::make_unique<GlobalVarSummary>(Flags); 165 GVarSummary->addRefEdges(RefEdges); 166 Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary)); 167 } 168 169 ModuleSummaryIndex llvm::buildModuleSummaryIndex( 170 const Module &M, 171 std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback, 172 ProfileSummaryInfo *PSI) { 173 ModuleSummaryIndex Index; 174 // Check if the module can be promoted, otherwise just disable importing from 175 // it by not emitting any summary. 176 // FIXME: we could still import *into* it most of the time. 177 if (!moduleCanBeRenamedForThinLTO(M)) 178 return Index; 179 180 // Compute summaries for all functions defined in module, and save in the 181 // index. 182 for (auto &F : M) { 183 if (F.isDeclaration()) 184 continue; 185 186 BlockFrequencyInfo *BFI = nullptr; 187 std::unique_ptr<BlockFrequencyInfo> BFIPtr; 188 if (GetBFICallback) 189 BFI = GetBFICallback(F); 190 else if (F.getEntryCount().hasValue()) { 191 LoopInfo LI{DominatorTree(const_cast<Function &>(F))}; 192 BranchProbabilityInfo BPI{F, LI}; 193 BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI); 194 BFI = BFIPtr.get(); 195 } 196 197 computeFunctionSummary(Index, M, F, BFI, PSI); 198 } 199 200 // Compute summaries for all variables defined in module, and save in the 201 // index. 202 for (const GlobalVariable &G : M.globals()) { 203 if (G.isDeclaration()) 204 continue; 205 computeVariableSummary(Index, G); 206 } 207 return Index; 208 } 209 210 char ModuleSummaryIndexAnalysis::PassID; 211 212 ModuleSummaryIndex 213 ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) { 214 ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M); 215 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 216 return buildModuleSummaryIndex( 217 M, 218 [&FAM](const Function &F) { 219 return &FAM.getResult<BlockFrequencyAnalysis>( 220 *const_cast<Function *>(&F)); 221 }, 222 &PSI); 223 } 224 225 char ModuleSummaryIndexWrapperPass::ID = 0; 226 INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 227 "Module Summary Analysis", false, true) 228 INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) 229 INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis", 230 "Module Summary Analysis", false, true) 231 232 ModulePass *llvm::createModuleSummaryIndexWrapperPass() { 233 return new ModuleSummaryIndexWrapperPass(); 234 } 235 236 ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass() 237 : ModulePass(ID) { 238 initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry()); 239 } 240 241 bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { 242 auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); 243 Index = buildModuleSummaryIndex( 244 M, 245 [this](const Function &F) { 246 return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>( 247 *const_cast<Function *>(&F)) 248 .getBFI()); 249 }, 250 &PSI); 251 return false; 252 } 253 254 bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) { 255 Index.reset(); 256 return false; 257 } 258 259 void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { 260 AU.setPreservesAll(); 261 AU.addRequired<BlockFrequencyInfoWrapperPass>(); 262 AU.addRequired<ProfileSummaryInfoWrapperPass>(); 263 } 264 265 bool llvm::moduleCanBeRenamedForThinLTO(const Module &M) { 266 // We cannot currently promote or rename anything used in inline assembly, 267 // which are not visible to the compiler. Detect a possible case by looking 268 // for a llvm.used local value, in conjunction with an inline assembly call 269 // in the module. Prevent importing of any modules containing these uses by 270 // suppressing generation of the index. This also prevents importing 271 // into this module, which is also necessary to avoid needing to rename 272 // in case of a name clash between a local in this module and an imported 273 // global. 274 // FIXME: If we find we need a finer-grained approach of preventing promotion 275 // and renaming of just the functions using inline assembly we will need to: 276 // - Add flag in the function summaries to identify those with inline asm. 277 // - Prevent importing of any functions with flag set. 278 // - Prevent importing of any global function with the same name as a 279 // function in current module that has the flag set. 280 // - For any llvm.used value that is exported and promoted, add a private 281 // alias to the original name in the current module (even if we don't 282 // export the function using those values in inline asm, another function 283 // with a reference could be exported). 284 SmallPtrSet<GlobalValue *, 8> Used; 285 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 286 bool LocalIsUsed = 287 any_of(Used, [](GlobalValue *V) { return V->hasLocalLinkage(); }); 288 if (!LocalIsUsed) 289 return true; 290 291 // Walk all the instructions in the module and find if one is inline ASM 292 auto HasInlineAsm = any_of(M, [](const Function &F) { 293 return any_of(instructions(F), [](const Instruction &I) { 294 const CallInst *CallI = dyn_cast<CallInst>(&I); 295 if (!CallI) 296 return false; 297 return CallI->isInlineAsm(); 298 }); 299 }); 300 return !HasInlineAsm; 301 } 302