+
+ /// Does the same as getSingleValue, but works only if subset contains
+ /// single numbers only.
+ const IntTy& getSingleNumber(unsigned idx) const {
+ assert(IsSingleNumbersOnly && "This method works properly if subset "
+ "contains single numbers only.");
+ return FlatCollection[idx];
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// IntegersSubset - currently is extension of IntegersSubsetGeneric
+/// that also supports conversion to/from Constant* object.
+class IntegersSubset : public IntegersSubsetGeneric<IntItem> {
+
+ typedef IntegersSubsetGeneric<IntItem> ParentTy;
+
+ Constant *Holder;
+
+ static unsigned getNumItemsFromConstant(Constant *C) {
+ return cast<ArrayType>(C->getType())->getNumElements();
+ }
+
+ static Range getItemFromConstant(Constant *C, unsigned idx) {
+ const Constant *CV = C->getAggregateElement(idx);
+
+ unsigned NumEls = cast<VectorType>(CV->getType())->getNumElements();
+ switch (NumEls) {
+ case 1:
+ return Range(IntItem::fromConstantInt(
+ cast<ConstantInt>(CV->getAggregateElement(0U))),
+ IntItem::fromConstantInt(cast<ConstantInt>(
+ cast<ConstantInt>(CV->getAggregateElement(0U)))));
+ case 2:
+ 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();
+ }
+ }
+
+ std::vector<Range> rangesFromConstant(Constant *C) {
+ unsigned NumItems = getNumItemsFromConstant(C);
+ std::vector<Range> r;
+ r.reserve(NumItems);
+ for (unsigned i = 0, e = NumItems; i != e; ++i)
+ r.push_back(getItemFromConstant(C, i));
+ return r;
+ }
+
+public:
+
+ explicit IntegersSubset(Constant *C) : ParentTy(rangesFromConstant(C)),
+ Holder(C) {}
+
+ IntegersSubset(const IntegersSubset& RHS) :
+ ParentTy(*(const ParentTy *)&RHS), // FIXME: tweak for msvc.
+ Holder(RHS.Holder) {}
+
+ template<class RangesCollectionTy>
+ explicit IntegersSubset(const RangesCollectionTy& Src) : ParentTy(Src) {
+ std::vector<Constant*> Elts;
+ Elts.reserve(Src.size());
+ for (typename RangesCollectionTy::const_iterator i = Src.begin(),
+ e = Src.end(); i != e; ++i) {
+ const Range &R = *i;
+ std::vector<Constant*> r;
+ 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.getLow().toConstantInt());
+ r.push_back(R.getHigh().toConstantInt());
+ } else {
+ r.reserve(1);
+ r.push_back(R.getLow().toConstantInt());
+ }
+ Constant *CV = ConstantVector::get(r);
+ Elts.push_back(CV);
+ }
+ ArrayType *ArrTy =
+ ArrayType::get(Elts.front()->getType(), (uint64_t)Elts.size());
+ Holder = ConstantArray::get(ArrTy, Elts);
+ }
+
+ operator Constant*() { return Holder; }
+ operator const Constant*() const { return Holder; }
+ Constant *operator->() { return Holder; }
+ const Constant *operator->() const { return Holder; }
+};