Bug Summary

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'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DwarfExpression.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/CodeGen/AsmPrinter -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/CodeGen/AsmPrinter -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

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
26using namespace llvm;
27
28void 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
42void 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
55void 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
67void DwarfExpression::addFBReg(int Offset) {
68 emitOp(dwarf::DW_OP_fbreg);
69 emitSigned(Offset);
70}
71
72void 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
89void DwarfExpression::addShr(unsigned ShiftBy) {
90 emitConstu(ShiftBy);
91 emitOp(dwarf::DW_OP_shr);
92}
93
94void DwarfExpression::addAnd(unsigned Mask) {
95 emitConstu(Mask);
96 emitOp(dwarf::DW_OP_and);
97}
98
99bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
100 unsigned MachineReg, unsigned MaxSize) {
101 if (!llvm::Register::isPhysicalRegister(MachineReg)) {
4
Calling 'Register::isPhysicalRegister'
11
Returning from 'Register::isPhysicalRegister'
12
Taking false branch
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) {
13
Assuming 'Reg' is < 0
14
Taking false branch
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) {
15
Loop condition is true. Entering loop body
18
Calling 'DiffListIterator::isValid'
20
Returning from 'DiffListIterator::isValid'
21
Loop condition is false. Execution continues on line 134
120 Reg = TRI.getDwarfRegNum(*SR, false);
121 if (Reg >= 0) {
16
Assuming 'Reg' is < 0
17
Taking false branch
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) {
22
Loop condition is true. Entering loop body
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)
23
Assuming 'Reg' is >= 0
24
Taking false branch
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)) {
25
Assuming 'Offset' is < 'MaxSize'
26
Taking true branch
160 // Emit a piece for any gap in the coverage.
161 if (Offset > CurPos)
27
Assuming 'Offset' is <= 'CurPos'
28
Taking false branch
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);
29
Passing the value 4294967295 via 2nd parameter 'E'
30
Calling 'SmallBitVector::set'
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
180void DwarfExpression::addStackValue() {
181 if (DwarfVersion >= 4)
182 emitOp(dwarf::DW_OP_stack_value);
183}
184
185void 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
192void 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
198void 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
218bool 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)) {
1
Assuming the condition is false
2
'?' condition is false
3
Calling 'DwarfExpression::addMachineReg'
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
317void 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
333void 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?".
348static 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
362void 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.
523void 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
531void 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
542void 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
554void 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
569void 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
576void 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}

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/CodeGen/Register.h

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
15namespace llvm {
16
17/// Wrapper class representing virtual and physical registers. Should be passed
18/// by value.
19class Register {
20 unsigned Reg;
21
22public:
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);
5
Calling 'MCRegister::isPhysicalRegister'
9
Returning from 'MCRegister::isPhysicalRegister'
10
Returning the value 1, which participates in a condition later
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
139template<> 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

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegister.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
15namespace llvm {
16
17/// An unsigned integer type large enough to represent all physical registers,
18/// but not necessarily virtual registers.
19using MCPhysReg = uint16_t;
20
21/// Wrapper class representing physical registers. Should be passed by value.
22class MCRegister {
23 unsigned Reg;
24
25public:
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__))
;
6
'?' condition is true
54 return int(Reg) > 0;
7
Assuming 'Reg' is > 0
8
Returning the value 1, which participates in a condition later
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
93template<> 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

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/MC/MCRegisterInfo.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
28namespace llvm {
29
30/// MCRegisterClass - Base class of TargetRegisterClass.
31class MCRegisterClass {
32public:
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///
98struct 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///
128class MCRegisterInfo {
129public:
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
148private:
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
181public:
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; }
19
Returning zero, which participates in a condition later
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.
587class MCSubRegIterator : public MCRegisterInfo::DiffListIterator {
588public:
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.
600class MCSubRegIndexIterator {
601 MCSubRegIterator SRIter;
602 const uint16_t *SRIndex;
603
604public:
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.
634class MCSuperRegIterator : public MCRegisterInfo::DiffListIterator {
635public:
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.
649inline 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.
670class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
671public:
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.
698class MCRegUnitMaskIterator {
699 MCRegUnitIterator RUIter;
700 const LaneBitmask *MaskListIter;
701
702public:
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.
738class MCRegUnitRootIterator {
739 uint16_t Reg0 = 0;
740 uint16_t Reg1 = 0;
741
742public:
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.
772class MCRegAliasIterator {
773private:
774 MCRegister Reg;
775 const MCRegisterInfo *MCRI;
776 bool IncludeSelf;
777
778 MCRegUnitIterator RI;
779 MCRegUnitRootIterator RRI;
780 MCSuperRegIterator SI;
781
782public:
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

/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/include/llvm/ADT/SmallBitVector.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
27namespace 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.
34class 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
62public:
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
93private:
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
139public:
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
30.1
'I' is <= 'E'
30.1
'I' is <= 'E'
30.1
'I' is <= 'E'
30.1
'I' is <= 'E'
30.1
'I' is <= 'E'
(I <= E && "Attempted to set backwards range!")((I <= E && "Attempted to set backwards range!") ?
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__))
;
31
'?' condition is true
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__))
;
32
Assuming the condition is true
33
'?' condition is true
387 if (I
33.1
'I' is not equal to 'E'
33.1
'I' is not equal to 'E'
33.1
'I' is not equal to 'E'
33.1
'I' is not equal to 'E'
33.1
'I' is not equal to 'E'
== E) return *this;
34
Taking false branch
388 if (isSmall()) {
35
Assuming the condition is true
36
Taking true branch
389 uintptr_t EMask = ((uintptr_t)1) << E;
37
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'
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
665private:
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
681inline SmallBitVector
682operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
683 SmallBitVector Result(LHS);
684 Result &= RHS;
685 return Result;
686}
687
688inline SmallBitVector
689operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
690 SmallBitVector Result(LHS);
691 Result |= RHS;
692 return Result;
693}
694
695inline SmallBitVector
696operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
697 SmallBitVector Result(LHS);
698 Result ^= RHS;
699 return Result;
700}
701
702} // end namespace llvm
703
704namespace std {
705
706/// Implement std::swap in terms of BitVector swap.
707inline void
708swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
709 LHS.swap(RHS);
710}
711
712} // end namespace std
713
714#endif // LLVM_ADT_SMALLBITVECTOR_H