Skip to content

Commit 2bc129c

Browse files
committedAug 29, 2016
[StatepointsForGC] Rematerialize in the presence of PHIs
Summary: While walking the use chain for identifying rematerializable values in RS4GC, add the case where the current value and base value are the same PHI nodes. This will aid rematerialization of geps and casts instead of relocating. Reviewers: sanjoy, reames, igor Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23920 llvm-svn: 279975
1 parent 6e711c3 commit 2bc129c

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed
 

‎llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,41 @@ static bool findRematerializableChainToBasePointer(
17971797
return true;
17981798
}
17991799

1800+
// Check for same values, when both BaseValue and CurrentValue are phi nodes.
1801+
// PHI nodes that have the same incoming values, and belonging to the same
1802+
// basic blocks are essentially the same SSA value. Such an example of same
1803+
// BaseValue, CurrentValue phis is created by findBasePointer, when a phi has
1804+
// incoming values with different base pointers. This phi is marked as
1805+
// conflict, and hence an additional phi with the same incoming values get
1806+
// generated. We need to identify the BaseValue (.base version of phi) and
1807+
// CurrentValue (the phi node itself) as the same, so that we can
1808+
// rematerialize the gep and casts below.
1809+
if (PHINode *CurrentPhi = dyn_cast<PHINode>(CurrentValue))
1810+
if (PHINode *BasePhi = dyn_cast<PHINode>(BaseValue)) {
1811+
auto PhiNum = CurrentPhi->getNumIncomingValues();
1812+
if (PhiNum != BasePhi->getNumIncomingValues() ||
1813+
CurrentPhi->getParent() != BasePhi->getParent())
1814+
return false;
1815+
// Map of incoming values and their corresponding basic blocks of
1816+
// CurrentPhi.
1817+
SmallDenseMap<Value *, BasicBlock *, 8> CurrentIncomingValues;
1818+
for (unsigned i = 0; i < PhiNum; i++)
1819+
CurrentIncomingValues[CurrentPhi->getIncomingValue(i)] =
1820+
CurrentPhi->getIncomingBlock(i);
1821+
1822+
// Both current and base PHIs should have same incoming values and
1823+
// the same basic blocks corresponding to the incoming values.
1824+
for (unsigned i = 0; i < PhiNum; i++) {
1825+
auto CIVI = CurrentIncomingValues.find(BasePhi->getIncomingValue(i));
1826+
if (CIVI == CurrentIncomingValues.end())
1827+
return false;
1828+
BasicBlock *CurrentIncomingBB = CIVI->second;
1829+
if (CurrentIncomingBB != BasePhi->getIncomingBlock(i))
1830+
return false;
1831+
}
1832+
return true;
1833+
}
1834+
18001835
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurrentValue)) {
18011836
ChainToBase.push_back(GEP);
18021837
return findRematerializableChainToBasePointer(ChainToBase,

‎llvm/test/Transforms/RewriteStatepointsForGC/rematerialize-derived-pointers.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,40 @@ entry:
259259
call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
260260
ret void
261261
}
262+
263+
264+
declare i32 addrspace(1)* @new_instance() nounwind "gc-leaf-function"
265+
266+
; remat the gep in presence of base pointer which is a phi node.
267+
; FIXME: We should remove the extra basephi.base as well.
268+
define void @contains_basephi(i1 %cond) gc "statepoint-example" {
269+
; CHECK-LABEL: contains_basephi
270+
entry:
271+
%base1 = call i32 addrspace(1)* @new_instance()
272+
%base2 = call i32 addrspace(1)* @new_instance()
273+
br i1 %cond, label %here, label %there
274+
275+
here:
276+
br label %merge
277+
278+
there:
279+
br label %merge
280+
281+
merge:
282+
; CHECK: %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0
283+
; CHECK: %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
284+
; CHECK: %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
285+
; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
286+
; 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)
287+
; CHECK: %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)*
288+
; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
289+
; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat)
290+
291+
292+
293+
%basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
294+
%ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
295+
call void @do_safepoint() ["deopt"() ]
296+
call void @use_obj32(i32 addrspace(1)* %ptr.gep)
297+
ret void
298+
}

0 commit comments

Comments
 (0)
Please sign in to comment.