forked from OSchip/llvm-project
[RS4GC] Re-purpose `normalizeForInvokeSafepoint`; NFC.
`normalizeForInvokeSafepoint` in RewriteStatepointsForGC.cpp, as it is written today, deals with `gc.relocate` and `gc.result` uses of a statepoint equally well. This change documents this fact and adds a test case. There is no functional change here -- only documentation of existing functionality. llvm-svn: 250784
This commit is contained in:
parent
ff3dba736a
commit
7ad67640e9
|
@ -1239,12 +1239,12 @@ static void recomputeLiveInValues(
|
|||
}
|
||||
}
|
||||
|
||||
// When inserting gc.relocate calls, we need to ensure there are no uses
|
||||
// of the original value between the gc.statepoint and the gc.relocate call.
|
||||
// One case which can arise is a phi node starting one of the successor blocks.
|
||||
// We also need to be able to insert the gc.relocates only on the path which
|
||||
// goes through the statepoint. We might need to split an edge to make this
|
||||
// possible.
|
||||
// When inserting gc.relocate and gc.result calls, we need to ensure there are
|
||||
// no uses of the original value / return value between the gc.statepoint and
|
||||
// the gc.relocate / gc.result call. One case which can arise is a phi node
|
||||
// starting one of the successor blocks. We also need to be able to insert the
|
||||
// gc.relocates only on the path which goes through the statepoint. We might
|
||||
// need to split an edge to make this possible.
|
||||
static BasicBlock *
|
||||
normalizeForInvokeSafepoint(BasicBlock *BB, BasicBlock *InvokeParent,
|
||||
DominatorTree &DT) {
|
||||
|
@ -1252,14 +1252,14 @@ normalizeForInvokeSafepoint(BasicBlock *BB, BasicBlock *InvokeParent,
|
|||
if (!BB->getUniquePredecessor())
|
||||
Ret = SplitBlockPredecessors(BB, InvokeParent, "", &DT);
|
||||
|
||||
// Now that 'ret' has unique predecessor we can safely remove all phi nodes
|
||||
// Now that 'Ret' has unique predecessor we can safely remove all phi nodes
|
||||
// from it
|
||||
FoldSingleEntryPHINodes(Ret);
|
||||
assert(!isa<PHINode>(Ret->begin()) &&
|
||||
"All PHI nodes should have been removed!");
|
||||
|
||||
// At this point, we can safely insert a gc.relocate as the first instruction
|
||||
// in Ret if needed.
|
||||
// At this point, we can safely insert a gc.relocate or gc.result as the first
|
||||
// instruction in Ret if needed.
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
; RUN: opt -rewrite-statepoints-for-gc -rs4gc-use-deopt-bundles -verify -S < %s | FileCheck %s
|
||||
|
||||
declare i8 addrspace(1)* @gc_call()
|
||||
|
||||
declare i32* @fake_personality_function()
|
||||
|
||||
define i8 addrspace(1)* @test(i1 %c) gc "statepoint-example" personality i32* ()* @fake_personality_function {
|
||||
; CHECK-LABEL: @test(
|
||||
entry:
|
||||
br i1 %c, label %gc_invoke, label %normal_dest
|
||||
|
||||
gc_invoke:
|
||||
; CHECK: [[TOKEN:%[^ ]+]] = invoke i32 {{[^@]+}}@llvm.experimental.gc.statepoint{{[^@]+}}@gc_call
|
||||
%obj = invoke i8 addrspace(1)* @gc_call() [ "deopt"(i32 0, i32 -1, i32 0, i32 0, i32 0) ]
|
||||
to label %normal_dest unwind label %unwind_dest
|
||||
|
||||
unwind_dest:
|
||||
; CHECK: unwind_dest:
|
||||
%lpad = landingpad { i8*, i32 }
|
||||
cleanup
|
||||
resume { i8*, i32 } undef
|
||||
|
||||
; CHECK: [[NORMAL_DEST_SPLIT:[^:]+:]]
|
||||
; CHECK-NEXT: [[RET_VAL:%[^ ]+]] = call i8 addrspace(1)* @llvm.experimental.gc.result.p1i8(i32 [[TOKEN]])
|
||||
; CHECK-NEXT: br label %normal_dest
|
||||
|
||||
normal_dest:
|
||||
; CHECK: normal_dest:
|
||||
; CHECK-NEXT: %merge = phi i8 addrspace(1)* [ null, %entry ], [ %obj.2, %normal_dest1 ]
|
||||
%merge = phi i8 addrspace(1)* [ null, %entry ], [ %obj, %gc_invoke ]
|
||||
ret i8 addrspace(1)* %merge
|
||||
}
|
Loading…
Reference in New Issue