mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Make explicit -fno-semantic-interposition (in -fpic mode) infer dso_local
-fno-semantic-interposition is currently the CC1 default. (The opposite disables some interprocedural optimizations.) However, it does not infer dso_local: on most targets accesses to ExternalLinkage functions/variables defined in the current module still need PLT/GOT. This patch makes explicit -fno-semantic-interposition infer dso_local, so that PLT/GOT can be eliminated if targets implement local aliases for AsmPrinter::getSymbolPreferLocal (currently only x86). Currently we check whether the module flag "SemanticInterposition" is 0. If yes, infer dso_local. In the future, we can infer dso_local unless "SemanticInterposition" is 1: frontends other than clang will also benefit from the optimization if they don't bother setting the flag. (There will be risks if they do want ELF interposition: they need to set "SemanticInterposition" to 1.)
This commit is contained in:
parent
11b91362f5
commit
b7d65e895d
@ -427,6 +427,7 @@ public:
|
||||
/// inlining across interposable call edges, since the callee can be
|
||||
/// replaced with something arbitrary.
|
||||
bool isInterposable() const;
|
||||
bool canBenefitFromLocalAlias() const;
|
||||
|
||||
bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); }
|
||||
bool hasAvailableExternallyLinkage() const {
|
||||
|
@ -857,6 +857,7 @@ public:
|
||||
|
||||
/// Returns whether semantic interposition is to be respected.
|
||||
bool getSemanticInterposition() const;
|
||||
bool noSemanticInterposition() const;
|
||||
|
||||
/// Set whether semantic interposition is to be respected.
|
||||
void setSemanticInterposition(bool);
|
||||
|
@ -462,10 +462,10 @@ MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {
|
||||
// assembler would otherwise be conservative and assume a global default
|
||||
// visibility symbol can be interposable, even if the code generator already
|
||||
// assumed it.
|
||||
if (TM.getTargetTriple().isOSBinFormatELF() &&
|
||||
GlobalObject::isExternalLinkage(GV.getLinkage()) && GV.isDSOLocal() &&
|
||||
!GV.isDeclaration() && !isa<GlobalIFunc>(GV) && !GV.hasComdat())
|
||||
return getSymbolWithGlobalValueBase(&GV, "$local");
|
||||
if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias())
|
||||
if (GV.isDSOLocal() || (TM.getTargetTriple().isX86() &&
|
||||
GV.getParent()->noSemanticInterposition()))
|
||||
return getSymbolWithGlobalValueBase(&GV, "$local");
|
||||
return TM.getSymbol(&GV);
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,12 @@ bool GlobalValue::isInterposable() const {
|
||||
!isDSOLocal();
|
||||
}
|
||||
|
||||
bool GlobalValue::canBenefitFromLocalAlias() const {
|
||||
// See AsmPrinter::getSymbolPreferLocal().
|
||||
return GlobalObject::isExternalLinkage(getLinkage()) && !isDeclaration() &&
|
||||
!isa<GlobalIFunc>(this) && !hasComdat();
|
||||
}
|
||||
|
||||
unsigned GlobalValue::getAlignment() const {
|
||||
if (auto *GA = dyn_cast<GlobalAlias>(this)) {
|
||||
// In general we cannot compute this at the IR level, but we try.
|
||||
|
@ -600,6 +600,13 @@ void Module::setSemanticInterposition(bool SI) {
|
||||
addModuleFlag(ModFlagBehavior::Error, "SemanticInterposition", SI);
|
||||
}
|
||||
|
||||
bool Module::noSemanticInterposition() const {
|
||||
// Conservatively require an explicit zero value for now.
|
||||
Metadata *MF = getModuleFlag("SemanticInterposition");
|
||||
auto *Val = cast_or_null<ConstantAsMetadata>(MF);
|
||||
return Val && cast<ConstantInt>(Val->getValue())->getZExtValue() == 0;
|
||||
}
|
||||
|
||||
void Module::setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB) {
|
||||
OwnedMemoryBuffer = std::move(MB);
|
||||
}
|
||||
|
@ -193,6 +193,14 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
|
||||
// Check if we can use copy relocations.
|
||||
if (!(GV && GV->isThreadLocal()) && RM == Reloc::Static)
|
||||
return true;
|
||||
} else if (TT.isOSBinFormatELF()) {
|
||||
// If dso_local allows AsmPrinter::getSymbolPreferLocal to use a local
|
||||
// alias, set the flag. We cannot set dso_local for other global values,
|
||||
// because otherwise direct accesses to a probably interposable symbol (even
|
||||
// if the codegen assumes not) will be rejected by the linker.
|
||||
if (!GV || !GV->canBenefitFromLocalAlias())
|
||||
return false;
|
||||
return TT.isX86() && M.noSemanticInterposition();
|
||||
}
|
||||
|
||||
// ELF & wasm support preemption of other symbols.
|
||||
|
46
test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll
Normal file
46
test/CodeGen/X86/semantic-interposition-infer-dsolocal.ll
Normal file
@ -0,0 +1,46 @@
|
||||
; RUN: llc -mtriple=x86_64 -relocation-model=pic < %s | FileCheck %s
|
||||
|
||||
;; With a module flag SemanticInterposition=0, infer dso_local flags even if PIC.
|
||||
;; Local aliases will be generated for applicable variables and functions.
|
||||
|
||||
@var = global i32 0, align 4
|
||||
|
||||
@ifunc = ifunc i32 (), bitcast (i32 ()* ()* @ifunc_resolver to i32 ()*)
|
||||
|
||||
define i32 @ifunc_impl() {
|
||||
entry:
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
define i32 ()* @ifunc_resolver() {
|
||||
entry:
|
||||
ret i32 ()* @ifunc_impl
|
||||
}
|
||||
|
||||
declare i32 @external()
|
||||
|
||||
define i32 @func() {
|
||||
ret i32 0
|
||||
}
|
||||
|
||||
;; Don't set dso_local on declarations or ifuncs.
|
||||
define i32 @foo() {
|
||||
; CHECK: movl .Lvar$local(%rip), %ebp
|
||||
; CHECK: callq external@PLT
|
||||
; CHECK: callq ifunc@PLT
|
||||
; CHECK: callq .Lfunc$local{{$}}
|
||||
entry:
|
||||
%0 = load i32, i32* @var, align 4
|
||||
%call = tail call i32 @external()
|
||||
%add = add nsw i32 %call, %0
|
||||
%call1 = tail call i32 @ifunc()
|
||||
%add2 = add nsw i32 %add, %call1
|
||||
%call2 = tail call i32 @func()
|
||||
%add3 = add nsw i32 %add, %call2
|
||||
ret i32 %add3
|
||||
}
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
|
||||
!0 = !{i32 1, !"SemanticInterposition", i32 0}
|
||||
!1 = !{i32 7, !"PIC Level", i32 2}
|
Loading…
x
Reference in New Issue
Block a user