aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-10 23:00:11 +0000
committerChris Lattner <sabre@nondot.org>2009-10-10 23:00:11 +0000
commit1a8d4de397c360a76f1389d15e862eba265d71fd (patch)
tree09c2ccd55ead3c29507d192cd2bdbbeb6ab4607c /lib
parent5fb107287fd8d35b8fc39aa3e6b084fb2871a8ff (diff)
downloadexternal_llvm-1a8d4de397c360a76f1389d15e862eba265d71fd.zip
external_llvm-1a8d4de397c360a76f1389d15e862eba265d71fd.tar.gz
external_llvm-1a8d4de397c360a76f1389d15e862eba265d71fd.tar.bz2
add the ability to get a rewritten value from the middle of a block,
not just at the end. Add a big comment explaining when this could be useful (which never happens for jump threading). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83741 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/SSAUpdater.cpp95
1 files changed, 92 insertions, 3 deletions
diff --git a/lib/Transforms/Utils/SSAUpdater.cpp b/lib/Transforms/Utils/SSAUpdater.cpp
index be9d147..294d9aa 100644
--- a/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/lib/Transforms/Utils/SSAUpdater.cpp
@@ -64,8 +64,8 @@ void SSAUpdater::AddAvailableValue(BasicBlock *BB, Value *V) {
getAvailableVals(AV)[BB] = V;
}
-/// GetValueAtEndOfBlock - Construct SSA form, materializing a value in the
-/// specified block.
+/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
+/// live at the end of the specified block.
Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
assert(getIncomingPredInfo(IPI).empty() && "Unexpected Internal State");
Value *Res = GetValueAtEndOfBlockInternal(BB);
@@ -73,6 +73,95 @@ Value *SSAUpdater::GetValueAtEndOfBlock(BasicBlock *BB) {
return Res;
}
+/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
+/// is live in the middle of the specified block.
+///
+/// GetValueInMiddleOfBlock is the same as GetValueAtEndOfBlock except in one
+/// important case: if there is a definition of the rewritten value after the
+/// 'use' in BB. Consider code like this:
+///
+/// X1 = ...
+/// SomeBB:
+/// use(X)
+/// X2 = ...
+/// br Cond, SomeBB, OutBB
+///
+/// In this case, there are two values (X1 and X2) added to the AvailableVals
+/// set by the client of the rewriter, and those values are both live out of
+/// their respective blocks. However, the use of X happens in the *middle* of
+/// a block. Because of this, we need to insert a new PHI node in SomeBB to
+/// merge the appropriate values, and this value isn't live out of the block.
+///
+Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
+ // If there is no definition of the renamed variable in this block, just use
+ // GetValueAtEndOfBlock to do our work.
+ if (!getAvailableVals(AV).count(BB))
+ return GetValueAtEndOfBlock(BB);
+
+ // Otherwise, we have the hard case. Get the live-in values for each
+ // predecessor.
+ SmallVector<std::pair<BasicBlock*, Value*>, 8> PredValues;
+ Value *SingularValue = 0;
+
+ // We can get our predecessor info by walking the pred_iterator list, but it
+ // is relatively slow. If we already have PHI nodes in this block, walk one
+ // of them to get the predecessor list instead.
+ if (PHINode *SomePhi = dyn_cast<PHINode>(BB->begin())) {
+ for (unsigned i = 0, e = SomePhi->getNumIncomingValues(); i != e; ++i) {
+ BasicBlock *PredBB = SomePhi->getIncomingBlock(i);
+ Value *PredVal = GetValueAtEndOfBlock(PredBB);
+ PredValues.push_back(std::make_pair(PredBB, PredVal));
+
+ // Compute SingularValue.
+ if (i == 0)
+ SingularValue = PredVal;
+ else if (PredVal != SingularValue)
+ SingularValue = 0;
+ }
+ } else {
+ bool isFirstPred = true;
+ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) {
+ BasicBlock *PredBB = *PI;
+ Value *PredVal = GetValueAtEndOfBlock(PredBB);
+ PredValues.push_back(std::make_pair(PredBB, PredVal));
+
+ // Compute SingularValue.
+ if (isFirstPred) {
+ SingularValue = PredVal;
+ isFirstPred = false;
+ } else if (PredVal != SingularValue)
+ SingularValue = 0;
+ }
+ }
+
+ // If there are no predecessors, just return undef.
+ if (PredValues.empty())
+ return UndefValue::get(PrototypeValue->getType());
+
+ // Otherwise, if all the merged values are the same, just use it.
+ if (SingularValue != 0)
+ return SingularValue;
+
+ // Otherwise, we do need a PHI: insert one now.
+ PHINode *InsertedPHI = PHINode::Create(PrototypeValue->getType(),
+ PrototypeValue->getName(),
+ &BB->front());
+ InsertedPHI->reserveOperandSpace(PredValues.size());
+
+ // Fill in all the predecessors of the PHI.
+ for (unsigned i = 0, e = PredValues.size(); i != e; ++i)
+ InsertedPHI->addIncoming(PredValues[i].second, PredValues[i].first);
+
+ // See if the PHI node can be merged to a single value. This can happen in
+ // loop cases when we get a PHI of itself and one other value.
+ if (Value *ConstVal = InsertedPHI->hasConstantValue()) {
+ InsertedPHI->eraseFromParent();
+ return ConstVal;
+ }
+ DEBUG(errs() << " Inserted PHI: " << *InsertedPHI << "\n");
+ return InsertedPHI;
+}
+
/// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
/// which use their value in the corresponding predecessor.
void SSAUpdater::RewriteUse(Use &U) {
@@ -81,7 +170,7 @@ void SSAUpdater::RewriteUse(Use &U) {
if (PHINode *UserPN = dyn_cast<PHINode>(User))
UseBB = UserPN->getIncomingBlock(U);
- U.set(GetValueAtEndOfBlock(UseBB));
+ U.set(GetValueInMiddleOfBlock(UseBB));
}