diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 99186f5f50a..7d82fdaa7a1 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -2660,7 +2660,7 @@ public: // FIXME: Currently we work with ConstantInt based cases. // So return CaseValue as ConstantInt. - return R.Low.toConstantInt(); + return R.getLow().toConstantInt(); } /// Resolves case value for current case. diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h index b6ffe1b5014..7f903cc8a00 100644 --- a/include/llvm/Support/IntegersSubset.h +++ b/include/llvm/Support/IntegersSubset.h @@ -172,34 +172,33 @@ public: }; template -struct IntRange { - - typedef IntRange self; +class IntRange { +protected: IntType Low; IntType High; bool IsEmpty : 1; bool IsSingleNumber : 1; -// TODO: -// public: - + +public: + typedef IntRange self; typedef std::pair SubRes; IntRange() : IsEmpty(true) {} - IntRange(const self &RHS) : - Low(RHS.Low), High(RHS.High), IsEmpty(false), IsSingleNumber(false) {} + IntRange(const IntType &C) : Low(C), High(C), IsEmpty(false), IsSingleNumber(true) {} + IntRange(const IntType &L, const IntType &H) : Low(L), High(H), - IsEmpty(false), IsSingleNumber(false) {} + IsEmpty(false), IsSingleNumber(Low == High) {} bool isEmpty() const { return IsEmpty; } bool isSingleNumber() const { return IsSingleNumber; } - const IntType& getLow() { + const IntType& getLow() const { assert(!IsEmpty && "Range is empty."); return Low; } - const IntType& getHigh() { + const IntType& getHigh() const { assert(!IsEmpty && "Range is empty."); return High; } @@ -296,10 +295,10 @@ public: for (typename RangesCollectionTy::const_iterator i = Links.begin(), e = Links.end(); i != e; ++i) { RangeLinkTy RangeLink; - FlatCollection.push_back(i->Low); + FlatCollection.push_back(i->getLow()); RangeLink.first = &FlatCollection.back(); - if (i->Low != i->High) - FlatCollection.push_back(i->High); + if (i->getLow() != i->getHigh()) + FlatCollection.push_back(i->getHigh()); RangeLink.second = &FlatCollection.back(); RangeLinks.push_back(RangeLink); } @@ -336,10 +335,17 @@ public: return RangeLinks.size(); } - bool isSingleNumber(unsigned idx) const { + /// Returns true if whole subset contains single element. + bool isSingleNumber() const { return RangeLinks.size() == 1 && RangeLinks[0].first == RangeLinks[0].second; } + + /// Does the same like getItem(idx).isSingleNumber(), but + /// works faster, since we avoid creation of temporary range object. + bool isSingleNumber(unsigned idx) const { + return RangeLinks[idx].first == RangeLinks[idx].second; + } /// Returns set the size, that equals number of all values + sizes of all /// ranges. @@ -347,10 +353,10 @@ public: /// E.g.: for range [<0>, <1>, <4,8>] the size will 7; /// for range [<0>, <1>, <5>] the size will 3 unsigned getSize() const { - APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0); + APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0); for (unsigned i = 0, e = getNumItems(); i != e; ++i) { - const APInt &Low = getItem(i).Low; - const APInt &High = getItem(i).High; + const APInt &Low = getItem(i).getLow(); + const APInt &High = getItem(i).getHigh(); const APInt &S = High - Low; sz += S; } @@ -362,10 +368,10 @@ public: /// [<1>, <4,8>] is considered as [1,4,5,6,7,8] /// For range [<1>, <4,8>] getSingleValue(3) returns 6. APInt getSingleValue(unsigned idx) const { - APInt sz(((const APInt&)getItem(0).Low).getBitWidth(), 0); + APInt sz(((const APInt&)getItem(0).getLow()).getBitWidth(), 0); for (unsigned i = 0, e = getNumItems(); i != e; ++i) { - const APInt &Low = getItem(i).Low; - const APInt &High = getItem(i).High; + const APInt &Low = getItem(i).getLow(); + const APInt &High = getItem(i).getHigh(); const APInt& S = High - Low; APInt oldSz = sz; sz += S; @@ -439,15 +445,15 @@ public: e = Src.end(); i != e; ++i) { const Range &R = *i; std::vector r; - if (R.Low != R.High) { + if (R.isSingleNumber()) { r.reserve(2); // 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()); + r.push_back(R.getLow().toConstantInt()); + r.push_back(R.getHigh().toConstantInt()); } else { r.reserve(1); - r.push_back(R.Low.toConstantInt()); + r.push_back(R.getLow().toConstantInt()); } Constant *CV = ConstantVector::get(r); Elts.push_back(CV); diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h index 7ff317b6325..b630119aea8 100644 --- a/include/llvm/Support/IntegersSubsetMapping.h +++ b/include/llvm/Support/IntegersSubsetMapping.h @@ -36,7 +36,7 @@ public: struct RangeEx : public RangeTy { RangeEx() : Weight(1) {} - RangeEx(const RangeTy &R) : RangeTy(R.Low, R.High), Weight(1) {} + RangeEx(const RangeTy &R) : RangeTy(R), Weight(1) {} RangeEx(const IntTy &C) : RangeTy(C), Weight(1) {} RangeEx(const IntTy &L, const IntTy &H) : RangeTy(L, H), Weight(1) {} RangeEx(const IntTy &L, const IntTy &H, unsigned W) : @@ -68,7 +68,7 @@ protected: bool Sorted; bool isIntersected(CaseItemIt& LItem, CaseItemIt& RItem) { - return LItem->first.High >= RItem->first.Low; + return LItem->first.getHigh() >= RItem->first.getLow(); } bool isJoinable(CaseItemIt& LItem, CaseItemIt& RItem) { @@ -77,10 +77,10 @@ protected: "Intersected items with different successors!"); return false; } - APInt RLow = RItem->first.Low; + APInt RLow = RItem->first.getLow(); if (RLow != APInt::getNullValue(RLow.getBitWidth())) --RLow; - return LItem->first.High >= RLow; + return LItem->first.getHigh() >= RLow; } void sort() { @@ -126,22 +126,22 @@ public: sort(); CaseItems OldItems = Items; Items.clear(); - IntTy *Low = &OldItems.begin()->first.Low; - IntTy *High = &OldItems.begin()->first.High; + const IntTy *Low = &OldItems.begin()->first.getLow(); + const IntTy *High = &OldItems.begin()->first.getHigh(); 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)) { - IntTy *CurHigh = &j->first.High; + const IntTy *CurHigh = &j->first.getHigh(); ++Weight; if (*CurHigh > *High) High = CurHigh; } else { RangeEx R(*Low, *High, Weight); add(R, Successor); - Low = &j->first.Low; - High = &j->first.High; + Low = &j->first.getLow(); + High = &j->first.getHigh(); Weight = 1; Successor = j->second; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 7dd18c87ffe..6526b012d81 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1161,16 +1161,15 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals64.push_back(CaseRanges.getNumItems()); for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) { IntegersSubset::Range r = CaseRanges.getItem(ri); + bool IsSingleNumber = r.isSingleNumber(); - Vals64.push_back(CaseRanges.isSingleNumber(ri)); + Vals64.push_back(IsSingleNumber); - const APInt &Low = r.Low; - const APInt &High = r.High; unsigned Code, Abbrev; // will unused. - EmitAPInt(Vals64, Code, Abbrev, Low, true); - if (r.Low != r.High) - EmitAPInt(Vals64, Code, Abbrev, High, true); + EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true); + if (!IsSingleNumber) + EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true); } Vals64.push_back(VE.getValueID(i.getCaseSuccessor())); } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 15c4258ddb8..305d03a2419 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2458,10 +2458,10 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases, // 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)); + Cases.push_back(Case(C.first.getLow().toConstantInt(), + C.first.getHigh().toConstantInt(), C.second, W)); - if (C.first.Low != C.first.High) + if (C.first.getLow() != C.first.getHigh()) // A range counts double, since it requires two compares. ++numCmps; } diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index d4b6ed00033..89c35438ef7 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -655,8 +655,8 @@ void Interpreter::visitSwitchInst(SwitchInst &I) { for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) { IntegersSubset::Range r = Case.getItem(n); // FIXME: Currently work with ConstantInt based numbers. - const ConstantInt *LowCI = r.Low.toConstantInt(); - const ConstantInt *HighCI = r.High.toConstantInt(); + const ConstantInt *LowCI = r.getLow().toConstantInt(); + const ConstantInt *HighCI = r.getHigh().toConstantInt(); GenericValue Low = getOperandValue(const_cast(LowCI), SF); GenericValue High = getOperandValue(const_cast(HighCI), SF); if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 && diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index a4ddfa5de3c..3c6793f3ad0 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -173,7 +173,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) { if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) { // FIXME: Currently work with ConstantInt based numbers. Value *Cond = Builder.CreateICmpEQ(SI->getCondition(), - CaseRanges.getItem(0).Low.toConstantInt(), + CaseRanges.getItem(0).getLow().toConstantInt(), "cond"); // Insert the new branch. diff --git a/lib/Transforms/Utils/LowerSwitch.cpp b/lib/Transforms/Utils/LowerSwitch.cpp index a4cf7732928..1547439b5c6 100644 --- a/lib/Transforms/Utils/LowerSwitch.cpp +++ b/lib/Transforms/Utils/LowerSwitch.cpp @@ -242,9 +242,9 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) { // 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) + Cases.push_back(CaseRange(C.first.getLow().toConstantInt(), + C.first.getHigh().toConstantInt(), C.second)); + if (C.first.isSingleNumber()) // A range counts double, since it requires two compares. ++numCmps; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 4d33c623af5..d9a535c9d86 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -813,9 +813,9 @@ void Verifier::visitSwitchInst(SwitchInst &SI) { IntegersSubset CaseRanges = i.getCaseValueEx(); for (unsigned ri = 0, rie = CaseRanges.getNumItems(); ri < rie; ++ri) { IntegersSubset::Range r = CaseRanges.getItem(ri); - Assert1(((const APInt&)r.Low).getBitWidth() == IntTy->getBitWidth(), + Assert1(((const APInt&)r.getLow()).getBitWidth() == IntTy->getBitWidth(), "Switch constants must all be same type as switch value!", &SI); - Assert1(((const APInt&)r.High).getBitWidth() == IntTy->getBitWidth(), + Assert1(((const APInt&)r.getHigh()).getBitWidth() == IntTy->getBitWidth(), "Switch constants must all be same type as switch value!", &SI); Mapping.add(r); RangeSetMap[r] = i.getCaseIndex();