mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
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). llvm-svn: 83741
This commit is contained in:
parent
9899ce267c
commit
db4d523cca
@ -48,16 +48,40 @@ public:
|
||||
/// updates. ProtoValue is the value used to name PHI nodes.
|
||||
void Initialize(Value *ProtoValue);
|
||||
|
||||
/// AddAvailableValue - Indicate that a rewritten value is available in the
|
||||
/// specified block with the specified value.
|
||||
/// AddAvailableValue - Indicate that a rewritten value is available at the
|
||||
/// end of the specified block with the specified value.
|
||||
void AddAvailableValue(BasicBlock *BB, Value *V);
|
||||
|
||||
/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
|
||||
/// live at the end of the specified block.
|
||||
Value *GetValueAtEndOfBlock(BasicBlock *BB);
|
||||
|
||||
/// 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 *GetValueInMiddleOfBlock(BasicBlock *BB);
|
||||
|
||||
/// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
|
||||
/// which use their value in the corresponding predecessor.
|
||||
/// which use their value in the corresponding predecessor. Note that this
|
||||
/// will not work if the use is supposed to be rewritten to a value defined in
|
||||
/// the same block as the use, but above it. Any 'AddAvailableValue's added
|
||||
/// for the use's block will be considered to be below it.
|
||||
void RewriteUse(Use &U);
|
||||
|
||||
private:
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user