aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2010-08-05 22:59:19 +0000
committerOwen Anderson <resistor@mac.com>2010-08-05 22:59:19 +0000
commit5be2e78fa1cc2df5d51d6ff3b107598a32974b49 (patch)
treeed98f68cc5a9d66ebb7e6d37fe979320d013c4ad /lib/Analysis
parent6387176c31d7a294f4a62e11255ded531bacb3e2 (diff)
downloadexternal_llvm-5be2e78fa1cc2df5d51d6ff3b107598a32974b49.zip
external_llvm-5be2e78fa1cc2df5d51d6ff3b107598a32974b49.tar.gz
external_llvm-5be2e78fa1cc2df5d51d6ff3b107598a32974b49.tar.bz2
Add the beginnings of infrastructure for range tracking.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110388 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/LazyValueInfo.cpp66
1 files changed, 60 insertions, 6 deletions
diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp
index c1e54f4..643fe63 100644
--- a/lib/Analysis/LazyValueInfo.cpp
+++ b/lib/Analysis/LazyValueInfo.cpp
@@ -19,6 +19,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/CFG.h"
+#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ValueHandle.h"
@@ -51,12 +52,15 @@ class LVILatticeVal {
enum LatticeValueTy {
/// undefined - This LLVM Value has no known value yet.
undefined,
+
/// constant - This LLVM Value has a specific constant value.
constant,
-
/// notconstant - This LLVM value is known to not have the specified value.
notconstant,
+ /// constantrange
+ constantrange,
+
/// overdefined - This instruction is not known to be constant, and we know
/// it has a value.
overdefined
@@ -66,9 +70,10 @@ class LVILatticeVal {
/// the constant if this is a 'constant' or 'notconstant' value.
LatticeValueTy Tag;
Constant *Val;
+ ConstantRange Range;
public:
- LVILatticeVal() : Tag(undefined), Val(0) {}
+ LVILatticeVal() : Tag(undefined), Val(0), Range(1, true) {}
static LVILatticeVal get(Constant *C) {
LVILatticeVal Res;
@@ -81,10 +86,11 @@ public:
return Res;
}
- bool isUndefined() const { return Tag == undefined; }
- bool isConstant() const { return Tag == constant; }
- bool isNotConstant() const { return Tag == notconstant; }
- bool isOverdefined() const { return Tag == overdefined; }
+ bool isUndefined() const { return Tag == undefined; }
+ bool isConstant() const { return Tag == constant; }
+ bool isNotConstant() const { return Tag == notconstant; }
+ bool isConstantRange() const { return Tag == constantrange; }
+ bool isOverdefined() const { return Tag == overdefined; }
Constant *getConstant() const {
assert(isConstant() && "Cannot get the constant of a non-constant!");
@@ -96,6 +102,12 @@ public:
return Val;
}
+ ConstantRange getConstantRange() const {
+ assert(isConstantRange() &&
+ "Cannot get the constant-range of a non-constant-range!");
+ return Range;
+ }
+
/// markOverdefined - Return true if this is a change in status.
bool markOverdefined() {
if (isOverdefined())
@@ -136,6 +148,32 @@ public:
return true;
}
+ /// markConstantRange - Return true if this is a change in status.
+ bool markConstantRange(const ConstantRange NewR) {
+ if (isConstantRange()) {
+ if (NewR.isEmptySet())
+ return markOverdefined();
+
+ assert(Range.contains(NewR) &&
+ "Marking constant range with non-subset range!");
+ bool changed = Range == NewR;
+ Range = NewR;
+ return changed;
+ }
+
+ assert(isUndefined());
+ if (NewR.isEmptySet())
+ return markOverdefined();
+ else if (NewR.isFullSet()) {
+ Tag = undefined;
+ return true;
+ }
+
+ Tag = constantrange;
+ Range = NewR;
+ 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) {
@@ -162,7 +200,23 @@ public:
return markNotConstant(RHS.getNotConstant());
}
+ if (RHS.isConstantRange()) {
+ if (isConstantRange()) {
+ ConstantRange NewR = Range.intersectWith(RHS.getConstantRange());
+ if (NewR.isEmptySet())
+ return markOverdefined();
+ else
+ return markConstantRange(NewR);
+ }
+
+ assert(isUndefined() && "Unexpected lattice");
+ return markConstantRange(RHS.getConstantRange());
+ }
+
// RHS must be a constant, we must be undef, constant, or notconstant.
+ assert(!isConstantRange() &&
+ "Constant and ConstantRange cannot be merged.");
+
if (isUndefined())
return markConstant(RHS.getConstant());