Add new cleanup pass:

//  1. PHI nodes with multiple entries for the same predecessor.  GCC sometimes
//     generates code that looks like this:
//
//  bb7:  br bool %cond1004, label %bb8, label %bb8
//  bb8: %reg119 = phi uint [ 0, %bb7 ], [ 1, %bb7 ]
//
//     which is completely illegal LLVM code.  To compensate for this, we insert
//     an extra basic block, and convert the code to look like this:
//
//  bb7: br bool %cond1004, label %bbX, label %bb8
//  bbX: br label bb8
//  bb8: %reg119 = phi uint [ 0, %bbX ], [ 1, %bb7 ]
//


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1114 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2001-11-03 21:08:59 +00:00
parent 3bf04d5b99
commit 5b497ee7c2

View File

@ -20,6 +20,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include <map>
#include <algorithm>
@ -354,16 +355,54 @@ bool CleanupGCCOutput::doOneCleanupPass(Method *M) {
// RefactorPredecessor - When we find out that a basic block is a repeated
// predecessor in a PHI node, we have to refactor the method until there is at
// most a single instance of a basic block in any predecessor list.
//
static inline void RefactorPredecessor(BasicBlock *BB, BasicBlock *Pred) {
Method *M = BB->getParent();
assert(find(BB->pred_begin(), BB->pred_end(), Pred) != BB->pred_end() &&
"Pred is not a predecessor of BB!");
// Create a new basic block, adding it to the end of the method.
BasicBlock *NewBB = new BasicBlock("", M);
// Add an unconditional branch to BB to the new block.
NewBB->getInstList().push_back(new BranchInst(BB));
// Get the terminator that causes a branch to BB from Pred.
TerminatorInst *TI = Pred->getTerminator();
// Find the first use of BB in the terminator...
User::op_iterator OI = find(TI->op_begin(), TI->op_end(), BB);
assert(OI != TI->op_end() && "Pred does not branch to BB!!!");
// Change the use of BB to point to the new stub basic block
*OI = NewBB;
// Now we need to loop through all of the PHI nodes in BB and convert their
// first incoming value for Pred to reference the new basic block instead.
//
for (BasicBlock::iterator I = BB->begin();
PHINode *PN = dyn_cast<PHINode>(*I); ++I) {
int BBIdx = PN->getBasicBlockIndex(Pred);
assert(BBIdx != -1 && "PHI node doesn't have an entry for Pred!");
// The value that used to look like it came from Pred now comes from NewBB
PN->setIncomingBlock((unsigned)BBIdx, NewBB);
}
}
// CheckIncomingValueFor - Make sure that the specified PHI node has an entry
// for the provided basic block. If it doesn't, add one and return true.
//
static inline bool CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
unsigned NumArgs = PN->getNumIncomingValues();
for (unsigned i = 0; i < NumArgs; ++i)
if (PN->getIncomingBlock(i) == BB) return false; // Already has value
static inline void CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
if (PN->getBasicBlockIndex(BB) != -1) return; // Already has value
Value *NewVal = 0;
const Type *Ty = PN->getType();
if (const PointerType *PT = dyn_cast<PointerType>(Ty))
NewVal = ConstPoolPointerNull::get(PT);
else if (Ty == Type::BoolTy)
@ -375,13 +414,24 @@ static inline bool CheckIncomingValueFor(PHINode *PN, BasicBlock *BB) {
assert(NewVal && "Unknown PHI node type!");
PN->addIncoming(NewVal, BB);
return true;
}
// fixLocalProblems - Loop through the method and fix problems with the PHI
// nodes in the current method. The two problems that are handled are:
//
// 1. PHI nodes with multiple entries for the same predecessor.
// 1. PHI nodes with multiple entries for the same predecessor. GCC sometimes
// generates code that looks like this:
//
// bb7: br bool %cond1004, label %bb8, label %bb8
// bb8: %reg119 = phi uint [ 0, %bb7 ], [ 1, %bb7 ]
//
// which is completely illegal LLVM code. To compensate for this, we insert
// an extra basic block, and convert the code to look like this:
//
// bb7: br bool %cond1004, label %bbX, label %bb8
// bbX: br label bb8
// bb8: %reg119 = phi uint [ 0, %bbX ], [ 1, %bb7 ]
//
//
// 2. PHI nodes with fewer arguments than predecessors.
// These can be generated by GCC if a variable is uninitalized over a path
@ -404,6 +454,21 @@ static bool fixLocalProblems(Method *M) {
if (isa<PHINode>(BB->front())) {
const vector<BasicBlock*> Preds(BB->pred_begin(), BB->pred_end());
// Handle Problem #1. Sort the list of predecessors so that it is easy to
// decide whether or not duplicate predecessors exist.
vector<BasicBlock*> SortedPreds(Preds);
sort(SortedPreds.begin(), SortedPreds.end());
// Loop over the predecessors, looking for adjacent BB's that are equal.
BasicBlock *LastOne = 0;
for (unsigned i = 0; i < Preds.size(); ++i) {
if (SortedPreds[i] == LastOne) { // Found a duplicate.
RefactorPredecessor(BB, SortedPreds[i]);
Changed = true;
}
LastOne = SortedPreds[i];
}
// Loop over all of the PHI nodes in the current BB. These PHI nodes are
// guaranteed to be at the beginning of the basic block.
//
@ -415,7 +480,8 @@ static bool fixLocalProblems(Method *M) {
assert(PN->getNumIncomingValues() <= Preds.size() &&
"Can't handle extra arguments to PHI nodes!");
for (unsigned i = 0; i < Preds.size(); ++i)
Changed |= CheckIncomingValueFor(PN, Preds[i]);
CheckIncomingValueFor(PN, Preds[i]);
Changed = true;
}
}
}