[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