llvm.org GIT mirror llvm / 3262806
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279975 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 3 years ago
2 changed file(s) with 72 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
17961796 return true;
17971797 }
17981798
1799 // Check for same values, when both BaseValue and CurrentValue are phi nodes.
1800 // PHI nodes that have the same incoming values, and belonging to the same
1801 // basic blocks are essentially the same SSA value. Such an example of same
1802 // BaseValue, CurrentValue phis is created by findBasePointer, when a phi has
1803 // incoming values with different base pointers. This phi is marked as
1804 // conflict, and hence an additional phi with the same incoming values get
1805 // generated. We need to identify the BaseValue (.base version of phi) and
1806 // CurrentValue (the phi node itself) as the same, so that we can
1807 // rematerialize the gep and casts below.
1808 if (PHINode *CurrentPhi = dyn_cast(CurrentValue))
1809 if (PHINode *BasePhi = dyn_cast(BaseValue)) {
1810 auto PhiNum = CurrentPhi->getNumIncomingValues();
1811 if (PhiNum != BasePhi->getNumIncomingValues() ||
1812 CurrentPhi->getParent() != BasePhi->getParent())
1813 return false;
1814 // Map of incoming values and their corresponding basic blocks of
1815 // CurrentPhi.
1816 SmallDenseMap CurrentIncomingValues;
1817 for (unsigned i = 0; i < PhiNum; i++)
1818 CurrentIncomingValues[CurrentPhi->getIncomingValue(i)] =
1819 CurrentPhi->getIncomingBlock(i);
1820
1821 // Both current and base PHIs should have same incoming values and
1822 // the same basic blocks corresponding to the incoming values.
1823 for (unsigned i = 0; i < PhiNum; i++) {
1824 auto CIVI = CurrentIncomingValues.find(BasePhi->getIncomingValue(i));
1825 if (CIVI == CurrentIncomingValues.end())
1826 return false;
1827 BasicBlock *CurrentIncomingBB = CIVI->second;
1828 if (CurrentIncomingBB != BasePhi->getIncomingBlock(i))
1829 return false;
1830 }
1831 return true;
1832 }
1833
17991834 if (GetElementPtrInst *GEP = dyn_cast(CurrentValue)) {
18001835 ChainToBase.push_back(GEP);
18011836 return findRematerializableChainToBasePointer(ChainToBase,
258258 call void @use_obj32(i32 addrspace(1)* %ptr.gep11)
259259 ret void
260260 }
261
262
263 declare i32 addrspace(1)* @new_instance() nounwind "gc-leaf-function"
264
265 ; remat the gep in presence of base pointer which is a phi node.
266 ; FIXME: We should remove the extra basephi.base as well.
267 define void @contains_basephi(i1 %cond) gc "statepoint-example" {
268 ; CHECK-LABEL: contains_basephi
269 entry:
270 %base1 = call i32 addrspace(1)* @new_instance()
271 %base2 = call i32 addrspace(1)* @new_instance()
272 br i1 %cond, label %here, label %there
273
274 here:
275 br label %merge
276
277 there:
278 br label %merge
279
280 merge:
281 ; CHECK: %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0
282 ; CHECK: %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
283 ; CHECK: %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
284 ; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint
285 ; 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)
286 ; 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
288 ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat)
289
290
291
292 %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ]
293 %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15
294 call void @do_safepoint() ["deopt"() ]
295 call void @use_obj32(i32 addrspace(1)* %ptr.gep)
296 ret void
297 }