diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-09-01 16:24:02 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-09-01 16:24:02 +0000 |
commit | 5e8b94c137d1a6f182dbb5afe0f739724c2dddd7 (patch) | |
tree | b8c6d7885390e5a0f3f477ffad408067c01ea42a /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | 6b54c7e11beb2e050de4f912d182938ce81f4221 (diff) | |
download | bcm5719-llvm-5e8b94c137d1a6f182dbb5afe0f739724c2dddd7.tar.gz bcm5719-llvm-5e8b94c137d1a6f182dbb5afe0f739724c2dddd7.zip |
ModuleSummaryAnalysis: Correctly handle refs from function inline asm to module inline asm.
If a function contains inline asm and the module-level inline asm
contains the definition of a local symbol, prevent the function from
being imported in case the function-level inline asm refers to a
symbol in the module-level inline asm.
Differential Revision: https://reviews.llvm.org/D37370
llvm-svn: 312332
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 110 |
1 files changed, 56 insertions, 54 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 886dac8314e..4950780ae75 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -198,7 +198,7 @@ static void addIntrinsicToSummary( static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, const Function &F, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, bool HasLocalsInUsed, + ProfileSummaryInfo *PSI, bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted) { // Summary not currently supported for anonymous functions, they should // have been named. @@ -234,7 +234,7 @@ computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, // a local value from inline assembly to ensure we don't export a // reference (which would require renaming and promotion of the // referenced value). - if (HasLocalsInUsed && CI && CI->isInlineAsm()) + if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm()) HasInlineAsmMaybeReferencingInternal = true; auto *CalledValue = CS.getCalledValue(); @@ -382,6 +382,58 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( } } + bool HasLocalInlineAsmSymbol = false; + if (!M.getModuleInlineAsm().empty()) { + // Collect the local values defined by module level asm, and set up + // summaries for these symbols so that they can be marked as NoRename, + // to prevent export of any use of them in regular IR that would require + // renaming within the module level asm. Note we don't need to create a + // summary for weak or global defs, as they don't need to be flagged as + // NoRename, and defs in module level asm can't be imported anyway. + // Also, any values used but not defined within module level asm should + // be listed on the llvm.used or llvm.compiler.used global and marked as + // referenced from there. + ModuleSymbolTable::CollectAsmSymbols( + M, [&](StringRef Name, object::BasicSymbolRef::Flags Flags) { + // Symbols not marked as Weak or Global are local definitions. + if (Flags & (object::BasicSymbolRef::SF_Weak | + object::BasicSymbolRef::SF_Global)) + return; + HasLocalInlineAsmSymbol = true; + GlobalValue *GV = M.getNamedValue(Name); + if (!GV) + return; + assert(GV->isDeclaration() && "Def in module asm already has definition"); + GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage, + /* NotEligibleToImport = */ true, + /* Live = */ true); + CantBePromoted.insert(GlobalValue::getGUID(Name)); + // Create the appropriate summary type. + if (Function *F = dyn_cast<Function>(GV)) { + std::unique_ptr<FunctionSummary> Summary = + llvm::make_unique<FunctionSummary>( + GVFlags, 0, + FunctionSummary::FFlags{ + F->hasFnAttribute(Attribute::ReadNone), + F->hasFnAttribute(Attribute::ReadOnly), + F->hasFnAttribute(Attribute::NoRecurse), + F->returnDoesNotAlias()}, + ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{}, + ArrayRef<GlobalValue::GUID>{}, + ArrayRef<FunctionSummary::VFuncId>{}, + ArrayRef<FunctionSummary::VFuncId>{}, + ArrayRef<FunctionSummary::ConstVCall>{}, + ArrayRef<FunctionSummary::ConstVCall>{}); + Index.addGlobalValueSummary(Name, std::move(Summary)); + } else { + std::unique_ptr<GlobalVarSummary> Summary = + llvm::make_unique<GlobalVarSummary>(GVFlags, + ArrayRef<ValueInfo>{}); + Index.addGlobalValueSummary(Name, std::move(Summary)); + } + }); + } + // Compute summaries for all functions defined in module, and save in the // index. for (auto &F : M) { @@ -399,7 +451,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( BFI = BFIPtr.get(); } - computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(), + computeFunctionSummary(Index, M, F, BFI, PSI, + !LocalsUsed.empty() || HasLocalInlineAsmSymbol, CantBePromoted); } @@ -437,57 +490,6 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( setLiveRoot(Index, "llvm.global_dtors"); setLiveRoot(Index, "llvm.global.annotations"); - if (!M.getModuleInlineAsm().empty()) { - // Collect the local values defined by module level asm, and set up - // summaries for these symbols so that they can be marked as NoRename, - // to prevent export of any use of them in regular IR that would require - // renaming within the module level asm. Note we don't need to create a - // summary for weak or global defs, as they don't need to be flagged as - // NoRename, and defs in module level asm can't be imported anyway. - // Also, any values used but not defined within module level asm should - // be listed on the llvm.used or llvm.compiler.used global and marked as - // referenced from there. - ModuleSymbolTable::CollectAsmSymbols( - M, [&M, &Index, &CantBePromoted](StringRef Name, - object::BasicSymbolRef::Flags Flags) { - // Symbols not marked as Weak or Global are local definitions. - if (Flags & (object::BasicSymbolRef::SF_Weak | - object::BasicSymbolRef::SF_Global)) - return; - GlobalValue *GV = M.getNamedValue(Name); - if (!GV) - return; - assert(GV->isDeclaration() && "Def in module asm already has definition"); - GlobalValueSummary::GVFlags GVFlags(GlobalValue::InternalLinkage, - /* NotEligibleToImport = */ true, - /* Live = */ true); - CantBePromoted.insert(GlobalValue::getGUID(Name)); - // Create the appropriate summary type. - if (Function *F = dyn_cast<Function>(GV)) { - std::unique_ptr<FunctionSummary> Summary = - llvm::make_unique<FunctionSummary>( - GVFlags, 0, - FunctionSummary::FFlags{ - F->hasFnAttribute(Attribute::ReadNone), - F->hasFnAttribute(Attribute::ReadOnly), - F->hasFnAttribute(Attribute::NoRecurse), - F->returnDoesNotAlias()}, - ArrayRef<ValueInfo>{}, ArrayRef<FunctionSummary::EdgeTy>{}, - ArrayRef<GlobalValue::GUID>{}, - ArrayRef<FunctionSummary::VFuncId>{}, - ArrayRef<FunctionSummary::VFuncId>{}, - ArrayRef<FunctionSummary::ConstVCall>{}, - ArrayRef<FunctionSummary::ConstVCall>{}); - Index.addGlobalValueSummary(Name, std::move(Summary)); - } else { - std::unique_ptr<GlobalVarSummary> Summary = - llvm::make_unique<GlobalVarSummary>(GVFlags, - ArrayRef<ValueInfo>{}); - Index.addGlobalValueSummary(Name, std::move(Summary)); - } - }); - } - bool IsThinLTO = true; if (auto *MD = mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO"))) |