[llvm] r273593 - [X86] Extract HiPE prologue constants into metadata

Michael Kuperstein via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 23 11:17:25 PDT 2016


Author: mkuper
Date: Thu Jun 23 13:17:25 2016
New Revision: 273593

URL: http://llvm.org/viewvc/llvm-project?rev=273593&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
    llvm/trunk/test/CodeGen/X86/hipe-cc.ll
    llvm/trunk/test/CodeGen/X86/hipe-cc64.ll
    llvm/trunk/test/CodeGen/X86/hipe-prologue.ll

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=273593&r1=273592&r2=273593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Thu Jun 23 13:17:25 2016
@@ -2298,6 +2298,28 @@ void X86FrameLowering::adjustForSegmente
 #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::adjustForHiPEProl
   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::adjustForHiPEProl
 
     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);

Modified: llvm/trunk/test/CodeGen/X86/hipe-cc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hipe-cc.ll?rev=273593&r1=273592&r2=273593&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/hipe-cc.ll (original)
+++ llvm/trunk/test/CodeGen/X86/hipe-cc.ll Thu Jun 23 13:17:25 2016
@@ -73,5 +73,9 @@ define cc 11 void @baz() nounwind {
   ret void
 }
 
+!hipe.literals = !{ !0, !1, !2 }
+!0 = !{ !"P_NSP_LIMIT", i32 84 }
+!1 = !{ !"X86_LEAF_WORDS", i32 24 }
+!2 = !{ !"AMD64_LEAF_WORDS", i32 24 }
 @clos = external constant i32
 declare cc 11 void @bar(i32, i32, i32, i32, i32)

Modified: llvm/trunk/test/CodeGen/X86/hipe-cc64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hipe-cc64.ll?rev=273593&r1=273592&r2=273593&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/hipe-cc64.ll (original)
+++ llvm/trunk/test/CodeGen/X86/hipe-cc64.ll Thu Jun 23 13:17:25 2016
@@ -83,5 +83,9 @@ define cc 11 void @baz() nounwind {
   ret void
 }
 
+!hipe.literals = !{ !0, !1, !2 }
+!0 = !{ !"P_NSP_LIMIT", i32 160 }
+!1 = !{ !"X86_LEAF_WORDS", i32 24 }
+!2 = !{ !"AMD64_LEAF_WORDS", i32 24 }
 @clos = external constant i64
 declare cc 11 void @bar(i64, i64, i64, i64, i64, i64)

Modified: llvm/trunk/test/CodeGen/X86/hipe-prologue.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/hipe-prologue.ll?rev=273593&r1=273592&r2=273593&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/hipe-prologue.ll (original)
+++ llvm/trunk/test/CodeGen/X86/hipe-prologue.ll Thu Jun 23 13:17:25 2016
@@ -25,7 +25,7 @@ define {i32, i32} @test_basic(i32 %hp, i
 define cc 11 {i32, i32} @test_basic_hipecc(i32 %hp, i32 %p) {
   ; X32-Linux-LABEL:       test_basic_hipecc:
   ; X32-Linux:       leal -140(%esp), %ebx
-  ; X32-Linux-NEXT:  cmpl 76(%ebp), %ebx
+  ; X32-Linux-NEXT:  cmpl 120(%ebp), %ebx
   ; X32-Linux-NEXT:  jb .LBB1_1
 
   ; X32-Linux:       ret
@@ -34,8 +34,8 @@ define cc 11 {i32, i32} @test_basic_hipe
   ; X32-Linux-NEXT:  calll inc_stack_0
 
   ; X64-Linux-LABEL:       test_basic_hipecc:
-  ; X64-Linux:       leaq -232(%rsp), %r14
-  ; X64-Linux-NEXT:  cmpq 144(%rbp), %r14
+  ; X64-Linux:       leaq -184(%rsp), %r14
+  ; X64-Linux-NEXT:  cmpq 120(%rbp), %r14
   ; X64-Linux-NEXT:  jb .LBB1_1
 
   ; X64-Linux:       ret
@@ -65,3 +65,8 @@ define cc 11 {i32,i32,i32} @test_nocall_
   %6 = insertvalue {i32, i32, i32} %5, i32 %p, 2
   ret {i32, i32, i32} %6
 }
+
+!hipe.literals = !{ !0, !1, !2 }
+!0 = !{ !"P_NSP_LIMIT", i32 120 }
+!1 = !{ !"X86_LEAF_WORDS", i32 24 }
+!2 = !{ !"AMD64_LEAF_WORDS", i32 18 }




More information about the llvm-commits mailing list