summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-12-30 20:05:19 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2014-12-30 20:05:19 +0000
commit7ef497b1f5758bb19ecac851a1f7918a5f029377 (patch)
tree695cb749a4fb826f259f5b1b42e98f48605e68fa
parenta7ee2734cf8d7756ea134936ce6a7ae995d736c0 (diff)
downloadbcm5719-llvm-7ef497b1f5758bb19ecac851a1f7918a5f029377.tar.gz
bcm5719-llvm-7ef497b1f5758bb19ecac851a1f7918a5f029377.zip
x86_64: Fix calls to __morestack under the large code model.
Under the large code model, we cannot assume that __morestack lives within 2^31 bytes of the call site, so we cannot use pc-relative addressing. We cannot perform the call via a temporary register, as the rax register may be used to store the static chain, and all other suitable registers may be either callee-save or used for parameter passing. We cannot use the stack at this point either because __morestack manipulates the stack directly. To avoid these issues, perform an indirect call via a read-only memory location containing the address. This solution is not perfect, as it assumes that the .rodata section is laid out within 2^31 bytes of each function body, but this seems to be sufficient for JIT. Differential Revision: http://reviews.llvm.org/D6787 llvm-svn: 225003
-rw-r--r--llvm/include/llvm/CodeGen/MachineModuleInfo.h15
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp17
-rw-r--r--llvm/lib/CodeGen/MachineModuleInfo.cpp2
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp36
-rw-r--r--llvm/test/CodeGen/X86/segmented-stacks.ll15
5 files changed, 78 insertions, 7 deletions
diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 287b3ebb0e2..584ce65c9d1 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -161,6 +161,13 @@ class MachineModuleInfo : public ImmutablePass {
/// to _fltused on Windows targets.
bool UsesVAFloatArgument;
+ /// UsesMorestackAddr - True if the module calls the __morestack function
+ /// indirectly, as is required under the large code model on x86. This is used
+ /// to emit a definition of a symbol, __morestack_addr, containing the
+ /// address. See comments in lib/Target/X86/X86FrameLowering.cpp for more
+ /// details.
+ bool UsesMorestackAddr;
+
public:
static char ID; // Pass identification, replacement for typeid
@@ -234,6 +241,14 @@ public:
UsesVAFloatArgument = b;
}
+ bool usesMorestackAddr() const {
+ return UsesMorestackAddr;
+ }
+
+ void setUsesMorestackAddr(bool b) {
+ UsesMorestackAddr = b;
+ }
+
/// \brief Returns a reference to a list of cfi instructions in the current
/// function's prologue. Used to construct frame maps for debug and exception
/// handling comsumers.
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 97ef12c8328..ff8fc60e603 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1011,6 +1011,23 @@ bool AsmPrinter::doFinalization(Module &M) {
// Emit llvm.ident metadata in an '.ident' directive.
EmitModuleIdents(M);
+ // Emit __morestack address if needed for indirect calls.
+ if (MMI->usesMorestackAddr()) {
+ const MCSection *ReadOnlySection =
+ getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly(),
+ /*C=*/nullptr);
+ OutStreamer.SwitchSection(ReadOnlySection);
+
+ MCSymbol *AddrSymbol =
+ OutContext.GetOrCreateSymbol(StringRef("__morestack_addr"));
+ OutStreamer.EmitLabel(AddrSymbol);
+
+ const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout();
+ unsigned PtrSize = DL.getPointerSize(0);
+ OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("__morestack"),
+ PtrSize);
+ }
+
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index eb3c0bf224d..baad411e2c5 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -273,7 +273,7 @@ bool MachineModuleInfo::doInitialization(Module &M) {
CurCallSite = 0;
CallsEHReturn = 0;
CallsUnwindInit = 0;
- DbgInfoAvailable = UsesVAFloatArgument = false;
+ DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
// Always emit some info, by default "no personality" info.
Personalities.push_back(nullptr);
AddrLabelSymbols = nullptr;
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index c408fddf890..95bca7d936f 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1648,12 +1648,36 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
}
// __morestack is in libgcc
- if (Is64Bit)
- BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32))
- .addExternalSymbol("__morestack");
- else
- BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32))
- .addExternalSymbol("__morestack");
+ if (Is64Bit && MF.getTarget().getCodeModel() == CodeModel::Large) {
+ // Under the large code model, we cannot assume that __morestack lives
+ // within 2^31 bytes of the call site, so we cannot use pc-relative
+ // addressing. We cannot perform the call via a temporary register,
+ // as the rax register may be used to store the static chain, and all
+ // other suitable registers may be either callee-save or used for
+ // parameter passing. We cannot use the stack at this point either
+ // because __morestack manipulates the stack directly.
+ //
+ // To avoid these issues, perform an indirect call via a read-only memory
+ // location containing the address.
+ //
+ // This solution is not perfect, as it assumes that the .rodata section
+ // is laid out within 2^31 bytes of each function body, but this seems
+ // to be sufficient for JIT.
+ BuildMI(allocMBB, DL, TII.get(X86::CALL64m))
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addExternalSymbol("__morestack_addr")
+ .addReg(0);
+ MF.getMMI().setUsesMorestackAddr(true);
+ } else {
+ if (Is64Bit)
+ BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32))
+ .addExternalSymbol("__morestack");
+ else
+ BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32))
+ .addExternalSymbol("__morestack");
+ }
if (IsNested)
BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET_RESTORE_R10));
diff --git a/llvm/test/CodeGen/X86/segmented-stacks.ll b/llvm/test/CodeGen/X86/segmented-stacks.ll
index 45e157ff7c7..3e47121a380 100644
--- a/llvm/test/CodeGen/X86/segmented-stacks.ll
+++ b/llvm/test/CodeGen/X86/segmented-stacks.ll
@@ -1,5 +1,6 @@
; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -verify-machineinstrs | FileCheck %s -check-prefix=X32-Linux
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux
+; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux -code-model=large -verify-machineinstrs | FileCheck %s -check-prefix=X64-Linux-Large
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-linux-gnux32 -verify-machineinstrs | FileCheck %s -check-prefix=X32ABI
; RUN: llc < %s -mcpu=generic -mtriple=i686-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X32-Darwin
; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin
@@ -57,6 +58,16 @@ define void @test_basic() #0 {
; X64-Linux-NEXT: callq __morestack
; X64-Linux-NEXT: ret
+; X64-Linux-Large-LABEL: test_basic:
+
+; X64-Linux-Large: cmpq %fs:112, %rsp
+; X64-Linux-Large-NEXT: ja .LBB0_2
+
+; X64-Linux-Large: movabsq $40, %r10
+; X64-Linux-Large-NEXT: movabsq $0, %r11
+; X64-Linux-Large-NEXT: callq *__morestack_addr(%rip)
+; X64-Linux-Large-NEXT: ret
+
; X32ABI-LABEL: test_basic:
; X32ABI: cmpl %fs:64, %esp
@@ -626,3 +637,7 @@ define void @test_nostack() #0 {
}
attributes #0 = { "split-stack" }
+
+; X64-Linux-Large: .rodata
+; X64-Linux-Large-NEXT: __morestack_addr:
+; X64-Linux-Large-NEXT: .quad __morestack
OpenPOWER on IntegriCloud