Index: llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp =================================================================== --- llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp +++ llvm/trunk/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -198,7 +198,7 @@ static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, const Function &F, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, bool HasLocalsInUsed, + ProfileSummaryInfo *PSI, bool HasLocalsInUsedOrAsm, DenseSet &CantBePromoted) { // Summary not currently supported for anonymous functions, they should // have been named. @@ -234,7 +234,7 @@ // 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 @@ } } + 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(GV)) { + std::unique_ptr Summary = + llvm::make_unique( + GVFlags, 0, + FunctionSummary::FFlags{ + F->hasFnAttribute(Attribute::ReadNone), + F->hasFnAttribute(Attribute::ReadOnly), + F->hasFnAttribute(Attribute::NoRecurse), + F->returnDoesNotAlias()}, + ArrayRef{}, ArrayRef{}, + ArrayRef{}, + ArrayRef{}, + ArrayRef{}, + ArrayRef{}, + ArrayRef{}); + Index.addGlobalValueSummary(Name, std::move(Summary)); + } else { + std::unique_ptr Summary = + llvm::make_unique(GVFlags, + ArrayRef{}); + 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 @@ 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 @@ 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(GV)) { - std::unique_ptr Summary = - llvm::make_unique( - GVFlags, 0, - FunctionSummary::FFlags{ - F->hasFnAttribute(Attribute::ReadNone), - F->hasFnAttribute(Attribute::ReadOnly), - F->hasFnAttribute(Attribute::NoRecurse), - F->returnDoesNotAlias()}, - ArrayRef{}, ArrayRef{}, - ArrayRef{}, - ArrayRef{}, - ArrayRef{}, - ArrayRef{}, - ArrayRef{}); - Index.addGlobalValueSummary(Name, std::move(Summary)); - } else { - std::unique_ptr Summary = - llvm::make_unique(GVFlags, - ArrayRef{}); - Index.addGlobalValueSummary(Name, std::move(Summary)); - } - }); - } - bool IsThinLTO = true; if (auto *MD = mdconst::extract_or_null(M.getModuleFlag("ThinLTO"))) Index: llvm/trunk/test/Bitcode/thinlto-asm-noimport.ll =================================================================== --- llvm/trunk/test/Bitcode/thinlto-asm-noimport.ll +++ llvm/trunk/test/Bitcode/thinlto-asm-noimport.ll @@ -0,0 +1,16 @@ +; REQUIRES: arm-registered-target +; RUN: opt -module-summary -o %t %s +; RUN: llvm-bcanalyzer -dump %t | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv7--linux-android" + +module asm "asm:" +module asm "bx lr" + +; NotEligibleToImport +; CHECK: