mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
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
This commit is contained in:
parent
1bbda74bca
commit
a538f8987b
@ -198,7 +198,7 @@ static void addIntrinsicToSummary(
|
|||||||
static void
|
static void
|
||||||
computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M,
|
||||||
const Function &F, BlockFrequencyInfo *BFI,
|
const Function &F, BlockFrequencyInfo *BFI,
|
||||||
ProfileSummaryInfo *PSI, bool HasLocalsInUsed,
|
ProfileSummaryInfo *PSI, bool HasLocalsInUsedOrAsm,
|
||||||
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
DenseSet<GlobalValue::GUID> &CantBePromoted) {
|
||||||
// Summary not currently supported for anonymous functions, they should
|
// Summary not currently supported for anonymous functions, they should
|
||||||
// have been named.
|
// 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
|
// a local value from inline assembly to ensure we don't export a
|
||||||
// reference (which would require renaming and promotion of the
|
// reference (which would require renaming and promotion of the
|
||||||
// referenced value).
|
// referenced value).
|
||||||
if (HasLocalsInUsed && CI && CI->isInlineAsm())
|
if (HasLocalsInUsedOrAsm && CI && CI->isInlineAsm())
|
||||||
HasInlineAsmMaybeReferencingInternal = true;
|
HasInlineAsmMaybeReferencingInternal = true;
|
||||||
|
|
||||||
auto *CalledValue = CS.getCalledValue();
|
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
|
// Compute summaries for all functions defined in module, and save in the
|
||||||
// index.
|
// index.
|
||||||
for (auto &F : M) {
|
for (auto &F : M) {
|
||||||
@ -399,7 +451,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
|||||||
BFI = BFIPtr.get();
|
BFI = BFIPtr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
computeFunctionSummary(Index, M, F, BFI, PSI, !LocalsUsed.empty(),
|
computeFunctionSummary(Index, M, F, BFI, PSI,
|
||||||
|
!LocalsUsed.empty() || HasLocalInlineAsmSymbol,
|
||||||
CantBePromoted);
|
CantBePromoted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -437,57 +490,6 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
|
|||||||
setLiveRoot(Index, "llvm.global_dtors");
|
setLiveRoot(Index, "llvm.global_dtors");
|
||||||
setLiveRoot(Index, "llvm.global.annotations");
|
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;
|
bool IsThinLTO = true;
|
||||||
if (auto *MD =
|
if (auto *MD =
|
||||||
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
|
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
|
||||||
|
16
test/Bitcode/thinlto-asm-noimport.ll
Normal file
16
test/Bitcode/thinlto-asm-noimport.ll
Normal file
@ -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: <PERMODULE {{.*}} op1=16
|
||||||
|
define void @f() {
|
||||||
|
call void asm sideeffect "bl asm\0A", ""()
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user