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
26namespace llvm {
27
28class raw_ostream;
29
30/// This class represents a list of constant ranges.
31class [[nodiscard]] ConstantRangeList {
32 SmallVector<ConstantRange, 2> Ranges;
33
34public:
35 ConstantRangeList() = default;
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(Elt: 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
49 ArrayRef<ConstantRange> rangesRef() const { return Ranges; }
50 SmallVectorImpl<ConstantRange>::iterator begin() { return Ranges.begin(); }
51 SmallVectorImpl<ConstantRange>::iterator end() { return Ranges.end(); }
52 SmallVectorImpl<ConstantRange>::const_iterator begin() const {
53 return Ranges.begin();
54 }
55 SmallVectorImpl<ConstantRange>::const_iterator end() const {
56 return Ranges.end();
57 }
58 ConstantRange getRange(unsigned i) const { return Ranges[i]; }
59
60 /// Return true if this list contains no members.
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.
65 uint32_t getBitWidth() const { return Ranges.front().getBitWidth(); }
66
67 /// Return the number of ranges in this ConstantRangeList.
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);
72 void insert(int64_t Lower, int64_t Upper) {
73 insert(NewRange: 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