aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Instructions.h13
-rw-r--r--include/llvm/Support/CRSBuilder.h68
-rw-r--r--include/llvm/Support/ConstantRangesSet.h286
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp11
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp4
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp7
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp7
-rw-r--r--lib/Transforms/Utils/Local.cpp4
-rw-r--r--lib/Transforms/Utils/LowerSwitch.cpp6
-rw-r--r--lib/VMCore/Instructions.cpp5
-rw-r--r--lib/VMCore/Verifier.cpp5
11 files changed, 262 insertions, 154 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 5af8517..3f67e26 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -2552,13 +2552,13 @@ public:
/// that it is handled by the default handler.
CaseIt findCaseValue(const ConstantInt *C) {
for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValueEx().isSatisfies(C))
+ if (i.getCaseValueEx().isSatisfies(C->getValue()))
return i;
return case_default();
}
ConstCaseIt findCaseValue(const ConstantInt *C) const {
for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValueEx().isSatisfies(C))
+ if (i.getCaseValueEx().isSatisfies(C->getValue()))
return i;
return case_default();
}
@@ -2657,7 +2657,10 @@ public:
ConstantRangesSet CRS =
reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
ConstantRangesSet::Range R = CRS.getItem(0);
- return R.Low;
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So return CaseValue as ConstantInt.
+ return R.Low.toConstantInt();
}
/// Resolves case value for current case.
@@ -2734,7 +2737,9 @@ public:
void setValue(ConstantInt *V) {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
CRSBuilder CB;
- CB.add(V);
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ CB.add(IntItem::fromConstantInt(V));
SI->setOperand(2 + Index*2,
reinterpret_cast<Value*>((Constant*)CB.getCase()));
}
diff --git a/include/llvm/Support/CRSBuilder.h b/include/llvm/Support/CRSBuilder.h
index 5608931..c5dfa9f 100644
--- a/include/llvm/Support/CRSBuilder.h
+++ b/include/llvm/Support/CRSBuilder.h
@@ -26,20 +26,19 @@
namespace llvm {
-template <class SuccessorClass, bool IsReadonly>
+template <class SuccessorClass>
class CRSBuilderBase {
public:
- typedef ConstantRangesSet::RangeT<IsReadonly> RangeTy;
+ typedef ConstantRangesSet::Range RangeTy;
struct RangeEx : public RangeTy {
- typedef ConstantRangesSet::RangeT<IsReadonly> RangeTy;
- typedef typename RangeTy::ConstantIntTy ConstantIntTy;
+ typedef ConstantRangesSet::Range RangeTy;
RangeEx() : Weight(1) {}
RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {}
- RangeEx(ConstantIntTy *C) : RangeTy(C), Weight(1) {}
- RangeEx(ConstantIntTy *L, ConstantIntTy *H) : RangeTy(L, H), Weight(1) {}
- RangeEx(ConstantIntTy *L, ConstantIntTy *H, unsigned W) :
+ RangeEx(const IntItem &C) : RangeTy(C), Weight(1) {}
+ RangeEx(const IntItem &L, const IntItem &H) : RangeTy(L, H), Weight(1) {}
+ RangeEx(const IntItem &L, const IntItem &H, unsigned W) :
RangeTy(L, H), Weight(W) {}
unsigned Weight;
};
@@ -62,7 +61,7 @@ protected:
bool Sorted;
bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) {
- return LItem->first.High->getValue().uge(RItem->first.Low->getValue());
+ return LItem->first.High->uge(RItem->first.Low);
}
bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) {
@@ -71,10 +70,10 @@ protected:
"Intersected items with different successors!");
return false;
}
- APInt RLow = RItem->first.Low->getValue();
+ APInt RLow = RItem->first.Low;
if (RLow != APInt::getNullValue(RLow.getBitWidth()))
--RLow;
- return LItem->first.High->getValue().uge(RLow);
+ return LItem->first.High->uge(RLow);
}
void sort() {
@@ -86,9 +85,6 @@ protected:
public:
- typedef typename CRSConstantTypes<IsReadonly>::ConstantIntTy ConstantIntTy;
- typedef typename CRSConstantTypes<IsReadonly>::ConstantRangesSetTy ConstantRangesSetTy;
-
// Don't public CaseItems itself. Don't allow edit the Items directly.
// Just present the user way to iterate over the internal collection
// sharing iterator, begin() and end(). Editing should be controlled by
@@ -120,55 +116,55 @@ public:
sort();
CaseItems OldItems = Items;
Items.clear();
- ConstantIntTy *Low = OldItems.begin()->first.Low;
- ConstantIntTy *High = OldItems.begin()->first.High;
+ IntItem *Low = &OldItems.begin()->first.Low;
+ IntItem *High = &OldItems.begin()->first.High;
unsigned Weight = 1;
SuccessorClass *Successor = OldItems.begin()->second;
for (CaseItemIt i = OldItems.begin(), j = i+1, e = OldItems.end();
j != e; i = j++) {
if (isJoinable(i, j)) {
- ConstantIntTy *CurHigh = j->first.High;
+ IntItem *CurHigh = &j->first.High;
++Weight;
- if (CurHigh->getValue().ugt(High->getValue()))
+ if ((*CurHigh)->ugt(*High))
High = CurHigh;
} else {
- RangeEx R(Low, High, Weight);
+ RangeEx R(*Low, *High, Weight);
add(R, Successor);
- Low = j->first.Low;
- High = j->first.High;
+ Low = &j->first.Low;
+ High = &j->first.High;
Weight = 1;
Successor = j->second;
}
}
- RangeEx R(Low, High, Weight);
+ RangeEx R(*Low, *High, Weight);
add(R, Successor);
// We recollected the Items, but we kept it sorted.
Sorted = true;
}
/// Adds a constant value.
- void add(ConstantIntTy *C, SuccessorClass *S = 0) {
+ void add(const IntItem &C, SuccessorClass *S = 0) {
RangeTy R(C);
add(R, S);
}
/// Adds a range.
- void add(ConstantIntTy *Low, ConstantIntTy *High, SuccessorClass *S = 0) {
+ void add(const IntItem &Low, const IntItem &High, SuccessorClass *S = 0) {
RangeTy R(Low, High);
add(R, S);
}
- void add(RangeTy &R, SuccessorClass *S = 0) {
+ void add(const RangeTy &R, SuccessorClass *S = 0) {
RangeEx REx = R;
add(REx, S);
}
- void add(RangeEx &R, SuccessorClass *S = 0) {
+ void add(const RangeEx &R, SuccessorClass *S = 0) {
Items.push_back(std::make_pair(R, S));
Sorted = false;
}
/// Adds all ranges and values from given ranges set to the current
/// CRSBuilder object.
- void add(ConstantRangesSetTy &CRS, SuccessorClass *S = 0) {
+ void add(const ConstantRangesSet &CRS, SuccessorClass *S = 0) {
for (unsigned i = 0, e = CRS.getNumItems(); i < e; ++i) {
RangeTy R = CRS.getItem(i);
add(R, S);
@@ -186,11 +182,11 @@ public:
};
template <class SuccessorClass>
-class CRSBuilderT : public CRSBuilderBase<SuccessorClass, false> {
+class CRSBuilderT : public CRSBuilderBase<SuccessorClass> {
public:
- typedef typename CRSBuilderBase<SuccessorClass, false>::RangeTy RangeTy;
- typedef typename CRSBuilderBase<SuccessorClass, false>::RangeIterator
+ typedef typename CRSBuilderBase<SuccessorClass>::RangeTy RangeTy;
+ typedef typename CRSBuilderBase<SuccessorClass>::RangeIterator
RangeIterator;
private:
@@ -205,15 +201,17 @@ private:
std::vector<Constant*> Elts;
Elts.reserve(Src.size());
for (RangesCollectionIt i = Src.begin(), e = Src.end(); i != e; ++i) {
- const RangeTy &R = *i;
+ RangeTy &R = *i;
std::vector<Constant*> r;
- if (R.Low != R.High) {
+ if (R.isSingleNumber()) {
r.reserve(2);
- r.push_back(R.Low);
- r.push_back(R.High);
+ // FIXME: Since currently we have ConstantInt based numbers
+ // use hack-conversion of IntItem to ConstantInt
+ r.push_back(R.Low.toConstantInt());
+ r.push_back(R.High.toConstantInt());
} else {
r.reserve(1);
- r.push_back(R.Low);
+ r.push_back(R.Low.toConstantInt());
}
Constant *CV = ConstantVector::get(r);
Elts.push_back(CV);
@@ -250,7 +248,7 @@ public:
class BasicBlock;
typedef CRSBuilderT<BasicBlock> CRSBuilder;
-typedef CRSBuilderBase<BasicBlock, true> CRSBuilderConst;
+typedef CRSBuilderBase<BasicBlock> CRSBuilderConst;
}
diff --git a/include/llvm/Support/ConstantRangesSet.h b/include/llvm/Support/ConstantRangesSet.h
index a3f082f..109bd5b 100644
--- a/include/llvm/Support/ConstantRangesSet.h
+++ b/include/llvm/Support/ConstantRangesSet.h
@@ -21,116 +21,171 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
namespace llvm {
-class ConstantRangesSet;
+template <class ImplTy>
+class IntItemBase {
+protected:
+ ImplTy Implementation;
+ typedef IntItemBase<ImplTy> self;
+public:
+
+ IntItemBase() {}
+
+ IntItemBase(const ImplTy &impl) : Implementation(impl) {}
+
+ // implicit
+ IntItemBase(const APInt& src) : Implementation(src) {}
-template <bool IsReadonly> struct CRSConstantTypes {
- typedef ConstantInt ConstantIntTy;
- typedef ConstantRangesSet ConstantRangesSetTy;
+ operator const APInt&() const {
+ return (const APInt&)Implementation;
+ }
+ bool operator<(const self& RHS) const {
+ return ((const APInt&)*this).ult(RHS);
+ }
+ bool operator==(const self& RHS) const {
+ return (const APInt&)*this == (const APInt&)RHS;
+ }
+ bool operator!=(const self& RHS) const {
+ return (const APInt&)*this != (const APInt&)RHS;
+ }
+ self& operator=(const ImplTy& RHS) {
+ Implementation = RHS;
+ return *this;
+ }
+ const APInt* operator->() const {
+ return &((const APInt&)Implementation);
+ }
+ const APInt& operator*() const {
+ return ((const APInt&)Implementation);
+ }
+ // FIXME: Hack. Will removed.
+ ImplTy& getImplementation() {
+ return Implementation;
+ }
+};
+
+class IntItemConstantIntImpl {
+ const ConstantInt *ConstantIntVal;
+public:
+ IntItemConstantIntImpl() : ConstantIntVal(0) {}
+ IntItemConstantIntImpl(const ConstantInt *Val) : ConstantIntVal(Val) {}
+ IntItemConstantIntImpl(LLVMContext &Ctx, const APInt& src) {
+ ConstantIntVal = cast<ConstantInt>(ConstantInt::get(Ctx, src));
+ }
+ explicit IntItemConstantIntImpl(const APInt& src) {
+ ConstantIntVal =
+ cast<ConstantInt>(ConstantInt::get(llvm::getGlobalContext(), src));
+ }
+ operator const APInt&() const {
+ return ConstantIntVal->getValue();
+ }
+ operator const ConstantInt*() {
+ return ConstantIntVal;
+ }
};
-template <>
-struct CRSConstantTypes<true> {
- typedef const ConstantInt ConstantIntTy;
- typedef const ConstantRangesSet ConstantRangesSetTy;
-};
-
-//===----------------------------------------------------------------------===//
-/// ConstantRangesSet - class that implements constant set of ranges.
-/// It is a wrapper for some real "holder" class (currently ConstantArray).
-/// It contains functions, that allows to parse "holder" like a set of ranges.
-/// Note: It is assumed that "holder" is inherited from Constant object.
-/// ConstantRangesSet may be converted to and from Constant* pointer.
-///
-class ConstantRangesSet {
- Constant *Array;
+class IntItem : public IntItemBase<IntItemConstantIntImpl> {
+ typedef IntItemBase<IntItemConstantIntImpl> ParentTy;
+ IntItem(const IntItemConstantIntImpl& Impl) : ParentTy(Impl) {}
public:
- bool IsWide;
+ IntItem() {}
// implicit
- ConstantRangesSet(Constant *V) : Array(V) {
- ArrayType *ArrTy = cast<ArrayType>(Array->getType());
- VectorType *VecTy = cast<VectorType>(ArrTy->getElementType());
- IntegerType *IntTy = cast<IntegerType>(VecTy->getElementType());
- IsWide = IntTy->getBitWidth() > 64;
- }
+ IntItem(const APInt& src) : ParentTy(src) {}
- operator Constant*() { return Array; }
- operator const Constant*() const { return Array; }
- Constant *operator->() { return Array; }
- const Constant *operator->() const { return Array; }
-
- template <bool IsReadonly>
- struct RangeT {
+ static IntItem fromConstantInt(const ConstantInt *V) {
+ IntItemConstantIntImpl Impl(V);
+ return IntItem(Impl);
+ }
+ static IntItem fromType(Type* Ty, const APInt& V) {
+ ConstantInt *C = cast<ConstantInt>(ConstantInt::get(Ty, V));
+ return fromConstantInt(C);
+ }
+ ConstantInt *toConstantInt() {
+ return const_cast<ConstantInt*>((const ConstantInt*)Implementation);
+ }
+};
+
+// TODO: it should be a class in next commit.
+struct IntRange {
+
+ IntItem Low;
+ IntItem High;
+ bool IsEmpty : 1;
+ bool IsSingleNumber : 1;
+// TODO:
+// public:
- typedef typename CRSConstantTypes<IsReadonly>::ConstantIntTy ConstantIntTy;
- typedef std::pair<RangeT, RangeT> SubRes;
+ typedef std::pair<IntRange, IntRange> SubRes;
- ConstantIntTy *Low;
- ConstantIntTy *High;
-
- RangeT() : Low(0), High(0) {}
- RangeT(const RangeT<false> &RHS) : Low(RHS.Low), High(RHS.High) {}
- RangeT(ConstantIntTy *C) : Low(C), High(C) {}
- RangeT(ConstantIntTy *L, ConstantIntTy *H) : Low(L), High(H) {}
+ IntRange() : IsEmpty(true) {}
+ IntRange(const IntRange &RHS) :
+ Low(RHS.Low), High(RHS.High), IsEmpty(false), IsSingleNumber(false) {}
+ IntRange(const IntItem &C) :
+ Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {}
+ IntRange(const IntItem &L, const IntItem &H) : Low(L), High(H),
+ IsEmpty(false), IsSingleNumber(false) {}
+
+ bool isEmpty() const { return IsEmpty; }
+ bool isSingleNumber() const { return IsSingleNumber; }
+
+ const IntItem& getLow() {
+ assert(!IsEmpty && "Range is empty.");
+ return Low;
+ }
+ const IntItem& getHigh() {
+ assert(!IsEmpty && "Range is empty.");
+ return High;
+ }
- bool operator<(const RangeT &RHS) const {
- assert(Low && High && "Case range is not initialized.");
- assert(RHS.Low && RHS.High && "Right case range is not initialized.");
- const APInt &LowInt = Low->getValue();
- const APInt &HighInt = High->getValue();
- const APInt &RHSLowInt = RHS.Low->getValue();
- const APInt &RHSHighInt = RHS.High->getValue();
- if (LowInt.getBitWidth() == RHSLowInt.getBitWidth()) {
- if (LowInt.eq(RHSLowInt)) {
- if (HighInt.ult(RHSHighInt))
+ bool operator<(const IntRange &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ if (Low->getBitWidth() == RHS.Low->getBitWidth()) {
+ if (Low->eq(RHS.Low)) {
+ if (High->ult(RHS.High))
return true;
return false;
}
- if (LowInt.ult(RHSLowInt))
+ if (Low->ult(RHS.Low))
return true;
return false;
} else
- return LowInt.getBitWidth() < RHSLowInt.getBitWidth();
+ return Low->getBitWidth() < RHS.Low->getBitWidth();
}
- bool operator==(const RangeT &RHS) const {
- assert(Low && High && "Case range is not initialized.");
- assert(RHS.Low && RHS.High && "Right case range is not initialized.");
- if (Low->getValue().getBitWidth() != RHS.Low->getValue().getBitWidth())
+ bool operator==(const IntRange &RHS) const {
+ assert(!IsEmpty && "Left range is empty.");
+ assert(!RHS.IsEmpty && "Right range is empty.");
+ if (Low->getBitWidth() != RHS.Low->getBitWidth())
return false;
- return Low->getValue() == RHS.Low->getValue() &&
- High->getValue() == RHS.High->getValue();
+ return Low == RHS.Low && High == RHS.High;
}
- bool operator!=(const RangeT &RHS) const {
+ bool operator!=(const IntRange &RHS) const {
return !operator ==(RHS);
}
- static bool LessBySize(const RangeT &LHS, const RangeT &RHS) {
+ static bool LessBySize(const IntRange &LHS, const IntRange &RHS) {
assert(LHS.Low->getBitWidth() == RHS.Low->getBitWidth() &&
"This type of comparison requires equal bit width for LHS and RHS");
- APInt LSize = LHS.High->getValue() - LHS.Low->getValue();
- APInt RSize = RHS.High->getValue() - RHS.Low->getValue();;
+ APInt LSize = *LHS.High - *LHS.Low;
+ APInt RSize = *RHS.High - *RHS.Low;
return LSize.ult(RSize);
}
bool isInRange(const APInt &IntVal) const {
- assert(Low && High && "Case range is not initialized.");
- if (IntVal.getBitWidth() != Low->getValue().getBitWidth())
+ assert(!IsEmpty && "Range is empty.");
+ if (IntVal.getBitWidth() != Low->getBitWidth())
return false;
- return IntVal.uge(Low->getValue()) && IntVal.ule(High->getValue());
+ return IntVal.uge(Low) && IntVal.ule(High);
}
- bool isInRange(const ConstantIntTy *CI) const {
- const APInt& IntVal = CI->getValue();
- return isInRange(IntVal);
- }
-
- SubRes sub(const RangeT &RHS) const {
+ SubRes sub(const IntRange &RHS) const {
SubRes Res;
// RHS is either more global and includes this range or
@@ -140,34 +195,59 @@ public:
// If RHS more global (it is enough to check
// only one border in this case.
if (RHS.isInRange(Low))
- return std::make_pair(RangeT(Low, High), RangeT());
+ return std::make_pair(IntRange(Low, High), IntRange());
return Res;
}
- const APInt& LoInt = Low->getValue();
- const APInt& HiInt = High->getValue();
- APInt RHSLoInt = RHS.Low->getValue();
- APInt RHSHiInt = RHS.High->getValue();
- if (LoInt.ult(RHSLoInt)) {
+ if (Low->ult(RHS.Low)) {
Res.first.Low = Low;
- Res.first.High = ConstantIntTy::get(RHS.Low->getContext(), --RHSLoInt);
+ APInt NewHigh = RHS.Low;
+ --NewHigh;
+ Res.first.High = NewHigh;
}
- if (HiInt.ugt(RHSHiInt)) {
- Res.second.Low = ConstantIntTy::get(RHS.High->getContext(), ++RHSHiInt);
+ if (High->ugt(RHS.High)) {
+ APInt NewLow = RHS.High;
+ ++NewLow;
+ Res.second.Low = NewLow;
Res.second.High = High;
}
return Res;
}
};
- typedef RangeT<false> Range;
+//===----------------------------------------------------------------------===//
+/// ConstantRangesSet - class that implements constant set of ranges.
+/// It is a wrapper for some real "holder" class (currently ConstantArray).
+/// It contains functions, that allows to parse "holder" like a set of ranges.
+/// Note: It is assumed that "holder" is inherited from Constant object.
+/// ConstantRangesSet may be converted to and from Constant* pointer.
+///
+class ConstantRangesSet {
+ Constant *Array;
+public:
+
+ bool IsWide;
+
+ // implicit
+ ConstantRangesSet(Constant *V) : Array(V) {
+ ArrayType *ArrTy = cast<ArrayType>(Array->getType());
+ VectorType *VecTy = cast<VectorType>(ArrTy->getElementType());
+ IntegerType *IntTy = cast<IntegerType>(VecTy->getElementType());
+ IsWide = IntTy->getBitWidth() > 64;
+ }
+
+ operator Constant*() { return Array; }
+ operator const Constant*() const { return Array; }
+ Constant *operator->() { return Array; }
+ const Constant *operator->() const { return Array; }
+
+ typedef IntRange Range;
/// Checks is the given constant satisfies this case. Returns
/// true if it equals to one of contained values or belongs to the one of
/// contained ranges.
- bool isSatisfies(const ConstantInt *C) const {
- const APInt &CheckingVal = C->getValue();
+ bool isSatisfies(const IntItem &CheckingVal) const {
for (unsigned i = 0, e = getNumItems(); i < e; ++i) {
const Constant *CV = Array->getAggregateElement(i);
unsigned VecSize = cast<VectorType>(CV->getType())->getNumElements();
@@ -200,11 +280,13 @@ public:
unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
switch (NumEls) {
case 1:
- return Range(cast<ConstantInt>(CV->getAggregateElement(0U)),
- cast<ConstantInt>(CV->getAggregateElement(0U)));
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))));
case 2:
- return Range(cast<ConstantInt>(CV->getAggregateElement(0U)),
- cast<ConstantInt>(CV->getAggregateElement(1)));
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(1U))));
default:
assert(0 && "Only pairs and single numbers are allowed here.");
return Range();
@@ -217,15 +299,15 @@ public:
unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
switch (NumEls) {
case 1:
- return Range(cast<ConstantInt>(
- const_cast<Constant*>(CV->getAggregateElement(0U))),
- cast<ConstantInt>(
- const_cast<Constant*>(CV->getAggregateElement(0U))));
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(cast<ConstantInt>(
+ cast<ConstantInt>(CV->getAggregateElement(0U)))));
case 2:
- return Range(cast<ConstantInt>(
- const_cast<Constant*>(CV->getAggregateElement(0U))),
- cast<ConstantInt>(
- const_cast<Constant*>(CV->getAggregateElement(1))));
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(1))));
default:
assert(0 && "Only pairs and single numbers are allowed here.");
return Range();
@@ -252,7 +334,9 @@ public:
unsigned getSize() const {
APInt sz(getItem(0).Low->getBitWidth(), 0);
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
- const APInt &S = getItem(i).High->getValue() - getItem(i).Low->getValue();
+ const APInt &Low = getItem(i).Low;
+ const APInt &High = getItem(i).High;
+ const APInt &S = High - Low;
sz += S;
}
return sz.getZExtValue();
@@ -265,11 +349,13 @@ public:
APInt getSingleValue(unsigned idx) const {
APInt sz(getItem(0).Low->getBitWidth(), 0);
for (unsigned i = 0, e = getNumItems(); i != e; ++i) {
- const APInt& S = getItem(i).High->getValue() - getItem(i).Low->getValue();
+ const APInt &Low = getItem(i).Low;
+ const APInt &High = getItem(i).High;
+ const APInt& S = High - Low;
APInt oldSz = sz;
sz += S;
if (oldSz.uge(i) && sz.ult(i)) {
- APInt Res = getItem(i).Low->getValue();
+ APInt Res = Low;
APInt Offset(oldSz.getBitWidth(), i);
Offset -= oldSz;
Res += Offset;
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 5a132a4..3477bbc 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2283,18 +2283,21 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
ActiveWords = Record[CurIdx++];
Low = ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
CurIdx += ActiveWords;
-
+
if (!isSingleNumber) {
ActiveWords = 1;
if (ValueBitWidth > 64)
ActiveWords = Record[CurIdx++];
APInt High =
ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
- CaseBuilder.add(cast<ConstantInt>(ConstantInt::get(OpTy, Low)),
- cast<ConstantInt>(ConstantInt::get(OpTy, High)));
+ IntItemConstantIntImpl HighImpl =
+ cast<ConstantInt>(ConstantInt::get(OpTy, High));
+
+ CaseBuilder.add(IntItem::fromType(OpTy, Low),
+ IntItem::fromType(OpTy, High));
CurIdx += ActiveWords;
} else
- CaseBuilder.add(cast<ConstantInt>(ConstantInt::get(OpTy, Low)));
+ CaseBuilder.add(IntItem::fromType(OpTy, Low));
}
BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
ConstantRangesSet Case = CaseBuilder.getCase();
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index 9557a44..c680866 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1175,8 +1175,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Vals64.push_back(CRS.isSingleNumber(ri));
- const APInt &Low = r.Low->getValue();
- const APInt &High = r.High->getValue();
+ const APInt &Low = r.Low;
+ const APInt &High = r.High;
unsigned Code, Abbrev; // will unused.
EmitAPInt(Vals64, Code, Abbrev, Low, true);
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 90fec6a..83df110 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2427,7 +2427,7 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
/// Use a shorter form of declaration, and also
/// show the we want to use CRSBuilder as Clusterifier.
- typedef CRSBuilderBase<MachineBasicBlock, true> Clusterifier;
+ typedef CRSBuilderBase<MachineBasicBlock> Clusterifier;
Clusterifier TheClusterifier;
@@ -2456,7 +2456,10 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
BPI->setEdgeWeight(SI.getParent(), C.second->getBasicBlock(), W);
}
- Cases.push_back(Case(C.first.Low, C.first.High, C.second, W));
+ // FIXME: Currently work with ConstantInt based numbers.
+ // Changing it to APInt based is a pretty heavy for this commit.
+ Cases.push_back(Case(C.first.Low.toConstantInt(),
+ C.first.High.toConstantInt(), C.second, W));
if (C.first.Low != C.first.High)
// A range counts double, since it requires two compares.
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 298ce2c..46ed6fd 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -654,8 +654,11 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
ConstantRangesSet Case = i.getCaseValueEx();
for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
ConstantRangesSet::Range r = Case.getItem(n);
- GenericValue Low = getOperandValue(r.Low, SF);
- GenericValue High = getOperandValue(r.High, SF);
+ // FIXME: Currently work with ConstantInt based numbers.
+ const ConstantInt *LowCI = r.Low.getImplementation();
+ const ConstantInt *HighCI = r.High.getImplementation();
+ GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
+ GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
Dest = cast<BasicBlock>(i.getCaseSuccessor());
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 179f29c..130b876 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/lib/Transforms/Utils/Local.cpp
@@ -171,8 +171,10 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
SwitchInst::CaseIt FirstCase = SI->case_begin();
ConstantRangesSet CRS = FirstCase.getCaseValueEx();
if (CRS.getNumItems() == 1 && CRS.isSingleNumber(0)) {
+ // FIXME: Currently work with ConstantInt based numbers.
Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
- CRS.getItem(0).Low, "cond");
+ CRS.getItem(0).Low.toConstantInt(),
+ "cond");
// Insert the new branch.
Builder.CreateCondBr(Cond, FirstCase.getCaseSuccessor(),
diff --git a/lib/Transforms/Utils/LowerSwitch.cpp b/lib/Transforms/Utils/LowerSwitch.cpp
index fa5a934..2362037 100644
--- a/lib/Transforms/Utils/LowerSwitch.cpp
+++ b/lib/Transforms/Utils/LowerSwitch.cpp
@@ -239,7 +239,11 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
for (CRSBuilder::RangeIterator i = TheClusterifier.begin(),
e = TheClusterifier.end(); i != e; ++i, ++numCmps) {
CRSBuilder::Cluster &C = *i;
- Cases.push_back(CaseRange(C.first.Low, C.first.High, C.second));
+
+ // FIXME: Currently work with ConstantInt based numbers.
+ // Changing it to APInt based is a pretty heavy for this commit.
+ Cases.push_back(CaseRange(C.first.Low.toConstantInt(),
+ C.first.High.toConstantInt(), C.second));
if (C.first.Low != C.first.High)
// A range counts double, since it requires two compares.
++numCmps;
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 819a090..42a92d9 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -3170,7 +3170,10 @@ SwitchInst::~SwitchInst() {
///
void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
CRSBuilder CB;
- CB.add(OnVal);
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ CB.add(IntItem::fromConstantInt(OnVal));
ConstantRangesSet CRS = CB.getCase();
addCase(CRS, Dest);
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 64b0876..c546e41 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -805,15 +805,16 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
// Check to make sure that all of the constants in the switch instruction
// have the same type as the switched-on value.
Type *SwitchTy = SI.getCondition()->getType();
+ IntegerType *IntTy = cast<IntegerType>(SwitchTy);
CRSBuilder Builder;
std::map<ConstantRangesSet::Range, unsigned> RangeSetMap;
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end(); i != e; ++i) {
ConstantRangesSet RS = i.getCaseValueEx();
for (unsigned ri = 0, rie = RS.getNumItems(); ri < rie; ++ri) {
ConstantRangesSet::Range r = RS.getItem(ri);
- Assert1(r.Low->getType() == SwitchTy,
+ Assert1(r.Low->getBitWidth() == IntTy->getBitWidth(),
"Switch constants must all be same type as switch value!", &SI);
- Assert1(r.High->getType() == SwitchTy,
+ Assert1(r.High->getBitWidth() == IntTy->getBitWidth(),
"Switch constants must all be same type as switch value!", &SI);
Builder.add(r);
RangeSetMap[r] = i.getCaseIndex();