forked from OSchip/llvm-project
Reverse ordering of base and derived pointer during safepoint lowering.
According to the documentation in StackMap section for the safepoint we should have: "The first Location in each pair describes the base pointer for the object. The second is the derived pointer actually being relocated." But before this change we emitted them in reverse order - derived pointer first, base pointer second. llvm-svn: 237126
This commit is contained in:
parent
5c8f90b1ad
commit
87ef5eaf46
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 0
|
||||
; Direct Spill Slot [RSP+0]
|
||||
; CHECK: .long 16
|
||||
; Direct Spill Slot [RSP+8]
|
||||
; CHECK: .byte 2
|
||||
; CHECK: .byte 8
|
||||
; CHECK: .short 7
|
||||
; CHECK: .long 0
|
||||
; 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
|
||||
|
|
Loading…
Reference in New Issue