diff options
-rw-r--r-- | include/llvm/Instructions.h | 13 | ||||
-rw-r--r-- | include/llvm/Support/CRSBuilder.h | 68 | ||||
-rw-r--r-- | include/llvm/Support/ConstantRangesSet.h | 286 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 11 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 7 | ||||
-rw-r--r-- | lib/ExecutionEngine/Interpreter/Execution.cpp | 7 | ||||
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Utils/LowerSwitch.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 5 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 5 |
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(); |