LCOV - code coverage report
Current view: top level - lib/Analysis - ModuleSummaryAnalysis.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 192 198 97.0 %
Date: 2018-09-23 13:06:45 Functions: 17 18 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       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/ADT/ArrayRef.h"
      17             : #include "llvm/ADT/DenseSet.h"
      18             : #include "llvm/ADT/MapVector.h"
      19             : #include "llvm/ADT/STLExtras.h"
      20             : #include "llvm/ADT/SetVector.h"
      21             : #include "llvm/ADT/SmallPtrSet.h"
      22             : #include "llvm/ADT/SmallVector.h"
      23             : #include "llvm/ADT/StringRef.h"
      24             : #include "llvm/Analysis/BlockFrequencyInfo.h"
      25             : #include "llvm/Analysis/BranchProbabilityInfo.h"
      26             : #include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
      27             : #include "llvm/Analysis/LoopInfo.h"
      28             : #include "llvm/Analysis/ProfileSummaryInfo.h"
      29             : #include "llvm/Analysis/TypeMetadataUtils.h"
      30             : #include "llvm/IR/Attributes.h"
      31             : #include "llvm/IR/BasicBlock.h"
      32             : #include "llvm/IR/CallSite.h"
      33             : #include "llvm/IR/Constant.h"
      34             : #include "llvm/IR/Constants.h"
      35             : #include "llvm/IR/Dominators.h"
      36             : #include "llvm/IR/Function.h"
      37             : #include "llvm/IR/GlobalAlias.h"
      38             : #include "llvm/IR/GlobalValue.h"
      39             : #include "llvm/IR/GlobalVariable.h"
      40             : #include "llvm/IR/Instructions.h"
      41             : #include "llvm/IR/IntrinsicInst.h"
      42             : #include "llvm/IR/Intrinsics.h"
      43             : #include "llvm/IR/Metadata.h"
      44             : #include "llvm/IR/Module.h"
      45             : #include "llvm/IR/ModuleSummaryIndex.h"
      46             : #include "llvm/IR/Use.h"
      47             : #include "llvm/IR/User.h"
      48             : #include "llvm/Object/ModuleSymbolTable.h"
      49             : #include "llvm/Object/SymbolicFile.h"
      50             : #include "llvm/Pass.h"
      51             : #include "llvm/Support/Casting.h"
      52             : #include "llvm/Support/CommandLine.h"
      53             : #include <algorithm>
      54             : #include <cassert>
      55             : #include <cstdint>
      56             : #include <vector>
      57             : 
      58             : using namespace llvm;
      59             : 
      60             : #define DEBUG_TYPE "module-summary-analysis"
      61             : 
      62             : // Option to force edges cold which will block importing when the
      63             : // -import-cold-multiplier is set to 0. Useful for debugging.
      64             : FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold =
      65             :     FunctionSummary::FSHT_None;
      66             : cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
      67             :     "force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold),
      68             :     cl::desc("Force all edges in the function summary to cold"),
      69             :     cl::values(clEnumValN(FunctionSummary::FSHT_None, "none", "None."),
      70             :                clEnumValN(FunctionSummary::FSHT_AllNonCritical,
      71             :                           "all-non-critical", "All non-critical edges."),
      72             :                clEnumValN(FunctionSummary::FSHT_All, "all", "All edges.")));
      73             : 
      74             : // Walk through the operands of a given User via worklist iteration and populate
      75             : // the set of GlobalValue references encountered. Invoked either on an
      76             : // Instruction or a GlobalVariable (which walks its initializer).
      77        2218 : static void findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
      78             :                          SetVector<ValueInfo> &RefEdges,
      79             :                          SmallPtrSet<const User *, 8> &Visited) {
      80             :   SmallVector<const User *, 32> Worklist;
      81        2218 :   Worklist.push_back(CurUser);
      82             : 
      83        5444 :   while (!Worklist.empty()) {
      84             :     const User *U = Worklist.pop_back_val();
      85             : 
      86        3226 :     if (!Visited.insert(U).second)
      87             :       continue;
      88             : 
      89             :     ImmutableCallSite CS(U);
      90             : 
      91        4658 :     for (const auto &OI : U->operands()) {
      92        1870 :       const User *Operand = dyn_cast<User>(OI);
      93        1870 :       if (!Operand)
      94         862 :         continue;
      95        1611 :       if (isa<BlockAddress>(Operand))
      96             :         continue;
      97             :       if (auto *GV = dyn_cast<GlobalValue>(Operand)) {
      98             :         // We have a reference to a global value. This should be added to
      99             :         // the reference set unless it is a callee. Callees are handled
     100             :         // specially by WriteFunction and are added to a separate list.
     101        1004 :         if (!(CS && CS.isCallee(&OI)))
     102         205 :           RefEdges.insert(Index.getOrInsertValueInfo(GV));
     103         603 :         continue;
     104             :       }
     105        1008 :       Worklist.push_back(Operand);
     106             :     }
     107             :   }
     108        2218 : }
     109             : 
     110          45 : static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount,
     111             :                                           ProfileSummaryInfo *PSI) {
     112          45 :   if (!PSI)
     113             :     return CalleeInfo::HotnessType::Unknown;
     114          45 :   if (PSI->isHotCount(ProfileCount))
     115             :     return CalleeInfo::HotnessType::Hot;
     116          25 :   if (PSI->isColdCount(ProfileCount))
     117          13 :     return CalleeInfo::HotnessType::Cold;
     118             :   return CalleeInfo::HotnessType::None;
     119             : }
     120             : 
     121         913 : static bool isNonRenamableLocal(const GlobalValue &GV) {
     122         913 :   return GV.hasSection() && GV.hasLocalLinkage();
     123             : }
     124             : 
     125             : /// Determine whether this call has all constant integer arguments (excluding
     126             : /// "this") and summarize it to VCalls or ConstVCalls as appropriate.
     127          16 : static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid,
     128             :                           SetVector<FunctionSummary::VFuncId> &VCalls,
     129             :                           SetVector<FunctionSummary::ConstVCall> &ConstVCalls) {
     130             :   std::vector<uint64_t> Args;
     131             :   // Start from the second argument to skip the "this" pointer.
     132          35 :   for (auto &Arg : make_range(Call.CS.arg_begin() + 1, Call.CS.arg_end())) {
     133             :     auto *CI = dyn_cast<ConstantInt>(Arg);
     134           4 :     if (!CI || CI->getBitWidth() > 64) {
     135          12 :       VCalls.insert({Guid, Call.Offset});
     136             :       return;
     137             :     }
     138           3 :     Args.push_back(CI->getZExtValue());
     139             :   }
     140          12 :   ConstVCalls.insert({{Guid, Call.Offset}, std::move(Args)});
     141             : }
     142             : 
     143             : /// If this intrinsic call requires that we add information to the function
     144             : /// summary, do so via the non-constant reference arguments.
     145          80 : static void addIntrinsicToSummary(
     146             :     const CallInst *CI, SetVector<GlobalValue::GUID> &TypeTests,
     147             :     SetVector<FunctionSummary::VFuncId> &TypeTestAssumeVCalls,
     148             :     SetVector<FunctionSummary::VFuncId> &TypeCheckedLoadVCalls,
     149             :     SetVector<FunctionSummary::ConstVCall> &TypeTestAssumeConstVCalls,
     150             :     SetVector<FunctionSummary::ConstVCall> &TypeCheckedLoadConstVCalls) {
     151          80 :   switch (CI->getCalledFunction()->getIntrinsicID()) {
     152          37 :   case Intrinsic::type_test: {
     153          37 :     auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
     154          37 :     auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
     155             :     if (!TypeId)
     156             :       break;
     157          72 :     GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
     158             : 
     159             :     // Produce a summary from type.test intrinsics. We only summarize type.test
     160             :     // intrinsics that are used other than by an llvm.assume intrinsic.
     161             :     // Intrinsics that are assumed are relevant only to the devirtualization
     162             :     // pass, not the type test lowering pass.
     163             :     bool HasNonAssumeUses = llvm::any_of(CI->uses(), [](const Use &CIU) {
     164             :       auto *AssumeCI = dyn_cast<CallInst>(CIU.getUser());
     165             :       if (!AssumeCI)
     166             :         return true;
     167             :       Function *F = AssumeCI->getCalledFunction();
     168             :       return !F || F->getIntrinsicID() != Intrinsic::assume;
     169             :     });
     170          36 :     if (HasNonAssumeUses)
     171          25 :       TypeTests.insert(Guid);
     172             : 
     173             :     SmallVector<DevirtCallSite, 4> DevirtCalls;
     174             :     SmallVector<CallInst *, 4> Assumes;
     175          36 :     findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI);
     176          42 :     for (auto &Call : DevirtCalls)
     177           6 :       addVCallToSet(Call, Guid, TypeTestAssumeVCalls,
     178             :                     TypeTestAssumeConstVCalls);
     179             : 
     180             :     break;
     181             :   }
     182             : 
     183          13 :   case Intrinsic::type_checked_load: {
     184          13 :     auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(2));
     185          13 :     auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
     186             :     if (!TypeId)
     187             :       break;
     188          24 :     GlobalValue::GUID Guid = GlobalValue::getGUID(TypeId->getString());
     189             : 
     190             :     SmallVector<DevirtCallSite, 4> DevirtCalls;
     191             :     SmallVector<Instruction *, 4> LoadedPtrs;
     192             :     SmallVector<Instruction *, 4> Preds;
     193          12 :     bool HasNonCallUses = false;
     194          12 :     findDevirtualizableCallsForTypeCheckedLoad(DevirtCalls, LoadedPtrs, Preds,
     195             :                                                HasNonCallUses, CI);
     196             :     // Any non-call uses of the result of llvm.type.checked.load will
     197             :     // prevent us from optimizing away the llvm.type.test.
     198          12 :     if (HasNonCallUses)
     199           1 :       TypeTests.insert(Guid);
     200          22 :     for (auto &Call : DevirtCalls)
     201          10 :       addVCallToSet(Call, Guid, TypeCheckedLoadVCalls,
     202             :                     TypeCheckedLoadConstVCalls);
     203             : 
     204             :     break;
     205             :   }
     206             :   default:
     207             :     break;
     208             :   }
     209          80 : }
     210             : 
     211             : static void
     212         626 : computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
     213             :                        const Function &F, BlockFrequencyInfo *BFI,
     214             :                        ProfileSummaryInfo *PSI, bool HasLocalsInUsedOrAsm,
     215             :                        DenseSet<GlobalValue::GUID> &CantBePromoted) {
     216             :   // Summary not currently supported for anonymous functions, they should
     217             :   // have been named.
     218             :   assert(F.hasName());
     219             : 
     220         626 :   unsigned NumInsts = 0;
     221             :   // Map from callee ValueId to profile count. Used to accumulate profile
     222             :   // counts for all static calls to a given callee.
     223         626 :   MapVector<ValueInfo, CalleeInfo> CallGraphEdges;
     224         626 :   SetVector<ValueInfo> RefEdges;
     225         626 :   SetVector<GlobalValue::GUID> TypeTests;
     226         626 :   SetVector<FunctionSummary::VFuncId> TypeTestAssumeVCalls,
     227         626 :       TypeCheckedLoadVCalls;
     228         626 :   SetVector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls,
     229         626 :       TypeCheckedLoadConstVCalls;
     230         626 :   ICallPromotionAnalysis ICallAnalysis;
     231             :   SmallPtrSet<const User *, 8> Visited;
     232             : 
     233             :   // Add personality function, prefix data and prologue data to function's ref
     234             :   // list.
     235         626 :   findRefEdges(Index, &F, RefEdges, Visited);
     236             : 
     237             :   bool HasInlineAsmMaybeReferencingInternal = false;
     238        1314 :   for (const BasicBlock &BB : F)
     239        2129 :     for (const Instruction &I : BB) {
     240             :       if (isa<DbgInfoIntrinsic>(I))
     241             :         continue;
     242        1436 :       ++NumInsts;
     243        1436 :       findRefEdges(Index, &I, RefEdges, Visited);
     244             :       auto CS = ImmutableCallSite(&I);
     245        1436 :       if (!CS)
     246             :         continue;
     247             : 
     248             :       const auto *CI = dyn_cast<CallInst>(&I);
     249             :       // Since we don't know exactly which local values are referenced in inline
     250             :       // assembly, conservatively mark the function as possibly referencing
     251             :       // a local value from inline assembly to ensure we don't export a
     252             :       // reference (which would require renaming and promotion of the
     253             :       // referenced value).
     254         435 :       if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm())
     255             :         HasInlineAsmMaybeReferencingInternal = true;
     256             : 
     257             :       auto *CalledValue = CS.getCalledValue();
     258             :       auto *CalledFunction = CS.getCalledFunction();
     259         435 :       if (CalledValue && !CalledFunction) {
     260          41 :         CalledValue = CalledValue->stripPointerCastsNoFollowAliases();
     261             :         // Stripping pointer casts can reveal a called function.
     262             :         CalledFunction = dyn_cast<Function>(CalledValue);
     263             :       }
     264             :       // Check if this is an alias to a function. If so, get the
     265             :       // called aliasee for the checks below.
     266             :       if (auto *GA = dyn_cast<GlobalAlias>(CalledValue)) {
     267             :         assert(!CalledFunction && "Expected null called function in callsite for alias");
     268           5 :         CalledFunction = dyn_cast<Function>(GA->getBaseObject());
     269             :       }
     270             :       // Check if this is a direct call to a known function or a known
     271             :       // intrinsic, or an indirect call with profile data.
     272         435 :       if (CalledFunction) {
     273         401 :         if (CI && CalledFunction->isIntrinsic()) {
     274          80 :           addIntrinsicToSummary(
     275             :               CI, TypeTests, TypeTestAssumeVCalls, TypeCheckedLoadVCalls,
     276             :               TypeTestAssumeConstVCalls, TypeCheckedLoadConstVCalls);
     277          80 :           continue;
     278             :         }
     279             :         // We should have named any anonymous globals
     280             :         assert(CalledFunction->hasName());
     281         321 :         auto ScaledCount = PSI->getProfileCount(&I, BFI);
     282          38 :         auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI)
     283         321 :                                    : CalleeInfo::HotnessType::Unknown;
     284         321 :         if (ForceSummaryEdgesCold != FunctionSummary::FSHT_None)
     285             :           Hotness = CalleeInfo::HotnessType::Cold;
     286             : 
     287             :         // Use the original CalledValue, in case it was an alias. We want
     288             :         // to record the call edge to the alias in that case. Eventually
     289             :         // an alias summary will be created to associate the alias and
     290             :         // aliasee.
     291         321 :         auto &ValueInfo = CallGraphEdges[Index.getOrInsertValueInfo(
     292         321 :             cast<GlobalValue>(CalledValue))];
     293             :         ValueInfo.updateHotness(Hotness);
     294             :         // Add the relative block frequency to CalleeInfo if there is no profile
     295             :         // information.
     296         321 :         if (BFI != nullptr && Hotness == CalleeInfo::HotnessType::Unknown) {
     297         275 :           uint64_t BBFreq = BFI->getBlockFreq(&BB).getFrequency();
     298         275 :           uint64_t EntryFreq = BFI->getEntryFreq();
     299         275 :           ValueInfo.updateRelBlockFreq(BBFreq, EntryFreq);
     300             :         }
     301             :       } else {
     302             :         // Skip inline assembly calls.
     303          34 :         if (CI && CI->isInlineAsm())
     304           3 :           continue;
     305             :         // Skip direct calls.
     306          32 :         if (!CalledValue || isa<Constant>(CalledValue))
     307             :           continue;
     308             : 
     309             :         // Check if the instruction has a callees metadata. If so, add callees
     310             :         // to CallGraphEdges to reflect the references from the metadata, and
     311             :         // to enable importing for subsequent indirect call promotion and
     312             :         // inlining.
     313           9 :         if (auto *MD = I.getMetadata(LLVMContext::MD_callees)) {
     314           3 :           for (auto &Op : MD->operands()) {
     315             :             Function *Callee = mdconst::extract_or_null<Function>(Op);
     316           2 :             if (Callee)
     317           2 :               CallGraphEdges[Index.getOrInsertValueInfo(Callee)];
     318             :           }
     319             :         }
     320             : 
     321             :         uint32_t NumVals, NumCandidates;
     322             :         uint64_t TotalCount;
     323             :         auto CandidateProfileData =
     324             :             ICallAnalysis.getPromotionCandidatesForInstruction(
     325          31 :                 &I, NumVals, TotalCount, NumCandidates);
     326          38 :         for (auto &Candidate : CandidateProfileData)
     327          14 :           CallGraphEdges[Index.getOrInsertValueInfo(Candidate.Value)]
     328           7 :               .updateHotness(getHotness(Candidate.Count, PSI));
     329             :       }
     330             :     }
     331             : 
     332             :   // Explicit add hot edges to enforce importing for designated GUIDs for
     333             :   // sample PGO, to enable the same inlines as the profiled optimized binary.
     334        1254 :   for (auto &I : F.getImportGUIDs())
     335           4 :     CallGraphEdges[Index.getOrInsertValueInfo(I)].updateHotness(
     336           2 :         ForceSummaryEdgesCold == FunctionSummary::FSHT_All
     337             :             ? CalleeInfo::HotnessType::Cold
     338             :             : CalleeInfo::HotnessType::Critical);
     339             : 
     340         626 :   bool NonRenamableLocal = isNonRenamableLocal(F);
     341             :   bool NotEligibleForImport =
     342         622 :       NonRenamableLocal || HasInlineAsmMaybeReferencingInternal ||
     343             :       // Inliner doesn't handle variadic functions.
     344             :       // FIXME: refactor this to use the same code that inliner is using.
     345        1245 :       F.isVarArg() ||
     346             :       // Don't try to import functions with noinline attribute.
     347        1245 :       F.getAttributes().hasFnAttribute(Attribute::NoInline);
     348             :   GlobalValueSummary::GVFlags Flags(F.getLinkage(), NotEligibleForImport,
     349             :                                     /* Live = */ false, F.isDSOLocal());
     350             :   FunctionSummary::FFlags FunFlags{
     351             :       F.hasFnAttribute(Attribute::ReadNone),
     352             :       F.hasFnAttribute(Attribute::ReadOnly),
     353             :       F.hasFnAttribute(Attribute::NoRecurse),
     354             :       F.returnDoesNotAlias(),
     355         626 :   };
     356             :   auto FuncSummary = llvm::make_unique<FunctionSummary>(
     357         626 :       Flags, NumInsts, FunFlags, RefEdges.takeVector(),
     358         626 :       CallGraphEdges.takeVector(), TypeTests.takeVector(),
     359         626 :       TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(),
     360         626 :       TypeTestAssumeConstVCalls.takeVector(),
     361         626 :       TypeCheckedLoadConstVCalls.takeVector());
     362         626 :   if (NonRenamableLocal)
     363           2 :     CantBePromoted.insert(F.getGUID());
     364        1252 :   Index.addGlobalValueSummary(F, std::move(FuncSummary));
     365         626 : }
     366             : 
     367             : static void
     368         156 : computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V,
     369             :                        DenseSet<GlobalValue::GUID> &CantBePromoted) {
     370         156 :   SetVector<ValueInfo> RefEdges;
     371             :   SmallPtrSet<const User *, 8> Visited;
     372         156 :   findRefEdges(Index, &V, RefEdges, Visited);
     373         156 :   bool NonRenamableLocal = isNonRenamableLocal(V);
     374             :   GlobalValueSummary::GVFlags Flags(V.getLinkage(), NonRenamableLocal,
     375             :                                     /* Live = */ false, V.isDSOLocal());
     376             :   auto GVarSummary =
     377         156 :       llvm::make_unique<GlobalVarSummary>(Flags, RefEdges.takeVector());
     378         156 :   if (NonRenamableLocal)
     379           2 :     CantBePromoted.insert(V.getGUID());
     380         312 :   Index.addGlobalValueSummary(V, std::move(GVarSummary));
     381         156 : }
     382             : 
     383             : static void
     384         131 : computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
     385             :                     DenseSet<GlobalValue::GUID> &CantBePromoted) {
     386         131 :   bool NonRenamableLocal = isNonRenamableLocal(A);
     387             :   GlobalValueSummary::GVFlags Flags(A.getLinkage(), NonRenamableLocal,
     388             :                                     /* Live = */ false, A.isDSOLocal());
     389         131 :   auto AS = llvm::make_unique<AliasSummary>(Flags);
     390         131 :   auto *Aliasee = A.getBaseObject();
     391         131 :   auto *AliaseeSummary = Index.getGlobalValueSummary(*Aliasee);
     392             :   assert(AliaseeSummary && "Alias expects aliasee summary to be parsed");
     393             :   AS->setAliasee(AliaseeSummary);
     394         131 :   if (NonRenamableLocal)
     395           0 :     CantBePromoted.insert(A.getGUID());
     396         262 :   Index.addGlobalValueSummary(A, std::move(AS));
     397         131 : }
     398             : 
     399             : // Set LiveRoot flag on entries matching the given value name.
     400        2060 : static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
     401        2060 :   if (ValueInfo VI = Index.getValueInfo(GlobalValue::getGUID(Name)))
     402          22 :     for (auto &Summary : VI.getSummaryList())
     403             :       Summary->setLive(true);
     404        2060 : }
     405             : 
     406         412 : ModuleSummaryIndex llvm::buildModuleSummaryIndex(
     407             :     const Module &M,
     408             :     std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
     409             :     ProfileSummaryInfo *PSI) {
     410             :   assert(PSI);
     411         412 :   ModuleSummaryIndex Index(/*HaveGVs=*/true);
     412             : 
     413             :   // Identify the local values in the llvm.used and llvm.compiler.used sets,
     414             :   // which should not be exported as they would then require renaming and
     415             :   // promotion, but we may have opaque uses e.g. in inline asm. We collect them
     416             :   // here because we use this information to mark functions containing inline
     417             :   // assembly calls as not importable.
     418             :   SmallPtrSet<GlobalValue *, 8> LocalsUsed;
     419             :   SmallPtrSet<GlobalValue *, 8> Used;
     420             :   // First collect those in the llvm.used set.
     421         412 :   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
     422             :   // Next collect those in the llvm.compiler.used set.
     423         412 :   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
     424             :   DenseSet<GlobalValue::GUID> CantBePromoted;
     425         416 :   for (auto *V : Used) {
     426             :     if (V->hasLocalLinkage()) {
     427           4 :       LocalsUsed.insert(V);
     428           4 :       CantBePromoted.insert(V->getGUID());
     429             :     }
     430             :   }
     431             : 
     432         412 :   bool HasLocalInlineAsmSymbol = false;
     433         412 :   if (!M.getModuleInlineAsm().empty()) {
     434             :     // Collect the local values defined by module level asm, and set up
     435             :     // summaries for these symbols so that they can be marked as NoRename,
     436             :     // to prevent export of any use of them in regular IR that would require
     437             :     // renaming within the module level asm. Note we don't need to create a
     438             :     // summary for weak or global defs, as they don't need to be flagged as
     439             :     // NoRename, and defs in module level asm can't be imported anyway.
     440             :     // Also, any values used but not defined within module level asm should
     441             :     // be listed on the llvm.used or llvm.compiler.used global and marked as
     442             :     // referenced from there.
     443          18 :     ModuleSymbolTable::CollectAsmSymbols(
     444             :         M, [&](StringRef Name, object::BasicSymbolRef::Flags Flags) {
     445             :           // Symbols not marked as Weak or Global are local definitions.
     446             :           if (Flags & (object::BasicSymbolRef::SF_Weak |
     447             :                        object::BasicSymbolRef::SF_Global))
     448             :             return;
     449             :           HasLocalInlineAsmSymbol = true;
     450             :           GlobalValue *GV = M.getNamedValue(Name);
     451             :           if (!GV)
     452             :             return;
     453             :           assert(GV->isDeclaration() && "Def in module asm already has definition");
     454             :           GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage,
     455             :                                               /* NotEligibleToImport = */ true,
     456             :                                               /* Live = */ true,
     457             :                                               /* Local */ GV->isDSOLocal());
     458             :           CantBePromoted.insert(GV->getGUID());
     459             :           // Create the appropriate summary type.
     460             :           if (Function *F = dyn_cast<Function>(GV)) {
     461             :             std::unique_ptr<FunctionSummary> Summary =
     462             :                 llvm::make_unique<FunctionSummary>(
     463             :                     GVFlags, 0,
     464             :                     FunctionSummary::FFlags{
     465             :                         F->hasFnAttribute(Attribute::ReadNone),
     466             :                         F->hasFnAttribute(Attribute::ReadOnly),
     467             :                         F->hasFnAttribute(Attribute::NoRecurse),
     468             :                         F->returnDoesNotAlias()},
     469             :                     ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{},
     470             :                     ArrayRef<GlobalValue::GUID>{},
     471             :                     ArrayRef<FunctionSummary::VFuncId>{},
     472             :                     ArrayRef<FunctionSummary::VFuncId>{},
     473             :                     ArrayRef<FunctionSummary::ConstVCall>{},
     474             :                     ArrayRef<FunctionSummary::ConstVCall>{});
     475             :             Index.addGlobalValueSummary(*GV, std::move(Summary));
     476             :           } else {
     477             :             std::unique_ptr<GlobalVarSummary> Summary =
     478             :                 llvm::make_unique<GlobalVarSummary>(GVFlags,
     479             :                                                     ArrayRef<ValueInfo>{});
     480             :             Index.addGlobalValueSummary(*GV, std::move(Summary));
     481             :           }
     482             :         });
     483             :   }
     484             : 
     485             :   // Compute summaries for all functions defined in module, and save in the
     486             :   // index.
     487        1377 :   for (auto &F : M) {
     488         965 :     if (F.isDeclaration())
     489         339 :       continue;
     490             : 
     491             :     BlockFrequencyInfo *BFI = nullptr;
     492        1252 :     std::unique_ptr<BlockFrequencyInfo> BFIPtr;
     493         626 :     if (GetBFICallback)
     494             :       BFI = GetBFICallback(F);
     495          50 :     else if (F.hasProfileData()) {
     496           0 :       LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
     497           0 :       BranchProbabilityInfo BPI{F, LI};
     498           0 :       BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
     499             :       BFI = BFIPtr.get();
     500             :     }
     501             : 
     502         626 :     computeFunctionSummary(Index, M, F, BFI, PSI,
     503         626 :                            !LocalsUsed.empty() || HasLocalInlineAsmSymbol,
     504             :                            CantBePromoted);
     505             :   }
     506             : 
     507             :   // Compute summaries for all variables defined in module, and save in the
     508             :   // index.
     509         617 :   for (const GlobalVariable &G : M.globals()) {
     510         205 :     if (G.isDeclaration())
     511             :       continue;
     512         156 :     computeVariableSummary(Index, G, CantBePromoted);
     513             :   }
     514             : 
     515             :   // Compute summaries for all aliases defined in module, and save in the
     516             :   // index.
     517         543 :   for (const GlobalAlias &A : M.aliases())
     518         131 :     computeAliasSummary(Index, A, CantBePromoted);
     519             : 
     520         416 :   for (auto *V : LocalsUsed) {
     521             :     auto *Summary = Index.getGlobalValueSummary(*V);
     522             :     assert(Summary && "Missing summary for global value");
     523             :     Summary->setNotEligibleToImport();
     524             :   }
     525             : 
     526             :   // The linker doesn't know about these LLVM produced values, so we need
     527             :   // to flag them as live in the index to ensure index-based dead value
     528             :   // analysis treats them as live roots of the analysis.
     529         412 :   setLiveRoot(Index, "llvm.used");
     530         412 :   setLiveRoot(Index, "llvm.compiler.used");
     531         412 :   setLiveRoot(Index, "llvm.global_ctors");
     532         412 :   setLiveRoot(Index, "llvm.global_dtors");
     533         412 :   setLiveRoot(Index, "llvm.global.annotations");
     534             : 
     535             :   bool IsThinLTO = true;
     536          40 :   if (auto *MD =
     537         824 :           mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
     538          40 :     IsThinLTO = MD->getZExtValue();
     539             : 
     540        1624 :   for (auto &GlobalList : Index) {
     541             :     // Ignore entries for references that are undefined in the current module.
     542        1212 :     if (GlobalList.second.SummaryList.empty())
     543             :       continue;
     544             : 
     545             :     assert(GlobalList.second.SummaryList.size() == 1 &&
     546             :            "Expected module's index to have one summary per GUID");
     547             :     auto &Summary = GlobalList.second.SummaryList[0];
     548         914 :     if (!IsThinLTO) {
     549             :       Summary->setNotEligibleToImport();
     550          55 :       continue;
     551             :     }
     552             : 
     553             :     bool AllRefsCanBeExternallyReferenced =
     554             :         llvm::all_of(Summary->refs(), [&](const ValueInfo &VI) {
     555             :           return !CantBePromoted.count(VI.getGUID());
     556             :         });
     557         859 :     if (!AllRefsCanBeExternallyReferenced) {
     558             :       Summary->setNotEligibleToImport();
     559           9 :       continue;
     560             :     }
     561             : 
     562             :     if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) {
     563             :       bool AllCallsCanBeExternallyReferenced = llvm::all_of(
     564             :           FuncSummary->calls(), [&](const FunctionSummary::EdgeTy &Edge) {
     565             :             return !CantBePromoted.count(Edge.first.getGUID());
     566             :           });
     567         601 :       if (!AllCallsCanBeExternallyReferenced)
     568             :         Summary->setNotEligibleToImport();
     569             :     }
     570             :   }
     571             : 
     572         412 :   return Index;
     573             : }
     574             : 
     575             : AnalysisKey ModuleSummaryIndexAnalysis::Key;
     576             : 
     577             : ModuleSummaryIndex
     578          18 : ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
     579             :   ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
     580          18 :   auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
     581             :   return buildModuleSummaryIndex(
     582             :       M,
     583             :       [&FAM](const Function &F) {
     584             :         return &FAM.getResult<BlockFrequencyAnalysis>(
     585             :             *const_cast<Function *>(&F));
     586             :       },
     587          18 :       &PSI);
     588             : }
     589             : 
     590             : char ModuleSummaryIndexWrapperPass::ID = 0;
     591             : 
     592       11001 : INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
     593             :                       "Module Summary Analysis", false, true)
     594       11001 : INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
     595       11001 : INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
     596       33036 : INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
     597             :                     "Module Summary Analysis", false, true)
     598             : 
     599           0 : ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
     600           0 :   return new ModuleSummaryIndexWrapperPass();
     601             : }
     602             : 
     603         341 : ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
     604         341 :     : ModulePass(ID) {
     605         341 :   initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
     606         341 : }
     607             : 
     608         341 : bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
     609         341 :   auto &PSI = *getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
     610         682 :   Index.emplace(buildModuleSummaryIndex(
     611             :       M,
     612             :       [this](const Function &F) {
     613             :         return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
     614         557 :                          *const_cast<Function *>(&F))
     615             :                      .getBFI());
     616             :       },
     617             :       &PSI));
     618         341 :   return false;
     619             : }
     620             : 
     621         341 : bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
     622             :   Index.reset();
     623         341 :   return false;
     624             : }
     625             : 
     626         341 : void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
     627             :   AU.setPreservesAll();
     628             :   AU.addRequired<BlockFrequencyInfoWrapperPass>();
     629             :   AU.addRequired<ProfileSummaryInfoWrapperPass>();
     630         341 : }

Generated by: LCOV version 1.13