summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86TargetMachine.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-06-21 21:55:08 +0000
committerReid Kleckner <rnk@google.com>2018-06-21 21:55:08 +0000
commit247fe6aeab964e31cb03beba3cf3f6a2cb972c31 (patch)
tree8dd9dfd25d4b8bd3e969dfb8030c2260e4f57716 /llvm/lib/Target/X86/X86TargetMachine.cpp
parent307c2eb94fcf943d30346c5a24a44cbdf00ac024 (diff)
downloadbcm5719-llvm-247fe6aeab964e31cb03beba3cf3f6a2cb972c31.tar.gz
bcm5719-llvm-247fe6aeab964e31cb03beba3cf3f6a2cb972c31.zip
[X86] Implement more of x86-64 large and medium PIC code models
Summary: The large code model allows code and data segments to exceed 2GB, which means that some symbol references may require a displacement that cannot be encoded as a displacement from RIP. The large PIC model even relaxes the assumption that the GOT itself is within 2GB of all code. Therefore, we need a special code sequence to materialize it: .LtmpN: leaq .LtmpN(%rip), %rbx movabsq $_GLOBAL_OFFSET_TABLE_-.LtmpN, %rax # Scratch addq %rax, %rbx # GOT base reg From that, non-local references go through the GOT base register instead of being PC-relative loads. Local references typically use GOTOFF symbols, like this: movq extern_gv@GOT(%rbx), %rax movq local_gv@GOTOFF(%rbx), %rax All calls end up being indirect: movabsq $local_fn@GOTOFF, %rax addq %rbx, %rax callq *%rax The medium code model retains the assumption that the code segment is less than 2GB, so calls are once again direct, and the RIP-relative loads can be used to access the GOT. Materializing the GOT is easy: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rbx # GOT base reg DSO local data accesses will use it: movq local_gv@GOTOFF(%rbx), %rax Non-local data accesses will use RIP-relative addressing, which means we may not always need to materialize the GOT base: movq extern_gv@GOTPCREL(%rip), %rax Direct calls are basically the same as they are in the small code model: They use direct, PC-relative addressing, and the PLT is used for calls to non-local functions. This patch adds reasonably comprehensive testing of LEA, but there are lots of interesting folding opportunities that are unimplemented. Reviewers: chandlerc, echristo Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D47211 llvm-svn: 335297
Diffstat (limited to 'llvm/lib/Target/X86/X86TargetMachine.cpp')
-rw-r--r--llvm/lib/Target/X86/X86TargetMachine.cpp5
1 files changed, 4 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index a713bddf7bf..92f5e795d7d 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -156,6 +156,7 @@ static std::string computeDataLayout(const Triple &TT) {
}
static Reloc::Model getEffectiveRelocModel(const Triple &TT,
+ bool JIT,
Optional<Reloc::Model> RM) {
bool is64Bit = TT.getArch() == Triple::x86_64;
if (!RM.hasValue()) {
@@ -167,6 +168,8 @@ static Reloc::Model getEffectiveRelocModel(const Triple &TT,
return Reloc::PIC_;
return Reloc::DynamicNoPIC;
}
+ if (JIT)
+ return Reloc::Static;
if (TT.isOSWindows() && is64Bit)
return Reloc::PIC_;
return Reloc::Static;
@@ -210,7 +213,7 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
CodeGenOpt::Level OL, bool JIT)
: LLVMTargetMachine(
T, computeDataLayout(TT), TT, CPU, FS, Options,
- getEffectiveRelocModel(TT, RM),
+ getEffectiveRelocModel(TT, JIT, RM),
getEffectiveCodeModel(CM, JIT, TT.getArch() == Triple::x86_64), OL),
TLOF(createTLOF(getTargetTriple())) {
// Windows stack unwinder gets confused when execution flow "falls through"
OpenPOWER on IntegriCloud