llvm.org GIT mirror llvm / 4bbf4cb
[RS4GC] Remat in presence of phi and use live value Summary: Reviewers: Subscribers: git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282150 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 2 years ago
2 changed file(s) with 54 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
19751975 // Utility function which clones all instructions from "ChainToBase"
19761976 // and inserts them before "InsertBefore". Returns rematerialized value
19771977 // which should be used after statepoint.
1978 auto rematerializeChain = [&ChainToBase](Instruction *InsertBefore) {
1978 auto rematerializeChain = [&ChainToBase](
1979 Instruction *InsertBefore, Value *RootOfChain, Value *AlternateLiveBase) {
19791980 Instruction *LastClonedValue = nullptr;
19801981 Instruction *LastValue = nullptr;
19811982 for (Instruction *Instr: ChainToBase) {
19951996 assert(LastValue);
19961997 ClonedValue->replaceUsesOfWith(LastValue, LastClonedValue);
19971998 #ifndef NDEBUG
1998 // Assert that cloned instruction does not use any instructions from
1999 // this chain other than LastClonedValue
20001999 for (auto OpValue : ClonedValue->operand_values()) {
2000 // Assert that cloned instruction does not use any instructions from
2001 // this chain other than LastClonedValue
20012002 assert(!is_contained(ChainToBase, OpValue) &&
20022003 "incorrect use in rematerialization chain");
2004 // Assert that the cloned instruction does not use the RootOfChain
2005 // or the AlternateLiveBase.
2006 assert(OpValue != RootOfChain && OpValue != AlternateLiveBase);
20032007 }
20042008 #endif
2009 } else {
2010 // For the first instruction, replace the use of unrelocated base i.e.
2011 // RootOfChain/OrigRootPhi, with the corresponding PHI present in the
2012 // live set. They have been proved to be the same PHI nodes. Note
2013 // that the *only* use of the RootOfChain in the ChainToBase list is
2014 // the first Value in the list.
2015 if (RootOfChain != AlternateLiveBase)
2016 ClonedValue->replaceUsesOfWith(RootOfChain, AlternateLiveBase);
20052017 }
20062018
20072019 LastClonedValue = ClonedValue;
20162028 if (CS.isCall()) {
20172029 Instruction *InsertBefore = CS.getInstruction()->getNextNode();
20182030 assert(InsertBefore);
2019 Instruction *RematerializedValue = rematerializeChain(InsertBefore);
2031 Instruction *RematerializedValue = rematerializeChain(
2032 InsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
20202033 Info.RematerializedValues[RematerializedValue] = LiveValue;
20212034 } else {
20222035 InvokeInst *Invoke = cast(CS.getInstruction());
20262039 Instruction *UnwindInsertBefore =
20272040 &*Invoke->getUnwindDest()->getFirstInsertionPt();
20282041
2029 Instruction *NormalRematerializedValue =
2030 rematerializeChain(NormalInsertBefore);
2031 Instruction *UnwindRematerializedValue =
2032 rematerializeChain(UnwindInsertBefore);
2042 Instruction *NormalRematerializedValue = rematerializeChain(
2043 NormalInsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
2044 Instruction *UnwindRematerializedValue = rematerializeChain(
2045 UnwindInsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
20332046
20342047 Info.RematerializedValues[NormalRematerializedValue] = LiveValue;
20352048 Info.RematerializedValues[UnwindRematerializedValue] = LiveValue;
284284 ; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
285285 ; CHECK: %basephi.base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%basephi.base, %basephi.base)
286286 ; CHECK: %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)*
287 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
287 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
288288 ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat)
289289
290290
295295 call void @use_obj32(i32 addrspace(1)* %ptr.gep)
296296 ret void
297297 }
298
299
300 define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" {
301 ; CHECK-LABEL: test_intersecting_chains_with_phi
302 entry:
303 %base1 = call i32 addrspace(1)* @new_instance()
304 %base2 = call i32 addrspace(1)* @new_instance()
305 br i1 %cond, label %here, label %there
306
307 here:
308 br label %merge
309
310 there:
311 br label %merge
312
313 merge:
314 %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
315 %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
316 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)*
317 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)*
318 call void @do_safepoint() [ "deopt"() ]
319 ; CHECK: statepoint
320 ; CHECK: %ptr.gep.remat1 = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
321 ; CHECK: %ptr.cast.remat = bitcast i32 addrspace(1)* %ptr.gep.remat1 to i64 addrspace(1)*
322 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15
323 ; CHECK: %ptr.cast2.remat = bitcast i32 addrspace(1)* %ptr.gep.remat to i16 addrspace(1)*
324 ; CHECK: call void @use_obj64(i64 addrspace(1)* %ptr.cast.remat)
325 ; CHECK: call void @use_obj16(i16 addrspace(1)* %ptr.cast2.remat)
326 call void @use_obj64(i64 addrspace(1)* %ptr.cast)
327 call void @use_obj16(i16 addrspace(1)* %ptr.cast2)
328 ret void
329 }