Make stackmap machineinstrs clobber the scratch regs too.
authorAndrew Trick <atrick@apple.com>
Wed, 5 Mar 2014 07:08:16 +0000 (07:08 +0000)
committerAndrew Trick <atrick@apple.com>
Wed, 5 Mar 2014 07:08:16 +0000 (07:08 +0000)
Patchpoints already did this. Doing it for stackmaps is a convenience
for the runtime in the event that it needs to scratch register to
patch or perform a runtime call thunk.

Unlike patchpoints, we just assume the AnyRegCC calling
convention. This is the only language and target independent calling
convention specific to stackmaps so makes sense.  Although the calling
convention is not currently used to select the scratch registers.

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

lib/CodeGen/SelectionDAG/InstrEmitter.cpp
test/CodeGen/X86/stackmap.ll

index 856ef34a2ad2e238da0689e9dd3386cc14b48e91..1c596b8c42eee47cf60950a357e5c271a3503c4a 100644 (file)
@@ -740,10 +740,16 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
   unsigned NumDefs = II.getNumDefs();
   const uint16_t *ScratchRegs = NULL;
 
-  // Handle PATCHPOINT specially and then use the generic code.
-  if (Opc == TargetOpcode::PATCHPOINT) {
-    unsigned CC = Node->getConstantOperandVal(PatchPointOpers::CCPos);
-    NumDefs = NumResults;
+  // Handle STACKMAP and PATCHPOINT specially and then use the generic code.
+  if (Opc == TargetOpcode::STACKMAP || Opc == TargetOpcode::PATCHPOINT) {
+    // Stackmaps do not have arguments and do not preserve their calling
+    // convention. However, to simplify runtime support, they clobber the same
+    // scratch registers as AnyRegCC.
+    unsigned CC = CallingConv::AnyReg;
+    if (Opc == TargetOpcode::PATCHPOINT) {
+      CC = Node->getConstantOperandVal(PatchPointOpers::CCPos);
+      NumDefs = NumResults;
+    }
     ScratchRegs = TLI->getScratchRegisters((CallingConv::ID) CC);
   }
 
index 2b7bb183007c92f8d6bd36c3671711545c5cee76..cfd0c6e884512be93f282cfbbd056968f4bc8c17 100644 (file)
@@ -6,7 +6,7 @@
 ; CHECK-NEXT:  __LLVM_StackMaps:
 ; CHECK-NEXT:   .long 0
 ; Num Functions
-; CHECK-NEXT:   .long 14
+; CHECK-NEXT:   .long 15
 ; CHECK-NEXT:   .long _constantargs
 ; CHECK-NEXT:   .long 8
 ; CHECK-NEXT:   .long _osrinline
 ; CHECK-NEXT:   .long 56
 ; CHECK-NEXT:   .long _longid
 ; CHECK-NEXT:   .long 8
+; CHECK-NEXT:   .long _clobberScratch
+; CHECK-NEXT:   .long 56
 ; Num LargeConstants
 ; CHECK-NEXT:   .long   3
 ; CHECK-NEXT:   .quad   2147483648
 ; CHECK-NEXT:   .quad   4294967295
 ; CHECK-NEXT:   .quad   4294967296
 ; Num Callsites
-; CHECK-NEXT:   .long   18
+; CHECK-NEXT:   .long   19
 
 ; Constant arguments
 ;
@@ -436,6 +438,24 @@ entry:
   ret void
 }
 
+; Map a value when R11 is the only free register.
+; The scratch register should not be used for a live stackmap value.
+;
+; CHECK-LABEL:  .long L{{.*}}-_clobberScratch
+; CHECK-NEXT:   .short 0
+; 1 location
+; CHECK-NEXT:   .short 1
+; Loc 0: Indirect fp - offset
+; CHECK-NEXT:   .byte   3
+; CHECK-NEXT:   .byte   4
+; CHECK-NEXT:   .short  6
+; CHECK-NEXT:   .long   -{{[0-9]+}}
+define void @clobberScratch(i32 %a) {
+  tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r12},~{r13},~{r14},~{r15}"() nounwind
+  tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 16, i32 8, i32 %a)
+  ret void
+}
+
 declare void @llvm.experimental.stackmap(i64, i32, ...)
 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
 declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)