mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
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
This commit is contained in:
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/Analysis/ConstantFolding.h"
|
#include "llvm/Analysis/ConstantFolding.h"
|
||||||
#include "llvm/Target/TargetData.h"
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
|
#include "llvm/Support/ConstantRange.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/ValueHandle.h"
|
#include "llvm/Support/ValueHandle.h"
|
||||||
@ -51,12 +52,15 @@ class LVILatticeVal {
|
|||||||
enum LatticeValueTy {
|
enum LatticeValueTy {
|
||||||
/// undefined - This LLVM Value has no known value yet.
|
/// undefined - This LLVM Value has no known value yet.
|
||||||
undefined,
|
undefined,
|
||||||
|
|
||||||
/// constant - This LLVM Value has a specific constant value.
|
/// constant - This LLVM Value has a specific constant value.
|
||||||
constant,
|
constant,
|
||||||
|
|
||||||
/// notconstant - This LLVM value is known to not have the specified value.
|
/// notconstant - This LLVM value is known to not have the specified value.
|
||||||
notconstant,
|
notconstant,
|
||||||
|
|
||||||
|
/// constantrange
|
||||||
|
constantrange,
|
||||||
|
|
||||||
/// overdefined - This instruction is not known to be constant, and we know
|
/// overdefined - This instruction is not known to be constant, and we know
|
||||||
/// it has a value.
|
/// it has a value.
|
||||||
overdefined
|
overdefined
|
||||||
@ -66,9 +70,10 @@ class LVILatticeVal {
|
|||||||
/// the constant if this is a 'constant' or 'notconstant' value.
|
/// the constant if this is a 'constant' or 'notconstant' value.
|
||||||
LatticeValueTy Tag;
|
LatticeValueTy Tag;
|
||||||
Constant *Val;
|
Constant *Val;
|
||||||
|
ConstantRange Range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LVILatticeVal() : Tag(undefined), Val(0) {}
|
LVILatticeVal() : Tag(undefined), Val(0), Range(1, true) {}
|
||||||
|
|
||||||
static LVILatticeVal get(Constant *C) {
|
static LVILatticeVal get(Constant *C) {
|
||||||
LVILatticeVal Res;
|
LVILatticeVal Res;
|
||||||
@ -81,10 +86,11 @@ public:
|
|||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isUndefined() const { return Tag == undefined; }
|
bool isUndefined() const { return Tag == undefined; }
|
||||||
bool isConstant() const { return Tag == constant; }
|
bool isConstant() const { return Tag == constant; }
|
||||||
bool isNotConstant() const { return Tag == notconstant; }
|
bool isNotConstant() const { return Tag == notconstant; }
|
||||||
bool isOverdefined() const { return Tag == overdefined; }
|
bool isConstantRange() const { return Tag == constantrange; }
|
||||||
|
bool isOverdefined() const { return Tag == overdefined; }
|
||||||
|
|
||||||
Constant *getConstant() const {
|
Constant *getConstant() const {
|
||||||
assert(isConstant() && "Cannot get the constant of a non-constant!");
|
assert(isConstant() && "Cannot get the constant of a non-constant!");
|
||||||
@ -96,6 +102,12 @@ public:
|
|||||||
return Val;
|
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.
|
/// markOverdefined - Return true if this is a change in status.
|
||||||
bool markOverdefined() {
|
bool markOverdefined() {
|
||||||
if (isOverdefined())
|
if (isOverdefined())
|
||||||
@ -136,6 +148,32 @@ public:
|
|||||||
return true;
|
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
|
/// mergeIn - Merge the specified lattice value into this one, updating this
|
||||||
/// one and returning true if anything changed.
|
/// one and returning true if anything changed.
|
||||||
bool mergeIn(const LVILatticeVal &RHS) {
|
bool mergeIn(const LVILatticeVal &RHS) {
|
||||||
@ -162,7 +200,23 @@ public:
|
|||||||
return markNotConstant(RHS.getNotConstant());
|
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.
|
// RHS must be a constant, we must be undef, constant, or notconstant.
|
||||||
|
assert(!isConstantRange() &&
|
||||||
|
"Constant and ConstantRange cannot be merged.");
|
||||||
|
|
||||||
if (isUndefined())
|
if (isUndefined())
|
||||||
return markConstant(RHS.getConstant());
|
return markConstant(RHS.getConstant());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user