Move EVER MORE stuff over to LLVMContext.
[oota-llvm.git] / lib / Transforms / Scalar / PredicateSimplifier.cpp
index 665a46bfd73fb82847287e21478dc1f5c80f4776..50d606311a17f1b25a41c44c51ce48ff31f193f8 100644 (file)
@@ -110,6 +110,8 @@ STATISTIC(NumSimple      , "Number of simple replacements");
 STATISTIC(NumBlocks      , "Number of blocks marked unreachable");
 STATISTIC(NumSnuggle     , "Number of comparisons snuggled");
 
+static const ConstantRange empty(1, false);
+
 namespace {
   class DomTreeDFS {
   public:
@@ -341,6 +343,7 @@ namespace {
     UGE = UGT | EQ_BIT
   };
 
+#ifndef NDEBUG
   /// validPredicate - determines whether a given value is actually a lattice
   /// value. Only used in assertions or debugging.
   static bool validPredicate(LatticeVal LV) {
@@ -355,6 +358,7 @@ namespace {
         return false;
     }
   }
+#endif
 
   /// reversePredicate - reverse the direction of the inequality
   static LatticeVal reversePredicate(LatticeVal LV) {
@@ -937,7 +941,6 @@ namespace {
       const_iterator end()   const { return RangeList.end(); }
 
       iterator find(DomTreeDFS::Node *Subtree) {
-        static ConstantRange empty(1, false);
         iterator E = end();
         iterator I = std::lower_bound(begin(), E,
                                       std::make_pair(Subtree, empty), swo);
@@ -947,7 +950,6 @@ namespace {
       }
 
       const_iterator find(DomTreeDFS::Node *Subtree) const {
-        static const ConstantRange empty(1, false);
         const_iterator E = end();
         const_iterator I = std::lower_bound(begin(), E,
                                             std::make_pair(Subtree, empty), swo);
@@ -960,7 +962,6 @@ namespace {
         assert(!CR.isEmptySet() && "Empty ConstantRange.");
         assert(!CR.isSingleElement() && "Refusing to store single element.");
 
-        static ConstantRange empty(1, false);
         iterator E = end();
         iterator I =
             std::lower_bound(begin(), E, std::make_pair(Subtree, empty), swo);
@@ -989,7 +990,7 @@ namespace {
       assert(!CR.isEmptySet() && "Can't deal with empty set.");
 
       if (LV == NE)
-        return makeConstantRange(ICmpInst::ICMP_NE, CR);
+        return ConstantRange::makeICmpRegion(ICmpInst::ICMP_NE, CR);
 
       unsigned LV_s = LV & (SGT_BIT|SLT_BIT);
       unsigned LV_u = LV & (UGT_BIT|ULT_BIT);
@@ -998,73 +999,24 @@ namespace {
       ConstantRange Range(CR.getBitWidth());
 
       if (LV_s == SGT_BIT) {
-        Range = Range.maximalIntersectWith(makeConstantRange(
+        Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion(
                     hasEQ ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, CR));
       } else if (LV_s == SLT_BIT) {
-        Range = Range.maximalIntersectWith(makeConstantRange(
+        Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion(
                     hasEQ ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, CR));
       }
 
       if (LV_u == UGT_BIT) {
-        Range = Range.maximalIntersectWith(makeConstantRange(
+        Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion(
                     hasEQ ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_UGT, CR));
       } else if (LV_u == ULT_BIT) {
-        Range = Range.maximalIntersectWith(makeConstantRange(
+        Range = Range.maximalIntersectWith(ConstantRange::makeICmpRegion(
                     hasEQ ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT, CR));
       }
 
       return Range;
     }
 
-    /// makeConstantRange - Creates a ConstantRange representing the set of all
-    /// value that match the ICmpInst::Predicate with any of the values in CR.
-    ConstantRange makeConstantRange(ICmpInst::Predicate ICmpOpcode,
-                                    const ConstantRange &CR) {
-      uint32_t W = CR.getBitWidth();
-      switch (ICmpOpcode) {
-        default: assert(!"Invalid ICmp opcode to makeConstantRange()");
-        case ICmpInst::ICMP_EQ:
-          return ConstantRange(CR.getLower(), CR.getUpper());
-        case ICmpInst::ICMP_NE:
-          if (CR.isSingleElement())
-            return ConstantRange(CR.getUpper(), CR.getLower());
-          return ConstantRange(W);
-        case ICmpInst::ICMP_ULT:
-          return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax());
-        case ICmpInst::ICMP_SLT:
-          return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax());
-        case ICmpInst::ICMP_ULE: {
-          APInt UMax(CR.getUnsignedMax());
-          if (UMax.isMaxValue())
-            return ConstantRange(W);
-          return ConstantRange(APInt::getMinValue(W), UMax + 1);
-        }
-        case ICmpInst::ICMP_SLE: {
-          APInt SMax(CR.getSignedMax());
-          if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue())
-            return ConstantRange(W);
-          return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
-        }
-        case ICmpInst::ICMP_UGT:
-          return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W));
-        case ICmpInst::ICMP_SGT:
-          return ConstantRange(CR.getSignedMin() + 1,
-                               APInt::getSignedMinValue(W));
-        case ICmpInst::ICMP_UGE: {
-          APInt UMin(CR.getUnsignedMin());
-          if (UMin.isMinValue())
-            return ConstantRange(W);
-          return ConstantRange(UMin, APInt::getNullValue(W));
-        }
-        case ICmpInst::ICMP_SGE: {
-          APInt SMin(CR.getSignedMin());
-          if (SMin.isMinSignedValue())
-            return ConstantRange(W);
-          return ConstantRange(SMin, APInt::getSignedMinValue(W));
-        }
-      }
-    }
-
 #ifndef NDEBUG
     bool isCanonical(Value *V, DomTreeDFS::Node *Subtree) {
       return V == VN.canonicalize(V, Subtree);
@@ -1389,6 +1341,7 @@ namespace {
     BasicBlock *TopBB;
     Instruction *TopInst;
     bool &modified;
+    LLVMContext *Context;
 
     typedef InequalityGraph::Node Node;
 
@@ -1523,12 +1476,12 @@ namespace {
         Instruction *I2 = dyn_cast<Instruction>(R);
         if (I2 && below(I2)) {
           std::vector<Instruction *> ToNotify;
-          for (Value::use_iterator UI = R->use_begin(), UE = R->use_end();
+          for (Value::use_iterator UI = I2->use_begin(), UE = I2->use_end();
                UI != UE;) {
             Use &TheUse = UI.getUse();
             ++UI;
-            if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser()))
-              ToNotify.push_back(I);
+            Instruction *I = cast<Instruction>(TheUse.getUser());
+            ToNotify.push_back(I);
           }
 
           DOUT << "Simply removing " << *I2
@@ -1656,10 +1609,9 @@ namespace {
           ++UI;
           Value *V = TheUse.getUser();
           if (!V->use_empty()) {
-            if (Instruction *Inst = dyn_cast<Instruction>(V)) {
-              if (aboveOrBelow(Inst))
-                opsToDef(Inst);
-            }
+            Instruction *Inst = cast<Instruction>(V);
+            if (aboveOrBelow(Inst))
+              opsToDef(Inst);
           }
         }
       }
@@ -1709,7 +1661,8 @@ namespace {
         Top(DTDFS->getNodeForBlock(TopBB)),
         TopBB(TopBB),
         TopInst(NULL),
-        modified(modified)
+        modified(modified),
+        Context(TopBB->getContext())
     {
       assert(Top && "VRPSolver created for unreachable basic block.");
     }
@@ -1801,7 +1754,7 @@ namespace {
         switch (BO->getOpcode()) {
           case Instruction::And: {
             // "and i32 %a, %b" EQ -1 then %a EQ -1 and %b EQ -1
-            ConstantInt *CI = ConstantInt::getAllOnesValue(Ty);
+            ConstantInt *CI = cast<ConstantInt>(Context->getAllOnesValue(Ty));
             if (Canonical == CI) {
               add(CI, Op0, ICmpInst::ICMP_EQ, NewContext);
               add(CI, Op1, ICmpInst::ICMP_EQ, NewContext);
@@ -1809,7 +1762,7 @@ namespace {
           } break;
           case Instruction::Or: {
             // "or i32 %a, %b" EQ 0 then %a EQ 0 and %b EQ 0
-            Constant *Zero = Constant::getNullValue(Ty);
+            Constant *Zero = Context->getNullValue(Ty);
             if (Canonical == Zero) {
               add(Zero, Op0, ICmpInst::ICMP_EQ, NewContext);
               add(Zero, Op1, ICmpInst::ICMP_EQ, NewContext);
@@ -1832,10 +1785,10 @@ namespace {
             }
             if (Canonical == LHS) {
               if (isa<ConstantInt>(Canonical))
-                add(RHS, Constant::getNullValue(Ty), ICmpInst::ICMP_EQ,
+                add(RHS, Context->getNullValue(Ty), ICmpInst::ICMP_EQ,
                     NewContext);
             } else if (isRelatedBy(LHS, Canonical, ICmpInst::ICMP_NE)) {
-              add(RHS, Constant::getNullValue(Ty), ICmpInst::ICMP_NE,
+              add(RHS, Context->getNullValue(Ty), ICmpInst::ICMP_NE,
                   NewContext);
             }
           } break;
@@ -1880,10 +1833,10 @@ namespace {
         }
         // TODO: The GEPI indices are all zero. Copy from definition to operand,
         // jumping the type plane as needed.
-        if (isRelatedBy(GEPI, Constant::getNullValue(GEPI->getType()),
+        if (isRelatedBy(GEPI, Context->getNullValue(GEPI->getType()),
                         ICmpInst::ICMP_NE)) {
           Value *Ptr = GEPI->getPointerOperand();
-          add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
+          add(Ptr, Context->getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
               NewContext);
         }
       } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
@@ -1937,27 +1890,82 @@ namespace {
         const Type *Ty = BO->getType();
         assert(!Ty->isFPOrFPVector() && "Float in work queue!");
 
-        Constant *Zero = Constant::getNullValue(Ty);
-        ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
+        Constant *Zero = Context->getNullValue(Ty);
+        Constant *One = Context->getConstantInt(Ty, 1);
+        ConstantInt *AllOnes = cast<ConstantInt>(Context->getAllOnesValue(Ty));
 
         switch (Opcode) {
           default: break;
           case Instruction::LShr:
           case Instruction::AShr:
           case Instruction::Shl:
+            if (Op1 == Zero) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Sub:
             if (Op1 == Zero) {
               add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
+            if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
+              unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
+              ConstantRange CR = VR.range(n_ci0, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(CI0->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
+              unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
+              ConstantRange CR = VR.range(n_ci1, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(CI1->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
             break;
           case Instruction::Or:
             if (Op0 == AllOnes || Op1 == AllOnes) {
               add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
               return;
-            } // fall-through
-          case Instruction::Xor:
+            }
+            if (Op0 == Zero) {
+              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            } else if (Op1 == Zero) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Add:
+            if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
+              unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
+              ConstantRange CR = VR.range(n_ci0, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(-CI0->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
+              unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
+              ConstantRange CR = VR.range(n_ci1, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(-CI1->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            // fall-through
+          case Instruction::Xor:
             if (Op0 == Zero) {
               add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
               return;
@@ -1974,19 +1982,30 @@ namespace {
               add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
-            // fall-through
+            if (Op0 == Zero || Op1 == Zero) {
+              add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Mul:
             if (Op0 == Zero || Op1 == Zero) {
               add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
+            if (Op0 == One) {
+              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            } else if (Op1 == One) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
             break;
         }
 
         // "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
         // "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
         // "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
-        // "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1
+        // "%x = udiv i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 1
 
         Value *Known = Op0, *Unknown = Op1,
               *TheBO = VN.canonicalize(BO, Top);
@@ -2009,10 +2028,8 @@ namespace {
             case Instruction::UDiv:
             case Instruction::SDiv:
               if (Unknown == Op1) break;
-              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
-                Constant *One = ConstantInt::get(Ty, 1);
+              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE))
                 add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
-              }
               break;
           }
         }
@@ -2095,9 +2112,9 @@ namespace {
         // TODO: The GEPI indices are all zero. Copy from operand to definition,
         // jumping the type plane as needed.
         Value *Ptr = GEPI->getPointerOperand();
-        if (isRelatedBy(Ptr, Constant::getNullValue(Ptr->getType()),
+        if (isRelatedBy(Ptr, Context->getNullValue(Ptr->getType()),
                         ICmpInst::ICMP_NE)) {
-          add(GEPI, Constant::getNullValue(GEPI->getType()), ICmpInst::ICMP_NE,
+          add(GEPI, Context->getNullValue(GEPI->getType()), ICmpInst::ICMP_NE,
               NewContext);
         }
       }
@@ -2196,10 +2213,9 @@ namespace {
                    UE = O.LHS->use_end(); UI != UE;) {
                 Use &TheUse = UI.getUse();
                 ++UI;
-                if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
-                  if (aboveOrBelow(I))
-                    opsToDef(I);
-                }
+                Instruction *I = cast<Instruction>(TheUse.getUser());
+                if (aboveOrBelow(I))
+                  opsToDef(I);
               }
             }
             if (Instruction *I2 = dyn_cast<Instruction>(O.RHS)) {
@@ -2211,10 +2227,9 @@ namespace {
                    UE = O.RHS->use_end(); UI != UE;) {
                 Use &TheUse = UI.getUse();
                 ++UI;
-                if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
-                  if (aboveOrBelow(I))
-                    opsToDef(I);
-                }
+                Instruction *I = cast<Instruction>(TheUse.getUser());
+                if (aboveOrBelow(I))
+                  opsToDef(I);
               }
             }
           }
@@ -2401,6 +2416,7 @@ namespace {
     delete DTDFS;
     delete VR;
     delete IG;
+    delete VN;
 
     modified |= UB.kill();
 
@@ -2482,17 +2498,19 @@ namespace {
 
   void PredicateSimplifier::Forwards::visitAllocaInst(AllocaInst &AI) {
     VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &AI);
-    VRP.add(Constant::getNullValue(AI.getType()), &AI, ICmpInst::ICMP_NE);
+    VRP.add(AI.getParent()->getContext()->getNullValue(AI.getType()),
+            &AI, ICmpInst::ICMP_NE);
     VRP.solve();
   }
 
   void PredicateSimplifier::Forwards::visitLoadInst(LoadInst &LI) {
     Value *Ptr = LI.getPointerOperand();
-    // avoid "load uint* null" -> null NE null.
+    // avoid "load i8* null" -> null NE null.
     if (isa<Constant>(Ptr)) return;
 
     VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &LI);
-    VRP.add(Constant::getNullValue(Ptr->getType()), Ptr, ICmpInst::ICMP_NE);
+    VRP.add(LI.getParent()->getContext()->getNullValue(Ptr->getType()),
+            Ptr, ICmpInst::ICMP_NE);
     VRP.solve();
   }
 
@@ -2501,7 +2519,8 @@ namespace {
     if (isa<Constant>(Ptr)) return;
 
     VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &SI);
-    VRP.add(Constant::getNullValue(Ptr->getType()), Ptr, ICmpInst::ICMP_NE);
+    VRP.add(SI.getParent()->getContext()->getNullValue(Ptr->getType()),
+            Ptr, ICmpInst::ICMP_NE);
     VRP.solve();
   }
 
@@ -2536,8 +2555,8 @@ namespace {
       case Instruction::SDiv: {
         Value *Divisor = BO.getOperand(1);
         VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
-        VRP.add(Constant::getNullValue(Divisor->getType()), Divisor,
-                ICmpInst::ICMP_NE);
+        VRP.add(BO.getParent()->getContext()->getNullValue(Divisor->getType()), 
+                Divisor, ICmpInst::ICMP_NE);
         VRP.solve();
         break;
       }
@@ -2624,14 +2643,14 @@ namespace {
           if (!Op1->getValue().isAllOnesValue())
             NextVal = ConstantInt::get(Op1->getValue()+1);
          break;
-
       }
+
       if (NextVal) {
         VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
         if (VRP.isRelatedBy(IC.getOperand(0), NextVal,
                             ICmpInst::getInversePredicate(Pred))) {
-          ICmpInst *NewIC = new ICmpInst(ICmpInst::ICMP_EQ, IC.getOperand(0),
-                                         NextVal, "", &IC);
+          ICmpInst *NewIC = new ICmpInst(&IC, ICmpInst::ICMP_EQ, 
+                                         IC.getOperand(0), NextVal, "");
           NewIC->takeName(&IC);
           IC.replaceAllUsesWith(NewIC);