diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2016-05-06 08:25:33 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2016-05-06 08:25:33 +0000 |
commit | 3b132e34b09bf45333adc8c0af33277f34bcebb2 (patch) | |
tree | 70e8057e250dbcd6079a5e9a7b777814c4b9aa5a /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | 31c9ebe2818b0a47a45867732d946356ca80423e (diff) | |
download | llvm-3b132e34b09bf45333adc8c0af33277f34bcebb2.zip llvm-3b132e34b09bf45333adc8c0af33277f34bcebb2.tar.gz llvm-3b132e34b09bf45333adc8c0af33277f34bcebb2.tar.bz2 |
ThinLTO: fix assertion and refactor check for hidden use from inline ASM in a helper function
This test was crashing, and currently it breaks bootstrapping clang with debuginfo
Differential Revision: http://reviews.llvm.org/D20008
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 268715
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 74 |
1 files changed, 43 insertions, 31 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index e33ec29..7c57c05 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -120,37 +120,11 @@ ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder( const Module *M, std::function<BlockFrequencyInfo *(const Function &F)> Ftor) : Index(llvm::make_unique<ModuleSummaryIndex>()), M(M) { - // We cannot currently promote or rename anything used in inline assembly, - // which are not visible to the compiler. Detect a possible case by looking - // for a llvm.used local value, in conjunction with an inline assembly call - // in the module. Prevent importing of any modules containing these uses by - // suppressing generation of the index. This also prevents importing - // into this module, which is also necessary to avoid needing to rename - // in case of a name clash between a local in this module and an imported - // global. - // FIXME: If we find we need a finer-grained approach of preventing promotion - // and renaming of just the functions using inline assembly we will need to: - // - Add flag in the function summaries to identify those with inline asm. - // - Prevent importing of any functions with flag set. - // - Prevent importing of any global function with the same name as a - // function in current module that has the flag set. - // - For any llvm.used value that is exported and promoted, add a private - // alias to the original name in the current module (even if we don't - // export the function using those values in inline asm, another function - // with a reference could be exported). - SmallPtrSet<GlobalValue *, 8> Used; - collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false); - bool LocalIsUsed = false; - for (GlobalValue *V : Used) { - if ((LocalIsUsed |= V->hasLocalLinkage())) - break; - } - if (LocalIsUsed) - for (auto &F : *M) - for (auto &I : instructions(F)) - if (const CallInst *CallI = dyn_cast<CallInst>(&I)) - if (CallI->isInlineAsm()) - return; + // Check if the module can be promoted, otherwise just disable importing from + // it by not emitting any summary. + // FIXME: we could still import *into* it most of the time. + if (!moduleCanBeRenamedForThinLTO(*M)) + return; // Compute summaries for all functions defined in module, and save in the // index. @@ -216,3 +190,41 @@ void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<BlockFrequencyInfoWrapperPass>(); } + +bool llvm::moduleCanBeRenamedForThinLTO(const Module &M) { + // We cannot currently promote or rename anything used in inline assembly, + // which are not visible to the compiler. Detect a possible case by looking + // for a llvm.used local value, in conjunction with an inline assembly call + // in the module. Prevent importing of any modules containing these uses by + // suppressing generation of the index. This also prevents importing + // into this module, which is also necessary to avoid needing to rename + // in case of a name clash between a local in this module and an imported + // global. + // FIXME: If we find we need a finer-grained approach of preventing promotion + // and renaming of just the functions using inline assembly we will need to: + // - Add flag in the function summaries to identify those with inline asm. + // - Prevent importing of any functions with flag set. + // - Prevent importing of any global function with the same name as a + // function in current module that has the flag set. + // - For any llvm.used value that is exported and promoted, add a private + // alias to the original name in the current module (even if we don't + // export the function using those values in inline asm, another function + // with a reference could be exported). + SmallPtrSet<GlobalValue *, 8> Used; + collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); + bool LocalIsUsed = + llvm::any_of(Used, [](GlobalValue *V) { return V->hasLocalLinkage(); }); + if (!LocalIsUsed) + return true; + + // Walk all the instructions in the module and find if one is inline ASM + auto HasInlineAsm = llvm::any_of(M, [](const Function &F) { + return llvm::any_of(instructions(F), [](const Instruction &I) { + const CallInst *CallI = dyn_cast<CallInst>(&I); + if (!CallI) + return false; + return CallI->isInlineAsm(); + }); + }); + return !HasInlineAsm; +} |