[llvm] dedcefe - [Statepoint] Constant fold FP deopt args.

Denis Antrushin via llvm-commits llvm-commits at lists.llvm.org
Thu May 21 01:06:43 PDT 2020


Author: Denis Antrushin
Date: 2020-05-21T11:02:54+03:00
New Revision: dedcefe09d18f1e9d60336541fb6ad03dae551ba

URL: https://github.com/llvm/llvm-project/commit/dedcefe09d18f1e9d60336541fb6ad03dae551ba
DIFF: https://github.com/llvm/llvm-project/commit/dedcefe09d18f1e9d60336541fb6ad03dae551ba.diff

LOG: [Statepoint] Constant fold FP deopt args.

We do not have any special handling for constant FP deopt arguments.
They are just spilled to stack or generated in register by MOVS
instruction. This is inefficient and, when we have too many such
constant arguments, may result in register allocation failure.
Instead, we can bitcast such constant FP operands to appropriately
sized integer and record as constant into statepoint and later, into
StackMap.

Reviewed By: skatkov
Differential Revision: https://reviews.llvm.org/D80318

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
    llvm/test/CodeGen/X86/statepoint-regs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
index cd0b976ba43f..d64515d763d3 100644
--- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp
@@ -229,7 +229,8 @@ static void reservePreviousStackSlotForValue(const Value *IncomingValue,
                                              SelectionDAGBuilder &Builder) {
   SDValue Incoming = Builder.getValue(IncomingValue);
 
-  if (isa<ConstantSDNode>(Incoming) || isa<FrameIndexSDNode>(Incoming)) {
+  if (isa<ConstantSDNode>(Incoming) || isa<ConstantFPSDNode>(Incoming) ||
+      isa<FrameIndexSDNode>(Incoming)) {
     // We won't need to spill this, so no need to check for previously
     // allocated stack slots
     return;
@@ -387,13 +388,16 @@ lowerIncomingStatepointValue(SDValue Incoming, bool RequireSpillSlot,
   // doing it here would be a small compile time win at most.
   SDValue Chain = Builder.getRoot();
 
-  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) {
-    // If the original value was a constant, make sure it gets recorded as
-    // such in the stackmap.  This is required so that the consumer can
-    // parse any internal format to the deopt state.  It also handles null
-    // pointers and other constant pointers in GC states.  Note the constant
-    // vectors do not appear to actually hit this path and that anything larger
-    // than an i64 value (not type!) will fail asserts here.
+  // If the original value was a constant, make sure it gets recorded as
+  // such in the stackmap.  This is required so that the consumer can
+  // parse any internal format to the deopt state.  It also handles null
+  // pointers and other constant pointers in GC states.  Note the constant
+  // vectors do not appear to actually hit this path and that anything larger
+  // than an i64 value (not type!) will fail asserts here.
+  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Incoming)) {
+    pushStackMapConstant(Ops, Builder,
+                         C->getValueAPF().bitcastToAPInt().getZExtValue());
+  } else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Incoming)) {
     pushStackMapConstant(Ops, Builder, C->getSExtValue());
   } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Incoming)) {
     // This handles allocas as arguments to the statepoint (this is only

diff  --git a/llvm/test/CodeGen/X86/statepoint-regs.ll b/llvm/test/CodeGen/X86/statepoint-regs.ll
index e3333bd51ab7..0f5bad8ee7dd 100644
--- a/llvm/test/CodeGen/X86/statepoint-regs.ll
+++ b/llvm/test/CodeGen/X86/statepoint-regs.ll
@@ -672,6 +672,168 @@ entry:
   ret void
 }
 
+define i32 addrspace(1)*  @test_fpconst_deopt(i32 addrspace(1)* %in) gc "statepoint-example" {
+; CHECK-LABEL: test_fpconst_deopt:
+; CHECK:       ## %bb.0:
+; CHECK-NEXT:    pushq %rax
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    movq %rdi, (%rsp)
+; CHECK-NEXT:    nopl 8(%rax,%rax)
+; CHECK-NEXT:  Ltmp18:
+; CHECK-NEXT:    movq (%rsp), %rax
+; CHECK-NEXT:    popq %rcx
+; CHECK-NEXT:    retq
+    %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2, i32 5, void ()* nonnull @bar, i32 0, i32 0, i32 0, i32 20,
+    float 0x40421A1CA0000000, float 0x40459A1CA0000000, float 0x40401A1CA0000000, float 0x40479A1CA0000000, float 0x403C343940000000,
+    float 0x403E343940000000, float 0x40469A1CA0000000, float 0x40489A1CA0000000, float 0x404A9A1CA0000000, float 0x40499A1CA0000000,
+    float 0xC05FCD2F20000000, float 0xC05C0D2F20000000, float 0xC060269780000000, float 0xC05B8D2F20000000, float 0xC060669780000000,
+    float 0xC05B0D2F20000000, float 0xC060A69780000000, float 0xC05A8D2F20000000, float 0xC060E69780000000, float 0x40439A1CA0000000, i32 addrspace(1)* %in)
+    %out = call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token %statepoint_token, i32 27, i32 27)
+    ret i32 addrspace(1)* %out
+}
+; CHECK-LABEL: __LLVM_StackMaps:
+; CHECK: .long   Ltmp18-_test_fpconst_deopt
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .short	25
+; CHECK-NEXT: .byte	4
+; CHECK-NEXT: .byte	0
+; CHECK-NEXT: .short	8
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .long	0
+; CHECK-NEXT: .byte	4
+; CHECK-NEXT: .byte	0
+; CHECK-NEXT: .short	8
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .long	0
+; CHECK-NEXT: .byte	4
+; CHECK-NEXT: .byte	0
+; CHECK-NEXT: .short	8
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .short	0
+; CHECK-NEXT: .long	20
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1108398309
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1110233317
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1107349733
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1111281893
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1105306058
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1106354634
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1110757605
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1111806181
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1112854757
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1112330469
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	0
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	2
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	3
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	4
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	5
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	6
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	7
+; CHECK: .byte	5
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	8
+; CHECK: .byte	4
+; CHECK: .byte	0
+; CHECK: .short	8
+; CHECK: .short	0
+; CHECK: .short	0
+; CHECK: .long	1109184741
+
 declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...)
 declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32, i32)
 


        


More information about the llvm-commits mailing list