File: | llvm/include/llvm/ADT/SmallBitVector.h |
Warning: | line 389, column 40 The result of the left shift is undefined due to shifting by '4294967295', which is greater or equal to the width of type 'uintptr_t' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===// | |||
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 | // This file contains support for writing dwarf debug info into asm files. | |||
10 | // | |||
11 | //===----------------------------------------------------------------------===// | |||
12 | ||||
13 | #include "DwarfExpression.h" | |||
14 | #include "DwarfCompileUnit.h" | |||
15 | #include "llvm/ADT/APInt.h" | |||
16 | #include "llvm/ADT/SmallBitVector.h" | |||
17 | #include "llvm/BinaryFormat/Dwarf.h" | |||
18 | #include "llvm/CodeGen/Register.h" | |||
19 | #include "llvm/CodeGen/TargetRegisterInfo.h" | |||
20 | #include "llvm/IR/DebugInfoMetadata.h" | |||
21 | #include "llvm/Support/ErrorHandling.h" | |||
22 | #include <algorithm> | |||
23 | #include <cassert> | |||
24 | #include <cstdint> | |||
25 | ||||
26 | using namespace llvm; | |||
27 | ||||
28 | void DwarfExpression::emitConstu(uint64_t Value) { | |||
29 | if (Value < 32) | |||
30 | emitOp(dwarf::DW_OP_lit0 + Value); | |||
31 | else if (Value == std::numeric_limits<uint64_t>::max()) { | |||
32 | // Only do this for 64-bit values as the DWARF expression stack uses | |||
33 | // target-address-size values. | |||
34 | emitOp(dwarf::DW_OP_lit0); | |||
35 | emitOp(dwarf::DW_OP_not); | |||
36 | } else { | |||
37 | emitOp(dwarf::DW_OP_constu); | |||
38 | emitUnsigned(Value); | |||
39 | } | |||
40 | } | |||
41 | ||||
42 | void DwarfExpression::addReg(int DwarfReg, const char *Comment) { | |||
43 | assert(DwarfReg >= 0 && "invalid negative dwarf register number")((DwarfReg >= 0 && "invalid negative dwarf register number" ) ? static_cast<void> (0) : __assert_fail ("DwarfReg >= 0 && \"invalid negative dwarf register number\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 43, __PRETTY_FUNCTION__)); | |||
44 | assert((isUnknownLocation() || isRegisterLocation()) &&(((isUnknownLocation() || isRegisterLocation()) && "location description already locked down" ) ? static_cast<void> (0) : __assert_fail ("(isUnknownLocation() || isRegisterLocation()) && \"location description already locked down\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 45, __PRETTY_FUNCTION__)) | |||
45 | "location description already locked down")(((isUnknownLocation() || isRegisterLocation()) && "location description already locked down" ) ? static_cast<void> (0) : __assert_fail ("(isUnknownLocation() || isRegisterLocation()) && \"location description already locked down\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 45, __PRETTY_FUNCTION__)); | |||
46 | LocationKind = Register; | |||
47 | if (DwarfReg < 32) { | |||
48 | emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment); | |||
49 | } else { | |||
50 | emitOp(dwarf::DW_OP_regx, Comment); | |||
51 | emitUnsigned(DwarfReg); | |||
52 | } | |||
53 | } | |||
54 | ||||
55 | void DwarfExpression::addBReg(int DwarfReg, int Offset) { | |||
56 | assert(DwarfReg >= 0 && "invalid negative dwarf register number")((DwarfReg >= 0 && "invalid negative dwarf register number" ) ? static_cast<void> (0) : __assert_fail ("DwarfReg >= 0 && \"invalid negative dwarf register number\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 56, __PRETTY_FUNCTION__)); | |||
57 | assert(!isRegisterLocation() && "location description already locked down")((!isRegisterLocation() && "location description already locked down" ) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation() && \"location description already locked down\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 57, __PRETTY_FUNCTION__)); | |||
58 | if (DwarfReg < 32) { | |||
59 | emitOp(dwarf::DW_OP_breg0 + DwarfReg); | |||
60 | } else { | |||
61 | emitOp(dwarf::DW_OP_bregx); | |||
62 | emitUnsigned(DwarfReg); | |||
63 | } | |||
64 | emitSigned(Offset); | |||
65 | } | |||
66 | ||||
67 | void DwarfExpression::addFBReg(int Offset) { | |||
68 | emitOp(dwarf::DW_OP_fbreg); | |||
69 | emitSigned(Offset); | |||
70 | } | |||
71 | ||||
72 | void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) { | |||
73 | if (!SizeInBits) | |||
74 | return; | |||
75 | ||||
76 | const unsigned SizeOfByte = 8; | |||
77 | if (OffsetInBits > 0 || SizeInBits % SizeOfByte) { | |||
78 | emitOp(dwarf::DW_OP_bit_piece); | |||
79 | emitUnsigned(SizeInBits); | |||
80 | emitUnsigned(OffsetInBits); | |||
81 | } else { | |||
82 | emitOp(dwarf::DW_OP_piece); | |||
83 | unsigned ByteSize = SizeInBits / SizeOfByte; | |||
84 | emitUnsigned(ByteSize); | |||
85 | } | |||
86 | this->OffsetInBits += SizeInBits; | |||
87 | } | |||
88 | ||||
89 | void DwarfExpression::addShr(unsigned ShiftBy) { | |||
90 | emitConstu(ShiftBy); | |||
91 | emitOp(dwarf::DW_OP_shr); | |||
92 | } | |||
93 | ||||
94 | void DwarfExpression::addAnd(unsigned Mask) { | |||
95 | emitConstu(Mask); | |||
96 | emitOp(dwarf::DW_OP_and); | |||
97 | } | |||
98 | ||||
99 | bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI, | |||
100 | unsigned MachineReg, unsigned MaxSize) { | |||
101 | if (!llvm::Register::isPhysicalRegister(MachineReg)) { | |||
102 | if (isFrameRegister(TRI, MachineReg)) { | |||
103 | DwarfRegs.push_back({-1, 0, nullptr}); | |||
104 | return true; | |||
105 | } | |||
106 | return false; | |||
107 | } | |||
108 | ||||
109 | int Reg = TRI.getDwarfRegNum(MachineReg, false); | |||
110 | ||||
111 | // If this is a valid register number, emit it. | |||
112 | if (Reg >= 0) { | |||
113 | DwarfRegs.push_back({Reg, 0, nullptr}); | |||
114 | return true; | |||
115 | } | |||
116 | ||||
117 | // Walk up the super-register chain until we find a valid number. | |||
118 | // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0. | |||
119 | for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { | |||
120 | Reg = TRI.getDwarfRegNum(*SR, false); | |||
121 | if (Reg >= 0) { | |||
122 | unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg); | |||
123 | unsigned Size = TRI.getSubRegIdxSize(Idx); | |||
124 | unsigned RegOffset = TRI.getSubRegIdxOffset(Idx); | |||
125 | DwarfRegs.push_back({Reg, 0, "super-register"}); | |||
126 | // Use a DW_OP_bit_piece to describe the sub-register. | |||
127 | setSubRegisterPiece(Size, RegOffset); | |||
128 | return true; | |||
129 | } | |||
130 | } | |||
131 | ||||
132 | // Otherwise, attempt to find a covering set of sub-register numbers. | |||
133 | // For example, Q0 on ARM is a composition of D0+D1. | |||
134 | unsigned CurPos = 0; | |||
135 | // The size of the register in bits. | |||
136 | const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg); | |||
137 | unsigned RegSize = TRI.getRegSizeInBits(*RC); | |||
138 | // Keep track of the bits in the register we already emitted, so we | |||
139 | // can avoid emitting redundant aliasing subregs. Because this is | |||
140 | // just doing a greedy scan of all subregisters, it is possible that | |||
141 | // this doesn't find a combination of subregisters that fully cover | |||
142 | // the register (even though one may exist). | |||
143 | SmallBitVector Coverage(RegSize, false); | |||
144 | for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) { | |||
145 | unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR); | |||
146 | unsigned Size = TRI.getSubRegIdxSize(Idx); | |||
147 | unsigned Offset = TRI.getSubRegIdxOffset(Idx); | |||
148 | Reg = TRI.getDwarfRegNum(*SR, false); | |||
149 | if (Reg < 0) | |||
150 | continue; | |||
151 | ||||
152 | // Intersection between the bits we already emitted and the bits | |||
153 | // covered by this subregister. | |||
154 | SmallBitVector CurSubReg(RegSize, false); | |||
155 | CurSubReg.set(Offset, Offset + Size); | |||
156 | ||||
157 | // If this sub-register has a DWARF number and we haven't covered | |||
158 | // its range, and its range covers the value, emit a DWARF piece for it. | |||
159 | if (Offset < MaxSize && CurSubReg.test(Coverage)) { | |||
160 | // Emit a piece for any gap in the coverage. | |||
161 | if (Offset > CurPos) | |||
162 | DwarfRegs.push_back( | |||
163 | {-1, Offset - CurPos, "no DWARF register encoding"}); | |||
164 | DwarfRegs.push_back( | |||
165 | {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"}); | |||
166 | } | |||
167 | // Mark it as emitted. | |||
168 | Coverage.set(Offset, Offset + Size); | |||
169 | CurPos = Offset + Size; | |||
170 | } | |||
171 | // Failed to find any DWARF encoding. | |||
172 | if (CurPos == 0) | |||
173 | return false; | |||
174 | // Found a partial or complete DWARF encoding. | |||
175 | if (CurPos < RegSize) | |||
176 | DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"}); | |||
177 | return true; | |||
178 | } | |||
179 | ||||
180 | void DwarfExpression::addStackValue() { | |||
181 | if (DwarfVersion >= 4) | |||
182 | emitOp(dwarf::DW_OP_stack_value); | |||
183 | } | |||
184 | ||||
185 | void DwarfExpression::addSignedConstant(int64_t Value) { | |||
186 | assert(isImplicitLocation() || isUnknownLocation())((isImplicitLocation() || isUnknownLocation()) ? static_cast< void> (0) : __assert_fail ("isImplicitLocation() || isUnknownLocation()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 186, __PRETTY_FUNCTION__)); | |||
187 | LocationKind = Implicit; | |||
188 | emitOp(dwarf::DW_OP_consts); | |||
189 | emitSigned(Value); | |||
190 | } | |||
191 | ||||
192 | void DwarfExpression::addUnsignedConstant(uint64_t Value) { | |||
193 | assert(isImplicitLocation() || isUnknownLocation())((isImplicitLocation() || isUnknownLocation()) ? static_cast< void> (0) : __assert_fail ("isImplicitLocation() || isUnknownLocation()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 193, __PRETTY_FUNCTION__)); | |||
194 | LocationKind = Implicit; | |||
195 | emitConstu(Value); | |||
196 | } | |||
197 | ||||
198 | void DwarfExpression::addUnsignedConstant(const APInt &Value) { | |||
199 | assert(isImplicitLocation() || isUnknownLocation())((isImplicitLocation() || isUnknownLocation()) ? static_cast< void> (0) : __assert_fail ("isImplicitLocation() || isUnknownLocation()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 199, __PRETTY_FUNCTION__)); | |||
200 | LocationKind = Implicit; | |||
201 | ||||
202 | unsigned Size = Value.getBitWidth(); | |||
203 | const uint64_t *Data = Value.getRawData(); | |||
204 | ||||
205 | // Chop it up into 64-bit pieces, because that's the maximum that | |||
206 | // addUnsignedConstant takes. | |||
207 | unsigned Offset = 0; | |||
208 | while (Offset < Size) { | |||
209 | addUnsignedConstant(*Data++); | |||
210 | if (Offset == 0 && Size <= 64) | |||
211 | break; | |||
212 | addStackValue(); | |||
213 | addOpPiece(std::min(Size - Offset, 64u), Offset); | |||
214 | Offset += 64; | |||
215 | } | |||
216 | } | |||
217 | ||||
218 | bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, | |||
219 | DIExpressionCursor &ExprCursor, | |||
220 | unsigned MachineReg, | |||
221 | unsigned FragmentOffsetInBits) { | |||
222 | auto Fragment = ExprCursor.getFragmentInfo(); | |||
223 | if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) { | |||
| ||||
224 | LocationKind = Unknown; | |||
225 | return false; | |||
226 | } | |||
227 | ||||
228 | bool HasComplexExpression = false; | |||
229 | auto Op = ExprCursor.peek(); | |||
230 | if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment) | |||
231 | HasComplexExpression = true; | |||
232 | ||||
233 | // If the register can only be described by a complex expression (i.e., | |||
234 | // multiple subregisters) it doesn't safely compose with another complex | |||
235 | // expression. For example, it is not possible to apply a DW_OP_deref | |||
236 | // operation to multiple DW_OP_pieces. | |||
237 | if (HasComplexExpression && DwarfRegs.size() > 1) { | |||
238 | DwarfRegs.clear(); | |||
239 | LocationKind = Unknown; | |||
240 | return false; | |||
241 | } | |||
242 | ||||
243 | // Handle simple register locations. If we are supposed to emit | |||
244 | // a call site parameter expression and if that expression is just a register | |||
245 | // location, emit it with addBReg and offset 0, because we should emit a DWARF | |||
246 | // expression representing a value, rather than a location. | |||
247 | if (!isMemoryLocation() && !HasComplexExpression && (!isParameterValue() || | |||
248 | isEntryValue())) { | |||
249 | for (auto &Reg : DwarfRegs) { | |||
250 | if (Reg.DwarfRegNo >= 0) | |||
251 | addReg(Reg.DwarfRegNo, Reg.Comment); | |||
252 | addOpPiece(Reg.Size); | |||
253 | } | |||
254 | ||||
255 | if (isEntryValue()) | |||
256 | finalizeEntryValue(); | |||
257 | ||||
258 | if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4) | |||
259 | emitOp(dwarf::DW_OP_stack_value); | |||
260 | ||||
261 | DwarfRegs.clear(); | |||
262 | return true; | |||
263 | } | |||
264 | ||||
265 | // Don't emit locations that cannot be expressed without DW_OP_stack_value. | |||
266 | if (DwarfVersion < 4) | |||
267 | if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool { | |||
268 | return Op.getOp() == dwarf::DW_OP_stack_value; | |||
269 | })) { | |||
270 | DwarfRegs.clear(); | |||
271 | LocationKind = Unknown; | |||
272 | return false; | |||
273 | } | |||
274 | ||||
275 | assert(DwarfRegs.size() == 1)((DwarfRegs.size() == 1) ? static_cast<void> (0) : __assert_fail ("DwarfRegs.size() == 1", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 275, __PRETTY_FUNCTION__)); | |||
276 | auto Reg = DwarfRegs[0]; | |||
277 | bool FBReg = isFrameRegister(TRI, MachineReg); | |||
278 | int SignedOffset = 0; | |||
279 | assert(Reg.Size == 0 && "subregister has same size as superregister")((Reg.Size == 0 && "subregister has same size as superregister" ) ? static_cast<void> (0) : __assert_fail ("Reg.Size == 0 && \"subregister has same size as superregister\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 279, __PRETTY_FUNCTION__)); | |||
280 | ||||
281 | // Pattern-match combinations for which more efficient representations exist. | |||
282 | // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset]. | |||
283 | if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) { | |||
284 | uint64_t Offset = Op->getArg(0); | |||
285 | uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); | |||
286 | if (Offset <= IntMax) { | |||
287 | SignedOffset = Offset; | |||
288 | ExprCursor.take(); | |||
289 | } | |||
290 | } | |||
291 | ||||
292 | // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset] | |||
293 | // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset] | |||
294 | // If Reg is a subregister we need to mask it out before subtracting. | |||
295 | if (Op && Op->getOp() == dwarf::DW_OP_constu) { | |||
296 | uint64_t Offset = Op->getArg(0); | |||
297 | uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max()); | |||
298 | auto N = ExprCursor.peekNext(); | |||
299 | if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) { | |||
300 | SignedOffset = Offset; | |||
301 | ExprCursor.consume(2); | |||
302 | } else if (N && N->getOp() == dwarf::DW_OP_minus && | |||
303 | !SubRegisterSizeInBits && Offset <= IntMax + 1) { | |||
304 | SignedOffset = -static_cast<int64_t>(Offset); | |||
305 | ExprCursor.consume(2); | |||
306 | } | |||
307 | } | |||
308 | ||||
309 | if (FBReg) | |||
310 | addFBReg(SignedOffset); | |||
311 | else | |||
312 | addBReg(Reg.DwarfRegNo, SignedOffset); | |||
313 | DwarfRegs.clear(); | |||
314 | return true; | |||
315 | } | |||
316 | ||||
317 | void DwarfExpression::beginEntryValueExpression( | |||
318 | DIExpressionCursor &ExprCursor) { | |||
319 | auto Op = ExprCursor.take(); | |||
320 | (void)Op; | |||
321 | assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value)((Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value ) ? static_cast<void> (0) : __assert_fail ("Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 321, __PRETTY_FUNCTION__)); | |||
322 | assert(!isMemoryLocation() &&((!isMemoryLocation() && "We don't support entry values of memory locations yet" ) ? static_cast<void> (0) : __assert_fail ("!isMemoryLocation() && \"We don't support entry values of memory locations yet\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 323, __PRETTY_FUNCTION__)) | |||
323 | "We don't support entry values of memory locations yet")((!isMemoryLocation() && "We don't support entry values of memory locations yet" ) ? static_cast<void> (0) : __assert_fail ("!isMemoryLocation() && \"We don't support entry values of memory locations yet\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 323, __PRETTY_FUNCTION__)); | |||
324 | assert(!IsEmittingEntryValue && "Already emitting entry value?")((!IsEmittingEntryValue && "Already emitting entry value?" ) ? static_cast<void> (0) : __assert_fail ("!IsEmittingEntryValue && \"Already emitting entry value?\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 324, __PRETTY_FUNCTION__)); | |||
325 | assert(Op->getArg(0) == 1 &&((Op->getArg(0) == 1 && "Can currently only emit entry values covering a single operation" ) ? static_cast<void> (0) : __assert_fail ("Op->getArg(0) == 1 && \"Can currently only emit entry values covering a single operation\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 326, __PRETTY_FUNCTION__)) | |||
326 | "Can currently only emit entry values covering a single operation")((Op->getArg(0) == 1 && "Can currently only emit entry values covering a single operation" ) ? static_cast<void> (0) : __assert_fail ("Op->getArg(0) == 1 && \"Can currently only emit entry values covering a single operation\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 326, __PRETTY_FUNCTION__)); | |||
327 | ||||
328 | emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value)); | |||
329 | IsEmittingEntryValue = true; | |||
330 | enableTemporaryBuffer(); | |||
331 | } | |||
332 | ||||
333 | void DwarfExpression::finalizeEntryValue() { | |||
334 | assert(IsEmittingEntryValue && "Entry value not open?")((IsEmittingEntryValue && "Entry value not open?") ? static_cast <void> (0) : __assert_fail ("IsEmittingEntryValue && \"Entry value not open?\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 334, __PRETTY_FUNCTION__)); | |||
335 | disableTemporaryBuffer(); | |||
336 | ||||
337 | // Emit the entry value's size operand. | |||
338 | unsigned Size = getTemporaryBufferSize(); | |||
339 | emitUnsigned(Size); | |||
340 | ||||
341 | // Emit the entry value's DWARF block operand. | |||
342 | commitTemporaryBuffer(); | |||
343 | ||||
344 | IsEmittingEntryValue = false; | |||
345 | } | |||
346 | ||||
347 | /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?". | |||
348 | static bool isMemoryLocation(DIExpressionCursor ExprCursor) { | |||
349 | while (ExprCursor) { | |||
350 | auto Op = ExprCursor.take(); | |||
351 | switch (Op->getOp()) { | |||
352 | case dwarf::DW_OP_deref: | |||
353 | case dwarf::DW_OP_LLVM_fragment: | |||
354 | break; | |||
355 | default: | |||
356 | return false; | |||
357 | } | |||
358 | } | |||
359 | return true; | |||
360 | } | |||
361 | ||||
362 | void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor, | |||
363 | unsigned FragmentOffsetInBits) { | |||
364 | // If we need to mask out a subregister, do it now, unless the next | |||
365 | // operation would emit an OpPiece anyway. | |||
366 | auto N = ExprCursor.peek(); | |||
367 | if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment)) | |||
368 | maskSubRegister(); | |||
369 | ||||
370 | Optional<DIExpression::ExprOperand> PrevConvertOp = None; | |||
371 | ||||
372 | while (ExprCursor) { | |||
373 | auto Op = ExprCursor.take(); | |||
374 | uint64_t OpNum = Op->getOp(); | |||
375 | ||||
376 | if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) { | |||
377 | emitOp(OpNum); | |||
378 | continue; | |||
379 | } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) { | |||
380 | addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0)); | |||
381 | continue; | |||
382 | } | |||
383 | ||||
384 | switch (OpNum) { | |||
385 | case dwarf::DW_OP_LLVM_fragment: { | |||
386 | unsigned SizeInBits = Op->getArg(1); | |||
387 | unsigned FragmentOffset = Op->getArg(0); | |||
388 | // The fragment offset must have already been adjusted by emitting an | |||
389 | // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base | |||
390 | // location. | |||
391 | assert(OffsetInBits >= FragmentOffset && "fragment offset not added?")((OffsetInBits >= FragmentOffset && "fragment offset not added?" ) ? static_cast<void> (0) : __assert_fail ("OffsetInBits >= FragmentOffset && \"fragment offset not added?\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 391, __PRETTY_FUNCTION__)); | |||
392 | assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow")((SizeInBits >= OffsetInBits - FragmentOffset && "size underflow" ) ? static_cast<void> (0) : __assert_fail ("SizeInBits >= OffsetInBits - FragmentOffset && \"size underflow\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 392, __PRETTY_FUNCTION__)); | |||
393 | ||||
394 | // If addMachineReg already emitted DW_OP_piece operations to represent | |||
395 | // a super-register by splicing together sub-registers, subtract the size | |||
396 | // of the pieces that was already emitted. | |||
397 | SizeInBits -= OffsetInBits - FragmentOffset; | |||
398 | ||||
399 | // If addMachineReg requested a DW_OP_bit_piece to stencil out a | |||
400 | // sub-register that is smaller than the current fragment's size, use it. | |||
401 | if (SubRegisterSizeInBits) | |||
402 | SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits); | |||
403 | ||||
404 | // Emit a DW_OP_stack_value for implicit location descriptions. | |||
405 | if (isImplicitLocation()) | |||
406 | addStackValue(); | |||
407 | ||||
408 | // Emit the DW_OP_piece. | |||
409 | addOpPiece(SizeInBits, SubRegisterOffsetInBits); | |||
410 | setSubRegisterPiece(0, 0); | |||
411 | // Reset the location description kind. | |||
412 | LocationKind = Unknown; | |||
413 | return; | |||
414 | } | |||
415 | case dwarf::DW_OP_plus_uconst: | |||
416 | assert(!isRegisterLocation())((!isRegisterLocation()) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 416, __PRETTY_FUNCTION__)); | |||
417 | emitOp(dwarf::DW_OP_plus_uconst); | |||
418 | emitUnsigned(Op->getArg(0)); | |||
419 | break; | |||
420 | case dwarf::DW_OP_plus: | |||
421 | case dwarf::DW_OP_minus: | |||
422 | case dwarf::DW_OP_mul: | |||
423 | case dwarf::DW_OP_div: | |||
424 | case dwarf::DW_OP_mod: | |||
425 | case dwarf::DW_OP_or: | |||
426 | case dwarf::DW_OP_and: | |||
427 | case dwarf::DW_OP_xor: | |||
428 | case dwarf::DW_OP_shl: | |||
429 | case dwarf::DW_OP_shr: | |||
430 | case dwarf::DW_OP_shra: | |||
431 | case dwarf::DW_OP_lit0: | |||
432 | case dwarf::DW_OP_not: | |||
433 | case dwarf::DW_OP_dup: | |||
434 | emitOp(OpNum); | |||
435 | break; | |||
436 | case dwarf::DW_OP_deref: | |||
437 | assert(!isRegisterLocation())((!isRegisterLocation()) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 437, __PRETTY_FUNCTION__)); | |||
438 | if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor)) | |||
439 | // Turning this into a memory location description makes the deref | |||
440 | // implicit. | |||
441 | LocationKind = Memory; | |||
442 | else | |||
443 | emitOp(dwarf::DW_OP_deref); | |||
444 | break; | |||
445 | case dwarf::DW_OP_constu: | |||
446 | assert(!isRegisterLocation())((!isRegisterLocation()) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 446, __PRETTY_FUNCTION__)); | |||
447 | emitConstu(Op->getArg(0)); | |||
448 | break; | |||
449 | case dwarf::DW_OP_LLVM_convert: { | |||
450 | unsigned BitSize = Op->getArg(0); | |||
451 | dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1)); | |||
452 | if (DwarfVersion >= 5) { | |||
453 | emitOp(dwarf::DW_OP_convert); | |||
454 | // Reuse the base_type if we already have one in this CU otherwise we | |||
455 | // create a new one. | |||
456 | unsigned I = 0, E = CU.ExprRefedBaseTypes.size(); | |||
457 | for (; I != E; ++I) | |||
458 | if (CU.ExprRefedBaseTypes[I].BitSize == BitSize && | |||
459 | CU.ExprRefedBaseTypes[I].Encoding == Encoding) | |||
460 | break; | |||
461 | ||||
462 | if (I == E) | |||
463 | CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding); | |||
464 | ||||
465 | // If targeting a location-list; simply emit the index into the raw | |||
466 | // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been | |||
467 | // fitted with means to extract it later. | |||
468 | // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef | |||
469 | // (containing the index and a resolve mechanism during emit) into the | |||
470 | // DIE value list. | |||
471 | emitBaseTypeRef(I); | |||
472 | } else { | |||
473 | if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) { | |||
474 | if (Encoding == dwarf::DW_ATE_signed) | |||
475 | emitLegacySExt(PrevConvertOp->getArg(0)); | |||
476 | else if (Encoding == dwarf::DW_ATE_unsigned) | |||
477 | emitLegacyZExt(PrevConvertOp->getArg(0)); | |||
478 | PrevConvertOp = None; | |||
479 | } else { | |||
480 | PrevConvertOp = Op; | |||
481 | } | |||
482 | } | |||
483 | break; | |||
484 | } | |||
485 | case dwarf::DW_OP_stack_value: | |||
486 | LocationKind = Implicit; | |||
487 | break; | |||
488 | case dwarf::DW_OP_swap: | |||
489 | assert(!isRegisterLocation())((!isRegisterLocation()) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 489, __PRETTY_FUNCTION__)); | |||
490 | emitOp(dwarf::DW_OP_swap); | |||
491 | break; | |||
492 | case dwarf::DW_OP_xderef: | |||
493 | assert(!isRegisterLocation())((!isRegisterLocation()) ? static_cast<void> (0) : __assert_fail ("!isRegisterLocation()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 493, __PRETTY_FUNCTION__)); | |||
494 | emitOp(dwarf::DW_OP_xderef); | |||
495 | break; | |||
496 | case dwarf::DW_OP_deref_size: | |||
497 | emitOp(dwarf::DW_OP_deref_size); | |||
498 | emitData1(Op->getArg(0)); | |||
499 | break; | |||
500 | case dwarf::DW_OP_LLVM_tag_offset: | |||
501 | TagOffset = Op->getArg(0); | |||
502 | break; | |||
503 | case dwarf::DW_OP_regx: | |||
504 | emitOp(dwarf::DW_OP_regx); | |||
505 | emitUnsigned(Op->getArg(0)); | |||
506 | break; | |||
507 | case dwarf::DW_OP_bregx: | |||
508 | emitOp(dwarf::DW_OP_bregx); | |||
509 | emitUnsigned(Op->getArg(0)); | |||
510 | emitSigned(Op->getArg(1)); | |||
511 | break; | |||
512 | default: | |||
513 | llvm_unreachable("unhandled opcode found in expression")::llvm::llvm_unreachable_internal("unhandled opcode found in expression" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 513); | |||
514 | } | |||
515 | } | |||
516 | ||||
517 | if (isImplicitLocation() && !isParameterValue()) | |||
518 | // Turn this into an implicit location description. | |||
519 | addStackValue(); | |||
520 | } | |||
521 | ||||
522 | /// add masking operations to stencil out a subregister. | |||
523 | void DwarfExpression::maskSubRegister() { | |||
524 | assert(SubRegisterSizeInBits && "no subregister was registered")((SubRegisterSizeInBits && "no subregister was registered" ) ? static_cast<void> (0) : __assert_fail ("SubRegisterSizeInBits && \"no subregister was registered\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 524, __PRETTY_FUNCTION__)); | |||
525 | if (SubRegisterOffsetInBits > 0) | |||
526 | addShr(SubRegisterOffsetInBits); | |||
527 | uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL; | |||
528 | addAnd(Mask); | |||
529 | } | |||
530 | ||||
531 | void DwarfExpression::finalize() { | |||
532 | assert(DwarfRegs.size() == 0 && "dwarf registers not emitted")((DwarfRegs.size() == 0 && "dwarf registers not emitted" ) ? static_cast<void> (0) : __assert_fail ("DwarfRegs.size() == 0 && \"dwarf registers not emitted\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 532, __PRETTY_FUNCTION__)); | |||
533 | // Emit any outstanding DW_OP_piece operations to mask out subregisters. | |||
534 | if (SubRegisterSizeInBits == 0) | |||
535 | return; | |||
536 | // Don't emit a DW_OP_piece for a subregister at offset 0. | |||
537 | if (SubRegisterOffsetInBits == 0) | |||
538 | return; | |||
539 | addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits); | |||
540 | } | |||
541 | ||||
542 | void DwarfExpression::addFragmentOffset(const DIExpression *Expr) { | |||
543 | if (!Expr || !Expr->isFragment()) | |||
544 | return; | |||
545 | ||||
546 | uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits; | |||
547 | assert(FragmentOffset >= OffsetInBits &&((FragmentOffset >= OffsetInBits && "overlapping or duplicate fragments" ) ? static_cast<void> (0) : __assert_fail ("FragmentOffset >= OffsetInBits && \"overlapping or duplicate fragments\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 548, __PRETTY_FUNCTION__)) | |||
548 | "overlapping or duplicate fragments")((FragmentOffset >= OffsetInBits && "overlapping or duplicate fragments" ) ? static_cast<void> (0) : __assert_fail ("FragmentOffset >= OffsetInBits && \"overlapping or duplicate fragments\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 548, __PRETTY_FUNCTION__)); | |||
549 | if (FragmentOffset > OffsetInBits) | |||
550 | addOpPiece(FragmentOffset - OffsetInBits); | |||
551 | OffsetInBits = FragmentOffset; | |||
552 | } | |||
553 | ||||
554 | void DwarfExpression::emitLegacySExt(unsigned FromBits) { | |||
555 | // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X | |||
556 | emitOp(dwarf::DW_OP_dup); | |||
557 | emitOp(dwarf::DW_OP_constu); | |||
558 | emitUnsigned(FromBits - 1); | |||
559 | emitOp(dwarf::DW_OP_shr); | |||
560 | emitOp(dwarf::DW_OP_lit0); | |||
561 | emitOp(dwarf::DW_OP_not); | |||
562 | emitOp(dwarf::DW_OP_mul); | |||
563 | emitOp(dwarf::DW_OP_constu); | |||
564 | emitUnsigned(FromBits); | |||
565 | emitOp(dwarf::DW_OP_shl); | |||
566 | emitOp(dwarf::DW_OP_or); | |||
567 | } | |||
568 | ||||
569 | void DwarfExpression::emitLegacyZExt(unsigned FromBits) { | |||
570 | // (X & (1 << FromBits - 1)) | |||
571 | emitOp(dwarf::DW_OP_constu); | |||
572 | emitUnsigned((1ULL << FromBits) - 1); | |||
573 | emitOp(dwarf::DW_OP_and); | |||
574 | } | |||
575 | ||||
576 | void DwarfExpression::addWasmLocation(unsigned Index, int64_t Offset) { | |||
577 | assert(LocationKind == Implicit || LocationKind == Unknown)((LocationKind == Implicit || LocationKind == Unknown) ? static_cast <void> (0) : __assert_fail ("LocationKind == Implicit || LocationKind == Unknown" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp" , 577, __PRETTY_FUNCTION__)); | |||
578 | LocationKind = Implicit; | |||
579 | emitOp(dwarf::DW_OP_WASM_location); | |||
580 | emitUnsigned(Index); | |||
581 | emitSigned(Offset); | |||
582 | } |
1 | //===-- llvm/CodeGen/Register.h ---------------------------------*- 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 | #ifndef LLVM_CODEGEN_REGISTER_H |
10 | #define LLVM_CODEGEN_REGISTER_H |
11 | |
12 | #include "llvm/MC/MCRegister.h" |
13 | #include <cassert> |
14 | |
15 | namespace llvm { |
16 | |
17 | /// Wrapper class representing virtual and physical registers. Should be passed |
18 | /// by value. |
19 | class Register { |
20 | unsigned Reg; |
21 | |
22 | public: |
23 | Register(unsigned Val = 0): Reg(Val) {} |
24 | Register(MCRegister Val): Reg(Val) {} |
25 | |
26 | // Register numbers can represent physical registers, virtual registers, and |
27 | // sometimes stack slots. The unsigned values are divided into these ranges: |
28 | // |
29 | // 0 Not a register, can be used as a sentinel. |
30 | // [1;2^30) Physical registers assigned by TableGen. |
31 | // [2^30;2^31) Stack slots. (Rarely used.) |
32 | // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo. |
33 | // |
34 | // Further sentinels can be allocated from the small negative integers. |
35 | // DenseMapInfo<unsigned> uses -1u and -2u. |
36 | |
37 | /// isStackSlot - Sometimes it is useful the be able to store a non-negative |
38 | /// frame index in a variable that normally holds a register. isStackSlot() |
39 | /// returns true if Reg is in the range used for stack slots. |
40 | /// |
41 | /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack |
42 | /// slots, so if a variable may contains a stack slot, always check |
43 | /// isStackSlot() first. |
44 | /// |
45 | static bool isStackSlot(unsigned Reg) { |
46 | return MCRegister::isStackSlot(Reg); |
47 | } |
48 | |
49 | /// Compute the frame index from a register value representing a stack slot. |
50 | static int stackSlot2Index(unsigned Reg) { |
51 | assert(isStackSlot(Reg) && "Not a stack slot")((isStackSlot(Reg) && "Not a stack slot") ? static_cast <void> (0) : __assert_fail ("isStackSlot(Reg) && \"Not a stack slot\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/CodeGen/Register.h" , 51, __PRETTY_FUNCTION__)); |
52 | return int(Reg - (1u << 30)); |
53 | } |
54 | |
55 | /// Convert a non-negative frame index to a stack slot register value. |
56 | static unsigned index2StackSlot(int FI) { |
57 | assert(FI >= 0 && "Cannot hold a negative frame index.")((FI >= 0 && "Cannot hold a negative frame index." ) ? static_cast<void> (0) : __assert_fail ("FI >= 0 && \"Cannot hold a negative frame index.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/CodeGen/Register.h" , 57, __PRETTY_FUNCTION__)); |
58 | return FI + (1u << 30); |
59 | } |
60 | |
61 | /// Return true if the specified register number is in |
62 | /// the physical register namespace. |
63 | static bool isPhysicalRegister(unsigned Reg) { |
64 | return MCRegister::isPhysicalRegister(Reg); |
65 | } |
66 | |
67 | /// Return true if the specified register number is in |
68 | /// the virtual register namespace. |
69 | static bool isVirtualRegister(unsigned Reg) { |
70 | assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.")((!isStackSlot(Reg) && "Not a register! Check isStackSlot() first." ) ? static_cast<void> (0) : __assert_fail ("!isStackSlot(Reg) && \"Not a register! Check isStackSlot() first.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/CodeGen/Register.h" , 70, __PRETTY_FUNCTION__)); |
71 | return int(Reg) < 0; |
72 | } |
73 | |
74 | /// Convert a virtual register number to a 0-based index. |
75 | /// The first virtual register in a function will get the index 0. |
76 | static unsigned virtReg2Index(unsigned Reg) { |
77 | assert(isVirtualRegister(Reg) && "Not a virtual register")((isVirtualRegister(Reg) && "Not a virtual register") ? static_cast<void> (0) : __assert_fail ("isVirtualRegister(Reg) && \"Not a virtual register\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/CodeGen/Register.h" , 77, __PRETTY_FUNCTION__)); |
78 | return Reg & ~(1u << 31); |
79 | } |
80 | |
81 | /// Convert a 0-based index to a virtual register number. |
82 | /// This is the inverse operation of VirtReg2IndexFunctor below. |
83 | static unsigned index2VirtReg(unsigned Index) { |
84 | return Index | (1u << 31); |
85 | } |
86 | |
87 | /// Return true if the specified register number is in the virtual register |
88 | /// namespace. |
89 | bool isVirtual() const { |
90 | return isVirtualRegister(Reg); |
91 | } |
92 | |
93 | /// Return true if the specified register number is in the physical register |
94 | /// namespace. |
95 | bool isPhysical() const { |
96 | return isPhysicalRegister(Reg); |
97 | } |
98 | |
99 | /// Convert a virtual register number to a 0-based index. The first virtual |
100 | /// register in a function will get the index 0. |
101 | unsigned virtRegIndex() const { |
102 | return virtReg2Index(Reg); |
103 | } |
104 | |
105 | operator unsigned() const { |
106 | return Reg; |
107 | } |
108 | |
109 | unsigned id() const { return Reg; } |
110 | |
111 | operator MCRegister() const { |
112 | return MCRegister(Reg); |
113 | } |
114 | |
115 | bool isValid() const { |
116 | return Reg != 0; |
117 | } |
118 | |
119 | /// Comparisons between register objects |
120 | bool operator==(const Register &Other) const { return Reg == Other.Reg; } |
121 | bool operator!=(const Register &Other) const { return Reg != Other.Reg; } |
122 | bool operator==(const MCRegister &Other) const { return Reg == Other.id(); } |
123 | bool operator!=(const MCRegister &Other) const { return Reg != Other.id(); } |
124 | |
125 | /// Comparisons against register constants. E.g. |
126 | /// * R == AArch64::WZR |
127 | /// * R == 0 |
128 | /// * R == VirtRegMap::NO_PHYS_REG |
129 | bool operator==(unsigned Other) const { return Reg == Other; } |
130 | bool operator!=(unsigned Other) const { return Reg != Other; } |
131 | bool operator==(int Other) const { return Reg == unsigned(Other); } |
132 | bool operator!=(int Other) const { return Reg != unsigned(Other); } |
133 | // MSVC requires that we explicitly declare these two as well. |
134 | bool operator==(MCPhysReg Other) const { return Reg == unsigned(Other); } |
135 | bool operator!=(MCPhysReg Other) const { return Reg != unsigned(Other); } |
136 | }; |
137 | |
138 | // Provide DenseMapInfo for Register |
139 | template<> struct DenseMapInfo<Register> { |
140 | static inline unsigned getEmptyKey() { |
141 | return DenseMapInfo<unsigned>::getEmptyKey(); |
142 | } |
143 | static inline unsigned getTombstoneKey() { |
144 | return DenseMapInfo<unsigned>::getTombstoneKey(); |
145 | } |
146 | static unsigned getHashValue(const Register &Val) { |
147 | return DenseMapInfo<unsigned>::getHashValue(Val.id()); |
148 | } |
149 | static bool isEqual(const Register &LHS, const Register &RHS) { |
150 | return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id()); |
151 | } |
152 | }; |
153 | |
154 | } |
155 | |
156 | #endif // ifndef LLVM_CODEGEN_REGISTER_H |
1 | //===-- llvm/MC/Register.h --------------------------------------*- 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 | #ifndef LLVM_MC_REGISTER_H |
10 | #define LLVM_MC_REGISTER_H |
11 | |
12 | #include "llvm/ADT/DenseMapInfo.h" |
13 | #include <cassert> |
14 | |
15 | namespace llvm { |
16 | |
17 | /// An unsigned integer type large enough to represent all physical registers, |
18 | /// but not necessarily virtual registers. |
19 | using MCPhysReg = uint16_t; |
20 | |
21 | /// Wrapper class representing physical registers. Should be passed by value. |
22 | class MCRegister { |
23 | unsigned Reg; |
24 | |
25 | public: |
26 | MCRegister(unsigned Val = 0): Reg(Val) {} |
27 | |
28 | // Register numbers can represent physical registers, virtual registers, and |
29 | // sometimes stack slots. The unsigned values are divided into these ranges: |
30 | // |
31 | // 0 Not a register, can be used as a sentinel. |
32 | // [1;2^30) Physical registers assigned by TableGen. |
33 | // [2^30;2^31) Stack slots. (Rarely used.) |
34 | // [2^31;2^32) Virtual registers assigned by MachineRegisterInfo. |
35 | // |
36 | // Further sentinels can be allocated from the small negative integers. |
37 | // DenseMapInfo<unsigned> uses -1u and -2u. |
38 | |
39 | /// This is the portion of the positive number space that is not a physical |
40 | /// register. StackSlot values do not exist in the MC layer, see |
41 | /// Register::isStackSlot() for the more information on them. |
42 | /// |
43 | /// Note that isVirtualRegister() and isPhysicalRegister() cannot handle stack |
44 | /// slots, so if a variable may contains a stack slot, always check |
45 | /// isStackSlot() first. |
46 | static bool isStackSlot(unsigned Reg) { |
47 | return int(Reg) >= (1 << 30); |
48 | } |
49 | |
50 | /// Return true if the specified register number is in |
51 | /// the physical register namespace. |
52 | static bool isPhysicalRegister(unsigned Reg) { |
53 | assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.")((!isStackSlot(Reg) && "Not a register! Check isStackSlot() first." ) ? static_cast<void> (0) : __assert_fail ("!isStackSlot(Reg) && \"Not a register! Check isStackSlot() first.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegister.h" , 53, __PRETTY_FUNCTION__)); |
54 | return int(Reg) > 0; |
55 | } |
56 | |
57 | /// Return true if the specified register number is in the physical register |
58 | /// namespace. |
59 | bool isPhysical() const { |
60 | return isPhysicalRegister(Reg); |
61 | } |
62 | |
63 | operator unsigned() const { |
64 | return Reg; |
65 | } |
66 | |
67 | unsigned id() const { |
68 | return Reg; |
69 | } |
70 | |
71 | bool isValid() const { |
72 | return Reg != 0; |
73 | } |
74 | |
75 | /// Comparisons between register objects |
76 | bool operator==(const MCRegister &Other) const { return Reg == Other.Reg; } |
77 | bool operator!=(const MCRegister &Other) const { return Reg != Other.Reg; } |
78 | |
79 | /// Comparisons against register constants. E.g. |
80 | /// * R == AArch64::WZR |
81 | /// * R == 0 |
82 | /// * R == VirtRegMap::NO_PHYS_REG |
83 | bool operator==(unsigned Other) const { return Reg == Other; } |
84 | bool operator!=(unsigned Other) const { return Reg != Other; } |
85 | bool operator==(int Other) const { return Reg == unsigned(Other); } |
86 | bool operator!=(int Other) const { return Reg != unsigned(Other); } |
87 | // MSVC requires that we explicitly declare these two as well. |
88 | bool operator==(MCPhysReg Other) const { return Reg == unsigned(Other); } |
89 | bool operator!=(MCPhysReg Other) const { return Reg != unsigned(Other); } |
90 | }; |
91 | |
92 | // Provide DenseMapInfo for MCRegister |
93 | template<> struct DenseMapInfo<MCRegister> { |
94 | static inline unsigned getEmptyKey() { |
95 | return DenseMapInfo<unsigned>::getEmptyKey(); |
96 | } |
97 | static inline unsigned getTombstoneKey() { |
98 | return DenseMapInfo<unsigned>::getTombstoneKey(); |
99 | } |
100 | static unsigned getHashValue(const MCRegister &Val) { |
101 | return DenseMapInfo<unsigned>::getHashValue(Val.id()); |
102 | } |
103 | static bool isEqual(const MCRegister &LHS, const MCRegister &RHS) { |
104 | return DenseMapInfo<unsigned>::isEqual(LHS.id(), RHS.id()); |
105 | } |
106 | }; |
107 | |
108 | } |
109 | |
110 | #endif // ifndef LLVM_MC_REGISTER_H |
1 | //===- MC/MCRegisterInfo.h - Target Register Description --------*- 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 | // This file describes an abstract interface used to get information about a |
10 | // target machines register file. This information is used for a variety of |
11 | // purposed, especially register allocation. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_MC_MCREGISTERINFO_H |
16 | #define LLVM_MC_MCREGISTERINFO_H |
17 | |
18 | #include "llvm/ADT/DenseMap.h" |
19 | #include "llvm/ADT/iterator.h" |
20 | #include "llvm/ADT/iterator_range.h" |
21 | #include "llvm/MC/LaneBitmask.h" |
22 | #include "llvm/MC/MCRegister.h" |
23 | #include <cassert> |
24 | #include <cstdint> |
25 | #include <iterator> |
26 | #include <utility> |
27 | |
28 | namespace llvm { |
29 | |
30 | /// MCRegisterClass - Base class of TargetRegisterClass. |
31 | class MCRegisterClass { |
32 | public: |
33 | using iterator = const MCPhysReg*; |
34 | using const_iterator = const MCPhysReg*; |
35 | |
36 | const iterator RegsBegin; |
37 | const uint8_t *const RegSet; |
38 | const uint32_t NameIdx; |
39 | const uint16_t RegsSize; |
40 | const uint16_t RegSetSize; |
41 | const uint16_t ID; |
42 | const int8_t CopyCost; |
43 | const bool Allocatable; |
44 | |
45 | /// getID() - Return the register class ID number. |
46 | /// |
47 | unsigned getID() const { return ID; } |
48 | |
49 | /// begin/end - Return all of the registers in this class. |
50 | /// |
51 | iterator begin() const { return RegsBegin; } |
52 | iterator end() const { return RegsBegin + RegsSize; } |
53 | |
54 | /// getNumRegs - Return the number of registers in this class. |
55 | /// |
56 | unsigned getNumRegs() const { return RegsSize; } |
57 | |
58 | /// getRegister - Return the specified register in the class. |
59 | /// |
60 | unsigned getRegister(unsigned i) const { |
61 | assert(i < getNumRegs() && "Register number out of range!")((i < getNumRegs() && "Register number out of range!" ) ? static_cast<void> (0) : __assert_fail ("i < getNumRegs() && \"Register number out of range!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 61, __PRETTY_FUNCTION__)); |
62 | return RegsBegin[i]; |
63 | } |
64 | |
65 | /// contains - Return true if the specified register is included in this |
66 | /// register class. This does not include virtual registers. |
67 | bool contains(MCRegister Reg) const { |
68 | unsigned RegNo = unsigned(Reg); |
69 | unsigned InByte = RegNo % 8; |
70 | unsigned Byte = RegNo / 8; |
71 | if (Byte >= RegSetSize) |
72 | return false; |
73 | return (RegSet[Byte] & (1 << InByte)) != 0; |
74 | } |
75 | |
76 | /// contains - Return true if both registers are in this class. |
77 | bool contains(MCRegister Reg1, MCRegister Reg2) const { |
78 | return contains(Reg1) && contains(Reg2); |
79 | } |
80 | |
81 | /// getCopyCost - Return the cost of copying a value between two registers in |
82 | /// this class. A negative number means the register class is very expensive |
83 | /// to copy e.g. status flag register classes. |
84 | int getCopyCost() const { return CopyCost; } |
85 | |
86 | /// isAllocatable - Return true if this register class may be used to create |
87 | /// virtual registers. |
88 | bool isAllocatable() const { return Allocatable; } |
89 | }; |
90 | |
91 | /// MCRegisterDesc - This record contains information about a particular |
92 | /// register. The SubRegs field is a zero terminated array of registers that |
93 | /// are sub-registers of the specific register, e.g. AL, AH are sub-registers |
94 | /// of AX. The SuperRegs field is a zero terminated array of registers that are |
95 | /// super-registers of the specific register, e.g. RAX, EAX, are |
96 | /// super-registers of AX. |
97 | /// |
98 | struct MCRegisterDesc { |
99 | uint32_t Name; // Printable name for the reg (for debugging) |
100 | uint32_t SubRegs; // Sub-register set, described above |
101 | uint32_t SuperRegs; // Super-register set, described above |
102 | |
103 | // Offset into MCRI::SubRegIndices of a list of sub-register indices for each |
104 | // sub-register in SubRegs. |
105 | uint32_t SubRegIndices; |
106 | |
107 | // RegUnits - Points to the list of register units. The low 4 bits holds the |
108 | // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator. |
109 | uint32_t RegUnits; |
110 | |
111 | /// Index into list with lane mask sequences. The sequence contains a lanemask |
112 | /// for every register unit. |
113 | uint16_t RegUnitLaneMasks; |
114 | }; |
115 | |
116 | /// MCRegisterInfo base class - We assume that the target defines a static |
117 | /// array of MCRegisterDesc objects that represent all of the machine |
118 | /// registers that the target has. As such, we simply have to track a pointer |
119 | /// to this array so that we can turn register number into a register |
120 | /// descriptor. |
121 | /// |
122 | /// Note this class is designed to be a base class of TargetRegisterInfo, which |
123 | /// is the interface used by codegen. However, specific targets *should never* |
124 | /// specialize this class. MCRegisterInfo should only contain getters to access |
125 | /// TableGen generated physical register data. It must not be extended with |
126 | /// virtual methods. |
127 | /// |
128 | class MCRegisterInfo { |
129 | public: |
130 | using regclass_iterator = const MCRegisterClass *; |
131 | |
132 | /// DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be |
133 | /// performed with a binary search. |
134 | struct DwarfLLVMRegPair { |
135 | unsigned FromReg; |
136 | unsigned ToReg; |
137 | |
138 | bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; } |
139 | }; |
140 | |
141 | /// SubRegCoveredBits - Emitted by tablegen: bit range covered by a subreg |
142 | /// index, -1 in any being invalid. |
143 | struct SubRegCoveredBits { |
144 | uint16_t Offset; |
145 | uint16_t Size; |
146 | }; |
147 | |
148 | private: |
149 | const MCRegisterDesc *Desc; // Pointer to the descriptor array |
150 | unsigned NumRegs; // Number of entries in the array |
151 | MCRegister RAReg; // Return address register |
152 | MCRegister PCReg; // Program counter register |
153 | const MCRegisterClass *Classes; // Pointer to the regclass array |
154 | unsigned NumClasses; // Number of entries in the array |
155 | unsigned NumRegUnits; // Number of regunits. |
156 | const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table. |
157 | const MCPhysReg *DiffLists; // Pointer to the difflists array |
158 | const LaneBitmask *RegUnitMaskSequences; // Pointer to lane mask sequences |
159 | // for register units. |
160 | const char *RegStrings; // Pointer to the string table. |
161 | const char *RegClassStrings; // Pointer to the class strings. |
162 | const uint16_t *SubRegIndices; // Pointer to the subreg lookup |
163 | // array. |
164 | const SubRegCoveredBits *SubRegIdxRanges; // Pointer to the subreg covered |
165 | // bit ranges array. |
166 | unsigned NumSubRegIndices; // Number of subreg indices. |
167 | const uint16_t *RegEncodingTable; // Pointer to array of register |
168 | // encodings. |
169 | |
170 | unsigned L2DwarfRegsSize; |
171 | unsigned EHL2DwarfRegsSize; |
172 | unsigned Dwarf2LRegsSize; |
173 | unsigned EHDwarf2LRegsSize; |
174 | const DwarfLLVMRegPair *L2DwarfRegs; // LLVM to Dwarf regs mapping |
175 | const DwarfLLVMRegPair *EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH |
176 | const DwarfLLVMRegPair *Dwarf2LRegs; // Dwarf to LLVM regs mapping |
177 | const DwarfLLVMRegPair *EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH |
178 | DenseMap<MCRegister, int> L2SEHRegs; // LLVM to SEH regs mapping |
179 | DenseMap<MCRegister, int> L2CVRegs; // LLVM to CV regs mapping |
180 | |
181 | public: |
182 | // Forward declaration to become a friend class of DiffListIterator. |
183 | template <class SubT> class mc_difflist_iterator; |
184 | |
185 | /// DiffListIterator - Base iterator class that can traverse the |
186 | /// differentially encoded register and regunit lists in DiffLists. |
187 | /// Don't use this class directly, use one of the specialized sub-classes |
188 | /// defined below. |
189 | class DiffListIterator { |
190 | uint16_t Val = 0; |
191 | const MCPhysReg *List = nullptr; |
192 | |
193 | protected: |
194 | /// Create an invalid iterator. Call init() to point to something useful. |
195 | DiffListIterator() = default; |
196 | |
197 | /// init - Point the iterator to InitVal, decoding subsequent values from |
198 | /// DiffList. The iterator will initially point to InitVal, sub-classes are |
199 | /// responsible for skipping the seed value if it is not part of the list. |
200 | void init(MCPhysReg InitVal, const MCPhysReg *DiffList) { |
201 | Val = InitVal; |
202 | List = DiffList; |
203 | } |
204 | |
205 | /// advance - Move to the next list position, return the applied |
206 | /// differential. This function does not detect the end of the list, that |
207 | /// is the caller's responsibility (by checking for a 0 return value). |
208 | MCRegister advance() { |
209 | assert(isValid() && "Cannot move off the end of the list.")((isValid() && "Cannot move off the end of the list." ) ? static_cast<void> (0) : __assert_fail ("isValid() && \"Cannot move off the end of the list.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 209, __PRETTY_FUNCTION__)); |
210 | MCPhysReg D = *List++; |
211 | Val += D; |
212 | return D; |
213 | } |
214 | |
215 | public: |
216 | /// isValid - returns true if this iterator is not yet at the end. |
217 | bool isValid() const { return List; } |
218 | |
219 | /// Dereference the iterator to get the value at the current position. |
220 | MCRegister operator*() const { return Val; } |
221 | |
222 | /// Pre-increment to move to the next position. |
223 | void operator++() { |
224 | // The end of the list is encoded as a 0 differential. |
225 | if (!advance()) |
226 | List = nullptr; |
227 | } |
228 | |
229 | template <class SubT> friend class MCRegisterInfo::mc_difflist_iterator; |
230 | }; |
231 | |
232 | /// Forward iterator using DiffListIterator. |
233 | template <class SubT> |
234 | class mc_difflist_iterator |
235 | : public iterator_facade_base<mc_difflist_iterator<SubT>, |
236 | std::forward_iterator_tag, MCPhysReg> { |
237 | MCRegisterInfo::DiffListIterator Iter; |
238 | /// Current value as MCPhysReg, so we can return a reference to it. |
239 | MCPhysReg Val; |
240 | |
241 | protected: |
242 | mc_difflist_iterator(MCRegisterInfo::DiffListIterator Iter) : Iter(Iter) {} |
243 | |
244 | // Allow conversion between instantiations where valid. |
245 | mc_difflist_iterator(MCRegister Reg, const MCPhysReg *DiffList) { |
246 | Iter.init(Reg, DiffList); |
247 | Val = *Iter; |
248 | } |
249 | |
250 | public: |
251 | // Allow default construction to build variables, but this doesn't build |
252 | // a useful iterator. |
253 | mc_difflist_iterator() = default; |
254 | |
255 | /// Return an iterator past the last element. |
256 | static SubT end() { |
257 | SubT End; |
258 | End.Iter.List = nullptr; |
259 | return End; |
260 | } |
261 | |
262 | bool operator==(const mc_difflist_iterator &Arg) const { |
263 | return Iter.List == Arg.Iter.List; |
264 | } |
265 | |
266 | const MCPhysReg &operator*() const { return Val; } |
267 | |
268 | using mc_difflist_iterator::iterator_facade_base::operator++; |
269 | void operator++() { |
270 | assert(Iter.List && "Cannot increment the end iterator!")((Iter.List && "Cannot increment the end iterator!") ? static_cast<void> (0) : __assert_fail ("Iter.List && \"Cannot increment the end iterator!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 270, __PRETTY_FUNCTION__)); |
271 | ++Iter; |
272 | Val = *Iter; |
273 | } |
274 | }; |
275 | |
276 | /// Forward iterator over all sub-registers. |
277 | /// TODO: Replace remaining uses of MCSubRegIterator. |
278 | class mc_subreg_iterator : public mc_difflist_iterator<mc_subreg_iterator> { |
279 | public: |
280 | mc_subreg_iterator(MCRegisterInfo::DiffListIterator Iter) |
281 | : mc_difflist_iterator(Iter) {} |
282 | mc_subreg_iterator() = default; |
283 | mc_subreg_iterator(MCRegister Reg, const MCRegisterInfo *MCRI) |
284 | : mc_difflist_iterator(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs) {} |
285 | }; |
286 | |
287 | /// Forward iterator over all super-registers. |
288 | /// TODO: Replace remaining uses of MCSuperRegIterator. |
289 | class mc_superreg_iterator |
290 | : public mc_difflist_iterator<mc_superreg_iterator> { |
291 | public: |
292 | mc_superreg_iterator(MCRegisterInfo::DiffListIterator Iter) |
293 | : mc_difflist_iterator(Iter) {} |
294 | mc_superreg_iterator() = default; |
295 | mc_superreg_iterator(MCRegister Reg, const MCRegisterInfo *MCRI) |
296 | : mc_difflist_iterator(Reg, |
297 | MCRI->DiffLists + MCRI->get(Reg).SuperRegs) {} |
298 | }; |
299 | |
300 | /// Return an iterator range over all sub-registers of \p Reg, excluding \p |
301 | /// Reg. |
302 | iterator_range<mc_subreg_iterator> subregs(MCRegister Reg) const { |
303 | return make_range(std::next(mc_subreg_iterator(Reg, this)), |
304 | mc_subreg_iterator::end()); |
305 | } |
306 | |
307 | /// Return an iterator range over all sub-registers of \p Reg, including \p |
308 | /// Reg. |
309 | iterator_range<mc_subreg_iterator> subregs_inclusive(MCRegister Reg) const { |
310 | return make_range({Reg, this}, mc_subreg_iterator::end()); |
311 | } |
312 | |
313 | /// Return an iterator range over all super-registers of \p Reg, excluding \p |
314 | /// Reg. |
315 | iterator_range<mc_superreg_iterator> superregs(MCRegister Reg) const { |
316 | return make_range(std::next(mc_superreg_iterator(Reg, this)), |
317 | mc_superreg_iterator::end()); |
318 | } |
319 | |
320 | /// Return an iterator range over all super-registers of \p Reg, including \p |
321 | /// Reg. |
322 | iterator_range<mc_superreg_iterator> |
323 | superregs_inclusive(MCRegister Reg) const { |
324 | return make_range({Reg, this}, mc_superreg_iterator::end()); |
325 | } |
326 | |
327 | /// Return an iterator range over all sub- and super-registers of \p Reg, |
328 | /// including \p Reg. |
329 | detail::concat_range<const MCPhysReg, iterator_range<mc_subreg_iterator>, |
330 | iterator_range<mc_superreg_iterator>> |
331 | sub_and_superregs_inclusive(MCRegister Reg) const { |
332 | return concat<const MCPhysReg>(subregs_inclusive(Reg), superregs(Reg)); |
333 | } |
334 | |
335 | // These iterators are allowed to sub-class DiffListIterator and access |
336 | // internal list pointers. |
337 | friend class MCSubRegIterator; |
338 | friend class MCSubRegIndexIterator; |
339 | friend class MCSuperRegIterator; |
340 | friend class MCRegUnitIterator; |
341 | friend class MCRegUnitMaskIterator; |
342 | friend class MCRegUnitRootIterator; |
343 | |
344 | /// Initialize MCRegisterInfo, called by TableGen |
345 | /// auto-generated routines. *DO NOT USE*. |
346 | void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, |
347 | unsigned PC, |
348 | const MCRegisterClass *C, unsigned NC, |
349 | const MCPhysReg (*RURoots)[2], |
350 | unsigned NRU, |
351 | const MCPhysReg *DL, |
352 | const LaneBitmask *RUMS, |
353 | const char *Strings, |
354 | const char *ClassStrings, |
355 | const uint16_t *SubIndices, |
356 | unsigned NumIndices, |
357 | const SubRegCoveredBits *SubIdxRanges, |
358 | const uint16_t *RET) { |
359 | Desc = D; |
360 | NumRegs = NR; |
361 | RAReg = RA; |
362 | PCReg = PC; |
363 | Classes = C; |
364 | DiffLists = DL; |
365 | RegUnitMaskSequences = RUMS; |
366 | RegStrings = Strings; |
367 | RegClassStrings = ClassStrings; |
368 | NumClasses = NC; |
369 | RegUnitRoots = RURoots; |
370 | NumRegUnits = NRU; |
371 | SubRegIndices = SubIndices; |
372 | NumSubRegIndices = NumIndices; |
373 | SubRegIdxRanges = SubIdxRanges; |
374 | RegEncodingTable = RET; |
375 | |
376 | // Initialize DWARF register mapping variables |
377 | EHL2DwarfRegs = nullptr; |
378 | EHL2DwarfRegsSize = 0; |
379 | L2DwarfRegs = nullptr; |
380 | L2DwarfRegsSize = 0; |
381 | EHDwarf2LRegs = nullptr; |
382 | EHDwarf2LRegsSize = 0; |
383 | Dwarf2LRegs = nullptr; |
384 | Dwarf2LRegsSize = 0; |
385 | } |
386 | |
387 | /// Used to initialize LLVM register to Dwarf |
388 | /// register number mapping. Called by TableGen auto-generated routines. |
389 | /// *DO NOT USE*. |
390 | void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size, |
391 | bool isEH) { |
392 | if (isEH) { |
393 | EHL2DwarfRegs = Map; |
394 | EHL2DwarfRegsSize = Size; |
395 | } else { |
396 | L2DwarfRegs = Map; |
397 | L2DwarfRegsSize = Size; |
398 | } |
399 | } |
400 | |
401 | /// Used to initialize Dwarf register to LLVM |
402 | /// register number mapping. Called by TableGen auto-generated routines. |
403 | /// *DO NOT USE*. |
404 | void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size, |
405 | bool isEH) { |
406 | if (isEH) { |
407 | EHDwarf2LRegs = Map; |
408 | EHDwarf2LRegsSize = Size; |
409 | } else { |
410 | Dwarf2LRegs = Map; |
411 | Dwarf2LRegsSize = Size; |
412 | } |
413 | } |
414 | |
415 | /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register |
416 | /// number mapping. By default the SEH register number is just the same |
417 | /// as the LLVM register number. |
418 | /// FIXME: TableGen these numbers. Currently this requires target specific |
419 | /// initialization code. |
420 | void mapLLVMRegToSEHReg(MCRegister LLVMReg, int SEHReg) { |
421 | L2SEHRegs[LLVMReg] = SEHReg; |
422 | } |
423 | |
424 | void mapLLVMRegToCVReg(MCRegister LLVMReg, int CVReg) { |
425 | L2CVRegs[LLVMReg] = CVReg; |
426 | } |
427 | |
428 | /// This method should return the register where the return |
429 | /// address can be found. |
430 | MCRegister getRARegister() const { |
431 | return RAReg; |
432 | } |
433 | |
434 | /// Return the register which is the program counter. |
435 | MCRegister getProgramCounter() const { |
436 | return PCReg; |
437 | } |
438 | |
439 | const MCRegisterDesc &operator[](MCRegister RegNo) const { |
440 | assert(RegNo < NumRegs &&((RegNo < NumRegs && "Attempting to access record for invalid register number!" ) ? static_cast<void> (0) : __assert_fail ("RegNo < NumRegs && \"Attempting to access record for invalid register number!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 441, __PRETTY_FUNCTION__)) |
441 | "Attempting to access record for invalid register number!")((RegNo < NumRegs && "Attempting to access record for invalid register number!" ) ? static_cast<void> (0) : __assert_fail ("RegNo < NumRegs && \"Attempting to access record for invalid register number!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 441, __PRETTY_FUNCTION__)); |
442 | return Desc[RegNo]; |
443 | } |
444 | |
445 | /// Provide a get method, equivalent to [], but more useful with a |
446 | /// pointer to this object. |
447 | const MCRegisterDesc &get(MCRegister RegNo) const { |
448 | return operator[](RegNo); |
449 | } |
450 | |
451 | /// Returns the physical register number of sub-register "Index" |
452 | /// for physical register RegNo. Return zero if the sub-register does not |
453 | /// exist. |
454 | MCRegister getSubReg(MCRegister Reg, unsigned Idx) const; |
455 | |
456 | /// Return a super-register of the specified register |
457 | /// Reg so its sub-register of index SubIdx is Reg. |
458 | MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, |
459 | const MCRegisterClass *RC) const; |
460 | |
461 | /// For a given register pair, return the sub-register index |
462 | /// if the second register is a sub-register of the first. Return zero |
463 | /// otherwise. |
464 | unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const; |
465 | |
466 | /// Get the size of the bit range covered by a sub-register index. |
467 | /// If the index isn't continuous, return the sum of the sizes of its parts. |
468 | /// If the index is used to access subregisters of different sizes, return -1. |
469 | unsigned getSubRegIdxSize(unsigned Idx) const; |
470 | |
471 | /// Get the offset of the bit range covered by a sub-register index. |
472 | /// If an Offset doesn't make sense (the index isn't continuous, or is used to |
473 | /// access sub-registers at different offsets), return -1. |
474 | unsigned getSubRegIdxOffset(unsigned Idx) const; |
475 | |
476 | /// Return the human-readable symbolic target-specific name for the |
477 | /// specified physical register. |
478 | const char *getName(MCRegister RegNo) const { |
479 | return RegStrings + get(RegNo).Name; |
480 | } |
481 | |
482 | /// Return the number of registers this target has (useful for |
483 | /// sizing arrays holding per register information) |
484 | unsigned getNumRegs() const { |
485 | return NumRegs; |
486 | } |
487 | |
488 | /// Return the number of sub-register indices |
489 | /// understood by the target. Index 0 is reserved for the no-op sub-register, |
490 | /// while 1 to getNumSubRegIndices() - 1 represent real sub-registers. |
491 | unsigned getNumSubRegIndices() const { |
492 | return NumSubRegIndices; |
493 | } |
494 | |
495 | /// Return the number of (native) register units in the |
496 | /// target. Register units are numbered from 0 to getNumRegUnits() - 1. They |
497 | /// can be accessed through MCRegUnitIterator defined below. |
498 | unsigned getNumRegUnits() const { |
499 | return NumRegUnits; |
500 | } |
501 | |
502 | /// Map a target register to an equivalent dwarf register |
503 | /// number. Returns -1 if there is no equivalent value. The second |
504 | /// parameter allows targets to use different numberings for EH info and |
505 | /// debugging info. |
506 | int getDwarfRegNum(MCRegister RegNum, bool isEH) const; |
507 | |
508 | /// Map a dwarf register back to a target register. Returns None is there is |
509 | /// no mapping. |
510 | Optional<unsigned> getLLVMRegNum(unsigned RegNum, bool isEH) const; |
511 | |
512 | /// Map a target EH register number to an equivalent DWARF register |
513 | /// number. |
514 | int getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const; |
515 | |
516 | /// Map a target register to an equivalent SEH register |
517 | /// number. Returns LLVM register number if there is no equivalent value. |
518 | int getSEHRegNum(MCRegister RegNum) const; |
519 | |
520 | /// Map a target register to an equivalent CodeView register |
521 | /// number. |
522 | int getCodeViewRegNum(MCRegister RegNum) const; |
523 | |
524 | regclass_iterator regclass_begin() const { return Classes; } |
525 | regclass_iterator regclass_end() const { return Classes+NumClasses; } |
526 | iterator_range<regclass_iterator> regclasses() const { |
527 | return make_range(regclass_begin(), regclass_end()); |
528 | } |
529 | |
530 | unsigned getNumRegClasses() const { |
531 | return (unsigned)(regclass_end()-regclass_begin()); |
532 | } |
533 | |
534 | /// Returns the register class associated with the enumeration |
535 | /// value. See class MCOperandInfo. |
536 | const MCRegisterClass& getRegClass(unsigned i) const { |
537 | assert(i < getNumRegClasses() && "Register Class ID out of range")((i < getNumRegClasses() && "Register Class ID out of range" ) ? static_cast<void> (0) : __assert_fail ("i < getNumRegClasses() && \"Register Class ID out of range\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 537, __PRETTY_FUNCTION__)); |
538 | return Classes[i]; |
539 | } |
540 | |
541 | const char *getRegClassName(const MCRegisterClass *Class) const { |
542 | return RegClassStrings + Class->NameIdx; |
543 | } |
544 | |
545 | /// Returns the encoding for RegNo |
546 | uint16_t getEncodingValue(MCRegister RegNo) const { |
547 | assert(RegNo < NumRegs &&((RegNo < NumRegs && "Attempting to get encoding for invalid register number!" ) ? static_cast<void> (0) : __assert_fail ("RegNo < NumRegs && \"Attempting to get encoding for invalid register number!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 548, __PRETTY_FUNCTION__)) |
548 | "Attempting to get encoding for invalid register number!")((RegNo < NumRegs && "Attempting to get encoding for invalid register number!" ) ? static_cast<void> (0) : __assert_fail ("RegNo < NumRegs && \"Attempting to get encoding for invalid register number!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 548, __PRETTY_FUNCTION__)); |
549 | return RegEncodingTable[RegNo]; |
550 | } |
551 | |
552 | /// Returns true if RegB is a sub-register of RegA. |
553 | bool isSubRegister(MCRegister RegA, MCRegister RegB) const { |
554 | return isSuperRegister(RegB, RegA); |
555 | } |
556 | |
557 | /// Returns true if RegB is a super-register of RegA. |
558 | bool isSuperRegister(MCRegister RegA, MCRegister RegB) const; |
559 | |
560 | /// Returns true if RegB is a sub-register of RegA or if RegB == RegA. |
561 | bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const { |
562 | return isSuperRegisterEq(RegB, RegA); |
563 | } |
564 | |
565 | /// Returns true if RegB is a super-register of RegA or if |
566 | /// RegB == RegA. |
567 | bool isSuperRegisterEq(MCRegister RegA, MCRegister RegB) const { |
568 | return RegA == RegB || isSuperRegister(RegA, RegB); |
569 | } |
570 | |
571 | /// Returns true if RegB is a super-register or sub-register of RegA |
572 | /// or if RegB == RegA. |
573 | bool isSuperOrSubRegisterEq(MCRegister RegA, MCRegister RegB) const { |
574 | return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB); |
575 | } |
576 | }; |
577 | |
578 | //===----------------------------------------------------------------------===// |
579 | // Register List Iterators |
580 | //===----------------------------------------------------------------------===// |
581 | |
582 | // MCRegisterInfo provides lists of super-registers, sub-registers, and |
583 | // aliasing registers. Use these iterator classes to traverse the lists. |
584 | |
585 | /// MCSubRegIterator enumerates all sub-registers of Reg. |
586 | /// If IncludeSelf is set, Reg itself is included in the list. |
587 | class MCSubRegIterator : public MCRegisterInfo::DiffListIterator { |
588 | public: |
589 | MCSubRegIterator(MCRegister Reg, const MCRegisterInfo *MCRI, |
590 | bool IncludeSelf = false) { |
591 | init(Reg, MCRI->DiffLists + MCRI->get(Reg).SubRegs); |
592 | // Initially, the iterator points to Reg itself. |
593 | if (!IncludeSelf) |
594 | ++*this; |
595 | } |
596 | }; |
597 | |
598 | /// Iterator that enumerates the sub-registers of a Reg and the associated |
599 | /// sub-register indices. |
600 | class MCSubRegIndexIterator { |
601 | MCSubRegIterator SRIter; |
602 | const uint16_t *SRIndex; |
603 | |
604 | public: |
605 | /// Constructs an iterator that traverses subregisters and their |
606 | /// associated subregister indices. |
607 | MCSubRegIndexIterator(MCRegister Reg, const MCRegisterInfo *MCRI) |
608 | : SRIter(Reg, MCRI) { |
609 | SRIndex = MCRI->SubRegIndices + MCRI->get(Reg).SubRegIndices; |
610 | } |
611 | |
612 | /// Returns current sub-register. |
613 | MCRegister getSubReg() const { |
614 | return *SRIter; |
615 | } |
616 | |
617 | /// Returns sub-register index of the current sub-register. |
618 | unsigned getSubRegIndex() const { |
619 | return *SRIndex; |
620 | } |
621 | |
622 | /// Returns true if this iterator is not yet at the end. |
623 | bool isValid() const { return SRIter.isValid(); } |
624 | |
625 | /// Moves to the next position. |
626 | void operator++() { |
627 | ++SRIter; |
628 | ++SRIndex; |
629 | } |
630 | }; |
631 | |
632 | /// MCSuperRegIterator enumerates all super-registers of Reg. |
633 | /// If IncludeSelf is set, Reg itself is included in the list. |
634 | class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator { |
635 | public: |
636 | MCSuperRegIterator() = default; |
637 | |
638 | MCSuperRegIterator(MCRegister Reg, const MCRegisterInfo *MCRI, |
639 | bool IncludeSelf = false) { |
640 | init(Reg, MCRI->DiffLists + MCRI->get(Reg).SuperRegs); |
641 | // Initially, the iterator points to Reg itself. |
642 | if (!IncludeSelf) |
643 | ++*this; |
644 | } |
645 | }; |
646 | |
647 | // Definition for isSuperRegister. Put it down here since it needs the |
648 | // iterator defined above in addition to the MCRegisterInfo class itself. |
649 | inline bool MCRegisterInfo::isSuperRegister(MCRegister RegA, MCRegister RegB) const{ |
650 | for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I) |
651 | if (*I == RegB) |
652 | return true; |
653 | return false; |
654 | } |
655 | |
656 | //===----------------------------------------------------------------------===// |
657 | // Register Units |
658 | //===----------------------------------------------------------------------===// |
659 | |
660 | // Register units are used to compute register aliasing. Every register has at |
661 | // least one register unit, but it can have more. Two registers overlap if and |
662 | // only if they have a common register unit. |
663 | // |
664 | // A target with a complicated sub-register structure will typically have many |
665 | // fewer register units than actual registers. MCRI::getNumRegUnits() returns |
666 | // the number of register units in the target. |
667 | |
668 | // MCRegUnitIterator enumerates a list of register units for Reg. The list is |
669 | // in ascending numerical order. |
670 | class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator { |
671 | public: |
672 | /// MCRegUnitIterator - Create an iterator that traverses the register units |
673 | /// in Reg. |
674 | MCRegUnitIterator() = default; |
675 | |
676 | MCRegUnitIterator(MCRegister Reg, const MCRegisterInfo *MCRI) { |
677 | assert(Reg && "Null register has no regunits")((Reg && "Null register has no regunits") ? static_cast <void> (0) : __assert_fail ("Reg && \"Null register has no regunits\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 677, __PRETTY_FUNCTION__)); |
678 | // Decode the RegUnits MCRegisterDesc field. |
679 | unsigned RU = MCRI->get(Reg).RegUnits; |
680 | unsigned Scale = RU & 15; |
681 | unsigned Offset = RU >> 4; |
682 | |
683 | // Initialize the iterator to Reg * Scale, and the List pointer to |
684 | // DiffLists + Offset. |
685 | init(Reg * Scale, MCRI->DiffLists + Offset); |
686 | |
687 | // That may not be a valid unit, we need to advance by one to get the real |
688 | // unit number. The first differential can be 0 which would normally |
689 | // terminate the list, but since we know every register has at least one |
690 | // unit, we can allow a 0 differential here. |
691 | advance(); |
692 | } |
693 | }; |
694 | |
695 | /// MCRegUnitMaskIterator enumerates a list of register units and their |
696 | /// associated lane masks for Reg. The register units are in ascending |
697 | /// numerical order. |
698 | class MCRegUnitMaskIterator { |
699 | MCRegUnitIterator RUIter; |
700 | const LaneBitmask *MaskListIter; |
701 | |
702 | public: |
703 | MCRegUnitMaskIterator() = default; |
704 | |
705 | /// Constructs an iterator that traverses the register units and their |
706 | /// associated LaneMasks in Reg. |
707 | MCRegUnitMaskIterator(MCRegister Reg, const MCRegisterInfo *MCRI) |
708 | : RUIter(Reg, MCRI) { |
709 | uint16_t Idx = MCRI->get(Reg).RegUnitLaneMasks; |
710 | MaskListIter = &MCRI->RegUnitMaskSequences[Idx]; |
711 | } |
712 | |
713 | /// Returns a (RegUnit, LaneMask) pair. |
714 | std::pair<unsigned,LaneBitmask> operator*() const { |
715 | return std::make_pair(*RUIter, *MaskListIter); |
716 | } |
717 | |
718 | /// Returns true if this iterator is not yet at the end. |
719 | bool isValid() const { return RUIter.isValid(); } |
720 | |
721 | /// Moves to the next position. |
722 | void operator++() { |
723 | ++MaskListIter; |
724 | ++RUIter; |
725 | } |
726 | }; |
727 | |
728 | // Each register unit has one or two root registers. The complete set of |
729 | // registers containing a register unit is the union of the roots and their |
730 | // super-registers. All registers aliasing Unit can be visited like this: |
731 | // |
732 | // for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) { |
733 | // for (MCSuperRegIterator SI(*RI, MCRI, true); SI.isValid(); ++SI) |
734 | // visit(*SI); |
735 | // } |
736 | |
737 | /// MCRegUnitRootIterator enumerates the root registers of a register unit. |
738 | class MCRegUnitRootIterator { |
739 | uint16_t Reg0 = 0; |
740 | uint16_t Reg1 = 0; |
741 | |
742 | public: |
743 | MCRegUnitRootIterator() = default; |
744 | |
745 | MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) { |
746 | assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit")((RegUnit < MCRI->getNumRegUnits() && "Invalid register unit" ) ? static_cast<void> (0) : __assert_fail ("RegUnit < MCRI->getNumRegUnits() && \"Invalid register unit\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 746, __PRETTY_FUNCTION__)); |
747 | Reg0 = MCRI->RegUnitRoots[RegUnit][0]; |
748 | Reg1 = MCRI->RegUnitRoots[RegUnit][1]; |
749 | } |
750 | |
751 | /// Dereference to get the current root register. |
752 | unsigned operator*() const { |
753 | return Reg0; |
754 | } |
755 | |
756 | /// Check if the iterator is at the end of the list. |
757 | bool isValid() const { |
758 | return Reg0; |
759 | } |
760 | |
761 | /// Preincrement to move to the next root register. |
762 | void operator++() { |
763 | assert(isValid() && "Cannot move off the end of the list.")((isValid() && "Cannot move off the end of the list." ) ? static_cast<void> (0) : __assert_fail ("isValid() && \"Cannot move off the end of the list.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 763, __PRETTY_FUNCTION__)); |
764 | Reg0 = Reg1; |
765 | Reg1 = 0; |
766 | } |
767 | }; |
768 | |
769 | /// MCRegAliasIterator enumerates all registers aliasing Reg. If IncludeSelf is |
770 | /// set, Reg itself is included in the list. This iterator does not guarantee |
771 | /// any ordering or that entries are unique. |
772 | class MCRegAliasIterator { |
773 | private: |
774 | MCRegister Reg; |
775 | const MCRegisterInfo *MCRI; |
776 | bool IncludeSelf; |
777 | |
778 | MCRegUnitIterator RI; |
779 | MCRegUnitRootIterator RRI; |
780 | MCSuperRegIterator SI; |
781 | |
782 | public: |
783 | MCRegAliasIterator(MCRegister Reg, const MCRegisterInfo *MCRI, |
784 | bool IncludeSelf) |
785 | : Reg(Reg), MCRI(MCRI), IncludeSelf(IncludeSelf) { |
786 | // Initialize the iterators. |
787 | for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) { |
788 | for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) { |
789 | for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) { |
790 | if (!(!IncludeSelf && Reg == *SI)) |
791 | return; |
792 | } |
793 | } |
794 | } |
795 | } |
796 | |
797 | bool isValid() const { return RI.isValid(); } |
798 | |
799 | MCRegister operator*() const { |
800 | assert(SI.isValid() && "Cannot dereference an invalid iterator.")((SI.isValid() && "Cannot dereference an invalid iterator." ) ? static_cast<void> (0) : __assert_fail ("SI.isValid() && \"Cannot dereference an invalid iterator.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 800, __PRETTY_FUNCTION__)); |
801 | return *SI; |
802 | } |
803 | |
804 | void advance() { |
805 | // Assuming SI is valid. |
806 | ++SI; |
807 | if (SI.isValid()) return; |
808 | |
809 | ++RRI; |
810 | if (RRI.isValid()) { |
811 | SI = MCSuperRegIterator(*RRI, MCRI, true); |
812 | return; |
813 | } |
814 | |
815 | ++RI; |
816 | if (RI.isValid()) { |
817 | RRI = MCRegUnitRootIterator(*RI, MCRI); |
818 | SI = MCSuperRegIterator(*RRI, MCRI, true); |
819 | } |
820 | } |
821 | |
822 | void operator++() { |
823 | assert(isValid() && "Cannot move off the end of the list.")((isValid() && "Cannot move off the end of the list." ) ? static_cast<void> (0) : __assert_fail ("isValid() && \"Cannot move off the end of the list.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.h" , 823, __PRETTY_FUNCTION__)); |
824 | do advance(); |
825 | while (!IncludeSelf && isValid() && *SI == Reg); |
826 | } |
827 | }; |
828 | |
829 | } // end namespace llvm |
830 | |
831 | #endif // LLVM_MC_MCREGISTERINFO_H |
1 | //===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- 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 | // This file implements the SmallBitVector class. | ||||||||||
10 | // | ||||||||||
11 | //===----------------------------------------------------------------------===// | ||||||||||
12 | |||||||||||
13 | #ifndef LLVM_ADT_SMALLBITVECTOR_H | ||||||||||
14 | #define LLVM_ADT_SMALLBITVECTOR_H | ||||||||||
15 | |||||||||||
16 | #include "llvm/ADT/BitVector.h" | ||||||||||
17 | #include "llvm/ADT/iterator_range.h" | ||||||||||
18 | #include "llvm/Support/MathExtras.h" | ||||||||||
19 | #include <algorithm> | ||||||||||
20 | #include <cassert> | ||||||||||
21 | #include <climits> | ||||||||||
22 | #include <cstddef> | ||||||||||
23 | #include <cstdint> | ||||||||||
24 | #include <limits> | ||||||||||
25 | #include <utility> | ||||||||||
26 | |||||||||||
27 | namespace llvm { | ||||||||||
28 | |||||||||||
29 | /// This is a 'bitvector' (really, a variable-sized bit array), optimized for | ||||||||||
30 | /// the case when the array is small. It contains one pointer-sized field, which | ||||||||||
31 | /// is directly used as a plain collection of bits when possible, or as a | ||||||||||
32 | /// pointer to a larger heap-allocated array when necessary. This allows normal | ||||||||||
33 | /// "small" cases to be fast without losing generality for large inputs. | ||||||||||
34 | class SmallBitVector { | ||||||||||
35 | // TODO: In "large" mode, a pointer to a BitVector is used, leading to an | ||||||||||
36 | // unnecessary level of indirection. It would be more efficient to use a | ||||||||||
37 | // pointer to memory containing size, allocation size, and the array of bits. | ||||||||||
38 | uintptr_t X = 1; | ||||||||||
39 | |||||||||||
40 | enum { | ||||||||||
41 | // The number of bits in this class. | ||||||||||
42 | NumBaseBits = sizeof(uintptr_t) * CHAR_BIT8, | ||||||||||
43 | |||||||||||
44 | // One bit is used to discriminate between small and large mode. The | ||||||||||
45 | // remaining bits are used for the small-mode representation. | ||||||||||
46 | SmallNumRawBits = NumBaseBits - 1, | ||||||||||
47 | |||||||||||
48 | // A few more bits are used to store the size of the bit set in small mode. | ||||||||||
49 | // Theoretically this is a ceil-log2. These bits are encoded in the most | ||||||||||
50 | // significant bits of the raw bits. | ||||||||||
51 | SmallNumSizeBits = (NumBaseBits == 32 ? 5 : | ||||||||||
52 | NumBaseBits == 64 ? 6 : | ||||||||||
53 | SmallNumRawBits), | ||||||||||
54 | |||||||||||
55 | // The remaining bits are used to store the actual set in small mode. | ||||||||||
56 | SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits | ||||||||||
57 | }; | ||||||||||
58 | |||||||||||
59 | static_assert(NumBaseBits == 64 || NumBaseBits == 32, | ||||||||||
60 | "Unsupported word size"); | ||||||||||
61 | |||||||||||
62 | public: | ||||||||||
63 | using size_type = unsigned; | ||||||||||
64 | |||||||||||
65 | // Encapsulation of a single bit. | ||||||||||
66 | class reference { | ||||||||||
67 | SmallBitVector &TheVector; | ||||||||||
68 | unsigned BitPos; | ||||||||||
69 | |||||||||||
70 | public: | ||||||||||
71 | reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {} | ||||||||||
72 | |||||||||||
73 | reference(const reference&) = default; | ||||||||||
74 | |||||||||||
75 | reference& operator=(reference t) { | ||||||||||
76 | *this = bool(t); | ||||||||||
77 | return *this; | ||||||||||
78 | } | ||||||||||
79 | |||||||||||
80 | reference& operator=(bool t) { | ||||||||||
81 | if (t) | ||||||||||
82 | TheVector.set(BitPos); | ||||||||||
83 | else | ||||||||||
84 | TheVector.reset(BitPos); | ||||||||||
85 | return *this; | ||||||||||
86 | } | ||||||||||
87 | |||||||||||
88 | operator bool() const { | ||||||||||
89 | return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos); | ||||||||||
90 | } | ||||||||||
91 | }; | ||||||||||
92 | |||||||||||
93 | private: | ||||||||||
94 | BitVector *getPointer() const { | ||||||||||
95 | assert(!isSmall())((!isSmall()) ? static_cast<void> (0) : __assert_fail ( "!isSmall()", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 95, __PRETTY_FUNCTION__)); | ||||||||||
96 | return reinterpret_cast<BitVector *>(X); | ||||||||||
97 | } | ||||||||||
98 | |||||||||||
99 | void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) { | ||||||||||
100 | X = 1; | ||||||||||
101 | setSmallSize(NewSize); | ||||||||||
102 | setSmallBits(NewSmallBits); | ||||||||||
103 | } | ||||||||||
104 | |||||||||||
105 | void switchToLarge(BitVector *BV) { | ||||||||||
106 | X = reinterpret_cast<uintptr_t>(BV); | ||||||||||
107 | assert(!isSmall() && "Tried to use an unaligned pointer")((!isSmall() && "Tried to use an unaligned pointer") ? static_cast<void> (0) : __assert_fail ("!isSmall() && \"Tried to use an unaligned pointer\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 107, __PRETTY_FUNCTION__)); | ||||||||||
108 | } | ||||||||||
109 | |||||||||||
110 | // Return all the bits used for the "small" representation; this includes | ||||||||||
111 | // bits for the size as well as the element bits. | ||||||||||
112 | uintptr_t getSmallRawBits() const { | ||||||||||
113 | assert(isSmall())((isSmall()) ? static_cast<void> (0) : __assert_fail ("isSmall()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 113, __PRETTY_FUNCTION__)); | ||||||||||
114 | return X >> 1; | ||||||||||
115 | } | ||||||||||
116 | |||||||||||
117 | void setSmallRawBits(uintptr_t NewRawBits) { | ||||||||||
118 | assert(isSmall())((isSmall()) ? static_cast<void> (0) : __assert_fail ("isSmall()" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 118, __PRETTY_FUNCTION__)); | ||||||||||
119 | X = (NewRawBits << 1) | uintptr_t(1); | ||||||||||
120 | } | ||||||||||
121 | |||||||||||
122 | // Return the size. | ||||||||||
123 | size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; } | ||||||||||
124 | |||||||||||
125 | void setSmallSize(size_t Size) { | ||||||||||
126 | setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits)); | ||||||||||
127 | } | ||||||||||
128 | |||||||||||
129 | // Return the element bits. | ||||||||||
130 | uintptr_t getSmallBits() const { | ||||||||||
131 | return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize()); | ||||||||||
132 | } | ||||||||||
133 | |||||||||||
134 | void setSmallBits(uintptr_t NewBits) { | ||||||||||
135 | setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) | | ||||||||||
136 | (getSmallSize() << SmallNumDataBits)); | ||||||||||
137 | } | ||||||||||
138 | |||||||||||
139 | public: | ||||||||||
140 | /// Creates an empty bitvector. | ||||||||||
141 | SmallBitVector() = default; | ||||||||||
142 | |||||||||||
143 | /// Creates a bitvector of specified number of bits. All bits are initialized | ||||||||||
144 | /// to the specified value. | ||||||||||
145 | explicit SmallBitVector(unsigned s, bool t = false) { | ||||||||||
146 | if (s <= SmallNumDataBits) | ||||||||||
147 | switchToSmall(t ? ~uintptr_t(0) : 0, s); | ||||||||||
148 | else | ||||||||||
149 | switchToLarge(new BitVector(s, t)); | ||||||||||
150 | } | ||||||||||
151 | |||||||||||
152 | /// SmallBitVector copy ctor. | ||||||||||
153 | SmallBitVector(const SmallBitVector &RHS) { | ||||||||||
154 | if (RHS.isSmall()) | ||||||||||
155 | X = RHS.X; | ||||||||||
156 | else | ||||||||||
157 | switchToLarge(new BitVector(*RHS.getPointer())); | ||||||||||
158 | } | ||||||||||
159 | |||||||||||
160 | SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) { | ||||||||||
161 | RHS.X = 1; | ||||||||||
162 | } | ||||||||||
163 | |||||||||||
164 | ~SmallBitVector() { | ||||||||||
165 | if (!isSmall()) | ||||||||||
166 | delete getPointer(); | ||||||||||
167 | } | ||||||||||
168 | |||||||||||
169 | using const_set_bits_iterator = const_set_bits_iterator_impl<SmallBitVector>; | ||||||||||
170 | using set_iterator = const_set_bits_iterator; | ||||||||||
171 | |||||||||||
172 | const_set_bits_iterator set_bits_begin() const { | ||||||||||
173 | return const_set_bits_iterator(*this); | ||||||||||
174 | } | ||||||||||
175 | |||||||||||
176 | const_set_bits_iterator set_bits_end() const { | ||||||||||
177 | return const_set_bits_iterator(*this, -1); | ||||||||||
178 | } | ||||||||||
179 | |||||||||||
180 | iterator_range<const_set_bits_iterator> set_bits() const { | ||||||||||
181 | return make_range(set_bits_begin(), set_bits_end()); | ||||||||||
182 | } | ||||||||||
183 | |||||||||||
184 | bool isSmall() const { return X & uintptr_t(1); } | ||||||||||
185 | |||||||||||
186 | /// Tests whether there are no bits in this bitvector. | ||||||||||
187 | bool empty() const { | ||||||||||
188 | return isSmall() ? getSmallSize() == 0 : getPointer()->empty(); | ||||||||||
189 | } | ||||||||||
190 | |||||||||||
191 | /// Returns the number of bits in this bitvector. | ||||||||||
192 | size_t size() const { | ||||||||||
193 | return isSmall() ? getSmallSize() : getPointer()->size(); | ||||||||||
194 | } | ||||||||||
195 | |||||||||||
196 | /// Returns the number of bits which are set. | ||||||||||
197 | size_type count() const { | ||||||||||
198 | if (isSmall()) { | ||||||||||
199 | uintptr_t Bits = getSmallBits(); | ||||||||||
200 | return countPopulation(Bits); | ||||||||||
201 | } | ||||||||||
202 | return getPointer()->count(); | ||||||||||
203 | } | ||||||||||
204 | |||||||||||
205 | /// Returns true if any bit is set. | ||||||||||
206 | bool any() const { | ||||||||||
207 | if (isSmall()) | ||||||||||
208 | return getSmallBits() != 0; | ||||||||||
209 | return getPointer()->any(); | ||||||||||
210 | } | ||||||||||
211 | |||||||||||
212 | /// Returns true if all bits are set. | ||||||||||
213 | bool all() const { | ||||||||||
214 | if (isSmall()) | ||||||||||
215 | return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1; | ||||||||||
216 | return getPointer()->all(); | ||||||||||
217 | } | ||||||||||
218 | |||||||||||
219 | /// Returns true if none of the bits are set. | ||||||||||
220 | bool none() const { | ||||||||||
221 | if (isSmall()) | ||||||||||
222 | return getSmallBits() == 0; | ||||||||||
223 | return getPointer()->none(); | ||||||||||
224 | } | ||||||||||
225 | |||||||||||
226 | /// Returns the index of the first set bit, -1 if none of the bits are set. | ||||||||||
227 | int find_first() const { | ||||||||||
228 | if (isSmall()) { | ||||||||||
229 | uintptr_t Bits = getSmallBits(); | ||||||||||
230 | if (Bits == 0) | ||||||||||
231 | return -1; | ||||||||||
232 | return countTrailingZeros(Bits); | ||||||||||
233 | } | ||||||||||
234 | return getPointer()->find_first(); | ||||||||||
235 | } | ||||||||||
236 | |||||||||||
237 | int find_last() const { | ||||||||||
238 | if (isSmall()) { | ||||||||||
239 | uintptr_t Bits = getSmallBits(); | ||||||||||
240 | if (Bits == 0) | ||||||||||
241 | return -1; | ||||||||||
242 | return NumBaseBits - countLeadingZeros(Bits) - 1; | ||||||||||
243 | } | ||||||||||
244 | return getPointer()->find_last(); | ||||||||||
245 | } | ||||||||||
246 | |||||||||||
247 | /// Returns the index of the first unset bit, -1 if all of the bits are set. | ||||||||||
248 | int find_first_unset() const { | ||||||||||
249 | if (isSmall()) { | ||||||||||
250 | if (count() == getSmallSize()) | ||||||||||
251 | return -1; | ||||||||||
252 | |||||||||||
253 | uintptr_t Bits = getSmallBits(); | ||||||||||
254 | return countTrailingOnes(Bits); | ||||||||||
255 | } | ||||||||||
256 | return getPointer()->find_first_unset(); | ||||||||||
257 | } | ||||||||||
258 | |||||||||||
259 | int find_last_unset() const { | ||||||||||
260 | if (isSmall()) { | ||||||||||
261 | if (count() == getSmallSize()) | ||||||||||
262 | return -1; | ||||||||||
263 | |||||||||||
264 | uintptr_t Bits = getSmallBits(); | ||||||||||
265 | // Set unused bits. | ||||||||||
266 | Bits |= ~uintptr_t(0) << getSmallSize(); | ||||||||||
267 | return NumBaseBits - countLeadingOnes(Bits) - 1; | ||||||||||
268 | } | ||||||||||
269 | return getPointer()->find_last_unset(); | ||||||||||
270 | } | ||||||||||
271 | |||||||||||
272 | /// Returns the index of the next set bit following the "Prev" bit. | ||||||||||
273 | /// Returns -1 if the next set bit is not found. | ||||||||||
274 | int find_next(unsigned Prev) const { | ||||||||||
275 | if (isSmall()) { | ||||||||||
276 | uintptr_t Bits = getSmallBits(); | ||||||||||
277 | // Mask off previous bits. | ||||||||||
278 | Bits &= ~uintptr_t(0) << (Prev + 1); | ||||||||||
279 | if (Bits == 0 || Prev + 1 >= getSmallSize()) | ||||||||||
280 | return -1; | ||||||||||
281 | return countTrailingZeros(Bits); | ||||||||||
282 | } | ||||||||||
283 | return getPointer()->find_next(Prev); | ||||||||||
284 | } | ||||||||||
285 | |||||||||||
286 | /// Returns the index of the next unset bit following the "Prev" bit. | ||||||||||
287 | /// Returns -1 if the next unset bit is not found. | ||||||||||
288 | int find_next_unset(unsigned Prev) const { | ||||||||||
289 | if (isSmall()) { | ||||||||||
290 | ++Prev; | ||||||||||
291 | uintptr_t Bits = getSmallBits(); | ||||||||||
292 | // Mask in previous bits. | ||||||||||
293 | uintptr_t Mask = (uintptr_t(1) << Prev) - 1; | ||||||||||
294 | Bits |= Mask; | ||||||||||
295 | |||||||||||
296 | if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize()) | ||||||||||
297 | return -1; | ||||||||||
298 | return countTrailingOnes(Bits); | ||||||||||
299 | } | ||||||||||
300 | return getPointer()->find_next_unset(Prev); | ||||||||||
301 | } | ||||||||||
302 | |||||||||||
303 | /// find_prev - Returns the index of the first set bit that precedes the | ||||||||||
304 | /// the bit at \p PriorTo. Returns -1 if all previous bits are unset. | ||||||||||
305 | int find_prev(unsigned PriorTo) const { | ||||||||||
306 | if (isSmall()) { | ||||||||||
307 | if (PriorTo == 0) | ||||||||||
308 | return -1; | ||||||||||
309 | |||||||||||
310 | --PriorTo; | ||||||||||
311 | uintptr_t Bits = getSmallBits(); | ||||||||||
312 | Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1); | ||||||||||
313 | if (Bits == 0) | ||||||||||
314 | return -1; | ||||||||||
315 | |||||||||||
316 | return NumBaseBits - countLeadingZeros(Bits) - 1; | ||||||||||
317 | } | ||||||||||
318 | return getPointer()->find_prev(PriorTo); | ||||||||||
319 | } | ||||||||||
320 | |||||||||||
321 | /// Clear all bits. | ||||||||||
322 | void clear() { | ||||||||||
323 | if (!isSmall()) | ||||||||||
324 | delete getPointer(); | ||||||||||
325 | switchToSmall(0, 0); | ||||||||||
326 | } | ||||||||||
327 | |||||||||||
328 | /// Grow or shrink the bitvector. | ||||||||||
329 | void resize(unsigned N, bool t = false) { | ||||||||||
330 | if (!isSmall()) { | ||||||||||
331 | getPointer()->resize(N, t); | ||||||||||
332 | } else if (SmallNumDataBits >= N) { | ||||||||||
333 | uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0; | ||||||||||
334 | setSmallSize(N); | ||||||||||
335 | setSmallBits(NewBits | getSmallBits()); | ||||||||||
336 | } else { | ||||||||||
337 | BitVector *BV = new BitVector(N, t); | ||||||||||
338 | uintptr_t OldBits = getSmallBits(); | ||||||||||
339 | for (size_t i = 0, e = getSmallSize(); i != e; ++i) | ||||||||||
340 | (*BV)[i] = (OldBits >> i) & 1; | ||||||||||
341 | switchToLarge(BV); | ||||||||||
342 | } | ||||||||||
343 | } | ||||||||||
344 | |||||||||||
345 | void reserve(unsigned N) { | ||||||||||
346 | if (isSmall()) { | ||||||||||
347 | if (N > SmallNumDataBits) { | ||||||||||
348 | uintptr_t OldBits = getSmallRawBits(); | ||||||||||
349 | size_t SmallSize = getSmallSize(); | ||||||||||
350 | BitVector *BV = new BitVector(SmallSize); | ||||||||||
351 | for (size_t i = 0; i < SmallSize; ++i) | ||||||||||
352 | if ((OldBits >> i) & 1) | ||||||||||
353 | BV->set(i); | ||||||||||
354 | BV->reserve(N); | ||||||||||
355 | switchToLarge(BV); | ||||||||||
356 | } | ||||||||||
357 | } else { | ||||||||||
358 | getPointer()->reserve(N); | ||||||||||
359 | } | ||||||||||
360 | } | ||||||||||
361 | |||||||||||
362 | // Set, reset, flip | ||||||||||
363 | SmallBitVector &set() { | ||||||||||
364 | if (isSmall()) | ||||||||||
365 | setSmallBits(~uintptr_t(0)); | ||||||||||
366 | else | ||||||||||
367 | getPointer()->set(); | ||||||||||
368 | return *this; | ||||||||||
369 | } | ||||||||||
370 | |||||||||||
371 | SmallBitVector &set(unsigned Idx) { | ||||||||||
372 | if (isSmall()) { | ||||||||||
373 | assert(Idx <= static_cast<unsigned>(((Idx <= static_cast<unsigned>( std::numeric_limits< uintptr_t>::digits) && "undefined behavior") ? static_cast <void> (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 375, __PRETTY_FUNCTION__)) | ||||||||||
374 | std::numeric_limits<uintptr_t>::digits) &&((Idx <= static_cast<unsigned>( std::numeric_limits< uintptr_t>::digits) && "undefined behavior") ? static_cast <void> (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 375, __PRETTY_FUNCTION__)) | ||||||||||
375 | "undefined behavior")((Idx <= static_cast<unsigned>( std::numeric_limits< uintptr_t>::digits) && "undefined behavior") ? static_cast <void> (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 375, __PRETTY_FUNCTION__)); | ||||||||||
376 | setSmallBits(getSmallBits() | (uintptr_t(1) << Idx)); | ||||||||||
377 | } | ||||||||||
378 | else | ||||||||||
379 | getPointer()->set(Idx); | ||||||||||
380 | return *this; | ||||||||||
381 | } | ||||||||||
382 | |||||||||||
383 | /// Efficiently set a range of bits in [I, E) | ||||||||||
384 | SmallBitVector &set(unsigned I, unsigned E) { | ||||||||||
385 | assert
static_cast<void> (0) : __assert_fail ("I <= E && \"Attempted to set backwards range!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 385, __PRETTY_FUNCTION__)); | ||||||||||
386 | assert(E <= size() && "Attempted to set out-of-bounds range!")((E <= size() && "Attempted to set out-of-bounds range!" ) ? static_cast<void> (0) : __assert_fail ("E <= size() && \"Attempted to set out-of-bounds range!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 386, __PRETTY_FUNCTION__)); | ||||||||||
387 | if (I
| ||||||||||
388 | if (isSmall()) { | ||||||||||
389 | uintptr_t EMask = ((uintptr_t)1) << E; | ||||||||||
| |||||||||||
390 | uintptr_t IMask = ((uintptr_t)1) << I; | ||||||||||
391 | uintptr_t Mask = EMask - IMask; | ||||||||||
392 | setSmallBits(getSmallBits() | Mask); | ||||||||||
393 | } else | ||||||||||
394 | getPointer()->set(I, E); | ||||||||||
395 | return *this; | ||||||||||
396 | } | ||||||||||
397 | |||||||||||
398 | SmallBitVector &reset() { | ||||||||||
399 | if (isSmall()) | ||||||||||
400 | setSmallBits(0); | ||||||||||
401 | else | ||||||||||
402 | getPointer()->reset(); | ||||||||||
403 | return *this; | ||||||||||
404 | } | ||||||||||
405 | |||||||||||
406 | SmallBitVector &reset(unsigned Idx) { | ||||||||||
407 | if (isSmall()) | ||||||||||
408 | setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx)); | ||||||||||
409 | else | ||||||||||
410 | getPointer()->reset(Idx); | ||||||||||
411 | return *this; | ||||||||||
412 | } | ||||||||||
413 | |||||||||||
414 | /// Efficiently reset a range of bits in [I, E) | ||||||||||
415 | SmallBitVector &reset(unsigned I, unsigned E) { | ||||||||||
416 | assert(I <= E && "Attempted to reset backwards range!")((I <= E && "Attempted to reset backwards range!") ? static_cast<void> (0) : __assert_fail ("I <= E && \"Attempted to reset backwards range!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 416, __PRETTY_FUNCTION__)); | ||||||||||
417 | assert(E <= size() && "Attempted to reset out-of-bounds range!")((E <= size() && "Attempted to reset out-of-bounds range!" ) ? static_cast<void> (0) : __assert_fail ("E <= size() && \"Attempted to reset out-of-bounds range!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 417, __PRETTY_FUNCTION__)); | ||||||||||
418 | if (I == E) return *this; | ||||||||||
419 | if (isSmall()) { | ||||||||||
420 | uintptr_t EMask = ((uintptr_t)1) << E; | ||||||||||
421 | uintptr_t IMask = ((uintptr_t)1) << I; | ||||||||||
422 | uintptr_t Mask = EMask - IMask; | ||||||||||
423 | setSmallBits(getSmallBits() & ~Mask); | ||||||||||
424 | } else | ||||||||||
425 | getPointer()->reset(I, E); | ||||||||||
426 | return *this; | ||||||||||
427 | } | ||||||||||
428 | |||||||||||
429 | SmallBitVector &flip() { | ||||||||||
430 | if (isSmall()) | ||||||||||
431 | setSmallBits(~getSmallBits()); | ||||||||||
432 | else | ||||||||||
433 | getPointer()->flip(); | ||||||||||
434 | return *this; | ||||||||||
435 | } | ||||||||||
436 | |||||||||||
437 | SmallBitVector &flip(unsigned Idx) { | ||||||||||
438 | if (isSmall()) | ||||||||||
439 | setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx)); | ||||||||||
440 | else | ||||||||||
441 | getPointer()->flip(Idx); | ||||||||||
442 | return *this; | ||||||||||
443 | } | ||||||||||
444 | |||||||||||
445 | // No argument flip. | ||||||||||
446 | SmallBitVector operator~() const { | ||||||||||
447 | return SmallBitVector(*this).flip(); | ||||||||||
448 | } | ||||||||||
449 | |||||||||||
450 | // Indexing. | ||||||||||
451 | reference operator[](unsigned Idx) { | ||||||||||
452 | assert(Idx < size() && "Out-of-bounds Bit access.")((Idx < size() && "Out-of-bounds Bit access.") ? static_cast <void> (0) : __assert_fail ("Idx < size() && \"Out-of-bounds Bit access.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 452, __PRETTY_FUNCTION__)); | ||||||||||
453 | return reference(*this, Idx); | ||||||||||
454 | } | ||||||||||
455 | |||||||||||
456 | bool operator[](unsigned Idx) const { | ||||||||||
457 | assert(Idx < size() && "Out-of-bounds Bit access.")((Idx < size() && "Out-of-bounds Bit access.") ? static_cast <void> (0) : __assert_fail ("Idx < size() && \"Out-of-bounds Bit access.\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 457, __PRETTY_FUNCTION__)); | ||||||||||
458 | if (isSmall()) | ||||||||||
459 | return ((getSmallBits() >> Idx) & 1) != 0; | ||||||||||
460 | return getPointer()->operator[](Idx); | ||||||||||
461 | } | ||||||||||
462 | |||||||||||
463 | bool test(unsigned Idx) const { | ||||||||||
464 | return (*this)[Idx]; | ||||||||||
465 | } | ||||||||||
466 | |||||||||||
467 | // Push single bit to end of vector. | ||||||||||
468 | void push_back(bool Val) { | ||||||||||
469 | resize(size() + 1, Val); | ||||||||||
470 | } | ||||||||||
471 | |||||||||||
472 | /// Test if any common bits are set. | ||||||||||
473 | bool anyCommon(const SmallBitVector &RHS) const { | ||||||||||
474 | if (isSmall() && RHS.isSmall()) | ||||||||||
475 | return (getSmallBits() & RHS.getSmallBits()) != 0; | ||||||||||
476 | if (!isSmall() && !RHS.isSmall()) | ||||||||||
477 | return getPointer()->anyCommon(*RHS.getPointer()); | ||||||||||
478 | |||||||||||
479 | for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) | ||||||||||
480 | if (test(i) && RHS.test(i)) | ||||||||||
481 | return true; | ||||||||||
482 | return false; | ||||||||||
483 | } | ||||||||||
484 | |||||||||||
485 | // Comparison operators. | ||||||||||
486 | bool operator==(const SmallBitVector &RHS) const { | ||||||||||
487 | if (size() != RHS.size()) | ||||||||||
488 | return false; | ||||||||||
489 | if (isSmall() && RHS.isSmall()) | ||||||||||
490 | return getSmallBits() == RHS.getSmallBits(); | ||||||||||
491 | else if (!isSmall() && !RHS.isSmall()) | ||||||||||
492 | return *getPointer() == *RHS.getPointer(); | ||||||||||
493 | else { | ||||||||||
494 | for (size_t i = 0, e = size(); i != e; ++i) { | ||||||||||
495 | if ((*this)[i] != RHS[i]) | ||||||||||
496 | return false; | ||||||||||
497 | } | ||||||||||
498 | return true; | ||||||||||
499 | } | ||||||||||
500 | } | ||||||||||
501 | |||||||||||
502 | bool operator!=(const SmallBitVector &RHS) const { | ||||||||||
503 | return !(*this == RHS); | ||||||||||
504 | } | ||||||||||
505 | |||||||||||
506 | // Intersection, union, disjoint union. | ||||||||||
507 | // FIXME BitVector::operator&= does not resize the LHS but this does | ||||||||||
508 | SmallBitVector &operator&=(const SmallBitVector &RHS) { | ||||||||||
509 | resize(std::max(size(), RHS.size())); | ||||||||||
510 | if (isSmall() && RHS.isSmall()) | ||||||||||
511 | setSmallBits(getSmallBits() & RHS.getSmallBits()); | ||||||||||
512 | else if (!isSmall() && !RHS.isSmall()) | ||||||||||
513 | getPointer()->operator&=(*RHS.getPointer()); | ||||||||||
514 | else { | ||||||||||
515 | size_t i, e; | ||||||||||
516 | for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i) | ||||||||||
517 | (*this)[i] = test(i) && RHS.test(i); | ||||||||||
518 | for (e = size(); i != e; ++i) | ||||||||||
519 | reset(i); | ||||||||||
520 | } | ||||||||||
521 | return *this; | ||||||||||
522 | } | ||||||||||
523 | |||||||||||
524 | /// Reset bits that are set in RHS. Same as *this &= ~RHS. | ||||||||||
525 | SmallBitVector &reset(const SmallBitVector &RHS) { | ||||||||||
526 | if (isSmall() && RHS.isSmall()) | ||||||||||
527 | setSmallBits(getSmallBits() & ~RHS.getSmallBits()); | ||||||||||
528 | else if (!isSmall() && !RHS.isSmall()) | ||||||||||
529 | getPointer()->reset(*RHS.getPointer()); | ||||||||||
530 | else | ||||||||||
531 | for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) | ||||||||||
532 | if (RHS.test(i)) | ||||||||||
533 | reset(i); | ||||||||||
534 | |||||||||||
535 | return *this; | ||||||||||
536 | } | ||||||||||
537 | |||||||||||
538 | /// Check if (This - RHS) is zero. This is the same as reset(RHS) and any(). | ||||||||||
539 | bool test(const SmallBitVector &RHS) const { | ||||||||||
540 | if (isSmall() && RHS.isSmall()) | ||||||||||
541 | return (getSmallBits() & ~RHS.getSmallBits()) != 0; | ||||||||||
542 | if (!isSmall() && !RHS.isSmall()) | ||||||||||
543 | return getPointer()->test(*RHS.getPointer()); | ||||||||||
544 | |||||||||||
545 | unsigned i, e; | ||||||||||
546 | for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i) | ||||||||||
547 | if (test(i) && !RHS.test(i)) | ||||||||||
548 | return true; | ||||||||||
549 | |||||||||||
550 | for (e = size(); i != e; ++i) | ||||||||||
551 | if (test(i)) | ||||||||||
552 | return true; | ||||||||||
553 | |||||||||||
554 | return false; | ||||||||||
555 | } | ||||||||||
556 | |||||||||||
557 | SmallBitVector &operator|=(const SmallBitVector &RHS) { | ||||||||||
558 | resize(std::max(size(), RHS.size())); | ||||||||||
559 | if (isSmall() && RHS.isSmall()) | ||||||||||
560 | setSmallBits(getSmallBits() | RHS.getSmallBits()); | ||||||||||
561 | else if (!isSmall() && !RHS.isSmall()) | ||||||||||
562 | getPointer()->operator|=(*RHS.getPointer()); | ||||||||||
563 | else { | ||||||||||
564 | for (size_t i = 0, e = RHS.size(); i != e; ++i) | ||||||||||
565 | (*this)[i] = test(i) || RHS.test(i); | ||||||||||
566 | } | ||||||||||
567 | return *this; | ||||||||||
568 | } | ||||||||||
569 | |||||||||||
570 | SmallBitVector &operator^=(const SmallBitVector &RHS) { | ||||||||||
571 | resize(std::max(size(), RHS.size())); | ||||||||||
572 | if (isSmall() && RHS.isSmall()) | ||||||||||
573 | setSmallBits(getSmallBits() ^ RHS.getSmallBits()); | ||||||||||
574 | else if (!isSmall() && !RHS.isSmall()) | ||||||||||
575 | getPointer()->operator^=(*RHS.getPointer()); | ||||||||||
576 | else { | ||||||||||
577 | for (size_t i = 0, e = RHS.size(); i != e; ++i) | ||||||||||
578 | (*this)[i] = test(i) != RHS.test(i); | ||||||||||
579 | } | ||||||||||
580 | return *this; | ||||||||||
581 | } | ||||||||||
582 | |||||||||||
583 | SmallBitVector &operator<<=(unsigned N) { | ||||||||||
584 | if (isSmall()) | ||||||||||
585 | setSmallBits(getSmallBits() << N); | ||||||||||
586 | else | ||||||||||
587 | getPointer()->operator<<=(N); | ||||||||||
588 | return *this; | ||||||||||
589 | } | ||||||||||
590 | |||||||||||
591 | SmallBitVector &operator>>=(unsigned N) { | ||||||||||
592 | if (isSmall()) | ||||||||||
593 | setSmallBits(getSmallBits() >> N); | ||||||||||
594 | else | ||||||||||
595 | getPointer()->operator>>=(N); | ||||||||||
596 | return *this; | ||||||||||
597 | } | ||||||||||
598 | |||||||||||
599 | // Assignment operator. | ||||||||||
600 | const SmallBitVector &operator=(const SmallBitVector &RHS) { | ||||||||||
601 | if (isSmall()) { | ||||||||||
602 | if (RHS.isSmall()) | ||||||||||
603 | X = RHS.X; | ||||||||||
604 | else | ||||||||||
605 | switchToLarge(new BitVector(*RHS.getPointer())); | ||||||||||
606 | } else { | ||||||||||
607 | if (!RHS.isSmall()) | ||||||||||
608 | *getPointer() = *RHS.getPointer(); | ||||||||||
609 | else { | ||||||||||
610 | delete getPointer(); | ||||||||||
611 | X = RHS.X; | ||||||||||
612 | } | ||||||||||
613 | } | ||||||||||
614 | return *this; | ||||||||||
615 | } | ||||||||||
616 | |||||||||||
617 | const SmallBitVector &operator=(SmallBitVector &&RHS) { | ||||||||||
618 | if (this != &RHS) { | ||||||||||
619 | clear(); | ||||||||||
620 | swap(RHS); | ||||||||||
621 | } | ||||||||||
622 | return *this; | ||||||||||
623 | } | ||||||||||
624 | |||||||||||
625 | void swap(SmallBitVector &RHS) { | ||||||||||
626 | std::swap(X, RHS.X); | ||||||||||
627 | } | ||||||||||
628 | |||||||||||
629 | /// Add '1' bits from Mask to this vector. Don't resize. | ||||||||||
630 | /// This computes "*this |= Mask". | ||||||||||
631 | void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { | ||||||||||
632 | if (isSmall()) | ||||||||||
633 | applyMask<true, false>(Mask, MaskWords); | ||||||||||
634 | else | ||||||||||
635 | getPointer()->setBitsInMask(Mask, MaskWords); | ||||||||||
636 | } | ||||||||||
637 | |||||||||||
638 | /// Clear any bits in this vector that are set in Mask. Don't resize. | ||||||||||
639 | /// This computes "*this &= ~Mask". | ||||||||||
640 | void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { | ||||||||||
641 | if (isSmall()) | ||||||||||
642 | applyMask<false, false>(Mask, MaskWords); | ||||||||||
643 | else | ||||||||||
644 | getPointer()->clearBitsInMask(Mask, MaskWords); | ||||||||||
645 | } | ||||||||||
646 | |||||||||||
647 | /// Add a bit to this vector for every '0' bit in Mask. Don't resize. | ||||||||||
648 | /// This computes "*this |= ~Mask". | ||||||||||
649 | void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { | ||||||||||
650 | if (isSmall()) | ||||||||||
651 | applyMask<true, true>(Mask, MaskWords); | ||||||||||
652 | else | ||||||||||
653 | getPointer()->setBitsNotInMask(Mask, MaskWords); | ||||||||||
654 | } | ||||||||||
655 | |||||||||||
656 | /// Clear a bit in this vector for every '0' bit in Mask. Don't resize. | ||||||||||
657 | /// This computes "*this &= Mask". | ||||||||||
658 | void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) { | ||||||||||
659 | if (isSmall()) | ||||||||||
660 | applyMask<false, true>(Mask, MaskWords); | ||||||||||
661 | else | ||||||||||
662 | getPointer()->clearBitsNotInMask(Mask, MaskWords); | ||||||||||
663 | } | ||||||||||
664 | |||||||||||
665 | private: | ||||||||||
666 | template <bool AddBits, bool InvertMask> | ||||||||||
667 | void applyMask(const uint32_t *Mask, unsigned MaskWords) { | ||||||||||
668 | assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!")((MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!" ) ? static_cast<void> (0) : __assert_fail ("MaskWords <= sizeof(uintptr_t) && \"Mask is larger than base!\"" , "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.h" , 668, __PRETTY_FUNCTION__)); | ||||||||||
669 | uintptr_t M = Mask[0]; | ||||||||||
670 | if (NumBaseBits == 64) | ||||||||||
671 | M |= uint64_t(Mask[1]) << 32; | ||||||||||
672 | if (InvertMask) | ||||||||||
673 | M = ~M; | ||||||||||
674 | if (AddBits) | ||||||||||
675 | setSmallBits(getSmallBits() | M); | ||||||||||
676 | else | ||||||||||
677 | setSmallBits(getSmallBits() & ~M); | ||||||||||
678 | } | ||||||||||
679 | }; | ||||||||||
680 | |||||||||||
681 | inline SmallBitVector | ||||||||||
682 | operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) { | ||||||||||
683 | SmallBitVector Result(LHS); | ||||||||||
684 | Result &= RHS; | ||||||||||
685 | return Result; | ||||||||||
686 | } | ||||||||||
687 | |||||||||||
688 | inline SmallBitVector | ||||||||||
689 | operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) { | ||||||||||
690 | SmallBitVector Result(LHS); | ||||||||||
691 | Result |= RHS; | ||||||||||
692 | return Result; | ||||||||||
693 | } | ||||||||||
694 | |||||||||||
695 | inline SmallBitVector | ||||||||||
696 | operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) { | ||||||||||
697 | SmallBitVector Result(LHS); | ||||||||||
698 | Result ^= RHS; | ||||||||||
699 | return Result; | ||||||||||
700 | } | ||||||||||
701 | |||||||||||
702 | } // end namespace llvm | ||||||||||
703 | |||||||||||
704 | namespace std { | ||||||||||
705 | |||||||||||
706 | /// Implement std::swap in terms of BitVector swap. | ||||||||||
707 | inline void | ||||||||||
708 | swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) { | ||||||||||
709 | LHS.swap(RHS); | ||||||||||
710 | } | ||||||||||
711 | |||||||||||
712 | } // end namespace std | ||||||||||
713 | |||||||||||
714 | #endif // LLVM_ADT_SMALLBITVECTOR_H |