[llvm-commits] CVS: llvm/lib/Transforms/Scalar/TailDuplication.cpp ADCE.cpp GCSE.cpp InstructionCombining.cpp Mem2Reg.cpp SCCP.cpp
John Criswell
criswell at choi.cs.uiuc.edu
Thu Jun 26 16:42:24 PDT 2003
Changes in directory llvm/lib/Transforms/Scalar:
TailDuplication.cpp added (r1.4.2.1)
ADCE.cpp updated: 1.53 -> 1.53.2.1
GCSE.cpp updated: 1.27 -> 1.27.2.1
InstructionCombining.cpp updated: 1.89 -> 1.89.2.1
Mem2Reg.cpp updated: 1.3 -> 1.3.2.1
SCCP.cpp updated: 1.69 -> 1.69.2.1
---
Log message:
Merged with mainline on Thursday, June 26, 2003.
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/TailDuplication.cpp
diff -c /dev/null llvm/lib/Transforms/Scalar/TailDuplication.cpp:1.1
*** /dev/null Thu Jun 26 16:37:38 2003
--- llvm/lib/Transforms/Scalar/TailDuplication.cpp Sun Jun 22 15:10:28 2003
***************
*** 0 ****
--- 1,324 ----
+ //===- TailDuplication.cpp - Simplify CFG through tail duplication --------===//
+ //
+ // This pass performs a limited form of tail duplication, intended to simplify
+ // CFGs by removing some unconditional branches. This pass is necessary to
+ // straighten out loops created by the C front-end, but also is capable of
+ // making other code nicer. After this pass is run, the CFG simplify pass
+ // should be run to clean up the mess.
+ //
+ // This pass could be enhanced in the future to use profile information to be
+ // more aggressive.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #include "llvm/Transforms/Scalar.h"
+ #include "llvm/Function.h"
+ #include "llvm/iPHINode.h"
+ #include "llvm/iTerminators.h"
+ #include "llvm/Pass.h"
+ #include "llvm/Type.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Transforms/Utils/Local.h"
+ #include "Support/Statistic.h"
+
+ namespace {
+ Statistic<> NumEliminated("tailduplicate",
+ "Number of unconditional branches eliminated");
+ Statistic<> NumPHINodes("tailduplicate", "Number of phi nodes inserted");
+
+ class TailDup : public FunctionPass {
+ bool runOnFunction(Function &F);
+ private:
+ inline bool shouldEliminateUnconditionalBranch(TerminatorInst *TI);
+ inline void eliminateUnconditionalBranch(BranchInst *BI);
+ inline void InsertPHINodesIfNecessary(Instruction *OrigInst, Value *NewInst,
+ BasicBlock *NewBlock);
+ inline Value *GetValueInBlock(BasicBlock *BB, Value *OrigVal,
+ std::map<BasicBlock*, Value*> &ValueMap,
+ std::map<BasicBlock*, Value*> &OutValueMap);
+ inline Value *GetValueOutBlock(BasicBlock *BB, Value *OrigVal,
+ std::map<BasicBlock*, Value*> &ValueMap,
+ std::map<BasicBlock*, Value*> &OutValueMap);
+ };
+ RegisterOpt<TailDup> X("tailduplicate", "Tail Duplication");
+ }
+
+ Pass *createTailDuplicationPass() { return new TailDup(); }
+
+ /// runOnFunction - Top level algorithm - Loop over each unconditional branch in
+ /// the function, eliminating it if it looks attractive enough.
+ ///
+ bool TailDup::runOnFunction(Function &F) {
+ bool Changed = false;
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; )
+ if (shouldEliminateUnconditionalBranch(I->getTerminator())) {
+ eliminateUnconditionalBranch(cast<BranchInst>(I->getTerminator()));
+ Changed = true;
+ } else {
+ ++I;
+ }
+ return Changed;
+ }
+
+ /// shouldEliminateUnconditionalBranch - Return true if this branch looks
+ /// attractive to eliminate. We eliminate the branch if the destination basic
+ /// block has <= 5 instructions in it, not counting PHI nodes. In practice,
+ /// since one of these is a terminator instruction, this means that we will add
+ /// up to 4 instructions to the new block.
+ ///
+ /// We don't count PHI nodes in the count since they will be removed when the
+ /// contents of the block are copied over.
+ ///
+ bool TailDup::shouldEliminateUnconditionalBranch(TerminatorInst *TI) {
+ BranchInst *BI = dyn_cast<BranchInst>(TI);
+ if (!BI || !BI->isUnconditional()) return false; // Not an uncond branch!
+
+ BasicBlock *Dest = BI->getSuccessor(0);
+ if (Dest == BI->getParent()) return false; // Do not loop infinitely!
+
+ // Do not bother working on dead blocks...
+ pred_iterator PI = pred_begin(Dest), PE = pred_end(Dest);
+ if (PI == PE && Dest != Dest->getParent()->begin())
+ return false; // It's just a dead block, ignore it...
+
+ // Also, do not bother with blocks with only a single predecessor: simplify
+ // CFG will fold these two blocks together!
+ ++PI;
+ if (PI == PE) return false; // Exactly one predecessor!
+
+ BasicBlock::iterator I = Dest->begin();
+ while (isa<PHINode>(*I)) ++I;
+
+ for (unsigned Size = 0; I != Dest->end(); ++Size, ++I)
+ if (Size == 6) return false; // The block is too large...
+ return true;
+ }
+
+
+ /// eliminateUnconditionalBranch - Clone the instructions from the destination
+ /// block into the source block, eliminating the specified unconditional branch.
+ /// If the destination block defines values used by successors of the dest
+ /// block, we may need to insert PHI nodes.
+ ///
+ void TailDup::eliminateUnconditionalBranch(BranchInst *Branch) {
+ BasicBlock *SourceBlock = Branch->getParent();
+ BasicBlock *DestBlock = Branch->getSuccessor(0);
+ assert(SourceBlock != DestBlock && "Our predicate is broken!");
+
+ DEBUG(std::cerr << "TailDuplication[" << SourceBlock->getParent()->getName()
+ << "]: Eliminating branch: " << *Branch);
+
+ // We are going to have to map operands from the original block B to the new
+ // copy of the block B'. If there are PHI nodes in the DestBlock, these PHI
+ // nodes also define part of this mapping. Loop over these PHI nodes, adding
+ // them to our mapping.
+ std::map<Value*, Value*> ValueMapping;
+
+ BasicBlock::iterator BI = DestBlock->begin();
+ bool HadPHINodes = isa<PHINode>(BI);
+ for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
+ ValueMapping[PN] = PN->getIncomingValueForBlock(SourceBlock);
+
+ // Clone the non-phi instructions of the dest block into the source block,
+ // keeping track of the mapping...
+ //
+ for (; BI != DestBlock->end(); ++BI) {
+ Instruction *New = BI->clone();
+ New->setName(BI->getName());
+ SourceBlock->getInstList().push_back(New);
+ ValueMapping[BI] = New;
+ }
+
+ // Now that we have built the mapping information and cloned all of the
+ // instructions (giving us a new terminator, among other things), walk the new
+ // instructions, rewriting references of old instructions to use new
+ // instructions.
+ //
+ BI = Branch; ++BI; // Get an iterator to the first new instruction
+ for (; BI != SourceBlock->end(); ++BI)
+ for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i)
+ if (Value *Remapped = ValueMapping[BI->getOperand(i)])
+ BI->setOperand(i, Remapped);
+
+ // Next we check to see if any of the successors of DestBlock had PHI nodes.
+ // If so, we need to add entries to the PHI nodes for SourceBlock now.
+ for (succ_iterator SI = succ_begin(DestBlock), SE = succ_end(DestBlock);
+ SI != SE; ++SI) {
+ BasicBlock *Succ = *SI;
+ for (BasicBlock::iterator PNI = Succ->begin();
+ PHINode *PN = dyn_cast<PHINode>(PNI); ++PNI) {
+ // Ok, we have a PHI node. Figure out what the incoming value was for the
+ // DestBlock.
+ Value *IV = PN->getIncomingValueForBlock(DestBlock);
+
+ // Remap the value if necessary...
+ if (Value *MappedIV = ValueMapping[IV])
+ IV = MappedIV;
+ PN->addIncoming(IV, SourceBlock);
+ }
+ }
+
+ // Now that all of the instructions are correctly copied into the SourceBlock,
+ // we have one more minor problem: the successors of the original DestBB may
+ // use the values computed in DestBB either directly (if DestBB dominated the
+ // block), or through a PHI node. In either case, we need to insert PHI nodes
+ // into any successors of DestBB (which are now our successors) for each value
+ // that is computed in DestBB, but is used outside of it. All of these uses
+ // we have to rewrite with the new PHI node.
+ //
+ if (succ_begin(SourceBlock) != succ_end(SourceBlock)) // Avoid wasting time...
+ for (BI = DestBlock->begin(); BI != DestBlock->end(); ++BI)
+ if (BI->getType() != Type::VoidTy)
+ InsertPHINodesIfNecessary(BI, ValueMapping[BI], SourceBlock);
+
+ // Final step: now that we have finished everything up, walk the cloned
+ // instructions one last time, constant propagating and DCE'ing them, because
+ // they may not be needed anymore.
+ //
+ BI = Branch; ++BI; // Get an iterator to the first new instruction
+ if (HadPHINodes)
+ while (BI != SourceBlock->end())
+ if (!dceInstruction(BI) && !doConstantPropagation(BI))
+ ++BI;
+
+ DestBlock->removePredecessor(SourceBlock); // Remove entries in PHI nodes...
+ SourceBlock->getInstList().erase(Branch); // Destroy the uncond branch...
+
+ ++NumEliminated; // We just killed a branch!
+ }
+
+ /// InsertPHINodesIfNecessary - So at this point, we cloned the OrigInst
+ /// instruction into the NewBlock with the value of NewInst. If OrigInst was
+ /// used outside of its defining basic block, we need to insert a PHI nodes into
+ /// the successors.
+ ///
+ void TailDup::InsertPHINodesIfNecessary(Instruction *OrigInst, Value *NewInst,
+ BasicBlock *NewBlock) {
+ // Loop over all of the uses of OrigInst, rewriting them to be newly inserted
+ // PHI nodes, unless they are in the same basic block as OrigInst.
+ BasicBlock *OrigBlock = OrigInst->getParent();
+ std::vector<Instruction*> Users;
+ Users.reserve(OrigInst->use_size());
+ for (Value::use_iterator I = OrigInst->use_begin(), E = OrigInst->use_end();
+ I != E; ++I) {
+ Instruction *In = cast<Instruction>(*I);
+ if (In->getParent() != OrigBlock) // Don't modify uses in the orig block!
+ Users.push_back(In);
+ }
+
+ // The common case is that the instruction is only used within the block that
+ // defines it. If we have this case, quick exit.
+ //
+ if (Users.empty()) return;
+
+ // Otherwise, we have a more complex case, handle it now. This requires the
+ // construction of a mapping between a basic block and the value to use when
+ // in the scope of that basic block. This map will map to the original and
+ // new values when in the original or new block, but will map to inserted PHI
+ // nodes when in other blocks.
+ //
+ std::map<BasicBlock*, Value*> ValueMap;
+ std::map<BasicBlock*, Value*> OutValueMap; // The outgoing value map
+ OutValueMap[OrigBlock] = OrigInst;
+ OutValueMap[NewBlock ] = NewInst; // Seed the initial values...
+
+ DEBUG(std::cerr << " ** Inserting PHI nodes for " << OrigInst);
+ while (!Users.empty()) {
+ Instruction *User = Users.back(); Users.pop_back();
+
+ if (PHINode *PN = dyn_cast<PHINode>(User)) {
+ // PHI nodes must be handled specially here, because their operands are
+ // actually defined in predecessor basic blocks, NOT in the block that the
+ // PHI node lives in. Note that we have already added entries to PHI nods
+ // which are in blocks that are immediate successors of OrigBlock, so
+ // don't modify them again.
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingValue(i) == OrigInst &&
+ PN->getIncomingBlock(i) != OrigBlock) {
+ Value *V = GetValueOutBlock(PN->getIncomingBlock(i), OrigInst,
+ ValueMap, OutValueMap);
+ PN->setIncomingValue(i, V);
+ }
+
+ } else {
+ // Any other user of the instruction can just replace any uses with the
+ // new value defined in the block it resides in.
+ Value *V = GetValueInBlock(User->getParent(), OrigInst, ValueMap,
+ OutValueMap);
+ User->replaceUsesOfWith(OrigInst, V);
+ }
+ }
+ }
+
+ /// GetValueInBlock - This is a recursive method which inserts PHI nodes into
+ /// the function until there is a value available in basic block BB.
+ ///
+ Value *TailDup::GetValueInBlock(BasicBlock *BB, Value *OrigVal,
+ std::map<BasicBlock*, Value*> &ValueMap,
+ std::map<BasicBlock*, Value*> &OutValueMap) {
+ Value*& BBVal = ValueMap[BB];
+ if (BBVal) return BBVal; // Value already computed for this block?
+
+ assert(pred_begin(BB) != pred_end(BB) &&
+ "Propagating PHI nodes to unreachable blocks?");
+
+ // If there is no value already available in this basic block, we need to
+ // either reuse a value from an incoming, dominating, basic block, or we need
+ // to create a new PHI node to merge in different incoming values. Because we
+ // don't know if we're part of a loop at this point or not, we create a PHI
+ // node, even if we will ultimately eliminate it.
+ PHINode *PN = new PHINode(OrigVal->getType(), OrigVal->getName()+".pn",
+ BB->begin());
+ BBVal = PN; // Insert this into the BBVal slot in case of cycles...
+
+ Value*& BBOutVal = OutValueMap[BB];
+ if (BBOutVal == 0) BBOutVal = PN;
+
+ // Now that we have created the PHI node, loop over all of the predecessors of
+ // this block, computing an incoming value for the predecessor.
+ std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB));
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ PN->addIncoming(GetValueOutBlock(Preds[i], OrigVal, ValueMap, OutValueMap),
+ Preds[i]);
+
+ // The PHI node is complete. In many cases, however the PHI node was
+ // ultimately unnecessary: we could have just reused a dominating incoming
+ // value. If this is the case, nuke the PHI node and replace the map entry
+ // with the dominating value.
+ //
+ assert(PN->getNumIncomingValues() > 0 && "No predecessors?");
+
+ // Check to see if all of the elements in the PHI node are either the PHI node
+ // itself or ONE particular value.
+ unsigned i = 0;
+ Value *ReplVal = PN->getIncomingValue(i);
+ for (; ReplVal == PN && i != PN->getNumIncomingValues(); ++i)
+ ReplVal = PN->getIncomingValue(i); // Skip values equal to the PN
+
+ for (; i != PN->getNumIncomingValues(); ++i)
+ if (PN->getIncomingValue(i) != PN && PN->getIncomingValue(i) != ReplVal) {
+ ReplVal = 0;
+ break;
+ }
+
+ // Found a value to replace the PHI node with?
+ if (ReplVal) {
+ PN->replaceAllUsesWith(ReplVal);
+ BBVal = ReplVal;
+ if (BBOutVal == PN) BBOutVal = ReplVal;
+ BB->getInstList().erase(PN); // Erase the PHI node...
+ } else {
+ ++NumPHINodes;
+ }
+
+ return BBVal;
+ }
+
+ Value *TailDup::GetValueOutBlock(BasicBlock *BB, Value *OrigVal,
+ std::map<BasicBlock*, Value*> &ValueMap,
+ std::map<BasicBlock*, Value*> &OutValueMap) {
+ Value*& BBVal = OutValueMap[BB];
+ if (BBVal) return BBVal; // Value already computed for this block?
+
+ return BBVal = GetValueInBlock(BB, OrigVal, ValueMap, OutValueMap);
+ }
Index: llvm/lib/Transforms/Scalar/ADCE.cpp
diff -u llvm/lib/Transforms/Scalar/ADCE.cpp:1.53 llvm/lib/Transforms/Scalar/ADCE.cpp:1.53.2.1
--- llvm/lib/Transforms/Scalar/ADCE.cpp:1.53 Thu May 22 17:00:06 2003
+++ llvm/lib/Transforms/Scalar/ADCE.cpp Thu Jun 26 16:35:28 2003
@@ -73,6 +73,8 @@
// instructions that are dead according to LiveSet.
bool dropReferencesOfDeadInstructionsInLiveBlock(BasicBlock *BB);
+ TerminatorInst *convertToUnconditionalBranch(TerminatorInst *TI);
+
inline void markInstructionLive(Instruction *I) {
if (LiveSet.count(I)) return;
DEBUG(std::cerr << "Insn Live: " << I);
@@ -105,8 +107,11 @@
bind_obj(this, &ADCE::markTerminatorLive));
}
- // If this basic block is live, then the terminator must be as well!
- markTerminatorLive(BB);
+ // If this basic block is live, and it ends in an unconditional branch, then
+ // the branch is alive as well...
+ if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()))
+ if (BI->isUnconditional())
+ markTerminatorLive(BB);
}
// dropReferencesOfDeadInstructionsInLiveBlock - Loop over all of the
@@ -136,6 +141,24 @@
}
+/// convertToUnconditionalBranch - Transform this conditional terminator
+/// instruction into an unconditional branch because we don't care which of the
+/// successors it goes to. This eliminate a use of the condition as well.
+///
+TerminatorInst *ADCE::convertToUnconditionalBranch(TerminatorInst *TI) {
+ BranchInst *NB = new BranchInst(TI->getSuccessor(0), TI);
+ BasicBlock *BB = TI->getParent();
+
+ // Remove entries from PHI nodes to avoid confusing ourself later...
+ for (unsigned i = 1, e = TI->getNumSuccessors(); i != e; ++i)
+ TI->getSuccessor(i)->removePredecessor(BB);
+
+ // Delete the old branch itself...
+ BB->getInstList().erase(TI);
+ return NB;
+}
+
+
// doADCE() - Run the Aggressive Dead Code Elimination algorithm, returning
// true if the function was modified.
//
@@ -166,6 +189,16 @@
}
}
+ // Check to ensure we have an exit node for this CFG. If we don't, we won't
+ // have any post-dominance information, thus we cannot perform our
+ // transformations safely.
+ //
+ PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
+ if (DT[&Func->getEntryNode()] == 0) {
+ WorkList.clear();
+ return MadeChanges;
+ }
+
DEBUG(std::cerr << "Processing work list\n");
// AliveBlocks - Set of basic blocks that we know have instructions that are
@@ -208,27 +241,38 @@
DEBUG(
std::cerr << "Current Function: X = Live\n";
- for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
+ for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I){
+ std::cerr << I->getName() << ":\t"
+ << (AliveBlocks.count(I) ? "LIVE\n" : "DEAD\n");
for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE; ++BI){
if (LiveSet.count(BI)) std::cerr << "X ";
std::cerr << *BI;
}
- );
+ });
// Find the first postdominator of the entry node that is alive. Make it the
// new entry node...
//
- PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
-
-
if (AliveBlocks.size() == Func->size()) { // No dead blocks?
- for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
+ for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I) {
// Loop over all of the instructions in the function, telling dead
// instructions to drop their references. This is so that the next sweep
// over the program can safely delete dead instructions without other dead
// instructions still refering to them.
//
dropReferencesOfDeadInstructionsInLiveBlock(I);
+
+ // Check to make sure the terminator instruction is live. If it isn't,
+ // this means that the condition that it branches on (we know it is not an
+ // unconditional branch), is not needed to make the decision of where to
+ // go to, because all outgoing edges go to the same place. We must remove
+ // the use of the condition (because it's probably dead), so we convert
+ // the terminator to a conditional branch.
+ //
+ TerminatorInst *TI = I->getTerminator();
+ if (!LiveSet.count(TI))
+ convertToUnconditionalBranch(TI);
+ }
} else { // If there are some blocks dead...
// If the entry node is dead, insert a new entry node to eliminate the entry
@@ -239,6 +283,7 @@
NewEntry->getInstList().push_back(new BranchInst(&Func->front()));
Func->getBasicBlockList().push_front(NewEntry);
AliveBlocks.insert(NewEntry); // This block is always alive!
+ LiveSet.insert(NewEntry->getTerminator()); // The branch is live
}
// Loop over all of the alive blocks in the function. If any successor
@@ -251,6 +296,14 @@
BasicBlock *BB = I;
TerminatorInst *TI = BB->getTerminator();
+ // If the terminator instruction is alive, but the block it is contained
+ // in IS alive, this means that this terminator is a conditional branch
+ // on a condition that doesn't matter. Make it an unconditional branch
+ // to ONE of the successors. This has the side effect of dropping a use
+ // of the conditional value, which may also be dead.
+ if (!LiveSet.count(TI))
+ TI = convertToUnconditionalBranch(TI);
+
// Loop over all of the successors, looking for ones that are not alive.
// We cannot save the number of successors in the terminator instruction
// here because we may remove them if we don't have a postdominator...
Index: llvm/lib/Transforms/Scalar/GCSE.cpp
diff -u llvm/lib/Transforms/Scalar/GCSE.cpp:1.27 llvm/lib/Transforms/Scalar/GCSE.cpp:1.27.2.1
--- llvm/lib/Transforms/Scalar/GCSE.cpp:1.27 Fri Jan 31 22:50:59 2003
+++ llvm/lib/Transforms/Scalar/GCSE.cpp Thu Jun 26 16:35:28 2003
@@ -120,6 +120,7 @@
// Erase the instruction from the program.
I->getParent()->getInstList().erase(I);
+ WorkList.erase(I);
}
return true;
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.89 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.89.2.1
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.89 Thu Jun 5 15:12:51 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Jun 26 16:35:28 2003
@@ -22,8 +22,10 @@
#include "llvm/Constants.h"
#include "llvm/ConstantHandling.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/CallSite.h"
#include "Support/Statistic.h"
#include <algorithm>
@@ -73,14 +75,20 @@
Instruction *visitSetCondInst(BinaryOperator &I);
Instruction *visitShiftInst(ShiftInst &I);
Instruction *visitCastInst(CastInst &CI);
+ Instruction *visitCallInst(CallInst &CI);
+ Instruction *visitInvokeInst(InvokeInst &II);
Instruction *visitPHINode(PHINode &PN);
Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
Instruction *visitAllocationInst(AllocationInst &AI);
+ Instruction *visitLoadInst(LoadInst &LI);
Instruction *visitBranchInst(BranchInst &BI);
// visitInstruction - Specify what to return for unhandled instructions...
Instruction *visitInstruction(Instruction &I) { return 0; }
+ private:
+ bool transformConstExprCastCall(CallSite CS);
+
// InsertNewInstBefore - insert an instruction New before instruction Old
// in the program. Add the new instruction to the worklist.
//
@@ -107,7 +115,6 @@
// SimplifyCommutative - This performs a few simplifications for commutative
// operators...
bool SimplifyCommutative(BinaryOperator &I);
-
};
RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
@@ -356,10 +363,11 @@
if (Constant *Op1 = dyn_cast<Constant>(I.getOperand(1))) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
const Type *Ty = CI->getType();
- uint64_t Val = Ty->isSigned() ?
- (uint64_t)cast<ConstantSInt>(CI)->getValue() :
- cast<ConstantUInt>(CI)->getValue();
+ int64_t Val = Ty->isSigned() ? cast<ConstantSInt>(CI)->getValue() :
+ (int64_t)cast<ConstantUInt>(CI)->getValue();
switch (Val) {
+ case -1: // X * -1 -> -X
+ return BinaryOperator::createNeg(Op0, I.getName());
case 0:
return ReplaceInstUsesWith(I, Op1); // Eliminate 'mul double %X, 0'
case 1:
@@ -893,15 +901,17 @@
// CastInst simplification
//
Instruction *InstCombiner::visitCastInst(CastInst &CI) {
+ Value *Src = CI.getOperand(0);
+
// If the user is casting a value to the same type, eliminate this cast
// instruction...
- if (CI.getType() == CI.getOperand(0)->getType())
- return ReplaceInstUsesWith(CI, CI.getOperand(0));
+ if (CI.getType() == Src->getType())
+ return ReplaceInstUsesWith(CI, Src);
// If casting the result of another cast instruction, try to eliminate this
// one!
//
- if (CastInst *CSrc = dyn_cast<CastInst>(CI.getOperand(0))) {
+ if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {
if (isEliminableCastOfCast(CI, CSrc)) {
// This instruction now refers directly to the cast's src operand. This
// has a good chance of making CSrc dead.
@@ -925,9 +935,192 @@
}
}
+ // If casting the result of a getelementptr instruction with no offset, turn
+ // this into a cast of the original pointer!
+ //
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
+ bool AllZeroOperands = true;
+ for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
+ if (!isa<Constant>(GEP->getOperand(i)) ||
+ !cast<Constant>(GEP->getOperand(i))->isNullValue()) {
+ AllZeroOperands = false;
+ break;
+ }
+ if (AllZeroOperands) {
+ CI.setOperand(0, GEP->getOperand(0));
+ return &CI;
+ }
+ }
+
+ // If this is a cast to bool (which is effectively a "!=0" test), then we can
+ // perform a few optimizations...
+ //
+ if (CI.getType() == Type::BoolTy) {
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Src)) {
+ Value *Op0 = BO->getOperand(0), *Op1 = BO->getOperand(1);
+
+ // Replace (cast (sub A, B) to bool) with (setne A, B)
+ if (BO->getOpcode() == Instruction::Sub)
+ return new SetCondInst(Instruction::SetNE, Op0, Op1);
+
+ // Replace (cast (add A, B) to bool) with (setne A, -B) if B is
+ // efficiently invertible, or if the add has just this one use.
+ if (BO->getOpcode() == Instruction::Add)
+ if (Value *NegVal = dyn_castNegVal(Op1))
+ return new SetCondInst(Instruction::SetNE, Op0, NegVal);
+ else if (Value *NegVal = dyn_castNegVal(Op0))
+ return new SetCondInst(Instruction::SetNE, NegVal, Op1);
+ else if (BO->use_size() == 1) {
+ Instruction *Neg = BinaryOperator::createNeg(Op1, BO->getName());
+ BO->setName("");
+ InsertNewInstBefore(Neg, CI);
+ return new SetCondInst(Instruction::SetNE, Op0, Neg);
+ }
+ }
+ }
+
return 0;
}
+// CallInst simplification
+//
+Instruction *InstCombiner::visitCallInst(CallInst &CI) {
+ if (transformConstExprCastCall(&CI)) return 0;
+ return 0;
+}
+
+// InvokeInst simplification
+//
+Instruction *InstCombiner::visitInvokeInst(InvokeInst &II) {
+ if (transformConstExprCastCall(&II)) return 0;
+ return 0;
+}
+
+// getPromotedType - Return the specified type promoted as it would be to pass
+// though a va_arg area...
+static const Type *getPromotedType(const Type *Ty) {
+ switch (Ty->getPrimitiveID()) {
+ case Type::SByteTyID:
+ case Type::ShortTyID: return Type::IntTy;
+ case Type::UByteTyID:
+ case Type::UShortTyID: return Type::UIntTy;
+ case Type::FloatTyID: return Type::DoubleTy;
+ default: return Ty;
+ }
+}
+
+// transformConstExprCastCall - If the callee is a constexpr cast of a function,
+// attempt to move the cast to the arguments of the call/invoke.
+//
+bool InstCombiner::transformConstExprCastCall(CallSite CS) {
+ if (!isa<ConstantExpr>(CS.getCalledValue())) return false;
+ ConstantExpr *CE = cast<ConstantExpr>(CS.getCalledValue());
+ if (CE->getOpcode() != Instruction::Cast ||
+ !isa<ConstantPointerRef>(CE->getOperand(0)))
+ return false;
+ ConstantPointerRef *CPR = cast<ConstantPointerRef>(CE->getOperand(0));
+ if (!isa<Function>(CPR->getValue())) return false;
+ Function *Callee = cast<Function>(CPR->getValue());
+ Instruction *Caller = CS.getInstruction();
+
+ // Okay, this is a cast from a function to a different type. Unless doing so
+ // would cause a type conversion of one of our arguments, change this call to
+ // be a direct call with arguments casted to the appropriate types.
+ //
+ const FunctionType *FT = Callee->getFunctionType();
+ const Type *OldRetTy = Caller->getType();
+
+ if (Callee->isExternal() &&
+ !OldRetTy->isLosslesslyConvertibleTo(FT->getReturnType()))
+ return false; // Cannot transform this return value...
+
+ unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin());
+ unsigned NumCommonArgs = std::min(FT->getNumParams(), NumActualArgs);
+
+ CallSite::arg_iterator AI = CS.arg_begin();
+ for (unsigned i = 0, e = NumCommonArgs; i != e; ++i, ++AI) {
+ const Type *ParamTy = FT->getParamType(i);
+ bool isConvertible = (*AI)->getType()->isLosslesslyConvertibleTo(ParamTy);
+ if (Callee->isExternal() && !isConvertible) return false;
+ }
+
+ if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() &&
+ Callee->isExternal())
+ return false; // Do not delete arguments unless we have a function body...
+
+ // Okay, we decided that this is a safe thing to do: go ahead and start
+ // inserting cast instructions as necessary...
+ std::vector<Value*> Args;
+ Args.reserve(NumActualArgs);
+
+ AI = CS.arg_begin();
+ for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
+ const Type *ParamTy = FT->getParamType(i);
+ if ((*AI)->getType() == ParamTy) {
+ Args.push_back(*AI);
+ } else {
+ Instruction *Cast = new CastInst(*AI, ParamTy, "tmp");
+ InsertNewInstBefore(Cast, *Caller);
+ Args.push_back(Cast);
+ }
+ }
+
+ // If the function takes more arguments than the call was taking, add them
+ // now...
+ for (unsigned i = NumCommonArgs; i != FT->getNumParams(); ++i)
+ Args.push_back(Constant::getNullValue(FT->getParamType(i)));
+
+ // If we are removing arguments to the function, emit an obnoxious warning...
+ if (FT->getNumParams() < NumActualArgs)
+ if (!FT->isVarArg()) {
+ std::cerr << "WARNING: While resolving call to function '"
+ << Callee->getName() << "' arguments were dropped!\n";
+ } else {
+ // Add all of the arguments in their promoted form to the arg list...
+ for (unsigned i = FT->getNumParams(); i != NumActualArgs; ++i, ++AI) {
+ const Type *PTy = getPromotedType((*AI)->getType());
+ if (PTy != (*AI)->getType()) {
+ // Must promote to pass through va_arg area!
+ Instruction *Cast = new CastInst(*AI, PTy, "tmp");
+ InsertNewInstBefore(Cast, *Caller);
+ Args.push_back(Cast);
+ } else {
+ Args.push_back(*AI);
+ }
+ }
+ }
+
+ if (FT->getReturnType() == Type::VoidTy)
+ Caller->setName(""); // Void type should not have a name...
+
+ Instruction *NC;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
+ NC = new InvokeInst(Callee, II->getNormalDest(), II->getExceptionalDest(),
+ Args, Caller->getName(), Caller);
+ } else {
+ NC = new CallInst(Callee, Args, Caller->getName(), Caller);
+ }
+
+ // Insert a cast of the return type as necessary...
+ Value *NV = NC;
+ if (Caller->getType() != NV->getType() && !Caller->use_empty()) {
+ if (NV->getType() != Type::VoidTy) {
+ NV = NC = new CastInst(NC, Caller->getType(), "tmp");
+ InsertNewInstBefore(NC, *Caller);
+ AddUsesToWorkList(*Caller);
+ } else {
+ NV = Constant::getNullValue(Caller->getType());
+ }
+ }
+
+ if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
+ Caller->replaceAllUsesWith(NV);
+ Caller->getParent()->getInstList().erase(Caller);
+ removeFromWorkList(Caller);
+ return true;
+}
+
+
// PHINode simplification
//
@@ -1069,6 +1262,52 @@
}
return 0;
}
+
+/// GetGEPGlobalInitializer - Given a constant, and a getelementptr
+/// constantexpr, return the constant value being addressed by the constant
+/// expression, or null if something is funny.
+///
+static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
+ if (CE->getOperand(1) != Constant::getNullValue(Type::LongTy))
+ return 0; // Do not allow stepping over the value!
+
+ // Loop over all of the operands, tracking down which value we are
+ // addressing...
+ for (unsigned i = 2, e = CE->getNumOperands(); i != e; ++i)
+ if (ConstantUInt *CU = dyn_cast<ConstantUInt>(CE->getOperand(i))) {
+ ConstantStruct *CS = cast<ConstantStruct>(C);
+ if (CU->getValue() >= CS->getValues().size()) return 0;
+ C = cast<Constant>(CS->getValues()[CU->getValue()]);
+ } else if (ConstantSInt *CS = dyn_cast<ConstantSInt>(CE->getOperand(i))) {
+ ConstantArray *CA = cast<ConstantArray>(C);
+ if ((uint64_t)CS->getValue() >= CA->getValues().size()) return 0;
+ C = cast<Constant>(CA->getValues()[CS->getValue()]);
+ } else
+ return 0;
+ return C;
+}
+
+Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
+ Value *Op = LI.getOperand(0);
+ if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Op))
+ Op = CPR->getValue();
+
+ // Instcombine load (constant global) into the value loaded...
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
+ if (GV->isConstant())
+ return ReplaceInstUsesWith(LI, GV->getInitializer());
+
+ // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op))
+ if (CE->getOpcode() == Instruction::GetElementPtr)
+ if (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0)))
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue()))
+ if (GV->isConstant())
+ if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
+ return ReplaceInstUsesWith(LI, V);
+ return 0;
+}
+
Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
// Change br (not X), label True, label False to: br X, label False, True
Index: llvm/lib/Transforms/Scalar/Mem2Reg.cpp
diff -u llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.3 llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.3.2.1
--- llvm/lib/Transforms/Scalar/Mem2Reg.cpp:1.3 Wed Apr 23 11:37:42 2003
+++ llvm/lib/Transforms/Scalar/Mem2Reg.cpp Thu Jun 26 16:35:28 2003
@@ -40,19 +40,26 @@
BasicBlock &BB = F.getEntryNode(); // Get the entry node for the function
- // Find allocas that are safe to promote, by looking at all instructions in
- // the entry node
- for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
- if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
- if (isAllocaPromotable(AI, TD))
- Allocas.push_back(AI);
+ bool Changed = false;
+
+ while (1) {
+ Allocas.clear();
+
+ // Find allocas that are safe to promote, by looking at all instructions in
+ // the entry node
+ for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
+ if (isAllocaPromotable(AI, TD))
+ Allocas.push_back(AI);
+
+ if (Allocas.empty()) break;
- if (!Allocas.empty()) {
PromoteMemToReg(Allocas, getAnalysis<DominanceFrontier>(), TD);
NumPromoted += Allocas.size();
- return true;
+ Changed = true;
}
- return false;
+
+ return Changed;
}
// createPromoteMemoryToRegister - Provide an entry point to create this pass.
Index: llvm/lib/Transforms/Scalar/SCCP.cpp
diff -u llvm/lib/Transforms/Scalar/SCCP.cpp:1.69 llvm/lib/Transforms/Scalar/SCCP.cpp:1.69.2.1
--- llvm/lib/Transforms/Scalar/SCCP.cpp:1.69 Tue May 20 16:01:16 2003
+++ llvm/lib/Transforms/Scalar/SCCP.cpp Thu Jun 26 16:35:28 2003
@@ -420,12 +420,13 @@
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
InstVal &IV = getValueState(PN.getIncomingValue(i));
if (IV.isUndefined()) continue; // Doesn't influence PHI node.
- if (IV.isOverdefined()) { // PHI node becomes overdefined!
- markOverdefined(&PN);
- return;
- }
if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
+ if (IV.isOverdefined()) { // PHI node becomes overdefined!
+ markOverdefined(&PN);
+ return;
+ }
+
if (OperandVal == 0) { // Grab the first value...
OperandVal = IV.getConstant();
} else { // Another value is being merged in!
More information about the llvm-commits
mailing list