diff options
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 97 |
1 files changed, 73 insertions, 24 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 8a1206f49c21..e7d529d0b51e 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -25,10 +25,10 @@ #include "llvm/Analysis/IndirectCallPromotionAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/Analysis/StackSafetyAnalysis.h" #include "llvm/Analysis/TypeMetadataUtils.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" @@ -83,7 +83,7 @@ cl::opt<std::string> ModuleSummaryDotFile( // to know when computing summary for global var, because if global variable // references basic block address we can't import it separately from function // containing that basic block. For simplicity we currently don't import such -// global vars at all. When importing function we aren't interested if any +// global vars at all. When importing function we aren't interested if any // instruction in it takes an address of any basic block, because instruction // can only take an address of basic block located in the same function. static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, @@ -99,7 +99,7 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, if (!Visited.insert(U).second) continue; - ImmutableCallSite CS(U); + const auto *CB = dyn_cast<CallBase>(U); for (const auto &OI : U->operands()) { const User *Operand = dyn_cast<User>(OI); @@ -113,7 +113,7 @@ static bool findRefEdges(ModuleSummaryIndex &Index, const User *CurUser, // We have a reference to a global value. This should be added to // the reference set unless it is a callee. Callees are handled // specially by WriteFunction and are added to a separate list. - if (!(CS && CS.isCallee(&OI))) + if (!(CB && CB->isCallee(&OI))) RefEdges.insert(Index.getOrInsertValueInfo(GV)); continue; } @@ -145,7 +145,7 @@ static void addVCallToSet(DevirtCallSite Call, GlobalValue::GUID Guid, SetVector<FunctionSummary::ConstVCall> &ConstVCalls) { std::vector<uint64_t> Args; // Start from the second argument to skip the "this" pointer. - for (auto &Arg : make_range(Call.CS.arg_begin() + 1, Call.CS.arg_end())) { + for (auto &Arg : make_range(Call.CB.arg_begin() + 1, Call.CB.arg_end())) { auto *CI = dyn_cast<ConstantInt>(Arg); if (!CI || CI->getBitWidth() > 64) { VCalls.insert({Guid, Call.Offset}); @@ -239,12 +239,12 @@ static bool isNonVolatileStore(const Instruction *I) { return false; } -static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, - const Function &F, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, DominatorTree &DT, - bool HasLocalsInUsedOrAsm, - DenseSet<GlobalValue::GUID> &CantBePromoted, - bool IsThinLTO) { +static void computeFunctionSummary( + ModuleSummaryIndex &Index, const Module &M, const Function &F, + BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT, + bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted, + bool IsThinLTO, + std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) { // Summary not currently supported for anonymous functions, they should // have been named. assert(F.hasName()); @@ -304,8 +304,8 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, } } findRefEdges(Index, &I, RefEdges, Visited); - auto CS = ImmutableCallSite(&I); - if (!CS) + const auto *CB = dyn_cast<CallBase>(&I); + if (!CB) continue; const auto *CI = dyn_cast<CallInst>(&I); @@ -317,8 +317,8 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm()) HasInlineAsmMaybeReferencingInternal = true; - auto *CalledValue = CS.getCalledValue(); - auto *CalledFunction = CS.getCalledFunction(); + auto *CalledValue = CB->getCalledOperand(); + auto *CalledFunction = CB->getCalledFunction(); if (CalledValue && !CalledFunction) { CalledValue = CalledValue->stripPointerCasts(); // Stripping pointer casts can reveal a called function. @@ -341,7 +341,7 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, } // We should have named any anonymous globals assert(CalledFunction->hasName()); - auto ScaledCount = PSI->getProfileCount(&I, BFI); + auto ScaledCount = PSI->getProfileCount(*CB, BFI); auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI) : CalleeInfo::HotnessType::Unknown; if (ForceSummaryEdgesCold != FunctionSummary::FSHT_None) @@ -391,6 +391,7 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, .updateHotness(getHotness(Candidate.Count, PSI)); } } + Index.addBlockCount(F.size()); std::vector<ValueInfo> Refs; if (IsThinLTO) { @@ -469,12 +470,15 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, // Don't try to import functions with noinline attribute. F.getAttributes().hasFnAttribute(Attribute::NoInline), F.hasFnAttribute(Attribute::AlwaysInline)}; + std::vector<FunctionSummary::ParamAccess> ParamAccesses; + if (auto *SSI = GetSSICallback(F)) + ParamAccesses = SSI->getParamAccesses(); auto FuncSummary = std::make_unique<FunctionSummary>( Flags, NumInsts, FunFlags, /*EntryCount=*/0, std::move(Refs), CallGraphEdges.takeVector(), TypeTests.takeVector(), TypeTestAssumeVCalls.takeVector(), TypeCheckedLoadVCalls.takeVector(), TypeTestAssumeConstVCalls.takeVector(), - TypeCheckedLoadConstVCalls.takeVector()); + TypeCheckedLoadConstVCalls.takeVector(), std::move(ParamAccesses)); if (NonRenamableLocal) CantBePromoted.insert(F.getGUID()); Index.addGlobalValueSummary(F, std::move(FuncSummary)); @@ -599,7 +603,10 @@ static void computeVariableSummary(ModuleSummaryIndex &Index, bool CanBeInternalized = !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() && !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass(); - GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized, CanBeInternalized); + bool Constant = V.isConstant(); + GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized, + Constant ? false : CanBeInternalized, + Constant, V.getVCallVisibility()); auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags, RefEdges.takeVector()); if (NonRenamableLocal) @@ -640,7 +647,8 @@ static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) { ModuleSummaryIndex llvm::buildModuleSummaryIndex( const Module &M, std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback, - ProfileSummaryInfo *PSI) { + ProfileSummaryInfo *PSI, + std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) { assert(PSI); bool EnableSplitLTOUnit = false; if (auto *MD = mdconst::extract_or_null<ConstantInt>( @@ -713,12 +721,16 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( ArrayRef<FunctionSummary::VFuncId>{}, ArrayRef<FunctionSummary::VFuncId>{}, ArrayRef<FunctionSummary::ConstVCall>{}, - ArrayRef<FunctionSummary::ConstVCall>{}); + ArrayRef<FunctionSummary::ConstVCall>{}, + ArrayRef<FunctionSummary::ParamAccess>{}); Index.addGlobalValueSummary(*GV, std::move(Summary)); } else { std::unique_ptr<GlobalVarSummary> Summary = std::make_unique<GlobalVarSummary>( - GVFlags, GlobalVarSummary::GVarFlags(false, false), + GVFlags, + GlobalVarSummary::GVarFlags( + false, false, cast<GlobalVariable>(GV)->isConstant(), + GlobalObject::VCallVisibilityPublic), ArrayRef<ValueInfo>{}); Index.addGlobalValueSummary(*GV, std::move(Summary)); } @@ -750,7 +762,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( computeFunctionSummary(Index, M, F, BFI, PSI, DT, !LocalsUsed.empty() || HasLocalInlineAsmSymbol, - CantBePromoted, IsThinLTO); + CantBePromoted, IsThinLTO, GetSSICallback); } // Compute summaries for all variables defined in module, and save in the @@ -832,13 +844,19 @@ ModuleSummaryIndex ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) { ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M); auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); + bool NeedSSI = needsParamAccessSummary(M); return buildModuleSummaryIndex( M, [&FAM](const Function &F) { return &FAM.getResult<BlockFrequencyAnalysis>( *const_cast<Function *>(&F)); }, - &PSI); + &PSI, + [&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * { + return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>( + const_cast<Function &>(F)) + : nullptr; + }); } char ModuleSummaryIndexWrapperPass::ID = 0; @@ -847,6 +865,7 @@ INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis", "Module Summary Analysis", false, true) INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass) INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis", "Module Summary Analysis", false, true) @@ -861,6 +880,7 @@ ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass() bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); + bool NeedSSI = needsParamAccessSummary(M); Index.emplace(buildModuleSummaryIndex( M, [this](const Function &F) { @@ -868,7 +888,13 @@ bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { *const_cast<Function *>(&F)) .getBFI()); }, - PSI)); + PSI, + [&](const Function &F) -> const StackSafetyInfo * { + return NeedSSI ? &getAnalysis<StackSafetyInfoWrapperPass>( + const_cast<Function &>(F)) + .getResult() + : nullptr; + })); return false; } @@ -881,4 +907,27 @@ void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<BlockFrequencyInfoWrapperPass>(); AU.addRequired<ProfileSummaryInfoWrapperPass>(); + AU.addRequired<StackSafetyInfoWrapperPass>(); +} + +char ImmutableModuleSummaryIndexWrapperPass::ID = 0; + +ImmutableModuleSummaryIndexWrapperPass::ImmutableModuleSummaryIndexWrapperPass( + const ModuleSummaryIndex *Index) + : ImmutablePass(ID), Index(Index) { + initializeImmutableModuleSummaryIndexWrapperPassPass( + *PassRegistry::getPassRegistry()); } + +void ImmutableModuleSummaryIndexWrapperPass::getAnalysisUsage( + AnalysisUsage &AU) const { + AU.setPreservesAll(); +} + +ImmutablePass *llvm::createImmutableModuleSummaryIndexWrapperPass( + const ModuleSummaryIndex *Index) { + return new ImmutableModuleSummaryIndexWrapperPass(Index); +} + +INITIALIZE_PASS(ImmutableModuleSummaryIndexWrapperPass, "module-summary-info", + "Module summary info", false, true) |