[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
; Test that we can correctly handle vectors of pointers in statepoint
|
|
|
|
; rewriting.
|
2016-02-23 05:01:28 +08:00
|
|
|
; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s
|
2017-12-15 17:32:11 +08:00
|
|
|
; RUN: opt < %s -passes=rewrite-statepoints-for-gc -S | FileCheck %s
|
[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
|
|
|
|
; A non-vector relocation for comparison
|
|
|
|
define i64 addrspace(1)* @test(i64 addrspace(1)* %obj) gc "statepoint-example" {
|
|
|
|
; CHECK-LABEL: test
|
|
|
|
; CHECK: gc.statepoint
|
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
|
|
|
; CHECK-NEXT: ret i64 addrspace(1)*
|
|
|
|
; A base vector from a argument
|
|
|
|
entry:
|
|
|
|
call void @do_safepoint() [ "deopt"() ]
|
|
|
|
ret i64 addrspace(1)* %obj
|
|
|
|
}
|
|
|
|
|
|
|
|
; A vector argument
|
|
|
|
define <2 x i64 addrspace(1)*> @test2(<2 x i64 addrspace(1)*> %obj) gc "statepoint-example" {
|
|
|
|
; CHECK-LABEL: test2
|
|
|
|
; CHECK-NEXT: gc.statepoint
|
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
|
|
|
|
call void @do_safepoint() [ "deopt"() ]
|
|
|
|
ret <2 x i64 addrspace(1)*> %obj
|
|
|
|
}
|
|
|
|
|
|
|
|
; A load
|
|
|
|
define <2 x i64 addrspace(1)*> @test3(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
|
|
|
|
; CHECK-LABEL: test3
|
|
|
|
; CHECK: load
|
|
|
|
; CHECK-NEXT: gc.statepoint
|
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
|
|
|
|
entry:
|
|
|
|
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
|
|
|
call void @do_safepoint() [ "deopt"() ]
|
|
|
|
ret <2 x i64 addrspace(1)*> %obj
|
|
|
|
}
|
|
|
|
|
|
|
|
declare i32 @fake_personality_function()
|
|
|
|
|
|
|
|
; When a statepoint is an invoke rather than a call
|
|
|
|
define <2 x i64 addrspace(1)*> @test4(<2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" personality i32 ()* @fake_personality_function {
|
|
|
|
; CHECK-LABEL: test4
|
|
|
|
; CHECK: load
|
|
|
|
; CHECK-NEXT: gc.statepoint
|
|
|
|
entry:
|
|
|
|
%obj = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
|
|
|
invoke void @do_safepoint() [ "deopt"() ]
|
|
|
|
to label %normal_return unwind label %exceptional_return
|
|
|
|
|
|
|
|
normal_return: ; preds = %entry
|
|
|
|
; CHECK-LABEL: normal_return:
|
|
|
|
; CHECK: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
|
|
|
|
ret <2 x i64 addrspace(1)*> %obj
|
|
|
|
|
|
|
|
exceptional_return: ; preds = %entry
|
|
|
|
; CHECK-LABEL: exceptional_return:
|
|
|
|
; CHECK: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
|
|
|
|
%landing_pad4 = landingpad token
|
|
|
|
cleanup
|
|
|
|
ret <2 x i64 addrspace(1)*> %obj
|
|
|
|
}
|
|
|
|
|
|
|
|
; A newly created vector
|
|
|
|
define <2 x i64 addrspace(1)*> @test5(i64 addrspace(1)* %p) gc "statepoint-example" {
|
|
|
|
; CHECK-LABEL: test5
|
|
|
|
; CHECK: insertelement
|
2016-02-23 04:45:56 +08:00
|
|
|
; CHECK-NEXT: insertelement
|
[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
; CHECK-NEXT: gc.statepoint
|
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
2016-02-23 04:45:56 +08:00
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*> %vec.relocated.casted
|
|
|
|
entry:
|
|
|
|
%vec = insertelement <2 x i64 addrspace(1)*> undef, i64 addrspace(1)* %p, i32 0
|
|
|
|
call void @do_safepoint() [ "deopt"() ]
|
|
|
|
ret <2 x i64 addrspace(1)*> %vec
|
|
|
|
}
|
|
|
|
|
|
|
|
; A merge point
|
|
|
|
define <2 x i64 addrspace(1)*> @test6(i1 %cnd, <2 x i64 addrspace(1)*>* %ptr) gc "statepoint-example" {
|
|
|
|
; CHECK-LABEL: test6
|
|
|
|
entry:
|
|
|
|
br i1 %cnd, label %taken, label %untaken
|
|
|
|
|
|
|
|
taken: ; preds = %entry
|
|
|
|
%obja = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
|
|
|
br label %merge
|
|
|
|
|
|
|
|
untaken: ; preds = %entry
|
|
|
|
%objb = load <2 x i64 addrspace(1)*>, <2 x i64 addrspace(1)*>* %ptr
|
|
|
|
br label %merge
|
|
|
|
|
|
|
|
merge: ; preds = %untaken, %taken
|
|
|
|
; CHECK-LABEL: merge:
|
|
|
|
; CHECK-NEXT: = phi
|
2016-02-23 04:45:56 +08:00
|
|
|
; CHECK-NEXT: = phi
|
[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
; CHECK-NEXT: gc.statepoint
|
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
2016-02-23 04:45:56 +08:00
|
|
|
; CHECK-NEXT: gc.relocate
|
|
|
|
; CHECK-NEXT: bitcast
|
[rs4gc] Optionally directly relocated vector of pointers
This patch teaches rewrite-statepoints-for-gc to relocate vector-of-pointers directly rather than trying to split them. This builds on the recent lowering/IR changes to allow vector typed gc.relocates.
The motivation for this is that we recently found a bug in the vector splitting code where depending on visit order, a vector might not be relocated at some safepoint. Specifically, the bug is that the splitting code wasn't updating the side tables (live vector) of other safepoints. As a result, a vector which was live at two safepoints might not be updated at one of them. However, if you happened to visit safepoints in post order over the dominator tree, everything worked correctly. Weirdly, it turns out that post order is actually an incredibly common order to visit instructions in in practice. Frustratingly, I have not managed to write a test case which actually hits this. I can only reproduce it in large IR files produced by actual applications.
Rather than continue to make this code more complicated, we can remove all of the complexity by just representing the relocation of the entire vector natively in the IR.
At the moment, the new functionality is hidden behind a flag. To use this code, you need to pass "-rs4gc-split-vector-values=0". Once I have a chance to stress test with this option and get feedback from other users, my plan is to flip the default and remove the original splitting code. I would just remove it now, but given the rareness of the bug, I figured it was better to leave it in place until the new approach has been stress tested.
Differential Revision: http://reviews.llvm.org/D15982
llvm-svn: 257244
2016-01-09 09:31:13 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i64 addrspace(1)*>
|
|
|
|
%obj = phi <2 x i64 addrspace(1)*> [ %obja, %taken ], [ %objb, %untaken ]
|
|
|
|
call void @do_safepoint() [ "deopt"() ]
|
|
|
|
ret <2 x i64 addrspace(1)*> %obj
|
|
|
|
}
|
|
|
|
|
|
|
|
declare void @do_safepoint()
|