[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