1 //===- ConstantRangeList.h - A list of constant ranges ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Represent a list of signed ConstantRange and do NOT support wrap around the 10 // end of the numeric range. Ranges in the list are ordered and not overlapping. 11 // Ranges should have the same bitwidth. Each range's lower should be less than 12 // its upper. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_IR_CONSTANTRANGELIST_H 17 #define LLVM_IR_CONSTANTRANGELIST_H 18 19 #include "llvm/ADT/APInt.h" 20 #include "llvm/IR/ConstantRange.h" 21 #include "llvm/Support/Debug.h" 22 #include <cstddef> 23 #include <cstdint> 24 25 namespace llvm { 26 27 class raw_ostream; 28 29 /// This class represents a list of constant ranges. 30 class [[nodiscard]] ConstantRangeList { 31 SmallVector<ConstantRange, 2> Ranges; 32 33 public: 34 ConstantRangeList() = default; ConstantRangeList(ArrayRef<ConstantRange> RangesRef)35 ConstantRangeList(ArrayRef<ConstantRange> RangesRef) { 36 assert(isOrderedRanges(RangesRef)); 37 for (const ConstantRange &R : RangesRef) { 38 assert(R.getBitWidth() == getBitWidth()); 39 Ranges.push_back(R); 40 } 41 } 42 43 // Return true if the ranges are non-overlapping and increasing. 44 static bool isOrderedRanges(ArrayRef<ConstantRange> RangesRef); 45 static std::optional<ConstantRangeList> 46 getConstantRangeList(ArrayRef<ConstantRange> RangesRef); 47 rangesRef()48 ArrayRef<ConstantRange> rangesRef() const { return Ranges; } begin()49 SmallVectorImpl<ConstantRange>::iterator begin() { return Ranges.begin(); } end()50 SmallVectorImpl<ConstantRange>::iterator end() { return Ranges.end(); } begin()51 SmallVectorImpl<ConstantRange>::const_iterator begin() const { 52 return Ranges.begin(); 53 } end()54 SmallVectorImpl<ConstantRange>::const_iterator end() const { 55 return Ranges.end(); 56 } getRange(unsigned i)57 ConstantRange getRange(unsigned i) const { return Ranges[i]; } 58 59 /// Return true if this list contains no members. empty()60 bool empty() const { return Ranges.empty(); } 61 62 /// Get the bit width of this ConstantRangeList. getBitWidth()63 uint32_t getBitWidth() const { return 64; } 64 65 /// Return the number of ranges in this ConstantRangeList. size()66 size_t size() const { return Ranges.size(); } 67 68 /// Insert a new range to Ranges and keep the list ordered. 69 void insert(const ConstantRange &NewRange); insert(int64_t Lower,int64_t Upper)70 void insert(int64_t Lower, int64_t Upper) { 71 insert(ConstantRange(APInt(64, Lower, /*isSigned=*/true), 72 APInt(64, Upper, /*isSigned=*/true))); 73 } 74 75 void subtract(const ConstantRange &SubRange); 76 77 /// Return the range list that results from the union of this 78 /// ConstantRangeList with another ConstantRangeList, "CRL". 79 ConstantRangeList unionWith(const ConstantRangeList &CRL) const; 80 81 /// Return the range list that results from the intersection of this 82 /// ConstantRangeList with another ConstantRangeList, "CRL". 83 ConstantRangeList intersectWith(const ConstantRangeList &CRL) const; 84 85 /// Return true if this range list is equal to another range list. 86 bool operator==(const ConstantRangeList &CRL) const { 87 return Ranges == CRL.Ranges; 88 } 89 bool operator!=(const ConstantRangeList &CRL) const { 90 return !operator==(CRL); 91 } 92 93 /// Print out the ranges to a stream. 94 void print(raw_ostream &OS) const; 95 96 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 97 void dump() const; 98 #endif 99 }; 100 101 } // end namespace llvm 102 103 #endif // LLVM_IR_CONSTANTRANGELIST_H 104