diff options
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp | 22 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/statepoint-stack-usage.ll | 8 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/statepoint-stackmap-format.ll | 149 |
3 files changed, 148 insertions, 31 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp index 6c40053cb46..4a21ce247c9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/StatepointLowering.cpp @@ -473,11 +473,12 @@ static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, SDValue Incoming = Builder.getValue(V); reservePreviousStackSlotForValue(Incoming, Builder); } - for (unsigned i = 0; i < Bases.size() * 2; ++i) { - // Even elements will contain base, odd elements - derived ptr - const Value *V = i % 2 ? Bases[i / 2] : Ptrs[i / 2]; - SDValue Incoming = Builder.getValue(V); - reservePreviousStackSlotForValue(Incoming, Builder); + for (unsigned i = 0; i < Bases.size(); ++i) { + const Value *Base = Bases[i]; + reservePreviousStackSlotForValue(Builder.getValue(Base), Builder); + + const Value *Ptr = Ptrs[i]; + reservePreviousStackSlotForValue(Builder.getValue(Ptr), Builder); } // First, prefix the list with the number of unique values to be @@ -512,11 +513,12 @@ static void lowerStatepointMetaArgs(SmallVectorImpl<SDValue> &Ops, // arrays interwoven with each (lowered) base pointer immediately followed by // it's (lowered) derived pointer. i.e // (base[0], ptr[0], base[1], ptr[1], ...) - for (unsigned i = 0; i < Bases.size() * 2; ++i) { - // Even elements will contain base, odd elements - derived ptr - const Value *V = i % 2 ? Bases[i / 2] : Ptrs[i / 2]; - SDValue Incoming = Builder.getValue(V); - lowerIncomingStatepointValue(Incoming, Ops, Builder); + for (unsigned i = 0; i < Bases.size(); ++i) { + const Value *Base = Bases[i]; + lowerIncomingStatepointValue(Builder.getValue(Base), Ops, Builder); + + const Value *Ptr = Ptrs[i]; + lowerIncomingStatepointValue(Builder.getValue(Ptr), Ops, Builder); } // If there are any explicit spill slots passed to the statepoint, record diff --git a/llvm/test/CodeGen/X86/statepoint-stack-usage.ll b/llvm/test/CodeGen/X86/statepoint-stack-usage.ll index c40fabf71c3..7c472880638 100644 --- a/llvm/test/CodeGen/X86/statepoint-stack-usage.ll +++ b/llvm/test/CodeGen/X86/statepoint-stack-usage.ll @@ -11,8 +11,8 @@ target triple = "x86_64-pc-linux-gnu" define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: back_to_back_calls ; The exact stores don't matter, but there need to be three stack slots created -; CHECK: movq %rdx, 16(%rsp) -; CHECK: movq %rdi, 8(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rdx, 8(%rsp) ; CHECK: movq %rsi, (%rsp) %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10) @@ -34,8 +34,8 @@ define i32 @back_to_back_calls(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 a define i32 @reserve_first(i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) #1 gc "statepoint-example" { ; CHECK-LABEL: reserve_first ; The exact stores don't matter, but there need to be three stack slots created -; CHECK: movq %rdx, 16(%rsp) -; CHECK: movq %rdi, 8(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rdx, 8(%rsp) ; CHECK: movq %rsi, (%rsp) %safepoint_token = tail call i32 (void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(void ()* undef, i32 0, i32 0, i32 0, i32 5, i32 0, i32 -1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a, i32 addrspace(1)* %b, i32 addrspace(1)* %c) %a1 = tail call coldcc i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 10, i32 10) diff --git a/llvm/test/CodeGen/X86/statepoint-stackmap-format.ll b/llvm/test/CodeGen/X86/statepoint-stackmap-format.ll index 371af83527d..14f48bce9fa 100644 --- a/llvm/test/CodeGen/X86/statepoint-stackmap-format.ll +++ b/llvm/test/CodeGen/X86/statepoint-stackmap-format.ll @@ -8,32 +8,64 @@ target triple = "x86_64-pc-linux-gnu" declare zeroext i1 @return_i1() -define i1 @test(i32 addrspace(1)* %ptr) gc "statepoint-example" { +define i1 @test(i32 addrspace(1)* %ptr_base, i32 %arg) + gc "statepoint-example" { ; CHECK-LABEL: test -; Do we see one spill for the local value and the store to the +; Do we see two spills for the local values and the store to the ; alloca? -; CHECK: subq $24, %rsp -; CHECK: movq $0, 8(%rsp) -; CHECK: movq %rdi, (%rsp) +; CHECK: subq $40, %rsp +; CHECK: movq $0, 24(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rax, 8(%rsp) ; CHECK: callq return_i1 -; CHECK: addq $24, %rsp +; CHECK: addq $40, %rsp ; CHECK: retq entry: %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 - %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr, i32 addrspace(1)* null, i32 addrspace(1)* %ptr, i32 addrspace(1)* null) + %ptr_derived = getelementptr i32, i32 addrspace(1)* %ptr_base, i32 %arg + %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null) %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) - %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 8, i32 8) + %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8) + %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) ; ret i1 %call1 } +; This is similar to the previous test except that we have derived pointer as +; argument to the function. Despite that this can not happen after the +; RewriteSafepointForGC pass, lowering should be able to handle it anyway. +define i1 @test_derived_arg(i32 addrspace(1)* %ptr_base, + i32 addrspace(1)* %ptr_derived) + gc "statepoint-example" { +; CHECK-LABEL: test_derived_arg +; Do we see two spills for the local values and the store to the +; alloca? +; CHECK: subq $40, %rsp +; CHECK: movq $0, 24(%rsp) +; CHECK: movq %rdi, 16(%rsp) +; CHECK: movq %rsi, 8(%rsp) +; CHECK: callq return_i1 +; CHECK: addq $40, %rsp +; CHECK: retq +entry: + %metadata1 = alloca i32 addrspace(1)*, i32 2, align 8 + store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1 + %safepoint_token = tail call i32 (i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* null, i32 addrspace(1)* %ptr_base, i32 addrspace(1)* %ptr_derived, i32 addrspace(1)* null) + %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token) + %a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7) + %b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 8) + %c = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 9, i32 9) +; + ret i1 %call1 +} + + declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...) declare i1 @llvm.experimental.gc.result.i1(i32) declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 - ; CHECK-LABEL: .section .llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header @@ -41,15 +73,21 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions -; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 2 ; Num LargeConstants ; CHECK-NEXT: .long 0 ; Num Callsites -; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 2 ; Functions and stack size ; CHECK-NEXT: .quad test -; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad 40 +; CHECK-NEXT: .quad test_derived_arg +; CHECK-NEXT: .quad 40 + +; +; test +; ; Large Constants ; Statepoint ID only @@ -59,7 +97,7 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 ; Constant arguments ; CHECK: .long .Ltmp1-test ; CHECK: .short 0 -; CHECK: .short 8 +; CHECK: .short 10 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -74,7 +112,7 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 -; CHECK: .long 0 +; CHECK: .long 16 ; SmallConstant (0) ; CHECK: .byte 4 ; CHECK: .byte 8 @@ -90,20 +128,97 @@ declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3 ; CHECK: .byte 8 ; CHECK: .short 0 ; CHECK: .long 0 -; Direct Spill Slot [RSP+0] +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 +; Direct Spill Slot [RSP+8] ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 +; CHECK: .long 8 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 + +; No Padding or LiveOuts +; CHECK: .short 0 +; CHECK: .short 0 +; CHECK: .align 8 + +; +; test_derived_arg +; + +; Large Constants +; Statepoint ID only +; CHECK: .quad 2882400000 + +; Callsites +; Constant arguments +; CHECK: .long .Ltmp3-test_derived_arg +; CHECK: .short 0 +; CHECK: .short 10 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 ; CHECK: .long 0 +; SmallConstant (2) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 2 ; Direct Spill Slot [RSP+0] ; CHECK: .byte 2 ; CHECK: .byte 8 ; CHECK: .short 7 +; CHECK: .long 16 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 0 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 ; CHECK: .long 0 +; SmallConstant (0) +; CHECK: .byte 4 +; CHECK: .byte 8 +; CHECK: .short 0 +; CHECK: .long 0 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 +; Direct Spill Slot [RSP+8] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 8 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 +; Direct Spill Slot [RSP+16] +; CHECK: .byte 2 +; CHECK: .byte 8 +; CHECK: .short 7 +; CHECK: .long 16 ; No Padding or LiveOuts ; CHECK: .short 0 ; CHECK: .short 0 ; CHECK: .align 8 - - |

