summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorAnna Thomas <anna@azul.com>2016-08-29 15:41:59 +0000
committerAnna Thomas <anna@azul.com>2016-08-29 15:41:59 +0000
commit2bc129c5fda5ccd3c0f6a4c169e998c9208c895e (patch)
tree4bcaf1a819e13cbf35b586c7e9237d8c1b9110bf /llvm/lib/Transforms
parent6e711c33b468f9802e515d42017552a85d82e5a9 (diff)
downloadbcm5719-llvm-2bc129c5fda5ccd3c0f6a4c169e998c9208c895e.tar.gz
bcm5719-llvm-2bc129c5fda5ccd3c0f6a4c169e998c9208c895e.zip
[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
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index 9179834dba3..6726e0e9642 100644
--- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -1797,6 +1797,41 @@ static bool findRematerializableChainToBasePointer(
return true;
}
+ // Check for same values, when both BaseValue and CurrentValue are phi nodes.
+ // PHI nodes that have the same incoming values, and belonging to the same
+ // basic blocks are essentially the same SSA value. Such an example of same
+ // BaseValue, CurrentValue phis is created by findBasePointer, when a phi has
+ // incoming values with different base pointers. This phi is marked as
+ // conflict, and hence an additional phi with the same incoming values get
+ // generated. We need to identify the BaseValue (.base version of phi) and
+ // CurrentValue (the phi node itself) as the same, so that we can
+ // rematerialize the gep and casts below.
+ if (PHINode *CurrentPhi = dyn_cast<PHINode>(CurrentValue))
+ if (PHINode *BasePhi = dyn_cast<PHINode>(BaseValue)) {
+ auto PhiNum = CurrentPhi->getNumIncomingValues();
+ if (PhiNum != BasePhi->getNumIncomingValues() ||
+ CurrentPhi->getParent() != BasePhi->getParent())
+ return false;
+ // Map of incoming values and their corresponding basic blocks of
+ // CurrentPhi.
+ SmallDenseMap<Value *, BasicBlock *, 8> CurrentIncomingValues;
+ for (unsigned i = 0; i < PhiNum; i++)
+ CurrentIncomingValues[CurrentPhi->getIncomingValue(i)] =
+ CurrentPhi->getIncomingBlock(i);
+
+ // Both current and base PHIs should have same incoming values and
+ // the same basic blocks corresponding to the incoming values.
+ for (unsigned i = 0; i < PhiNum; i++) {
+ auto CIVI = CurrentIncomingValues.find(BasePhi->getIncomingValue(i));
+ if (CIVI == CurrentIncomingValues.end())
+ return false;
+ BasicBlock *CurrentIncomingBB = CIVI->second;
+ if (CurrentIncomingBB != BasePhi->getIncomingBlock(i))
+ return false;
+ }
+ return true;
+ }
+
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurrentValue)) {
ChainToBase.push_back(GEP);
return findRematerializableChainToBasePointer(ChainToBase,
OpenPOWER on IntegriCloud