1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

New llc option pie-copy-relocations to optimize access to extern globals.

This option indicates copy relocations support is available from the linker
when building as PIE and allows accesses to extern globals to avoid the GOT.

Differential Revision: https://reviews.llvm.org/D24849

llvm-svn: 284160
This commit is contained in:
Sriraman Tallam 2016-10-13 20:54:39 +00:00
parent 7c2dd71bf8
commit 404f8de41a
5 changed files with 129 additions and 5 deletions

View File

@ -41,6 +41,7 @@ public:
bool MCSaveTempLabels : 1;
bool MCUseDwarfDirectory : 1;
bool MCIncrementalLinkerCompatible : 1;
bool MCPIECopyRelocations : 1;
bool ShowMCEncoding : 1;
bool ShowMCInst : 1;
bool AsmVerbose : 1;
@ -67,6 +68,7 @@ inline bool operator==(const MCTargetOptions &LHS, const MCTargetOptions &RHS) {
ARE_EQUAL(MCSaveTempLabels) &&
ARE_EQUAL(MCUseDwarfDirectory) &&
ARE_EQUAL(MCIncrementalLinkerCompatible) &&
ARE_EQUAL(MCPIECopyRelocations) &&
ARE_EQUAL(ShowMCEncoding) &&
ARE_EQUAL(ShowMCInst) &&
ARE_EQUAL(AsmVerbose) &&

View File

@ -38,6 +38,8 @@ cl::opt<bool> IncrementalLinkerCompatible(
"When used with filetype=obj, "
"emit an object file which can be used with an incremental linker"));
cl::opt<bool> PIECopyRelocations("pie-copy-relocations", cl::desc("PIE Copy Relocations"));
cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
cl::init(0));
@ -62,6 +64,7 @@ static inline MCTargetOptions InitMCTargetOptionsFromFlags() {
(AsmInstrumentation == MCTargetOptions::AsmInstrumentationAddress);
Options.MCRelaxAll = RelaxAll;
Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
Options.MCPIECopyRelocations = PIECopyRelocations;
Options.DwarfVersion = DwarfVersion;
Options.ShowMCInst = ShowMCInst;
Options.ABIName = ABIName;

View File

@ -16,7 +16,8 @@ MCTargetOptions::MCTargetOptions()
: SanitizeAddress(false), MCRelaxAll(false), MCNoExecStack(false),
MCFatalWarnings(false), MCNoWarn(false), MCSaveTempLabels(false),
MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false),
ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
MCPIECopyRelocations(false), ShowMCEncoding(false),
ShowMCInst(false), AsmVerbose(false),
PreserveAsmComments(true), DwarfVersion(0), ABIName() {}
StringRef MCTargetOptions::getABIName() const {

View File

@ -115,9 +115,6 @@ static TLSModel::Model getSelectedTLSModel(const GlobalValue *GV) {
llvm_unreachable("invalid TLS model");
}
// FIXME: make this a proper option
static bool CanUseCopyRelocWithPIE = false;
bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
const GlobalValue *GV) const {
Reloc::Model RM = getRelocationModel();
@ -154,8 +151,10 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
return true;
bool IsTLS = GV && GV->isThreadLocal();
bool IsAccessViaCopyRelocs =
Options.MCOptions.MCPIECopyRelocations && GV && isa<GlobalVariable>(GV);
// Check if we can use copy relocations.
if (!IsTLS && (RM == Reloc::Static || CanUseCopyRelocWithPIE))
if (!IsTLS && (RM == Reloc::Static || IsAccessViaCopyRelocs))
return true;
}

View File

@ -0,0 +1,119 @@
; RUN: llc < %s -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -pie-copy-relocations \
; RUN: | FileCheck -check-prefix=X64 %s
; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -pie-copy-relocations \
; RUN: | FileCheck -check-prefix=X32 %s
; External Linkage
@a = global i32 0, align 4
define i32 @my_access_global_a() #0 {
; X32-LABEL: my_access_global_a:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
; X32-NEXT: movl a@GOTOFF(%eax), %eax
; X64-LABEL: my_access_global_a:
; X64: movl a(%rip), %eax
entry:
%0 = load i32, i32* @a, align 4
ret i32 %0
}
; WeakAny Linkage
@b = weak global i32 0, align 4
define i32 @my_access_global_b() #0 {
; X32-LABEL: my_access_global_b:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
; X32-NEXT: movl b@GOTOFF(%eax), %eax
; X64-LABEL: my_access_global_b:
; X64: movl b(%rip), %eax
entry:
%0 = load i32, i32* @b, align 4
ret i32 %0
}
; Internal Linkage
@c = internal global i32 0, align 4
define i32 @my_access_global_c() #0 {
; X32-LABEL: my_access_global_c:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
; X32-NEXT: movl c@GOTOFF(%eax), %eax
; X64-LABEL: my_access_global_c:
; X64: movl c(%rip), %eax
entry:
%0 = load i32, i32* @c, align 4
ret i32 %0
}
; External Linkage, only declaration.
@d = external global i32, align 4
define i32 @my_access_global_load_d() #0 {
; X32-LABEL: my_access_global_load_d:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
; X32-NEXT: movl d@GOTOFF(%eax), %eax
; X64-LABEL: my_access_global_load_d:
; X64: movl d(%rip), %eax
entry:
%0 = load i32, i32* @d, align 4
ret i32 %0
}
; External Linkage, only declaration, store a value.
define i32 @my_access_global_store_d() #0 {
; X32-LABEL: my_access_global_store_d:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
; X32-NEXT: movl $2, d@GOTOFF(%eax)
; X64-LABEL: my_access_global_store_d:
; X64: movl $2, d(%rip)
entry:
store i32 2, i32* @d, align 4
ret i32 0
}
; External Linkage, function pointer access.
declare i32 @access_fp(i32 ()*)
declare i32 @foo()
define i32 @my_access_fp_foo() #0 {
; X32-LABEL: my_access_fp_foo:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %ebx
; X32-NEXT: movl foo@GOT(%ebx), %eax
; X64-LABEL: my_access_fp_foo:
; X64: movq foo@GOTPCREL(%rip), %rdi
entry:
%call = call i32 @access_fp(i32 ()* @foo)
ret i32 %call
}
; LinkOnceODR Linkage, function pointer access.
$bar = comdat any
define linkonce_odr i32 @bar() comdat {
entry:
ret i32 0
}
define i32 @my_access_fp_bar() #0 {
; X32-LABEL: my_access_fp_bar:
; X32: addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %ebx
; X32-NEXT: leal bar@GOTOFF(%ebx), %eax
; X64-LABEL: my_access_fp_bar:
; X64: leaq bar(%rip), %rdi
entry:
%call = call i32 @access_fp(i32 ()* @bar)
ret i32 %call
}
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"PIC Level", i32 1}
!1 = !{i32 1, !"PIE Level", i32 1}