mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
[X86] enable PIE for functions
Call locally defined function directly for PIE/fPIE Differential Revision: http://reviews.llvm.org/D19226 llvm-svn: 266863
This commit is contained in:
parent
c7e838369e
commit
9cc5def4a3
@ -3157,25 +3157,10 @@ bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) {
|
||||
unsigned CallOpc = Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32;
|
||||
|
||||
// See if we need any target-specific flags on the GV operand.
|
||||
unsigned char OpFlags = 0;
|
||||
|
||||
// On ELF targets, in both X86-64 and X86-32 mode, direct calls to
|
||||
// external symbols most go through the PLT in PIC mode. If the symbol
|
||||
// has hidden or protected visibility, or if it is static or local, then
|
||||
// we don't need to use the PLT - we can directly call it.
|
||||
if (Subtarget->isTargetELF() &&
|
||||
TM.getRelocationModel() == Reloc::PIC_ &&
|
||||
GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) {
|
||||
OpFlags = X86II::MO_PLT;
|
||||
} else if (Subtarget->isPICStyleStubAny() &&
|
||||
!GV->isStrongDefinitionForLinker() &&
|
||||
(!Subtarget->getTargetTriple().isMacOSX() ||
|
||||
Subtarget->getTargetTriple().isMacOSXVersionLT(10, 5))) {
|
||||
// PC-relative references to external symbols should go through $stub,
|
||||
// unless we're building with the leopard linker or later, which
|
||||
// automatically synthesizes these stubs.
|
||||
OpFlags = X86II::MO_DARWIN_STUB;
|
||||
}
|
||||
unsigned char OpFlags = Subtarget->classifyGlobalFunctionReference(GV, TM);
|
||||
// Ignore NonLazyBind attribute in FastISel
|
||||
if (OpFlags == X86II::MO_GOTPCREL)
|
||||
OpFlags = 0;
|
||||
|
||||
MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(CallOpc));
|
||||
if (Symbol)
|
||||
|
@ -3273,31 +3273,8 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
// non-JIT mode.
|
||||
const GlobalValue *GV = G->getGlobal();
|
||||
if (!GV->hasDLLImportStorageClass()) {
|
||||
unsigned char OpFlags = 0;
|
||||
|
||||
// On ELF targets, in both X86-64 and X86-32 mode, direct calls to
|
||||
// external symbols most go through the PLT in PIC mode. If the symbol
|
||||
// has hidden or protected visibility, or if it is static or local, then
|
||||
// we don't need to use the PLT - we can directly call it.
|
||||
if (Subtarget.isTargetELF() &&
|
||||
DAG.getTarget().getRelocationModel() == Reloc::PIC_ &&
|
||||
GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) {
|
||||
OpFlags = X86II::MO_PLT;
|
||||
} else if (Subtarget.isPICStyleStubAny() &&
|
||||
!GV->isStrongDefinitionForLinker() &&
|
||||
(!Subtarget.getTargetTriple().isMacOSX() ||
|
||||
Subtarget.getTargetTriple().isMacOSXVersionLT(10, 5))) {
|
||||
// PC-relative references to external symbols should go through $stub,
|
||||
// unless we're building with the leopard linker or later, which
|
||||
// automatically synthesizes these stubs.
|
||||
OpFlags = X86II::MO_DARWIN_STUB;
|
||||
} else if (Subtarget.isPICStyleRIPRel() && isa<Function>(GV) &&
|
||||
cast<Function>(GV)->hasFnAttribute(Attribute::NonLazyBind)) {
|
||||
// If the function is marked as non-lazy, generate an indirect call
|
||||
// which loads from the GOT directly. This avoids runtime overhead
|
||||
// at the cost of eager binding (and one extra byte of encoding).
|
||||
OpFlags = X86II::MO_GOTPCREL;
|
||||
}
|
||||
unsigned char OpFlags =
|
||||
Subtarget.classifyGlobalFunctionReference(GV, DAG.getTarget());
|
||||
|
||||
Callee = DAG.getTargetGlobalAddress(
|
||||
GV, dl, getPointerTy(DAG.getDataLayout()), G->getOffset(), OpFlags);
|
||||
|
@ -144,6 +144,35 @@ ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const {
|
||||
return X86II::MO_NO_FLAG;
|
||||
}
|
||||
|
||||
unsigned char X86Subtarget::classifyGlobalFunctionReference(
|
||||
const GlobalValue *GV, const TargetMachine &TM) const {
|
||||
// On ELF targets, in both X86-64 and X86-32 mode, direct calls to
|
||||
// external symbols most go through the PLT in PIC mode. If the symbol
|
||||
// has hidden or protected visibility, or if it is static or local, then
|
||||
// we don't need to use the PLT - we can directly call it.
|
||||
// In PIE mode, calls to global functions don't need to go through PLT
|
||||
if (isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ &&
|
||||
(!TM.Options.PositionIndependentExecutable ||
|
||||
GV->isDeclarationForLinker()) &&
|
||||
GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) {
|
||||
return X86II::MO_PLT;
|
||||
} else if (isPICStyleStubAny() && !GV->isStrongDefinitionForLinker() &&
|
||||
(!getTargetTriple().isMacOSX() ||
|
||||
getTargetTriple().isMacOSXVersionLT(10, 5))) {
|
||||
// PC-relative references to external symbols should go through $stub,
|
||||
// unless we're building with the leopard linker or later, which
|
||||
// automatically synthesizes these stubs.
|
||||
return X86II::MO_DARWIN_STUB;
|
||||
} else if (isPICStyleRIPRel() && isa<Function>(GV) &&
|
||||
cast<Function>(GV)->hasFnAttribute(Attribute::NonLazyBind)) {
|
||||
// If the function is marked as non-lazy, generate an indirect call
|
||||
// which loads from the GOT directly. This avoids runtime overhead
|
||||
// at the cost of eager binding (and one extra byte of encoding).
|
||||
return X86II::MO_GOTPCREL;
|
||||
}
|
||||
|
||||
return X86II::MO_NO_FLAG;
|
||||
}
|
||||
|
||||
/// This function returns the name of a function which has an interface like
|
||||
/// the non-standard bzero function, if such a function exists on the
|
||||
|
@ -554,6 +554,11 @@ public:
|
||||
unsigned char ClassifyGlobalReference(const GlobalValue *GV,
|
||||
const TargetMachine &TM)const;
|
||||
|
||||
/// classifyGlobalFunctionReference - Classify a global function reference
|
||||
/// for the current subtarget.
|
||||
unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
|
||||
const TargetMachine &TM) const;
|
||||
|
||||
/// Classify a blockaddress reference for the current subtarget according to
|
||||
/// how we should reference it in a non-pcrel context.
|
||||
unsigned char ClassifyBlockAddressReference() const;
|
||||
|
41
test/CodeGen/X86/pie.ll
Normal file
41
test/CodeGen/X86/pie.ll
Normal file
@ -0,0 +1,41 @@
|
||||
; RUN: llc < %s -O0 -mcpu=generic -mtriple=i686-linux-gnu -relocation-model=pic -enable-pie | FileCheck %s
|
||||
; RUN: llc < %s -O0 -mcpu=generic -mtriple=i686-linux-gnu -fast-isel -relocation-model=pic -enable-pie | FileCheck %s
|
||||
; RUN: llc < %s -O0 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie | FileCheck %s
|
||||
; RUN: llc < %s -O0 -mcpu=generic -mtriple=x86_64-linux-gnu -fast-isel -relocation-model=pic -enable-pie | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: bar:
|
||||
; CHECK: call{{l|q}} foo{{$}}
|
||||
; CHECK: call{{l|q}} weak_odr_foo{{$}}
|
||||
; CHECK: call{{l|q}} weak_foo{{$}}
|
||||
; CHECK: call{{l|q}} internal_foo{{$}}
|
||||
; CHECK: call{{l|q}} ext_baz@PLT
|
||||
|
||||
define weak void @weak_foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define weak_odr void @weak_odr_foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define internal void @internal_foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare i32 @ext_baz()
|
||||
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @bar() {
|
||||
entry:
|
||||
call void @foo()
|
||||
call void @weak_odr_foo()
|
||||
call void @weak_foo()
|
||||
call void @internal_foo()
|
||||
call i32 @ext_baz()
|
||||
ret void
|
||||
}
|
||||
|
||||
; -fpie for local global data tests should be added here
|
Loading…
Reference in New Issue
Block a user