Check for volatile loads only once.
[oota-llvm.git] / lib / Transforms / Scalar / SCCP.cpp
index 7682e5a9e188e59688788fa8515cb37aa9b95735..d9d74ca8ea93b627c49d0895ae978e576b13f5ae 100644 (file)
@@ -1,10 +1,10 @@
 //===- SCCP.cpp - Sparse Conditional Constant Propagation -----------------===//
-// 
+//
 //                     The LLVM Compiler Infrastructure
 //
 // This file was developed by the LLVM research group and is distributed under
 // the University of Illinois Open Source License. See LICENSE.TXT for details.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
 // This file implements sparse conditional constant propagation and merging:
@@ -45,7 +45,7 @@ using namespace llvm;
 namespace {
 
 class LatticeVal {
-  enum { 
+  enum {
     undefined,           // This instruction has no known value
     constant,            // This instruction has a constant value
     overdefined          // This instruction has an unknown value
@@ -198,7 +198,7 @@ public:
 
 private:
   // markConstant - Make a value be marked as "constant".  If the value
-  // is not already a constant, add it to the instruction work list so that 
+  // is not already a constant, add it to the instruction work list so that
   // the users of the instruction are updated later.
   //
   inline void markConstant(LatticeVal &IV, Value *V, Constant *C) {
@@ -212,12 +212,16 @@ private:
   }
 
   // markOverdefined - Make a value be marked as "overdefined". If the
-  // value is not already overdefined, add it to the overdefined instruction 
+  // value is not already overdefined, add it to the overdefined instruction
   // work list so that the users of the instruction are updated later.
-  
+
   inline void markOverdefined(LatticeVal &IV, Value *V) {
     if (IV.markOverdefined()) {
-      DEBUG(std::cerr << "markOverdefined: " << *V);
+      DEBUG(std::cerr << "markOverdefined: ";
+            if (Function *F = dyn_cast<Function>(V))
+              std::cerr << "Function '" << F->getName() << "'\n";
+            else
+              std::cerr << *V);
       // Only instructions go on the work list
       OverdefinedInstWorkList.push_back(V);
     }
@@ -258,9 +262,9 @@ private:
     return ValueState[V];
   }
 
-  // markEdgeExecutable - Mark a basic block as executable, adding it to the BB 
+  // markEdgeExecutable - Mark a basic block as executable, adding it to the BB
   // work list if it is not already executable...
-  // 
+  //
   void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
     if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
       return;  // This edge is already known to be executable!
@@ -304,7 +308,7 @@ private:
 private:
   friend class InstVisitor<SCCPSolver>;
 
-  // visit implementations - Something changed in this instruction... Either an 
+  // visit implementations - Something changed in this instruction... Either an
   // operand made a transition, or the instruction is newly executable.  Change
   // the value type of I to reflect these changes if appropriate.
   //
@@ -402,7 +406,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
 
   // Make sure the source basic block is executable!!
   if (!BBExecutable.count(From)) return false;
-  
+
   // Check to make sure this edge itself is actually feasible now...
   TerminatorInst *TI = From->getTerminator();
   if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
@@ -418,7 +422,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
         if (!isa<ConstantBool>(BCValue.getConstant())) return true;
 
         // Constant condition variables mean the branch can only go a single way
-        return BI->getSuccessor(BCValue.getConstant() == 
+        return BI->getSuccessor(BCValue.getConstant() ==
                                        ConstantBool::False) == To;
       }
       return false;
@@ -507,7 +511,7 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
     LatticeVal &IV = getValueState(PN.getIncomingValue(i));
     if (IV.isUndefined()) continue;  // Doesn't influence PHI node.
-    
+
     if (isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) {
       if (IV.isOverdefined()) {   // PHI node becomes overdefined!
         markOverdefined(PNIV, &PN);
@@ -520,7 +524,7 @@ void SCCPSolver::visitPHINode(PHINode &PN) {
         // There is already a reachable operand.  If we conflict with it,
         // then the PHI node becomes overdefined.  If we agree with it, we
         // can continue on.
-        
+
         // Check to see if there are two different constants merging...
         if (IV.getConstant() != OperandVal) {
           // Yes there is.  This means the PHI node is not constant.
@@ -611,6 +615,43 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
   LatticeVal &V2State = getValueState(I.getOperand(1));
 
   if (V1State.isOverdefined() || V2State.isOverdefined()) {
+    // If this is an AND or OR with 0 or -1, it doesn't matter that the other
+    // operand is overdefined.
+    if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Or) {
+      LatticeVal *NonOverdefVal = 0;
+      if (!V1State.isOverdefined()) {
+        NonOverdefVal = &V1State;
+      } else if (!V2State.isOverdefined()) {
+        NonOverdefVal = &V2State;
+      }
+
+      if (NonOverdefVal) {
+        if (NonOverdefVal->isUndefined()) {
+          // Could annihilate value.
+          if (I.getOpcode() == Instruction::And)
+            markConstant(IV, &I, Constant::getNullValue(I.getType()));
+          else
+            markConstant(IV, &I, ConstantInt::getAllOnesValue(I.getType()));
+          return;
+        } else {
+          if (I.getOpcode() == Instruction::And) {
+            if (NonOverdefVal->getConstant()->isNullValue()) {
+              markConstant(IV, &I, NonOverdefVal->getConstant());
+              return;      // X or 0 = -1
+            }
+          } else {
+            if (ConstantIntegral *CI =
+                     dyn_cast<ConstantIntegral>(NonOverdefVal->getConstant()))
+              if (CI->isAllOnesValue()) {
+                markConstant(IV, &I, NonOverdefVal->getConstant());
+                return;    // X or -1 = -1
+              }
+          }
+        }
+      }
+    }
+
+
     // If both operands are PHI nodes, it is possible that this instruction has
     // a constant value, despite the fact that the PHI node doesn't.  Check for
     // this condition now.
@@ -712,7 +753,7 @@ void SCCPSolver::visitGetElementPtrInst(GetElementPtrInst &I) {
   Constant *Ptr = Operands[0];
   Operands.erase(Operands.begin());  // Erase the pointer from idx list...
 
-  markConstant(IV, &I, ConstantExpr::getGetElementPtr(Ptr, Operands));  
+  markConstant(IV, &I, ConstantExpr::getGetElementPtr(Ptr, Operands));
 }
 
 /// GetGEPGlobalInitializer - Given a constant and a getelementptr constantexpr,
@@ -730,12 +771,12 @@ static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
       ConstantStruct *CS = dyn_cast<ConstantStruct>(C);
       if (CS == 0) return 0;
       if (CU->getValue() >= CS->getNumOperands()) return 0;
-      C = CS->getOperand(CU->getValue());
+      C = CS->getOperand((unsigned)CU->getValue());
     } else if (ConstantSInt *CS = dyn_cast<ConstantSInt>(CE->getOperand(i))) {
       ConstantArray *CA = dyn_cast<ConstantArray>(C);
       if (CA == 0) return 0;
       if ((uint64_t)CS->getValue() >= CA->getNumOperands()) return 0;
-      C = CA->getOperand(CS->getValue());
+      C = CA->getOperand((unsigned)CS->getValue());
     } else
       return 0;
   return C;
@@ -772,7 +813,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
       markConstant(IV, &I, Constant::getNullValue(I.getType()));
       return;
     }
-      
+
     // Transform load (constant global) into the value loaded.
     if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) {
       if (GV->isConstant()) {
@@ -794,13 +835,13 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
     // Transform load (constantexpr_GEP global, 0, ...) into the value loaded.
     if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr))
       if (CE->getOpcode() == Instruction::GetElementPtr)
-       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
-         if (GV->isConstant() && !GV->isExternal())
-           if (Constant *V = 
-               GetGEPGlobalInitializer(GV->getInitializer(), CE)) {
-             markConstant(IV, &I, V);
-             return;
-           }
+    if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
+      if (GV->isConstant() && !GV->isExternal())
+        if (Constant *V =
+        GetGEPGlobalInitializer(GV->getInitializer(), CE)) {
+          markConstant(IV, &I, V);
+          return;
+        }
   }
 
   // Otherwise we cannot say for certain what value this load will produce.
@@ -816,7 +857,7 @@ void SCCPSolver::visitCallSite(CallSite CS) {
   hash_map<Function*, LatticeVal>::iterator TFRVI =TrackedFunctionRetVals.end();
   if (F && F->hasInternalLinkage())
     TFRVI = TrackedFunctionRetVals.find(F);
-  
+
   if (TFRVI != TrackedFunctionRetVals.end()) {
     // If this is the first call to the function hit, mark its entry block
     // executable.
@@ -824,7 +865,7 @@ void SCCPSolver::visitCallSite(CallSite CS) {
       MarkBlockExecutable(F->begin());
 
     CallSite::arg_iterator CAI = CS.arg_begin();
-    for (Function::aiterator AI = F->abegin(), E = F->aend();
+    for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
          AI != E; ++AI, ++CAI) {
       LatticeVal &IV = ValueState[AI];
       if (!IV.isOverdefined())
@@ -842,7 +883,7 @@ void SCCPSolver::visitCallSite(CallSite CS) {
     mergeInValue(IV, I, TFRVI->second);
     return;
   }
-  
+
   if (F == 0 || !F->isExternal() || !canConstantFoldCallTo(F)) {
     markOverdefined(IV, I);
     return;
@@ -873,15 +914,15 @@ void SCCPSolver::visitCallSite(CallSite CS) {
 
 void SCCPSolver::Solve() {
   // Process the work lists until they are empty!
-  while (!BBWorkList.empty() || !InstWorkList.empty() || 
-        !OverdefinedInstWorkList.empty()) {
+  while (!BBWorkList.empty() || !InstWorkList.empty() ||
+         !OverdefinedInstWorkList.empty()) {
     // Process the instruction work list...
     while (!OverdefinedInstWorkList.empty()) {
       Value *I = OverdefinedInstWorkList.back();
       OverdefinedInstWorkList.pop_back();
 
       DEBUG(std::cerr << "\nPopped off OI-WL: " << *I);
-      
+
       // "I" got into the work list because it either made the transition from
       // bottom to constant
       //
@@ -899,7 +940,7 @@ void SCCPSolver::Solve() {
       InstWorkList.pop_back();
 
       DEBUG(std::cerr << "\nPopped off I-WL: " << *I);
-      
+
       // "I" got into the work list because it either made the transition from
       // bottom to constant
       //
@@ -912,14 +953,14 @@ void SCCPSolver::Solve() {
              UI != E; ++UI)
           OperandChangedState(*UI);
     }
-    
+
     // Process the basic block work list...
     while (!BBWorkList.empty()) {
       BasicBlock *BB = BBWorkList.back();
       BBWorkList.pop_back();
-      
+
       DEBUG(std::cerr << "\nPopped off BBWL: " << *BB);
-      
+
       // Notify all instructions in this basic block that they are newly
       // executable.
       visit(BB);
@@ -934,26 +975,29 @@ void SCCPSolver::Solve() {
 /// should be rerun.
 bool SCCPSolver::ResolveBranchesIn(Function &F) {
   bool BranchesResolved = false;
-  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
-    TerminatorInst *TI = BB->getTerminator();
-    if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
-      if (BI->isConditional()) {
-        LatticeVal &BCValue = getValueState(BI->getCondition());
-        if (BCValue.isUndefined()) {
-          BI->setCondition(ConstantBool::True);
+  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+    if (BBExecutable.count(BB)) {
+      TerminatorInst *TI = BB->getTerminator();
+      if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
+        if (BI->isConditional()) {
+          LatticeVal &BCValue = getValueState(BI->getCondition());
+          if (BCValue.isUndefined()) {
+            BI->setCondition(ConstantBool::True);
+            BranchesResolved = true;
+            visit(BI);
+          }
+        }
+      } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
+        LatticeVal &SCValue = getValueState(SI->getCondition());
+        if (SCValue.isUndefined()) {
+          const Type *CondTy = SI->getCondition()->getType();
+          SI->setCondition(Constant::getNullValue(CondTy));
           BranchesResolved = true;
-          visit(BI);
+          visit(SI);
         }
       }
-    } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
-      LatticeVal &SCValue = getValueState(SI->getCondition());
-      if (SCValue.isUndefined()) {
-        SI->setCondition(Constant::getNullValue(SI->getCondition()->getType()));
-        BranchesResolved = true;
-        visit(SI);
-      }
     }
-  }
+
   return BranchesResolved;
 }
 
@@ -972,7 +1016,7 @@ namespace {
     // algorithm, and return true if the function was modified.
     //
     bool runOnFunction(Function &F);
-    
+
     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
       AU.setPreservesCFG();
     }
@@ -1000,13 +1044,14 @@ bool SCCP::runOnFunction(Function &F) {
 
   // Mark all arguments to the function as being overdefined.
   hash_map<Value*, LatticeVal> &Values = Solver.getValueMapping();
-  for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI)
+  for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E; ++AI)
     Values[AI].markOverdefined();
 
   // Solve for constants.
   bool ResolvedBranches = true;
   while (ResolvedBranches) {
     Solver.Solve();
+    DEBUG(std::cerr << "RESOLVING UNDEF BRANCHES\n");
     ResolvedBranches = Solver.ResolveBranchesIn(F);
   }
 
@@ -1050,13 +1095,13 @@ bool SCCP::runOnFunction(Function &F) {
             Constant *Const = IV.isConstant()
               ? IV.getConstant() : UndefValue::get(Inst->getType());
             DEBUG(std::cerr << "  Constant: " << *Const << " = " << *Inst);
-            
+
             // Replaces all of the uses of a variable with uses of the constant.
             Inst->replaceAllUsesWith(Const);
-            
+
             // Delete the instruction.
             BB->getInstList().erase(Inst);
-            
+
             // Hey, we just changed something!
             MadeChanges = true;
             ++NumInstRemoved;
@@ -1096,6 +1141,9 @@ ModulePass *llvm::createIPSCCPPass() {
 
 
 static bool AddressIsTaken(GlobalValue *GV) {
+  // Delete any dead constantexpr klingons.
+  GV->removeDeadConstantUsers();
+
   for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end();
        UI != E; ++UI)
     if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
@@ -1128,7 +1176,8 @@ bool IPSCCP::runOnModule(Module &M) {
     if (!F->hasInternalLinkage() || AddressIsTaken(F)) {
       if (!F->isExternal())
         Solver.MarkBlockExecutable(F->begin());
-      for (Function::aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI)
+      for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
+           AI != E; ++AI)
         Values[AI].markOverdefined();
     } else {
       Solver.AddTrackedFunction(F);
@@ -1137,7 +1186,8 @@ bool IPSCCP::runOnModule(Module &M) {
   // Loop over global variables.  We inform the solver about any internal global
   // variables that do not have their 'addresses taken'.  If they don't have
   // their addresses taken, we can propagate constants through them.
-  for (Module::giterator G = M.gbegin(), E = M.gend(); G != E; ++G)
+  for (Module::global_iterator G = M.global_begin(), E = M.global_end();
+       G != E; ++G)
     if (!G->isConstant() && G->hasInternalLinkage() && !AddressIsTaken(G))
       Solver.TrackValueOfGlobalVariable(G);
 
@@ -1146,6 +1196,7 @@ bool IPSCCP::runOnModule(Module &M) {
   while (ResolvedBranches) {
     Solver.Solve();
 
+    DEBUG(std::cerr << "RESOLVING UNDEF BRANCHES\n");
     ResolvedBranches = false;
     for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
       ResolvedBranches |= Solver.ResolveBranchesIn(*F);
@@ -1158,14 +1209,15 @@ bool IPSCCP::runOnModule(Module &M) {
   //
   std::set<BasicBlock*> &ExecutableBBs = Solver.getExecutableBlocks();
   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
-    for (Function::aiterator AI = F->abegin(), E = F->aend(); AI != E; ++AI)
+    for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end();
+         AI != E; ++AI)
       if (!AI->use_empty()) {
         LatticeVal &IV = Values[AI];
         if (IV.isConstant() || IV.isUndefined()) {
           Constant *CST = IV.isConstant() ?
             IV.getConstant() : UndefValue::get(AI->getType());
           DEBUG(std::cerr << "***  Arg " << *AI << " = " << *CST <<"\n");
-          
+
           // Replaces all of the uses of a variable with uses of the
           // constant.
           AI->replaceAllUsesWith(CST);
@@ -1195,7 +1247,7 @@ bool IPSCCP::runOnModule(Module &M) {
           MadeChanges = true;
           ++IPNumInstRemoved;
         }
-        
+
         for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) {
           BasicBlock *Succ = TI->getSuccessor(i);
           if (Succ->begin() != Succ->end() && isa<PHINode>(Succ->begin()))
@@ -1220,11 +1272,11 @@ bool IPSCCP::runOnModule(Module &M) {
               Constant *Const = IV.isConstant()
                 ? IV.getConstant() : UndefValue::get(Inst->getType());
               DEBUG(std::cerr << "  Constant: " << *Const << " = " << *Inst);
-              
+
               // Replaces all of the uses of a variable with uses of the
               // constant.
               Inst->replaceAllUsesWith(Const);
-              
+
               // Delete the instruction.
               if (!isa<TerminatorInst>(Inst) && !isa<CallInst>(Inst))
                 BB->getInstList().erase(Inst);
@@ -1248,7 +1300,7 @@ bool IPSCCP::runOnModule(Module &M) {
         bool Folded = ConstantFoldTerminator(I->getParent());
         assert(Folded && "Didn't fold away reference to block!");
       }
-        
+
       // Finally, delete the basic block.
       F->getBasicBlockList().erase(DeadBB);
     }
@@ -1284,7 +1336,8 @@ bool IPSCCP::runOnModule(Module &M) {
       SI->eraseFromParent();
     }
     M.getGlobalList().erase(GV);
+    ++IPNumGlobalConst;
   }
-  
+
   return MadeChanges;
 }