diff options
author | Michael Kuperstein <mkuper@google.com> | 2016-06-23 18:17:25 +0000 |
---|---|---|
committer | Michael Kuperstein <mkuper@google.com> | 2016-06-23 18:17:25 +0000 |
commit | 0194d30e09252492207c2920c3871bcde6c648ec (patch) | |
tree | 99102b810dd46b4fbbc8e18beb996ef6e50892dd /llvm/lib/Target/X86/X86FrameLowering.cpp | |
parent | e3ffbc38d92ac2776631ac4a9de470bcebac743a (diff) | |
download | bcm5719-llvm-0194d30e09252492207c2920c3871bcde6c648ec.tar.gz bcm5719-llvm-0194d30e09252492207c2920c3871bcde6c648ec.zip |
[X86] Extract HiPE prologue constants into metadata
X86FrameLowering::adjustForHiPEPrologue() contains a hard-coded offset
into an Erlang Runtime System-internal data structure (the PCB). As the
layout of this data structure is prone to change, this poses problems
for maintaining compatibility.
To address this problem, the compiler can produce this information as
module-level named metadata. For example (where P_NSP_LIMIT is the
offending offset):
!hipe.literals = !{ !2, !3, !4 }
!2 = !{ !"P_NSP_LIMIT", i32 152 }
!3 = !{ !"X86_LEAF_WORDS", i32 24 }
!4 = !{ !"AMD64_LEAF_WORDS", i32 24 }
Patch by Magnus Lang
Differential Revision: http://reviews.llvm.org/D20363
llvm-svn: 273593
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 83446336fd7..ab219f680ba 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2298,6 +2298,28 @@ void X86FrameLowering::adjustForSegmentedStacks( #endif } +/// Lookup an ERTS parameter in the !hipe.literals named metadata node. +/// HiPE provides Erlang Runtime System-internal parameters, such as PCB offsets +/// to fields it needs, through a named metadata node "hipe.literals" containing +/// name-value pairs. +static unsigned getHiPELiteral( + NamedMDNode *HiPELiteralsMD, const StringRef LiteralName) { + for (int i = 0, e = HiPELiteralsMD->getNumOperands(); i != e; ++i) { + MDNode *Node = HiPELiteralsMD->getOperand(i); + if (Node->getNumOperands() != 2) continue; + MDString *NodeName = dyn_cast<MDString>(Node->getOperand(0)); + ValueAsMetadata *NodeVal = dyn_cast<ValueAsMetadata>(Node->getOperand(1)); + if (!NodeName || !NodeVal) continue; + ConstantInt *ValConst = dyn_cast_or_null<ConstantInt>(NodeVal->getValue()); + if (ValConst && NodeName->getString() == LiteralName) { + return ValConst->getZExtValue(); + } + } + + report_fatal_error("HiPE literal " + LiteralName + + " required but not provided"); +} + /// Erlang programs may need a special prologue to handle the stack size they /// might need at runtime. That is because Erlang/OTP does not implement a C /// stack but uses a custom implementation of hybrid stack/heap architecture. @@ -2323,7 +2345,14 @@ void X86FrameLowering::adjustForHiPEPrologue( assert(&(*MF.begin()) == &PrologueMBB && "Shrink-wrapping not supported yet"); // HiPE-specific values - const unsigned HipeLeafWords = 24; + NamedMDNode *HiPELiteralsMD = MF.getMMI().getModule() + ->getNamedMetadata("hipe.literals"); + if (!HiPELiteralsMD) + report_fatal_error( + "Can't generate HiPE prologue without runtime parameters"); + const unsigned HipeLeafWords + = getHiPELiteral(HiPELiteralsMD, + Is64Bit ? "AMD64_LEAF_WORDS" : "X86_LEAF_WORDS"); const unsigned CCRegisteredArgs = Is64Bit ? 6 : 5; const unsigned Guaranteed = HipeLeafWords * SlotSize; unsigned CallerStkArity = MF.getFunction()->arg_size() > CCRegisteredArgs ? @@ -2395,20 +2424,19 @@ void X86FrameLowering::adjustForHiPEPrologue( unsigned ScratchReg, SPReg, PReg, SPLimitOffset; unsigned LEAop, CMPop, CALLop; + SPLimitOffset = getHiPELiteral(HiPELiteralsMD, "P_NSP_LIMIT"); if (Is64Bit) { SPReg = X86::RSP; PReg = X86::RBP; LEAop = X86::LEA64r; CMPop = X86::CMP64rm; CALLop = X86::CALL64pcrel32; - SPLimitOffset = 0x90; } else { SPReg = X86::ESP; PReg = X86::EBP; LEAop = X86::LEA32r; CMPop = X86::CMP32rm; CALLop = X86::CALLpcrel32; - SPLimitOffset = 0x4c; } ScratchReg = GetScratchRegister(Is64Bit, IsLP64, MF, true); |