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/Compiler.h" 22 #include "llvm/Support/Debug.h" 23 #include <cstddef> 24 #include <cstdint> 25 26 namespace llvm { 27 28 class raw_ostream; 29 30 /// This class represents a list of constant ranges. 31 class [[nodiscard]] ConstantRangeList { 32 SmallVector<ConstantRange, 2> Ranges; 33 34 public: 35 ConstantRangeList() = default; ConstantRangeList(ArrayRef<ConstantRange> RangesRef)36 ConstantRangeList(ArrayRef<ConstantRange> RangesRef) { 37 assert(isOrderedRanges(RangesRef)); 38 for (const ConstantRange &R : RangesRef) { 39 assert(empty() || R.getBitWidth() == getBitWidth()); 40 Ranges.push_back(R); 41 } 42 } 43 44 // Return true if the ranges are non-overlapping and increasing. 45 LLVM_ABI static bool isOrderedRanges(ArrayRef<ConstantRange> RangesRef); 46 LLVM_ABI static std::optional<ConstantRangeList> 47 getConstantRangeList(ArrayRef<ConstantRange> RangesRef); 48 rangesRef()49 ArrayRef<ConstantRange> rangesRef() const { return Ranges; } begin()50 SmallVectorImpl<ConstantRange>::iterator begin() { return Ranges.begin(); } end()51 SmallVectorImpl<ConstantRange>::iterator end() { return Ranges.end(); } begin()52 SmallVectorImpl<ConstantRange>::const_iterator begin() const { 53 return Ranges.begin(); 54 } end()55 SmallVectorImpl<ConstantRange>::const_iterator end() const { 56 return Ranges.end(); 57 } getRange(unsigned i)58 ConstantRange getRange(unsigned i) const { return Ranges[i]; } 59 60 /// Return true if this list contains no members. empty()61 bool empty() const { return Ranges.empty(); } 62 63 /// Get the bit width of this ConstantRangeList. It is invalid to call this 64 /// with an empty range. getBitWidth()65 uint32_t getBitWidth() const { return Ranges.front().getBitWidth(); } 66 67 /// Return the number of ranges in this ConstantRangeList. size()68 size_t size() const { return Ranges.size(); } 69 70 /// Insert a new range to Ranges and keep the list ordered. 71 LLVM_ABI void insert(const ConstantRange &NewRange); insert(int64_t Lower,int64_t Upper)72 void insert(int64_t Lower, int64_t Upper) { 73 insert(ConstantRange(APInt(64, Lower, /*isSigned=*/true), 74 APInt(64, Upper, /*isSigned=*/true))); 75 } 76 77 LLVM_ABI void subtract(const ConstantRange &SubRange); 78 79 /// Return the range list that results from the union of this 80 /// ConstantRangeList with another ConstantRangeList, "CRL". 81 LLVM_ABI ConstantRangeList unionWith(const ConstantRangeList &CRL) const; 82 83 /// Return the range list that results from the intersection of this 84 /// ConstantRangeList with another ConstantRangeList, "CRL". 85 LLVM_ABI ConstantRangeList intersectWith(const ConstantRangeList &CRL) const; 86 87 /// Return true if this range list is equal to another range list. 88 bool operator==(const ConstantRangeList &CRL) const { 89 return Ranges == CRL.Ranges; 90 } 91 bool operator!=(const ConstantRangeList &CRL) const { 92 return !operator==(CRL); 93 } 94 95 /// Print out the ranges to a stream. 96 LLVM_ABI void print(raw_ostream &OS) const; 97 98 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 99 void dump() const; 100 #endif 101 }; 102 103 } // end namespace llvm 104 105 #endif // LLVM_IR_CONSTANTRANGELIST_H 106