Add a fix for an issue where LCSSA would fail to insert undef's in some corner

cases.  Ideally, this issue will go away in the future as LCSSA gets smarter
about which Phi nodes it inserts.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29076 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2006-07-09 08:14:06 +00:00
parent 00fbdf1471
commit e4e1ecd37c

View File

@ -28,6 +28,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
@ -73,12 +74,12 @@ namespace {
} }
private: private:
SetVector<Instruction*> getLoopValuesUsedOutsideLoop(Loop *L); SetVector<Instruction*> getLoopValuesUsedOutsideLoop(Loop *L);
Instruction *getValueDominatingBlock(BasicBlock *BB, Value *getValueDominatingBlock(BasicBlock *BB,
std::map<BasicBlock*, Instruction*>& PotDoms) { std::map<BasicBlock*, Value*>& PotDoms) {
return getValueDominatingDTNode(DT->getNode(BB), PotDoms); return getValueDominatingDTNode(DT->getNode(BB), PotDoms);
} }
Instruction *getValueDominatingDTNode(DominatorTree::Node *Node, Value *getValueDominatingDTNode(DominatorTree::Node *Node,
std::map<BasicBlock*, Instruction*>& PotDoms); std::map<BasicBlock*, Value*>& PotDoms);
/// inLoop - returns true if the given block is within the current loop /// inLoop - returns true if the given block is within the current loop
const bool inLoop(BasicBlock* B) { const bool inLoop(BasicBlock* B) {
@ -149,7 +150,7 @@ void LCSSA::processInstruction(Instruction* Instr,
{ {
++NumLCSSA; // We are applying the transformation ++NumLCSSA; // We are applying the transformation
std::map<BasicBlock*, Instruction*> Phis; std::map<BasicBlock*, Value*> Phis;
// Add the base instruction to the Phis list. This makes tracking down // Add the base instruction to the Phis list. This makes tracking down
// the dominating values easier when we're filling in Phi nodes. This will // the dominating values easier when we're filling in Phi nodes. This will
@ -161,7 +162,7 @@ void LCSSA::processInstruction(Instruction* Instr,
for (std::vector<BasicBlock*>::const_iterator BBI = exitBlocks.begin(), for (std::vector<BasicBlock*>::const_iterator BBI = exitBlocks.begin(),
BBE = exitBlocks.end(); BBI != BBE; ++BBI) { BBE = exitBlocks.end(); BBI != BBE; ++BBI) {
Instruction*& phi = Phis[*BBI]; Value*& phi = Phis[*BBI];
if (phi == 0 && if (phi == 0 &&
DT->getNode(Instr->getParent())->dominates(DT->getNode(*BBI))) { DT->getNode(Instr->getParent())->dominates(DT->getNode(*BBI))) {
phi = new PHINode(Instr->getType(), Instr->getName()+".lcssa", phi = new PHINode(Instr->getType(), Instr->getName()+".lcssa",
@ -191,7 +192,7 @@ void LCSSA::processInstruction(Instruction* Instr,
for (DominanceFrontier::DomSetType::const_iterator P = S.begin(), for (DominanceFrontier::DomSetType::const_iterator P = S.begin(),
PE = S.end(); P != PE; ++P) { PE = S.end(); P != PE; ++P) {
if (DT->getNode(Instr->getParent())->dominates(DT->getNode(*P))) { if (DT->getNode(Instr->getParent())->dominates(DT->getNode(*P))) {
Instruction *&Phi = Phis[*P]; Value *&Phi = Phis[*P];
if (Phi == 0) { if (Phi == 0) {
// Still doesn't have operands... // Still doesn't have operands...
Phi = new PHINode(Instr->getType(), Instr->getName()+".lcssa", Phi = new PHINode(Instr->getType(), Instr->getName()+".lcssa",
@ -206,12 +207,11 @@ void LCSSA::processInstruction(Instruction* Instr,
// Fill in all Phis we've inserted that need their incoming values filled in. // Fill in all Phis we've inserted that need their incoming values filled in.
for (std::vector<PHINode*>::iterator IVI = needIncomingValues.begin(), for (std::vector<PHINode*>::iterator IVI = needIncomingValues.begin(),
IVE = needIncomingValues.end(); IVI != IVE; ++IVI) { IVE = needIncomingValues.end(); IVI != IVE; ++IVI)
for (pred_iterator PI = pred_begin((*IVI)->getParent()), for (pred_iterator PI = pred_begin((*IVI)->getParent()),
E = pred_end((*IVI)->getParent()); PI != E; ++PI) E = pred_end((*IVI)->getParent()); PI != E; ++PI)
(*IVI)->addIncoming(getValueDominatingBlock(*PI, Phis), (*IVI)->addIncoming(getValueDominatingBlock(*PI, Phis),
*PI); *PI);
}
// Find all uses of the affected value, and replace them with the // Find all uses of the affected value, and replace them with the
// appropriate Phi. // appropriate Phi.
@ -235,7 +235,7 @@ void LCSSA::processInstruction(Instruction* Instr,
if (PHINode* phi = dyn_cast<PHINode>(*II)) { if (PHINode* phi = dyn_cast<PHINode>(*II)) {
for (unsigned int i = 0; i < phi->getNumIncomingValues(); ++i) { for (unsigned int i = 0; i < phi->getNumIncomingValues(); ++i) {
if (phi->getIncomingValue(i) == Instr) { if (phi->getIncomingValue(i) == Instr) {
Instruction* dominator = Value* dominator =
getValueDominatingBlock(phi->getIncomingBlock(i), Phis); getValueDominatingBlock(phi->getIncomingBlock(i), Phis);
phi->setIncomingValue(i, dominator); phi->setIncomingValue(i, dominator);
} }
@ -279,10 +279,17 @@ SetVector<Instruction*> LCSSA::getLoopValuesUsedOutsideLoop(Loop *L) {
/// getValueDominatingBlock - Return the value within the potential dominators /// getValueDominatingBlock - Return the value within the potential dominators
/// map that dominates the given block. /// map that dominates the given block.
Instruction *LCSSA::getValueDominatingDTNode(DominatorTree::Node *Node, Value *LCSSA::getValueDominatingDTNode(DominatorTree::Node *Node,
std::map<BasicBlock*, Instruction*>& PotDoms) { std::map<BasicBlock*, Value*>& PotDoms) {
assert(Node != 0 && "Didn't find dom value?"); // FIXME: The following insertion should be in place rather than the if
Instruction *&CacheSlot = PotDoms[Node->getBlock()]; // statement. Currently, this is due to the fact that LCSSA isn't smart
// enough to avoid inserting IDF Phis that don't dominate any uses. In some
// of those cases, it could ask us to provide a dominating value for a block
// that has none, so we need to return undef.
//assert(Node != 0 && "Didn't find dom value?");
if (Node == 0) return UndefValue::get(PotDoms.begin()->second->getType());
Value *&CacheSlot = PotDoms[Node->getBlock()];
if (CacheSlot) return CacheSlot; if (CacheSlot) return CacheSlot;
// Otherwise, return the value of the idom and remember this for next time. // Otherwise, return the value of the idom and remember this for next time.