annotate include/llvm/Support/KnownBits.h @ 121:803732b1fca8

LLVM 5.0
author kono
date Fri, 27 Oct 2017 17:07:41 +0900
parents
children 3a76565eade5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
4 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 // This file contains a class for representing known zeros and ones used by
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 // computeKnownBits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 #ifndef LLVM_SUPPORT_KNOWNBITS_H
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16 #define LLVM_SUPPORT_KNOWNBITS_H
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18 #include "llvm/ADT/APInt.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
19
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 namespace llvm {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 // Struct for tracking the known zeros and ones of a value.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23 struct KnownBits {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 APInt Zero;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25 APInt One;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27 private:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28 // Internal constructor for creating a KnownBits from two APInts.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29 KnownBits(APInt Zero, APInt One)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30 : Zero(std::move(Zero)), One(std::move(One)) {}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 public:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33 // Default construct Zero and One.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 KnownBits() {}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36 /// Create a known bits object of BitWidth bits initialized to unknown.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37 KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39 /// Get the bit width of this value.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40 unsigned getBitWidth() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41 assert(Zero.getBitWidth() == One.getBitWidth() &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42 "Zero and One should have the same width!");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43 return Zero.getBitWidth();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46 /// Returns true if there is conflicting information.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47 bool hasConflict() const { return Zero.intersects(One); }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49 /// Returns true if we know the value of all bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 bool isConstant() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 assert(!hasConflict() && "KnownBits conflict!");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 return Zero.countPopulation() + One.countPopulation() == getBitWidth();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55 /// Returns the value when all bits have a known value. This just returns One
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56 /// with a protective assertion.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57 const APInt &getConstant() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58 assert(isConstant() && "Can only get value when all bits are known");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59 return One;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62 /// Returns true if we don't know any bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63 bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65 /// Resets the known state of all bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66 void resetAll() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 Zero.clearAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
68 One.clearAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
69 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 /// Returns true if value is all zero.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72 bool isZero() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 assert(!hasConflict() && "KnownBits conflict!");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74 return Zero.isAllOnesValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
76
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
77 /// Returns true if value is all one bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 bool isAllOnes() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79 assert(!hasConflict() && "KnownBits conflict!");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 return One.isAllOnesValue();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
82
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
83 /// Make all bits known to be zero and discard any previous information.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84 void setAllZero() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85 Zero.setAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86 One.clearAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89 /// Make all bits known to be one and discard any previous information.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 void setAllOnes() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91 Zero.clearAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 One.setAllBits();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 /// Returns true if this value is known to be negative.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 bool isNegative() const { return One.isSignBitSet(); }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98 /// Returns true if this value is known to be non-negative.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99 bool isNonNegative() const { return Zero.isSignBitSet(); }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101 /// Make this value negative.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 void makeNegative() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103 assert(!isNonNegative() && "Can't make a non-negative value negative");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 One.setSignBit();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 /// Make this value negative.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108 void makeNonNegative() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109 assert(!isNegative() && "Can't make a negative value non-negative");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 Zero.setSignBit();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113 /// Truncate the underlying known Zero and One bits. This is equivalent
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114 /// to truncating the value we're tracking.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 KnownBits trunc(unsigned BitWidth) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
116 return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
117 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 /// Zero extends the underlying known Zero and One bits. This is equivalent
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
120 /// to zero extending the value we're tracking.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121 KnownBits zext(unsigned BitWidth) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
123 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
124
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
125 /// Sign extends the underlying known Zero and One bits. This is equivalent
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
126 /// to sign extending the value we're tracking.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
127 KnownBits sext(unsigned BitWidth) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
128 return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
129 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 /// Zero extends or truncates the underlying known Zero and One bits. This is
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
132 /// equivalent to zero extending or truncating the value we're tracking.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133 KnownBits zextOrTrunc(unsigned BitWidth) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137 /// Returns the minimum number of trailing zero bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 unsigned countMinTrailingZeros() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139 return Zero.countTrailingOnes();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 /// Returns the minimum number of trailing one bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143 unsigned countMinTrailingOnes() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 return One.countTrailingOnes();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147 /// Returns the minimum number of leading zero bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
148 unsigned countMinLeadingZeros() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
149 return Zero.countLeadingOnes();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
150 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
151
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152 /// Returns the minimum number of leading one bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
153 unsigned countMinLeadingOnes() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
154 return One.countLeadingOnes();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
155 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
156
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
157 /// Returns the number of times the sign bit is replicated into the other
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
158 /// bits.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
159 unsigned countMinSignBits() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
160 if (isNonNegative())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
161 return countMinLeadingZeros();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
162 if (isNegative())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
163 return countMinLeadingOnes();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
164 return 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
165 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
166
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
167 /// Returns the maximum number of trailing zero bits possible.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
168 unsigned countMaxTrailingZeros() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
169 return One.countTrailingZeros();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
170 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
171
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
172 /// Returns the maximum number of trailing one bits possible.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
173 unsigned countMaxTrailingOnes() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
174 return Zero.countTrailingZeros();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
175 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
176
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
177 /// Returns the maximum number of leading zero bits possible.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
178 unsigned countMaxLeadingZeros() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
179 return One.countLeadingZeros();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
180 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
181
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
182 /// Returns the maximum number of leading one bits possible.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
183 unsigned countMaxLeadingOnes() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
184 return Zero.countLeadingZeros();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
185 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
186
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
187 /// Returns the number of bits known to be one.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
188 unsigned countMinPopulation() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
189 return One.countPopulation();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
190 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
191
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
192 /// Returns the maximum number of bits that could be one.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
193 unsigned countMaxPopulation() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
194 return getBitWidth() - Zero.countPopulation();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
195 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
196
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
197 /// Compute known bits resulting from adding LHS and RHS.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
198 static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
199 KnownBits RHS);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
200 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
201
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
202 } // end namespace llvm
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
203
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
204 #endif