[llvm-commits] [llvm] r157576 - in /llvm/trunk: include/llvm/Instructions.h include/llvm/Support/CRSBuilder.h include/llvm/Support/ConstantRangesSet.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/CodeGen/Selection

David Blaikie dblaikie at gmail.com
Mon May 28 11:30:02 PDT 2012


On Mon, May 28, 2012 at 5:39 AM, Stepan Dyatkovskiy <stpworld at narod.ru> wrote:
> Author: dyatkovskiy
> Date: Mon May 28 07:39:09 2012
> New Revision: 157576
>
> URL: http://llvm.org/viewvc/llvm-project?rev=157576&view=rev
> Log:
> PR1255: Case Ranges
> Implemented IntItem - the wrapper around APInt. Why not to use APInt item directly right now?
> 1. It will very difficult to implement case ranges as series of small patches. We got several large and heavy patches. Each patch will about 90-120 kb. If you replace ConstantInt with APInt in SwitchInst you will need to changes at the same time all Readers,Writers and absolutely all passes that uses SwitchInst.
> 2. We can implement APInt pool inside and save memory space. E.g. we use several switches that works with 256 bit items (switch on signatures, or strings). We can avoid value duplicates in this case.
> 3. IntItem can be easyly easily replaced with APInt.
> 4. Currenly we can interpret IntItem both as ConstantInt and as APInt. It allows to provide SwitchInst methods that works with ConstantInt for non-updated passes.
>
> Why I need it right now? Currently I need to update SimplifyCFG pass (EqualityComparisons). I need to work with APInts directly a lot, so peaces of code
> ConstantInt *V = ...;
> if (V->getValue().ugt(AnotherV->getValue()) {
>  ...
> }
> will look awful. Much more better this way:
> IntItem V = ConstantIntVal->getValue();
> if (AnotherV < V) {
> }
>
> Of course any reviews are welcome.
>
> P.S.: I'm also going to rename ConstantRangesSet to IntegersSubset, and CRSBuilder to IntegersSubsetMapping (allows to map individual subsets of integers to the BasicBlocks).
> Since in future these classes will founded on APInt, it will possible to use them in more generic ways.
>
>
>
> Modified:
>    llvm/trunk/include/llvm/Instructions.h
>    llvm/trunk/include/llvm/Support/CRSBuilder.h
>    llvm/trunk/include/llvm/Support/ConstantRangesSet.h
>    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>    llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp
>    llvm/trunk/lib/Transforms/Utils/Local.cpp
>    llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
>    llvm/trunk/lib/VMCore/Instructions.cpp
>    llvm/trunk/lib/VMCore/Verifier.cpp
>
> Modified: llvm/trunk/include/llvm/Instructions.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Instructions.h (original)
> +++ llvm/trunk/include/llvm/Instructions.h Mon May 28 07:39:09 2012
> @@ -2552,13 +2552,13 @@
>   /// 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 @@
>       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 @@
>     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()));
>     }
>
> Modified: llvm/trunk/include/llvm/Support/CRSBuilder.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CRSBuilder.h?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/CRSBuilder.h (original)
> +++ llvm/trunk/include/llvm/Support/CRSBuilder.h Mon May 28 07:39:09 2012
> @@ -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 @@
>   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 @@
>              "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 @@
>
>  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 @@
>     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 @@
>  };
>
>  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 @@
>     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 @@
>
>  class BasicBlock;
>  typedef CRSBuilderT<BasicBlock> CRSBuilder;
> -typedef CRSBuilderBase<BasicBlock, true> CRSBuilderConst;
> +typedef CRSBuilderBase<BasicBlock> CRSBuilderConst;
>
>  }
>
>
> Modified: llvm/trunk/include/llvm/Support/ConstantRangesSet.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ConstantRangesSet.h?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/ConstantRangesSet.h (original)
> +++ llvm/trunk/include/llvm/Support/ConstantRangesSet.h Mon May 28 07:39:09 2012
> @@ -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 @@
>         // 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 @@
>     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 @@
>     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 @@
>   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 @@
>   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;
>
> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon May 28 07:39:09 2012
> @@ -2283,18 +2283,21 @@
>               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));

This variable was unused. In the interests of unblocking Clang+Werror
builds, I've removed it in r157586. I wasn't entirely sure if the
accident was that the use is missing, but I couldn't find any
immediate use at first glance - feel free to re-add it/use it if
that's what it should've been.

- David

> +
> +              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();
>
> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon May 28 07:39:09 2012
> @@ -1175,8 +1175,8 @@
>
>           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);
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon May 28 07:39:09 2012
> @@ -2427,7 +2427,7 @@
>
>   /// 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 @@
>       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.
>
> Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Mon May 28 07:39:09 2012
> @@ -654,8 +654,11 @@
>     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());
>
> Modified: llvm/trunk/lib/Transforms/Utils/Local.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Local.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/Local.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/Local.cpp Mon May 28 07:39:09 2012
> @@ -171,8 +171,10 @@
>       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(),
>
> Modified: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp Mon May 28 07:39:09 2012
> @@ -239,7 +239,11 @@
>   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;
>
> Modified: llvm/trunk/lib/VMCore/Instructions.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Instructions.cpp (original)
> +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon May 28 07:39:09 2012
> @@ -3170,7 +3170,10 @@
>  ///
>  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);
>  }
>
> Modified: llvm/trunk/lib/VMCore/Verifier.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=157576&r1=157575&r2=157576&view=diff
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Verifier.cpp (original)
> +++ llvm/trunk/lib/VMCore/Verifier.cpp Mon May 28 07:39:09 2012
> @@ -805,15 +805,16 @@
>   // 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();
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list