[llvm-commits] [llvm] r86950 - in /llvm/trunk: include/llvm/Analysis/LazyValueInfo.h lib/Analysis/LazyValueInfo.cpp

Chris Lattner sabre at nondot.org
Wed Nov 11 20:36:58 PST 2009


Author: lattner
Date: Wed Nov 11 22:36:58 2009
New Revision: 86950

URL: http://llvm.org/viewvc/llvm-project?rev=86950&view=rev
Log:
Add a new getPredicateOnEdge method which returns more rich information for
constant constraints.  Improve the LVI lattice to include inequality 
constraints.

Modified:
    llvm/trunk/include/llvm/Analysis/LazyValueInfo.h
    llvm/trunk/lib/Analysis/LazyValueInfo.cpp

Modified: llvm/trunk/include/llvm/Analysis/LazyValueInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyValueInfo.h?rev=86950&r1=86949&r2=86950&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/LazyValueInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/LazyValueInfo.h Wed Nov 11 22:36:58 2009
@@ -31,19 +31,21 @@
   static char ID;
   LazyValueInfo() : FunctionPass(&ID), PImpl(0) {}
 
-  /// Tristate - This is used to return yes/no/dunno results.
+  /// Tristate - This is used to return true/false/dunno results.
   enum Tristate {
-    Unknown = -1, No = 0, Yes = 1
+    Unknown = -1, False = 0, True = 1
   };
   
   
   // Public query interface.
   
+  /// getPredicateOnEdge - Determine whether the specified value comparison
+  /// with a constant is known to be true or false on the specified CFG edge.
+  /// Pred is a CmpInst predicate.
+  Tristate getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
+                              BasicBlock *FromBB, BasicBlock *ToBB);
+  
   
-  /// isEqual - Determine whether the specified value is known to be equal or
-  /// not-equal to the specified constant at the end of the specified block.
-  Tristate isEqual(Value *V, Constant *C, BasicBlock *BB);
-
   /// getConstant - Determine whether the specified value is known to be a
   /// constant at the end of the specified block.  Return null if not.
   Constant *getConstant(Value *V, BasicBlock *BB);

Modified: llvm/trunk/lib/Analysis/LazyValueInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyValueInfo.cpp?rev=86950&r1=86949&r2=86950&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/LazyValueInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/LazyValueInfo.cpp Wed Nov 11 22:36:58 2009
@@ -51,13 +51,17 @@
     undefined,
     /// constant - This LLVM Value has a specific constant value.
     constant,
+    
+    /// notconstant - This LLVM value is known to not have the specified value.
+    notconstant,
+    
     /// overdefined - This instruction is not known to be constant, and we know
     /// it has a value.
     overdefined
   };
   
   /// Val: This stores the current lattice value along with the Constant* for
-  /// the constant if this is a 'constant' value.
+  /// the constant if this is a 'constant' or 'notconstant' value.
   PointerIntPair<Constant *, 2, LatticeValueTy> Val;
   
 public:
@@ -68,9 +72,15 @@
     Res.markConstant(C);
     return Res;
   }
+  static LVILatticeVal getNot(Constant *C) {
+    LVILatticeVal Res;
+    Res.markNotConstant(C);
+    return Res;
+  }
   
   bool isUndefined() const   { return Val.getInt() == undefined; }
   bool isConstant() const    { return Val.getInt() == constant; }
+  bool isNotConstant() const { return Val.getInt() == notconstant; }
   bool isOverdefined() const { return Val.getInt() == overdefined; }
   
   Constant *getConstant() const {
@@ -78,12 +88,9 @@
     return Val.getPointer();
   }
   
-  /// getConstantInt - If this is a constant with a ConstantInt value, return it
-  /// otherwise return null.
-  ConstantInt *getConstantInt() const {
-    if (isConstant())
-      return dyn_cast<ConstantInt>(getConstant());
-    return 0;
+  Constant *getNotConstant() const {
+    assert(isNotConstant() && "Cannot get the constant of a non-notconstant!");
+    return Val.getPointer();
   }
   
   /// markOverdefined - Return true if this is a change in status.
@@ -108,12 +115,41 @@
     return true;
   }
   
