diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 5af85177b96..3f67e26f73a 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(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((Constant*)CB.getCase())); } diff --git a/include/llvm/Support/CRSBuilder.h b/include/llvm/Support/CRSBuilder.h index 56089319369..c5dfa9f3f11 100644 --- a/include/llvm/Support/CRSBuilder.h +++ b/include/llvm/Support/CRSBuilder.h @@ -26,20 +26,19 @@ namespace llvm { -template +template class CRSBuilderBase { public: - typedef ConstantRangesSet::RangeT RangeTy; + typedef ConstantRangesSet::Range RangeTy; struct RangeEx : public RangeTy { - typedef ConstantRangesSet::RangeT 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::ConstantIntTy ConstantIntTy; - typedef typename CRSConstantTypes::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 CRSBuilderT : public CRSBuilderBase { +class CRSBuilderT : public CRSBuilderBase { public: - typedef typename CRSBuilderBase::RangeTy RangeTy; - typedef typename CRSBuilderBase::RangeIterator + typedef typename CRSBuilderBase::RangeTy RangeTy; + typedef typename CRSBuilderBase::RangeIterator RangeIterator; private: @@ -205,15 +201,17 @@ private: std::vector 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 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 CRSBuilder; -typedef CRSBuilderBase CRSBuilderConst; +typedef CRSBuilderBase CRSBuilderConst; } diff --git a/include/llvm/Support/ConstantRangesSet.h b/include/llvm/Support/ConstantRangesSet.h index a3f082f8228..109bd5b26e9 100644 --- a/include/llvm/Support/ConstantRangesSet.h +++ b/include/llvm/Support/ConstantRangesSet.h @@ -21,22 +21,201 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/LLVMContext.h" namespace llvm { -class ConstantRangesSet; +template +class IntItemBase { +protected: + ImplTy Implementation; + typedef IntItemBase self; +public: -template struct CRSConstantTypes { - typedef ConstantInt ConstantIntTy; - typedef ConstantRangesSet ConstantRangesSetTy; + IntItemBase() {} + + IntItemBase(const ImplTy &impl) : Implementation(impl) {} + + // implicit + IntItemBase(const APInt& src) : Implementation(src) {} + + 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::get(Ctx, src)); + } + explicit IntItemConstantIntImpl(const APInt& src) { + ConstantIntVal = + cast(ConstantInt::get(llvm::getGlobalContext(), src)); + } + operator const APInt&() const { + return ConstantIntVal->getValue(); + } + operator const ConstantInt*() { + return ConstantIntVal; + } }; -template <> -struct CRSConstantTypes { - typedef const ConstantInt ConstantIntTy; - typedef const ConstantRangesSet ConstantRangesSetTy; -}; +class IntItem : public IntItemBase { + typedef IntItemBase ParentTy; + IntItem(const IntItemConstantIntImpl& Impl) : ParentTy(Impl) {} +public: + IntItem() {} + + // implicit + IntItem(const APInt& src) : ParentTy(src) {} + + static IntItem fromConstantInt(const ConstantInt *V) { + IntItemConstantIntImpl Impl(V); + return IntItem(Impl); + } + static IntItem fromType(Type* Ty, const APInt& V) { + ConstantInt *C = cast(ConstantInt::get(Ty, V)); + return fromConstantInt(C); + } + ConstantInt *toConstantInt() { + return const_cast((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 std::pair SubRes; + + 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 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 (Low->ult(RHS.Low)) + return true; + return false; + } else + return Low->getBitWidth() < RHS.Low->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 == RHS.Low && High == RHS.High; + } + + bool operator!=(const IntRange &RHS) const { + return !operator ==(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 - *LHS.Low; + APInt RSize = *RHS.High - *RHS.Low; + return LSize.ult(RSize); + } + + bool isInRange(const APInt &IntVal) const { + assert(!IsEmpty && "Range is empty."); + if (IntVal.getBitWidth() != Low->getBitWidth()) + return false; + return IntVal.uge(Low) && IntVal.ule(High); + } + + SubRes sub(const IntRange &RHS) const { + SubRes Res; + + // RHS is either more global and includes this range or + // if it doesn't intersected with this range. + if (!isInRange(RHS.Low) && !isInRange(RHS.High)) { + + // If RHS more global (it is enough to check + // only one border in this case. + if (RHS.isInRange(Low)) + return std::make_pair(IntRange(Low, High), IntRange()); + + return Res; + } + + if (Low->ult(RHS.Low)) { + Res.first.Low = Low; + APInt NewHigh = RHS.Low; + --NewHigh; + Res.first.High = NewHigh; + } + if (High->ugt(RHS.High)) { + APInt NewLow = RHS.High; + ++NewLow; + Res.second.Low = NewLow; + Res.second.High = High; + } + return Res; + } + }; + //===----------------------------------------------------------------------===// /// ConstantRangesSet - class that implements constant set of ranges. /// It is a wrapper for some real "holder" class (currently ConstantArray). @@ -62,112 +241,13 @@ public: operator const Constant*() const { return Array; } Constant *operator->() { return Array; } const Constant *operator->() const { return Array; } - - template - struct RangeT { - - typedef typename CRSConstantTypes::ConstantIntTy ConstantIntTy; - typedef std::pair SubRes; - - ConstantIntTy *Low; - ConstantIntTy *High; - - RangeT() : Low(0), High(0) {} - RangeT(const RangeT &RHS) : Low(RHS.Low), High(RHS.High) {} - RangeT(ConstantIntTy *C) : Low(C), High(C) {} - RangeT(ConstantIntTy *L, ConstantIntTy *H) : Low(L), High(H) {} - - 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)) - return true; - return false; - } - if (LowInt.ult(RHSLowInt)) - return true; - return false; - } else - return LowInt.getBitWidth() < RHSLowInt.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()) - return false; - return Low->getValue() == RHS.Low->getValue() && - High->getValue() == RHS.High->getValue(); - } - - bool operator!=(const RangeT &RHS) const { - return !operator ==(RHS); - } - - static bool LessBySize(const RangeT &LHS, const RangeT &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();; - return LSize.ult(RSize); - } - - bool isInRange(const APInt &IntVal) const { - assert(Low && High && "Case range is not initialized."); - if (IntVal.getBitWidth() != Low->getValue().getBitWidth()) - return false; - return IntVal.uge(Low->getValue()) && IntVal.ule(High->getValue()); - } - bool isInRange(const ConstantIntTy *CI) const { - const APInt& IntVal = CI->getValue(); - return isInRange(IntVal); - } - - SubRes sub(const RangeT &RHS) const { - SubRes Res; - - // RHS is either more global and includes this range or - // if it doesn't intersected with this range. - if (!isInRange(RHS.Low) && !isInRange(RHS.High)) { - - // 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 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)) { - Res.first.Low = Low; - Res.first.High = ConstantIntTy::get(RHS.Low->getContext(), --RHSLoInt); - } - if (HiInt.ugt(RHSHiInt)) { - Res.second.Low = ConstantIntTy::get(RHS.High->getContext(), ++RHSHiInt); - Res.second.High = High; - } - return Res; - } - }; - - typedef RangeT Range; + 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(CV->getType())->getNumElements(); @@ -200,11 +280,13 @@ public: unsigned NumEls = cast(CV->getType())->getNumElements(); switch (NumEls) { case 1: - return Range(cast(CV->getAggregateElement(0U)), - cast(CV->getAggregateElement(0U))); + return Range(IntItem::fromConstantInt( + cast(CV->getAggregateElement(0U)))); case 2: - return Range(cast(CV->getAggregateElement(0U)), - cast(CV->getAggregateElement(1))); + return Range(IntItem::fromConstantInt( + cast(CV->getAggregateElement(0U))), + IntItem::fromConstantInt( + cast(CV->getAggregateElement(1U)))); default: assert(0 && "Only pairs and single numbers are allowed here."); return Range(); @@ -217,15 +299,15 @@ public: unsigned NumEls = cast(CV->getType())->getNumElements(); switch (NumEls) { case 1: - return Range(cast( - const_cast(CV->getAggregateElement(0U))), - cast( - const_cast(CV->getAggregateElement(0U)))); + return Range(IntItem::fromConstantInt( + cast(CV->getAggregateElement(0U))), + IntItem::fromConstantInt(cast( + cast(CV->getAggregateElement(0U))))); case 2: - return Range(cast( - const_cast(CV->getAggregateElement(0U))), - cast( - const_cast(CV->getAggregateElement(1)))); + return Range(IntItem::fromConstantInt( + cast(CV->getAggregateElement(0U))), + IntItem::fromConstantInt( + cast(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 5a132a4f2ff..3477bbc02b7 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::get(OpTy, Low)), - cast(ConstantInt::get(OpTy, High))); + IntItemConstantIntImpl HighImpl = + cast(ConstantInt::get(OpTy, High)); + + CaseBuilder.add(IntItem::fromType(OpTy, Low), + IntItem::fromType(OpTy, High)); CurIdx += ActiveWords; } else - CaseBuilder.add(cast(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 9557a44992c..c68086655fc 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 90fec6a28ea..83df110d73f 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 Clusterifier; + typedef CRSBuilderBase 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 298ce2c2b95..46ed6fdfbf5 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(LowCI), SF); + GenericValue High = getOperandValue(const_cast(HighCI), SF); if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 && executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) { Dest = cast(i.getCaseSuccessor()); diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 179f29cdafa..130b876ee96 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 fa5a9340f47..23620373a06 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 819a090cc3c..42a92d955c1 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 64b087631e9..c546e416f45 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(SwitchTy); CRSBuilder Builder; std::map 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();