[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