+  /// markNotConstant - Return true if this is a change in status.
+  bool markNotConstant(Constant *V) {
+    if (isNotConstant()) {
+      assert(getNotConstant() == V && "Marking !constant with different value");
+      return false;
+    }
+    
+    if (isConstant())
+      assert(getConstant() != V && "Marking not constant with different value");
+    else
+      assert(isUndefined());
+
+    Val.setInt(notconstant);
+    assert(V && "Marking constant with NULL");
+    Val.setPointer(V);
+    return true;
+  }
+  
   /// mergeIn - Merge the specified lattice value into this one, updating this
   /// one and returning true if anything changed.
   bool mergeIn(const LVILatticeVal &RHS) {
     if (RHS.isUndefined() || isOverdefined()) return false;
     if (RHS.isOverdefined()) return markOverdefined();
 
+    if (RHS.isNotConstant()) {
+      if (isNotConstant()) {
+        if (getNotConstant() != RHS.getNotConstant())
+          return markOverdefined();
+        return false;
+      }
+      if (isConstant() && getConstant() != RHS.getNotConstant())
+        return markOverdefined();
+      return markNotConstant(RHS.getNotConstant());
+    }
+    
     // RHS must be a constant, we must be undef or constant.
     if (isConstant() && getConstant() != RHS.getConstant())
       return markOverdefined();
@@ -130,6 +166,9 @@
     return OS << "undefined";
   if (Val.isOverdefined())
     return OS << "overdefined";
+
+  if (Val.isNotConstant())
+    return OS << "notconstant<" << *Val.getNotConstant() << '>';
   return OS << "constant<" << *Val.getConstant() << '>';
 }
 }
@@ -181,6 +220,7 @@
           // false SETNE. 
           if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ))
             return LVILatticeVal::get(cast<Constant>(ICI->getOperand(1)));
+          return LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1)));
         }
     }
   }
@@ -291,22 +331,50 @@
   return 0;
 }
 
-/// isEqual - Determine whether the specified value is known to be equal or
-/// not-equal to the specified constant at the end of the specified block.
+/// getPredicateOnEdge - Determine whether the specified value comparison
+/// with a constant is known to be true or false on the specified CFG edge.
+/// Pred is a CmpInst predicate.
 LazyValueInfo::Tristate
-LazyValueInfo::isEqual(Value *V, Constant *C, BasicBlock *BB) {
+LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C,
+                                  BasicBlock *FromBB, BasicBlock *ToBB) {
+  LVILatticeVal Result;
+  
   // If already a constant, we can use constant folding.
   if (Constant *VC = dyn_cast<Constant>(V)) {
-    // Ignore FP for now.  TODO, consider what form of equality we want.
-    if (C->getType()->isFPOrFPVector())
-      return Unknown;
+    Result = LVILatticeVal::get(VC);
+  } else {
+    DenseMap<BasicBlock*, LVILatticeVal> BlockValues;
     
-    Constant *Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ, VC,C,TD);
-    if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
-      return ResCI->isZero() ? No : Yes;
+    DEBUG(errs() << "Getting value " << *V << " on edge from '"
+          << FromBB->getName() << "' to '" << ToBB->getName() << "'\n");
+    Result = GetValueOnEdge(V, FromBB, ToBB, BlockValues);
+    DEBUG(errs() << "  Result = " << Result << "\n");
+  }
+  
+  // If we know the value is a constant, evaluate the conditional.
+  Constant *Res = 0;
+  if (Result.isConstant()) {
+    Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD);
+    if (ConstantInt *ResCI = dyn_cast_or_null<ConstantInt>(Res))
+      return ResCI->isZero() ? False : True;
+  } else if (Result.isNotConstant()) {
+    // If this is an equality comparison, we can try to fold it knowing that
+    // "V != C1".
+    if (Pred == ICmpInst::ICMP_EQ) {
+      // !C1 == C -> false iff C1 == C.
+      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
+                                            Result.getNotConstant(), C, TD);
+      if (Res->isNullValue())
+        return False;
+    } else if (Pred == ICmpInst::ICMP_NE) {
+      // !C1 != C -> true iff C1 == C.
+      Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_EQ,
+                                            Result.getNotConstant(), C, TD);
+      if (Res->isNullValue())
+        return True;
+    }
   }
   
-  // Not a very good implementation.
   return Unknown;
 }
 





More information about the llvm-commits mailing list