xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/ConstantRangeList.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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