Teach gcroot how to handle dynamically realigned frames
authorPhilip Reames <listmail@philipreames.com>
Thu, 2 Apr 2015 05:00:40 +0000 (05:00 +0000)
committerPhilip Reames <listmail@philipreames.com>
Thu, 2 Apr 2015 05:00:40 +0000 (05:00 +0000)
I'm playing with supporting custom stack map formats with statepoints.  While
doing so, I noticed that the existing implementation didn't indicate inherently
unsized frames.  This change essentially just ports the functionality that already
exists for the default StackMaps section to custom stackmaps.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233891 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GCRootLowering.cpp
test/CodeGen/X86/GC/dynamic-frame-size.ll [new file with mode: 0644]

index 9d38e4cad13087fce1f7c3fef0180626d2c77278..ac351656a4ae019dfd2182dacd5740888aa57393 100644 (file)
@@ -332,19 +332,22 @@ bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) {
     return false;
 
   FI = &getAnalysis<GCModuleInfo>().getFunctionInfo(*MF.getFunction());
-  if (!FI->getStrategy().needsSafePoints())
-    return false;
-
   MMI = &getAnalysis<MachineModuleInfo>();
   TII = MF.getSubtarget().getInstrInfo();
 
-  // Find the size of the stack frame.
-  FI->setFrameSize(MF.getFrameInfo()->getStackSize());
+  // Find the size of the stack frame.  There may be no correct static frame
+  // size, we use UINT64_MAX to represent this.
+  const MachineFrameInfo *MFI = MF.getFrameInfo();
+  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
+  const bool DynamicFrameSize = MFI->hasVarSizedObjects() ||
+    RegInfo->needsStackRealignment(MF);
+  FI->setFrameSize(DynamicFrameSize ? UINT64_MAX : MFI->getStackSize());
 
   // Find all safe points.
-  FindSafePoints(MF);
+  if (FI->getStrategy().needsSafePoints())
+    FindSafePoints(MF);
 
-  // Find the stack offsets for all roots.
+  // Find the concrete stack offsets for all roots (stack slots)
   FindStackOffsets(MF);
 
   return false;
diff --git a/test/CodeGen/X86/GC/dynamic-frame-size.ll b/test/CodeGen/X86/GC/dynamic-frame-size.ll
new file mode 100644 (file)
index 0000000..a3583d4
--- /dev/null
@@ -0,0 +1,28 @@
+; RUN: llc < %s | FileCheck %s
+target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+declare void @use(<4 x i8*>*)
+
+; Test that a frame which requires dynamic relocation produces a stack map
+; with a size of UINT64_MAX.
+define void @test(i8* %ptr) gc "erlang" {
+   ; 32 byte alignment (for the alloca) is larger than the default
+   ; 16 byte alignment
+   %slot = alloca <4 x i8*>
+   call void @use(<4 x i8*>* %slot);
+   ret void
+}
+
+; CHECK: .note.gc
+; CHECK-NEXT: .align 8
+; safe point count
+; CHECK .short 1
+; CHECK .long  .Ltmp0
+; stack frame size (in words)
+; CHECK .short -1
+; stack arity (arguments on the stack)
+; CHECK .short 0
+; live root count
+; CHECK .short 0
+