Bug Summary

File:build/source/llvm/lib/CodeGen/MachineOperand.cpp
Warning:line 1191, column 39
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name MachineOperand.cpp -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 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm -resource-dir /usr/lib/llvm-16/lib/clang/16.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/CodeGen -I /build/source/llvm/lib/CodeGen -I include -I /build/source/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-16/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm=build-llvm -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm=build-llvm -fcoverage-prefix-map=/build/source/= -source-date-epoch 1668078801 -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm -fdebug-prefix-map=/build/source/build-llvm=build-llvm -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-11-10-135928-647445-1 -x c++ /build/source/llvm/lib/CodeGen/MachineOperand.cpp

/build/source/llvm/lib/CodeGen/MachineOperand.cpp

1//===- lib/CodeGen/MachineOperand.cpp -------------------------------------===//
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/// \file Methods common to all machine operands.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/CodeGen/MachineOperand.h"
14#include "llvm/ADT/FoldingSet.h"
15#include "llvm/ADT/StringExtras.h"
16#include "llvm/Analysis/Loads.h"
17#include "llvm/CodeGen/MIRFormatter.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineJumpTableInfo.h"
20#include "llvm/CodeGen/MachineRegisterInfo.h"
21#include "llvm/CodeGen/StableHashing.h"
22#include "llvm/CodeGen/TargetInstrInfo.h"
23#include "llvm/CodeGen/TargetRegisterInfo.h"
24#include "llvm/Config/llvm-config.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/IRPrintingPasses.h"
27#include "llvm/IR/Instructions.h"
28#include "llvm/IR/ModuleSlotTracker.h"
29#include "llvm/MC/MCDwarf.h"
30#include "llvm/Target/TargetIntrinsicInfo.h"
31#include "llvm/Target/TargetMachine.h"
32
33using namespace llvm;
34
35static cl::opt<int>
36 PrintRegMaskNumRegs("print-regmask-num-regs",
37 cl::desc("Number of registers to limit to when "
38 "printing regmask operands in IR dumps. "
39 "unlimited = -1"),
40 cl::init(32), cl::Hidden);
41
42static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
43 if (const MachineInstr *MI = MO.getParent())
44 if (const MachineBasicBlock *MBB = MI->getParent())
45 if (const MachineFunction *MF = MBB->getParent())
46 return MF;
47 return nullptr;
48}
49
50static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
51 return const_cast<MachineFunction *>(
52 getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
53}
54
55void MachineOperand::setReg(Register Reg) {
56 if (getReg() == Reg)
57 return; // No change.
58
59 // Clear the IsRenamable bit to keep it conservatively correct.
60 IsRenamable = false;
61
62 // Otherwise, we have to change the register. If this operand is embedded
63 // into a machine function, we need to update the old and new register's
64 // use/def lists.
65 if (MachineFunction *MF = getMFIfAvailable(*this)) {
66 MachineRegisterInfo &MRI = MF->getRegInfo();
67 MRI.removeRegOperandFromUseList(this);
68 SmallContents.RegNo = Reg;
69 MRI.addRegOperandToUseList(this);
70 return;
71 }
72
73 // Otherwise, just change the register, no problem. :)
74 SmallContents.RegNo = Reg;
75}
76
77void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
78 const TargetRegisterInfo &TRI) {
79 assert(Reg.isVirtual())(static_cast <bool> (Reg.isVirtual()) ? void (0) : __assert_fail
("Reg.isVirtual()", "llvm/lib/CodeGen/MachineOperand.cpp", 79
, __extension__ __PRETTY_FUNCTION__))
;
80 if (SubIdx && getSubReg())
81 SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
82 setReg(Reg);
83 if (SubIdx)
84 setSubReg(SubIdx);
85}
86
87void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
88 assert(Register::isPhysicalRegister(Reg))(static_cast <bool> (Register::isPhysicalRegister(Reg))
? void (0) : __assert_fail ("Register::isPhysicalRegister(Reg)"
, "llvm/lib/CodeGen/MachineOperand.cpp", 88, __extension__ __PRETTY_FUNCTION__
))
;
89 if (getSubReg()) {
90 Reg = TRI.getSubReg(Reg, getSubReg());
91 // Note that getSubReg() may return 0 if the sub-register doesn't exist.
92 // That won't happen in legal code.
93 setSubReg(0);
94 if (isDef())
95 setIsUndef(false);
96 }
97 setReg(Reg);
98}
99
100/// Change a def to a use, or a use to a def.
101void MachineOperand::setIsDef(bool Val) {
102 assert(isReg() && "Wrong MachineOperand accessor")(static_cast <bool> (isReg() && "Wrong MachineOperand accessor"
) ? void (0) : __assert_fail ("isReg() && \"Wrong MachineOperand accessor\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 102, __extension__ __PRETTY_FUNCTION__
))
;
103 assert((!Val || !isDebug()) && "Marking a debug operation as def")(static_cast <bool> ((!Val || !isDebug()) && "Marking a debug operation as def"
) ? void (0) : __assert_fail ("(!Val || !isDebug()) && \"Marking a debug operation as def\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 103, __extension__ __PRETTY_FUNCTION__
))
;
104 if (IsDef == Val)
105 return;
106 assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported")(static_cast <bool> (!IsDeadOrKill && "Changing def/use with dead/kill set not supported"
) ? void (0) : __assert_fail ("!IsDeadOrKill && \"Changing def/use with dead/kill set not supported\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 106, __extension__ __PRETTY_FUNCTION__
))
;
107 // MRI may keep uses and defs in different list positions.
108 if (MachineFunction *MF = getMFIfAvailable(*this)) {
109 MachineRegisterInfo &MRI = MF->getRegInfo();
110 MRI.removeRegOperandFromUseList(this);
111 IsDef = Val;
112 MRI.addRegOperandToUseList(this);
113 return;
114 }
115 IsDef = Val;
116}
117
118bool MachineOperand::isRenamable() const {
119 assert(isReg() && "Wrong MachineOperand accessor")(static_cast <bool> (isReg() && "Wrong MachineOperand accessor"
) ? void (0) : __assert_fail ("isReg() && \"Wrong MachineOperand accessor\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 119, __extension__ __PRETTY_FUNCTION__
))
;
120 assert(Register::isPhysicalRegister(getReg()) &&(static_cast <bool> (Register::isPhysicalRegister(getReg
()) && "isRenamable should only be checked on physical registers"
) ? void (0) : __assert_fail ("Register::isPhysicalRegister(getReg()) && \"isRenamable should only be checked on physical registers\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 121, __extension__ __PRETTY_FUNCTION__
))
121 "isRenamable should only be checked on physical registers")(static_cast <bool> (Register::isPhysicalRegister(getReg
()) && "isRenamable should only be checked on physical registers"
) ? void (0) : __assert_fail ("Register::isPhysicalRegister(getReg()) && \"isRenamable should only be checked on physical registers\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 121, __extension__ __PRETTY_FUNCTION__
))
;
122 if (!IsRenamable)
123 return false;
124
125 const MachineInstr *MI = getParent();
126 if (!MI)
127 return true;
128
129 if (isDef())
130 return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
131
132 assert(isUse() && "Reg is not def or use")(static_cast <bool> (isUse() && "Reg is not def or use"
) ? void (0) : __assert_fail ("isUse() && \"Reg is not def or use\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 132, __extension__ __PRETTY_FUNCTION__
))
;
133 return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
134}
135
136void MachineOperand::setIsRenamable(bool Val) {
137 assert(isReg() && "Wrong MachineOperand accessor")(static_cast <bool> (isReg() && "Wrong MachineOperand accessor"
) ? void (0) : __assert_fail ("isReg() && \"Wrong MachineOperand accessor\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 137, __extension__ __PRETTY_FUNCTION__
))
;
138 assert(Register::isPhysicalRegister(getReg()) &&(static_cast <bool> (Register::isPhysicalRegister(getReg
()) && "setIsRenamable should only be called on physical registers"
) ? void (0) : __assert_fail ("Register::isPhysicalRegister(getReg()) && \"setIsRenamable should only be called on physical registers\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 139, __extension__ __PRETTY_FUNCTION__
))
139 "setIsRenamable should only be called on physical registers")(static_cast <bool> (Register::isPhysicalRegister(getReg
()) && "setIsRenamable should only be called on physical registers"
) ? void (0) : __assert_fail ("Register::isPhysicalRegister(getReg()) && \"setIsRenamable should only be called on physical registers\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 139, __extension__ __PRETTY_FUNCTION__
))
;
140 IsRenamable = Val;
141}
142
143// If this operand is currently a register operand, and if this is in a
144// function, deregister the operand from the register's use/def list.
145void MachineOperand::removeRegFromUses() {
146 if (!isReg() || !isOnRegUseList())
147 return;
148
149 if (MachineFunction *MF = getMFIfAvailable(*this))
150 MF->getRegInfo().removeRegOperandFromUseList(this);
151}
152
153/// ChangeToImmediate - Replace this operand with a new immediate operand of
154/// the specified value. If an operand is known to be an immediate already,
155/// the setImm method should be used.
156void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
157 assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an imm") ? void (0) : __assert_fail
("(!isReg() || !isTied()) && \"Cannot change a tied operand into an imm\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 157, __extension__ __PRETTY_FUNCTION__
))
;
158
159 removeRegFromUses();
160
161 OpKind = MO_Immediate;
162 Contents.ImmVal = ImmVal;
163 setTargetFlags(TargetFlags);
164}
165
166void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
167 unsigned TargetFlags) {
168 assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an imm") ? void (0) : __assert_fail
("(!isReg() || !isTied()) && \"Cannot change a tied operand into an imm\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 168, __extension__ __PRETTY_FUNCTION__
))
;
169
170 removeRegFromUses();
171
172 OpKind = MO_FPImmediate;
173 Contents.CFP = FPImm;
174 setTargetFlags(TargetFlags);
175}
176
177void MachineOperand::ChangeToES(const char *SymName,
178 unsigned TargetFlags) {
179 assert((!isReg() || !isTied()) &&(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an external symbol") ? void
(0) : __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into an external symbol\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 180, __extension__ __PRETTY_FUNCTION__
))
180 "Cannot change a tied operand into an external symbol")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an external symbol") ? void
(0) : __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into an external symbol\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 180, __extension__ __PRETTY_FUNCTION__
))
;
181
182 removeRegFromUses();
183
184 OpKind = MO_ExternalSymbol;
185 Contents.OffsetedInfo.Val.SymbolName = SymName;
186 setOffset(0); // Offset is always 0.
187 setTargetFlags(TargetFlags);
188}
189
190void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
191 unsigned TargetFlags) {
192 assert((!isReg() || !isTied()) &&(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a global address") ? void
(0) : __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a global address\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 193, __extension__ __PRETTY_FUNCTION__
))
193 "Cannot change a tied operand into a global address")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a global address") ? void
(0) : __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a global address\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 193, __extension__ __PRETTY_FUNCTION__
))
;
194
195 removeRegFromUses();
196
197 OpKind = MO_GlobalAddress;
198 Contents.OffsetedInfo.Val.GV = GV;
199 setOffset(Offset);
200 setTargetFlags(TargetFlags);
201}
202
203void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
204 assert((!isReg() || !isTied()) &&(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an MCSymbol") ? void (0) :
__assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into an MCSymbol\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 205, __extension__ __PRETTY_FUNCTION__
))
205 "Cannot change a tied operand into an MCSymbol")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into an MCSymbol") ? void (0) :
__assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into an MCSymbol\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 205, __extension__ __PRETTY_FUNCTION__
))
;
206
207 removeRegFromUses();
208
209 OpKind = MO_MCSymbol;
210 Contents.Sym = Sym;
211 setTargetFlags(TargetFlags);
212}
213
214void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
215 assert((!isReg() || !isTied()) &&(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a FrameIndex") ? void (0)
: __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a FrameIndex\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 216, __extension__ __PRETTY_FUNCTION__
))
216 "Cannot change a tied operand into a FrameIndex")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a FrameIndex") ? void (0)
: __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a FrameIndex\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 216, __extension__ __PRETTY_FUNCTION__
))
;
217
218 removeRegFromUses();
219
220 OpKind = MO_FrameIndex;
221 setIndex(Idx);
222 setTargetFlags(TargetFlags);
223}
224
225void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
226 unsigned TargetFlags) {
227 assert((!isReg() || !isTied()) &&(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a FrameIndex") ? void (0)
: __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a FrameIndex\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 228, __extension__ __PRETTY_FUNCTION__
))
228 "Cannot change a tied operand into a FrameIndex")(static_cast <bool> ((!isReg() || !isTied()) &&
"Cannot change a tied operand into a FrameIndex") ? void (0)
: __assert_fail ("(!isReg() || !isTied()) && \"Cannot change a tied operand into a FrameIndex\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 228, __extension__ __PRETTY_FUNCTION__
))
;
229
230 removeRegFromUses();
231
232 OpKind = MO_TargetIndex;
233 setIndex(Idx);
234 setOffset(Offset);
235 setTargetFlags(TargetFlags);
236}
237
238/// ChangeToRegister - Replace this operand with a new register operand of
239/// the specified value. If an operand is known to be an register already,
240/// the setReg method should be used.
241void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp,
242 bool isKill, bool isDead, bool isUndef,
243 bool isDebug) {
244 MachineRegisterInfo *RegInfo = nullptr;
245 if (MachineFunction *MF = getMFIfAvailable(*this))
246 RegInfo = &MF->getRegInfo();
247 // If this operand is already a register operand, remove it from the
248 // register's use/def lists.
249 bool WasReg = isReg();
250 if (RegInfo && WasReg)
251 RegInfo->removeRegOperandFromUseList(this);
252
253 // Ensure debug instructions set debug flag on register uses.
254 const MachineInstr *MI = getParent();
255 if (!isDef && MI && MI->isDebugInstr())
256 isDebug = true;
257
258 // Change this to a register and set the reg#.
259 assert(!(isDead && !isDef) && "Dead flag on non-def")(static_cast <bool> (!(isDead && !isDef) &&
"Dead flag on non-def") ? void (0) : __assert_fail ("!(isDead && !isDef) && \"Dead flag on non-def\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 259, __extension__ __PRETTY_FUNCTION__
))
;
260 assert(!(isKill && isDef) && "Kill flag on def")(static_cast <bool> (!(isKill && isDef) &&
"Kill flag on def") ? void (0) : __assert_fail ("!(isKill && isDef) && \"Kill flag on def\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 260, __extension__ __PRETTY_FUNCTION__
))
;
261 OpKind = MO_Register;
262 SmallContents.RegNo = Reg;
263 SubReg_TargetFlags = 0;
264 IsDef = isDef;
265 IsImp = isImp;
266 IsDeadOrKill = isKill | isDead;
267 IsRenamable = false;
268 IsUndef = isUndef;
269 IsInternalRead = false;
270 IsEarlyClobber = false;
271 IsDebug = isDebug;
272 // Ensure isOnRegUseList() returns false.
273 Contents.Reg.Prev = nullptr;
274 // Preserve the tie when the operand was already a register.
275 if (!WasReg)
276 TiedTo = 0;
277
278 // If this operand is embedded in a function, add the operand to the
279 // register's use/def list.
280 if (RegInfo)
281 RegInfo->addRegOperandToUseList(this);
282}
283
284/// isIdenticalTo - Return true if this operand is identical to the specified
285/// operand. Note that this should stay in sync with the hash_value overload
286/// below.
287bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
288 if (getType() != Other.getType() ||
289 getTargetFlags() != Other.getTargetFlags())
290 return false;
291
292 switch (getType()) {
293 case MachineOperand::MO_Register:
294 return getReg() == Other.getReg() && isDef() == Other.isDef() &&
295 getSubReg() == Other.getSubReg();
296 case MachineOperand::MO_Immediate:
297 return getImm() == Other.getImm();
298 case MachineOperand::MO_CImmediate:
299 return getCImm() == Other.getCImm();
300 case MachineOperand::MO_FPImmediate:
301 return getFPImm() == Other.getFPImm();
302 case MachineOperand::MO_MachineBasicBlock:
303 return getMBB() == Other.getMBB();
304 case MachineOperand::MO_FrameIndex:
305 return getIndex() == Other.getIndex();
306 case MachineOperand::MO_ConstantPoolIndex:
307 case MachineOperand::MO_TargetIndex:
308 return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
309 case MachineOperand::MO_JumpTableIndex:
310 return getIndex() == Other.getIndex();
311 case MachineOperand::MO_GlobalAddress:
312 return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
313 case MachineOperand::MO_ExternalSymbol:
314 return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
315 getOffset() == Other.getOffset();
316 case MachineOperand::MO_BlockAddress:
317 return getBlockAddress() == Other.getBlockAddress() &&
318 getOffset() == Other.getOffset();
319 case MachineOperand::MO_RegisterMask:
320 case MachineOperand::MO_RegisterLiveOut: {
321 // Shallow compare of the two RegMasks
322 const uint32_t *RegMask = getRegMask();
323 const uint32_t *OtherRegMask = Other.getRegMask();
324 if (RegMask == OtherRegMask)
325 return true;
326
327 if (const MachineFunction *MF = getMFIfAvailable(*this)) {
328 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
329 unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
330 // Deep compare of the two RegMasks
331 return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
332 }
333 // We don't know the size of the RegMask, so we can't deep compare the two
334 // reg masks.
335 return false;
336 }
337 case MachineOperand::MO_MCSymbol:
338 return getMCSymbol() == Other.getMCSymbol();
339 case MachineOperand::MO_CFIIndex:
340 return getCFIIndex() == Other.getCFIIndex();
341 case MachineOperand::MO_Metadata:
342 return getMetadata() == Other.getMetadata();
343 case MachineOperand::MO_IntrinsicID:
344 return getIntrinsicID() == Other.getIntrinsicID();
345 case MachineOperand::MO_Predicate:
346 return getPredicate() == Other.getPredicate();
347 case MachineOperand::MO_ShuffleMask:
348 return getShuffleMask() == Other.getShuffleMask();
349 }
350 llvm_unreachable("Invalid machine operand type")::llvm::llvm_unreachable_internal("Invalid machine operand type"
, "llvm/lib/CodeGen/MachineOperand.cpp", 350)
;
351}
352
353// Note: this must stay exactly in sync with isIdenticalTo above.
354hash_code llvm::hash_value(const MachineOperand &MO) {
355 switch (MO.getType()) {
356 case MachineOperand::MO_Register:
357 // Register operands don't have target flags.
358 return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef());
359 case MachineOperand::MO_Immediate:
360 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
361 case MachineOperand::MO_CImmediate:
362 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
363 case MachineOperand::MO_FPImmediate:
364 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
365 case MachineOperand::MO_MachineBasicBlock:
366 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
367 case MachineOperand::MO_FrameIndex:
368 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
369 case MachineOperand::MO_ConstantPoolIndex:
370 case MachineOperand::MO_TargetIndex:
371 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
372 MO.getOffset());
373 case MachineOperand::MO_JumpTableIndex:
374 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
375 case MachineOperand::MO_ExternalSymbol:
376 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
377 StringRef(MO.getSymbolName()));
378 case MachineOperand::MO_GlobalAddress:
379 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
380 MO.getOffset());
381 case MachineOperand::MO_BlockAddress:
382 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
383 MO.getOffset());
384 case MachineOperand::MO_RegisterMask:
385 case MachineOperand::MO_RegisterLiveOut: {
386 if (const MachineFunction *MF = getMFIfAvailable(MO)) {
387 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
388 unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
389 const uint32_t *RegMask = MO.getRegMask();
390 std::vector<stable_hash> RegMaskHashes(RegMask, RegMask + RegMaskSize);
391 return hash_combine(MO.getType(), MO.getTargetFlags(),
392 stable_hash_combine_array(RegMaskHashes.data(),
393 RegMaskHashes.size()));
394 }
395
396 assert(0 && "MachineOperand not associated with any MachineFunction")(static_cast <bool> (0 && "MachineOperand not associated with any MachineFunction"
) ? void (0) : __assert_fail ("0 && \"MachineOperand not associated with any MachineFunction\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 396, __extension__ __PRETTY_FUNCTION__
))
;
397 return hash_combine(MO.getType(), MO.getTargetFlags());
398 }
399 case MachineOperand::MO_Metadata:
400 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
401 case MachineOperand::MO_MCSymbol:
402 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
403 case MachineOperand::MO_CFIIndex:
404 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
405 case MachineOperand::MO_IntrinsicID:
406 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
407 case MachineOperand::MO_Predicate:
408 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
409 case MachineOperand::MO_ShuffleMask:
410 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
411 }
412 llvm_unreachable("Invalid machine operand type")::llvm::llvm_unreachable_internal("Invalid machine operand type"
, "llvm/lib/CodeGen/MachineOperand.cpp", 412)
;
413}
414
415// Try to crawl up to the machine function and get TRI and IntrinsicInfo from
416// it.
417static void tryToGetTargetInfo(const MachineOperand &MO,
418 const TargetRegisterInfo *&TRI,
419 const TargetIntrinsicInfo *&IntrinsicInfo) {
420 if (const MachineFunction *MF = getMFIfAvailable(MO)) {
421 TRI = MF->getSubtarget().getRegisterInfo();
422 IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
423 }
424}
425
426static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
427 const auto *TII = MF.getSubtarget().getInstrInfo();
428 assert(TII && "expected instruction info")(static_cast <bool> (TII && "expected instruction info"
) ? void (0) : __assert_fail ("TII && \"expected instruction info\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 428, __extension__ __PRETTY_FUNCTION__
))
;
429 auto Indices = TII->getSerializableTargetIndices();
430 auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
431 return I.first == Index;
432 });
433 if (Found != Indices.end())
434 return Found->second;
435 return nullptr;
436}
437
438const char *MachineOperand::getTargetIndexName() const {
439 const MachineFunction *MF = getMFIfAvailable(*this);
440 return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
441}
442
443static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
444 auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
445 for (const auto &I : Flags) {
446 if (I.first == TF) {
447 return I.second;
448 }
449 }
450 return nullptr;
451}
452
453static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
454 const TargetRegisterInfo *TRI) {
455 if (!TRI) {
456 OS << "%dwarfreg." << DwarfReg;
457 return;
458 }
459
460 if (Optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true))
461 OS << printReg(*Reg, TRI);
462 else
463 OS << "<badreg>";
464}
465
466static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
467 ModuleSlotTracker &MST) {
468 OS << "%ir-block.";
469 if (BB.hasName()) {
470 printLLVMNameWithoutPrefix(OS, BB.getName());
471 return;
472 }
473 Optional<int> Slot;
474 if (const Function *F = BB.getParent()) {
475 if (F == MST.getCurrentFunction()) {
476 Slot = MST.getLocalSlot(&BB);
477 } else if (const Module *M = F->getParent()) {
478 ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
479 CustomMST.incorporateFunction(*F);
480 Slot = CustomMST.getLocalSlot(&BB);
481 }
482 }
483 if (Slot)
484 MachineOperand::printIRSlotNumber(OS, *Slot);
485 else
486 OS << "<unknown>";
487}
488
489static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
490 SyncScope::ID SSID,
491 SmallVectorImpl<StringRef> &SSNs) {
492 switch (SSID) {
493 case SyncScope::System:
494 break;
495 default:
496 if (SSNs.empty())
497 Context.getSyncScopeNames(SSNs);
498
499 OS << "syncscope(\"";
500 printEscapedString(SSNs[SSID], OS);
501 OS << "\") ";
502 break;
503 }
504}
505
506static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
507 unsigned TMMOFlag) {
508 auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
509 for (const auto &I : Flags) {
510 if (I.first == TMMOFlag) {
511 return I.second;
512 }
513 }
514 return nullptr;
515}
516
517static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
518 const MachineFrameInfo *MFI) {
519 StringRef Name;
520 if (MFI) {
521 IsFixed = MFI->isFixedObjectIndex(FrameIndex);
522 if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
523 if (Alloca->hasName())
524 Name = Alloca->getName();
525 if (IsFixed)
526 FrameIndex -= MFI->getObjectIndexBegin();
527 }
528 MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
529}
530
531void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
532 const TargetRegisterInfo *TRI) {
533 OS << "%subreg.";
534 if (TRI && Index != 0 && Index < TRI->getNumSubRegIndices())
535 OS << TRI->getSubRegIndexName(Index);
536 else
537 OS << Index;
538}
539
540void MachineOperand::printTargetFlags(raw_ostream &OS,
541 const MachineOperand &Op) {
542 if (!Op.getTargetFlags())
543 return;
544 const MachineFunction *MF = getMFIfAvailable(Op);
545 if (!MF)
546 return;
547
548 const auto *TII = MF->getSubtarget().getInstrInfo();
549 assert(TII && "expected instruction info")(static_cast <bool> (TII && "expected instruction info"
) ? void (0) : __assert_fail ("TII && \"expected instruction info\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 549, __extension__ __PRETTY_FUNCTION__
))
;
550 auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
551 OS << "target-flags(";
552 const bool HasDirectFlags = Flags.first;
553 const bool HasBitmaskFlags = Flags.second;
554 if (!HasDirectFlags && !HasBitmaskFlags) {
555 OS << "<unknown>) ";
556 return;
557 }
558 if (HasDirectFlags) {
559 if (const auto *Name = getTargetFlagName(TII, Flags.first))
560 OS << Name;
561 else
562 OS << "<unknown target flag>";
563 }
564 if (!HasBitmaskFlags) {
565 OS << ") ";
566 return;
567 }
568 bool IsCommaNeeded = HasDirectFlags;
569 unsigned BitMask = Flags.second;
570 auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
571 for (const auto &Mask : BitMasks) {
572 // Check if the flag's bitmask has the bits of the current mask set.
573 if ((BitMask & Mask.first) == Mask.first) {
574 if (IsCommaNeeded)
575 OS << ", ";
576 IsCommaNeeded = true;
577 OS << Mask.second;
578 // Clear the bits which were serialized from the flag's bitmask.
579 BitMask &= ~(Mask.first);
580 }
581 }
582 if (BitMask) {
583 // When the resulting flag's bitmask isn't zero, we know that we didn't
584 // serialize all of the bit flags.
585 if (IsCommaNeeded)
586 OS << ", ";
587 OS << "<unknown bitmask target flag>";
588 }
589 OS << ") ";
590}
591
592void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
593 OS << "<mcsymbol " << Sym << ">";
594}
595
596void MachineOperand::printStackObjectReference(raw_ostream &OS,
597 unsigned FrameIndex,
598 bool IsFixed, StringRef Name) {
599 if (IsFixed) {
600 OS << "%fixed-stack." << FrameIndex;
601 return;
602 }
603
604 OS << "%stack." << FrameIndex;
605 if (!Name.empty())
606 OS << '.' << Name;
607}
608
609void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
610 if (Offset == 0)
611 return;
612 if (Offset < 0) {
613 OS << " - " << -Offset;
614 return;
615 }
616 OS << " + " << Offset;
617}
618
619void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
620 if (Slot == -1)
621 OS << "<badref>";
622 else
623 OS << Slot;
624}
625
626static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
627 const TargetRegisterInfo *TRI) {
628 switch (CFI.getOperation()) {
629 case MCCFIInstruction::OpSameValue:
630 OS << "same_value ";
631 if (MCSymbol *Label = CFI.getLabel())
632 MachineOperand::printSymbol(OS, *Label);
633 printCFIRegister(CFI.getRegister(), OS, TRI);
634 break;
635 case MCCFIInstruction::OpRememberState:
636 OS << "remember_state ";
637 if (MCSymbol *Label = CFI.getLabel())
638 MachineOperand::printSymbol(OS, *Label);
639 break;
640 case MCCFIInstruction::OpRestoreState:
641 OS << "restore_state ";
642 if (MCSymbol *Label = CFI.getLabel())
643 MachineOperand::printSymbol(OS, *Label);
644 break;
645 case MCCFIInstruction::OpOffset:
646 OS << "offset ";
647 if (MCSymbol *Label = CFI.getLabel())
648 MachineOperand::printSymbol(OS, *Label);
649 printCFIRegister(CFI.getRegister(), OS, TRI);
650 OS << ", " << CFI.getOffset();
651 break;
652 case MCCFIInstruction::OpDefCfaRegister:
653 OS << "def_cfa_register ";
654 if (MCSymbol *Label = CFI.getLabel())
655 MachineOperand::printSymbol(OS, *Label);
656 printCFIRegister(CFI.getRegister(), OS, TRI);
657 break;
658 case MCCFIInstruction::OpDefCfaOffset:
659 OS << "def_cfa_offset ";
660 if (MCSymbol *Label = CFI.getLabel())
661 MachineOperand::printSymbol(OS, *Label);
662 OS << CFI.getOffset();
663 break;
664 case MCCFIInstruction::OpDefCfa:
665 OS << "def_cfa ";
666 if (MCSymbol *Label = CFI.getLabel())
667 MachineOperand::printSymbol(OS, *Label);
668 printCFIRegister(CFI.getRegister(), OS, TRI);
669 OS << ", " << CFI.getOffset();
670 break;
671 case MCCFIInstruction::OpLLVMDefAspaceCfa:
672 OS << "llvm_def_aspace_cfa ";
673 if (MCSymbol *Label = CFI.getLabel())
674 MachineOperand::printSymbol(OS, *Label);
675 printCFIRegister(CFI.getRegister(), OS, TRI);
676 OS << ", " << CFI.getOffset();
677 OS << ", " << CFI.getAddressSpace();
678 break;
679 case MCCFIInstruction::OpRelOffset:
680 OS << "rel_offset ";
681 if (MCSymbol *Label = CFI.getLabel())
682 MachineOperand::printSymbol(OS, *Label);
683 printCFIRegister(CFI.getRegister(), OS, TRI);
684 OS << ", " << CFI.getOffset();
685 break;
686 case MCCFIInstruction::OpAdjustCfaOffset:
687 OS << "adjust_cfa_offset ";
688 if (MCSymbol *Label = CFI.getLabel())
689 MachineOperand::printSymbol(OS, *Label);
690 OS << CFI.getOffset();
691 break;
692 case MCCFIInstruction::OpRestore:
693 OS << "restore ";
694 if (MCSymbol *Label = CFI.getLabel())
695 MachineOperand::printSymbol(OS, *Label);
696 printCFIRegister(CFI.getRegister(), OS, TRI);
697 break;
698 case MCCFIInstruction::OpEscape: {
699 OS << "escape ";
700 if (MCSymbol *Label = CFI.getLabel())
701 MachineOperand::printSymbol(OS, *Label);
702 if (!CFI.getValues().empty()) {
703 size_t e = CFI.getValues().size() - 1;
704 for (size_t i = 0; i < e; ++i)
705 OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
706 OS << format("0x%02x", uint8_t(CFI.getValues()[e]));
707 }
708 break;
709 }
710 case MCCFIInstruction::OpUndefined:
711 OS << "undefined ";
712 if (MCSymbol *Label = CFI.getLabel())
713 MachineOperand::printSymbol(OS, *Label);
714 printCFIRegister(CFI.getRegister(), OS, TRI);
715 break;
716 case MCCFIInstruction::OpRegister:
717 OS << "register ";
718 if (MCSymbol *Label = CFI.getLabel())
719 MachineOperand::printSymbol(OS, *Label);
720 printCFIRegister(CFI.getRegister(), OS, TRI);
721 OS << ", ";
722 printCFIRegister(CFI.getRegister2(), OS, TRI);
723 break;
724 case MCCFIInstruction::OpWindowSave:
725 OS << "window_save ";
726 if (MCSymbol *Label = CFI.getLabel())
727 MachineOperand::printSymbol(OS, *Label);
728 break;
729 case MCCFIInstruction::OpNegateRAState:
730 OS << "negate_ra_sign_state ";
731 if (MCSymbol *Label = CFI.getLabel())
732 MachineOperand::printSymbol(OS, *Label);
733 break;
734 default:
735 // TODO: Print the other CFI Operations.
736 OS << "<unserializable cfi directive>";
737 break;
738 }
739}
740
741void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
742 const TargetIntrinsicInfo *IntrinsicInfo) const {
743 print(OS, LLT{}, TRI, IntrinsicInfo);
744}
745
746void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
747 const TargetRegisterInfo *TRI,
748 const TargetIntrinsicInfo *IntrinsicInfo) const {
749 tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
750 ModuleSlotTracker DummyMST(nullptr);
751 print(OS, DummyMST, TypeToPrint, None, /*PrintDef=*/false,
752 /*IsStandalone=*/true,
753 /*ShouldPrintRegisterTies=*/true,
754 /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
755}
756
757void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
758 LLT TypeToPrint, Optional<unsigned> OpIdx, bool PrintDef,
759 bool IsStandalone, bool ShouldPrintRegisterTies,
760 unsigned TiedOperandIdx,
761 const TargetRegisterInfo *TRI,
762 const TargetIntrinsicInfo *IntrinsicInfo) const {
763 printTargetFlags(OS, *this);
764 switch (getType()) {
765 case MachineOperand::MO_Register: {
766 Register Reg = getReg();
767 if (isImplicit())
768 OS << (isDef() ? "implicit-def " : "implicit ");
769 else if (PrintDef && isDef())
770 // Print the 'def' flag only when the operand is defined after '='.
771 OS << "def ";
772 if (isInternalRead())
773 OS << "internal ";
774 if (isDead())
775 OS << "dead ";
776 if (isKill())
777 OS << "killed ";
778 if (isUndef())
779 OS << "undef ";
780 if (isEarlyClobber())
781 OS << "early-clobber ";
782 if (Register::isPhysicalRegister(getReg()) && isRenamable())
783 OS << "renamable ";
784 // isDebug() is exactly true for register operands of a DBG_VALUE. So we
785 // simply infer it when parsing and do not need to print it.
786
787 const MachineRegisterInfo *MRI = nullptr;
788 if (Register::isVirtualRegister(Reg)) {
789 if (const MachineFunction *MF = getMFIfAvailable(*this)) {
790 MRI = &MF->getRegInfo();
791 }
792 }
793
794 OS << printReg(Reg, TRI, 0, MRI);
795 // Print the sub register.
796 if (unsigned SubReg = getSubReg()) {
797 if (TRI)
798 OS << '.' << TRI->getSubRegIndexName(SubReg);
799 else
800 OS << ".subreg" << SubReg;
801 }
802 // Print the register class / bank.
803 if (Register::isVirtualRegister(Reg)) {
804 if (const MachineFunction *MF = getMFIfAvailable(*this)) {
805 const MachineRegisterInfo &MRI = MF->getRegInfo();
806 if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
807 OS << ':';
808 OS << printRegClassOrBank(Reg, MRI, TRI);
809 }
810 }
811 }
812 // Print ties.
813 if (ShouldPrintRegisterTies && isTied() && !isDef())
814 OS << "(tied-def " << TiedOperandIdx << ")";
815 // Print types.
816 if (TypeToPrint.isValid())
817 OS << '(' << TypeToPrint << ')';
818 break;
819 }
820 case MachineOperand::MO_Immediate: {
821 const MIRFormatter *Formatter = nullptr;
822 if (const MachineFunction *MF = getMFIfAvailable(*this)) {
823 const auto *TII = MF->getSubtarget().getInstrInfo();
824 assert(TII && "expected instruction info")(static_cast <bool> (TII && "expected instruction info"
) ? void (0) : __assert_fail ("TII && \"expected instruction info\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 824, __extension__ __PRETTY_FUNCTION__
))
;
825 Formatter = TII->getMIRFormatter();
826 }
827 if (Formatter)
828 Formatter->printImm(OS, *getParent(), OpIdx, getImm());
829 else
830 OS << getImm();
831 break;
832 }
833 case MachineOperand::MO_CImmediate:
834 getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
835 break;
836 case MachineOperand::MO_FPImmediate:
837 getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
838 break;
839 case MachineOperand::MO_MachineBasicBlock:
840 OS << printMBBReference(*getMBB());
841 break;
842 case MachineOperand::MO_FrameIndex: {
843 int FrameIndex = getIndex();
844 bool IsFixed = false;
845 const MachineFrameInfo *MFI = nullptr;
846 if (const MachineFunction *MF = getMFIfAvailable(*this))
847 MFI = &MF->getFrameInfo();
848 printFrameIndex(OS, FrameIndex, IsFixed, MFI);
849 break;
850 }
851 case MachineOperand::MO_ConstantPoolIndex:
852 OS << "%const." << getIndex();
853 printOperandOffset(OS, getOffset());
854 break;
855 case MachineOperand::MO_TargetIndex: {
856 OS << "target-index(";
857 const char *Name = "<unknown>";
858 if (const MachineFunction *MF = getMFIfAvailable(*this))
859 if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
860 Name = TargetIndexName;
861 OS << Name << ')';
862 printOperandOffset(OS, getOffset());
863 break;
864 }
865 case MachineOperand::MO_JumpTableIndex:
866 OS << printJumpTableEntryReference(getIndex());
867 break;
868 case MachineOperand::MO_GlobalAddress:
869 getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
870 printOperandOffset(OS, getOffset());
871 break;
872 case MachineOperand::MO_ExternalSymbol: {
873 StringRef Name = getSymbolName();
874 OS << '&';
875 if (Name.empty()) {
876 OS << "\"\"";
877 } else {
878 printLLVMNameWithoutPrefix(OS, Name);
879 }
880 printOperandOffset(OS, getOffset());
881 break;
882 }
883 case MachineOperand::MO_BlockAddress: {
884 OS << "blockaddress(";
885 getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
886 MST);
887 OS << ", ";
888 printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
889 OS << ')';
890 MachineOperand::printOperandOffset(OS, getOffset());
891 break;
892 }
893 case MachineOperand::MO_RegisterMask: {
894 OS << "<regmask";
895 if (TRI) {
896 unsigned NumRegsInMask = 0;
897 unsigned NumRegsEmitted = 0;
898 for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
899 unsigned MaskWord = i / 32;
900 unsigned MaskBit = i % 32;
901 if (getRegMask()[MaskWord] & (1 << MaskBit)) {
902 if (PrintRegMaskNumRegs < 0 ||
903 NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
904 OS << " " << printReg(i, TRI);
905 NumRegsEmitted++;
906 }
907 NumRegsInMask++;
908 }
909 }
910 if (NumRegsEmitted != NumRegsInMask)
911 OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
912 } else {
913 OS << " ...";
914 }
915 OS << ">";
916 break;
917 }
918 case MachineOperand::MO_RegisterLiveOut: {
919 const uint32_t *RegMask = getRegLiveOut();
920 OS << "liveout(";
921 if (!TRI) {
922 OS << "<unknown>";
923 } else {
924 bool IsCommaNeeded = false;
925 for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
926 if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
927 if (IsCommaNeeded)
928 OS << ", ";
929 OS << printReg(Reg, TRI);
930 IsCommaNeeded = true;
931 }
932 }
933 }
934 OS << ")";
935 break;
936 }
937 case MachineOperand::MO_Metadata:
938 getMetadata()->printAsOperand(OS, MST);
939 break;
940 case MachineOperand::MO_MCSymbol:
941 printSymbol(OS, *getMCSymbol());
942 break;
943 case MachineOperand::MO_CFIIndex: {
944 if (const MachineFunction *MF = getMFIfAvailable(*this))
945 printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
946 else
947 OS << "<cfi directive>";
948 break;
949 }
950 case MachineOperand::MO_IntrinsicID: {
951 Intrinsic::ID ID = getIntrinsicID();
952 if (ID < Intrinsic::num_intrinsics)
953 OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
954 else if (IntrinsicInfo)
955 OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
956 else
957 OS << "intrinsic(" << ID << ')';
958 break;
959 }
960 case MachineOperand::MO_Predicate: {
961 auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
962 OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
963 << CmpInst::getPredicateName(Pred) << ')';
964 break;
965 }
966 case MachineOperand::MO_ShuffleMask:
967 OS << "shufflemask(";
968 ArrayRef<int> Mask = getShuffleMask();
969 StringRef Separator;
970 for (int Elt : Mask) {
971 if (Elt == -1)
972 OS << Separator << "undef";
973 else
974 OS << Separator << Elt;
975 Separator = ", ";
976 }
977
978 OS << ')';
979 break;
980 }
981}
982
983#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
984LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void MachineOperand::dump() const { dbgs() << *this << '\n'; }
985#endif
986
987//===----------------------------------------------------------------------===//
988// MachineMemOperand Implementation
989//===----------------------------------------------------------------------===//
990
991/// getAddrSpace - Return the LLVM IR address space number that this pointer
992/// points into.
993unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
994
995/// isDereferenceable - Return true if V is always dereferenceable for
996/// Offset + Size byte.
997bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
998 const DataLayout &DL) const {
999 if (!V.is<const Value *>())
1000 return false;
1001
1002 const Value *BasePtr = V.get<const Value *>();
1003 if (BasePtr == nullptr)
1004 return false;
1005
1006 return isDereferenceableAndAlignedPointer(
1007 BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
1008}
1009
1010/// getConstantPool - Return a MachinePointerInfo record that refers to the
1011/// constant pool.
1012MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
1013 return MachinePointerInfo(MF.getPSVManager().getConstantPool());
1014}
1015
1016/// getFixedStack - Return a MachinePointerInfo record that refers to the
1017/// the specified FrameIndex.
1018MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
1019 int FI, int64_t Offset) {
1020 return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
1021}
1022
1023MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
1024 return MachinePointerInfo(MF.getPSVManager().getJumpTable());
1025}
1026
1027MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
1028 return MachinePointerInfo(MF.getPSVManager().getGOT());
1029}
1030
1031MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
1032 int64_t Offset, uint8_t ID) {
1033 return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
1034}
1035
1036MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
1037 return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
1038}
1039
1040MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
1041 LLT type, Align a, const AAMDNodes &AAInfo,
1042 const MDNode *Ranges, SyncScope::ID SSID,
1043 AtomicOrdering Ordering,
1044 AtomicOrdering FailureOrdering)
1045 : PtrInfo(ptrinfo), MemoryType(type), FlagVals(f), BaseAlign(a),
1046 AAInfo(AAInfo), Ranges(Ranges) {
1047 assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||(static_cast <bool> ((PtrInfo.V.isNull() || PtrInfo.V.is
<const PseudoSourceValue *>() || isa<PointerType>
(PtrInfo.V.get<const Value *>()->getType())) &&
"invalid pointer value") ? void (0) : __assert_fail ("(PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && \"invalid pointer value\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1049, __extension__ __PRETTY_FUNCTION__
))
1048 isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&(static_cast <bool> ((PtrInfo.V.isNull() || PtrInfo.V.is
<const PseudoSourceValue *>() || isa<PointerType>
(PtrInfo.V.get<const Value *>()->getType())) &&
"invalid pointer value") ? void (0) : __assert_fail ("(PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && \"invalid pointer value\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1049, __extension__ __PRETTY_FUNCTION__
))
1049 "invalid pointer value")(static_cast <bool> ((PtrInfo.V.isNull() || PtrInfo.V.is
<const PseudoSourceValue *>() || isa<PointerType>
(PtrInfo.V.get<const Value *>()->getType())) &&
"invalid pointer value") ? void (0) : __assert_fail ("(PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && \"invalid pointer value\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1049, __extension__ __PRETTY_FUNCTION__
))
;
1050 assert((isLoad() || isStore()) && "Not a load/store!")(static_cast <bool> ((isLoad() || isStore()) &&
"Not a load/store!") ? void (0) : __assert_fail ("(isLoad() || isStore()) && \"Not a load/store!\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1050, __extension__ __PRETTY_FUNCTION__
))
;
1051
1052 AtomicInfo.SSID = static_cast<unsigned>(SSID);
1053 assert(getSyncScopeID() == SSID && "Value truncated")(static_cast <bool> (getSyncScopeID() == SSID &&
"Value truncated") ? void (0) : __assert_fail ("getSyncScopeID() == SSID && \"Value truncated\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1053, __extension__ __PRETTY_FUNCTION__
))
;
1054 AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
1055 assert(getSuccessOrdering() == Ordering && "Value truncated")(static_cast <bool> (getSuccessOrdering() == Ordering &&
"Value truncated") ? void (0) : __assert_fail ("getSuccessOrdering() == Ordering && \"Value truncated\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1055, __extension__ __PRETTY_FUNCTION__
))
;
1056 AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
1057 assert(getFailureOrdering() == FailureOrdering && "Value truncated")(static_cast <bool> (getFailureOrdering() == FailureOrdering
&& "Value truncated") ? void (0) : __assert_fail ("getFailureOrdering() == FailureOrdering && \"Value truncated\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1057, __extension__ __PRETTY_FUNCTION__
))
;
1058}
1059
1060MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
1061 uint64_t s, Align a,
1062 const AAMDNodes &AAInfo,
1063 const MDNode *Ranges, SyncScope::ID SSID,
1064 AtomicOrdering Ordering,
1065 AtomicOrdering FailureOrdering)
1066 : MachineMemOperand(ptrinfo, f,
1067 s == ~UINT64_C(0)0UL ? LLT() : LLT::scalar(8 * s), a,
1068 AAInfo, Ranges, SSID, Ordering, FailureOrdering) {}
1069
1070/// Profile - Gather unique data for the object.
1071///
1072void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
1073 ID.AddInteger(getOffset());
1074 ID.AddInteger(getMemoryType().getUniqueRAWLLTData());
1075 ID.AddPointer(getOpaqueValue());
1076 ID.AddInteger(getFlags());
1077 ID.AddInteger(getBaseAlign().value());
1078}
1079
1080void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
1081 // The Value and Offset may differ due to CSE. But the flags and size
1082 // should be the same.
1083 assert(MMO->getFlags() == getFlags() && "Flags mismatch!")(static_cast <bool> (MMO->getFlags() == getFlags() &&
"Flags mismatch!") ? void (0) : __assert_fail ("MMO->getFlags() == getFlags() && \"Flags mismatch!\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1083, __extension__ __PRETTY_FUNCTION__
))
;
1084 assert((MMO->getSize() == ~UINT64_C(0) || getSize() == ~UINT64_C(0) ||(static_cast <bool> ((MMO->getSize() == ~0UL || getSize
() == ~0UL || MMO->getSize() == getSize()) && "Size mismatch!"
) ? void (0) : __assert_fail ("(MMO->getSize() == ~UINT64_C(0) || getSize() == ~UINT64_C(0) || MMO->getSize() == getSize()) && \"Size mismatch!\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1086, __extension__ __PRETTY_FUNCTION__
))
1085 MMO->getSize() == getSize()) &&(static_cast <bool> ((MMO->getSize() == ~0UL || getSize
() == ~0UL || MMO->getSize() == getSize()) && "Size mismatch!"
) ? void (0) : __assert_fail ("(MMO->getSize() == ~UINT64_C(0) || getSize() == ~UINT64_C(0) || MMO->getSize() == getSize()) && \"Size mismatch!\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1086, __extension__ __PRETTY_FUNCTION__
))
1086 "Size mismatch!")(static_cast <bool> ((MMO->getSize() == ~0UL || getSize
() == ~0UL || MMO->getSize() == getSize()) && "Size mismatch!"
) ? void (0) : __assert_fail ("(MMO->getSize() == ~UINT64_C(0) || getSize() == ~UINT64_C(0) || MMO->getSize() == getSize()) && \"Size mismatch!\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1086, __extension__ __PRETTY_FUNCTION__
))
;
1087
1088 if (MMO->getBaseAlign() >= getBaseAlign()) {
1089 // Update the alignment value.
1090 BaseAlign = MMO->getBaseAlign();
1091 // Also update the base and offset, because the new alignment may
1092 // not be applicable with the old ones.
1093 PtrInfo = MMO->PtrInfo;
1094 }
1095}
1096
1097/// getAlign - Return the minimum known alignment in bytes of the
1098/// actual memory reference.
1099Align MachineMemOperand::getAlign() const {
1100 return commonAlignment(getBaseAlign(), getOffset());
1101}
1102
1103void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
1104 SmallVectorImpl<StringRef> &SSNs,
1105 const LLVMContext &Context,
1106 const MachineFrameInfo *MFI,
1107 const TargetInstrInfo *TII) const {
1108 OS << '(';
1109 if (isVolatile())
1
Assuming the condition is false
2
Taking false branch
1110 OS << "volatile ";
1111 if (isNonTemporal())
3
Assuming the condition is false
4
Taking false branch
1112 OS << "non-temporal ";
1113 if (isDereferenceable())
5
Assuming the condition is false
6
Taking false branch
1114 OS << "dereferenceable ";
1115 if (isInvariant())
7
Assuming the condition is false
8
Taking false branch
1116 OS << "invariant ";
1117 if (TII) {
9
Assuming 'TII' is null
10
Taking false branch
1118 if (getFlags() & MachineMemOperand::MOTargetFlag1)
1119 OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
1120 << "\" ";
1121 if (getFlags() & MachineMemOperand::MOTargetFlag2)
1122 OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
1123 << "\" ";
1124 if (getFlags() & MachineMemOperand::MOTargetFlag3)
1125 OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
1126 << "\" ";
1127 } else {
1128 if (getFlags() & MachineMemOperand::MOTargetFlag1)
11
Assuming the condition is false
12
Taking false branch
1129 OS << "\"MOTargetFlag1\" ";
1130 if (getFlags() & MachineMemOperand::MOTargetFlag2)
13
Assuming the condition is false
14
Taking false branch
1131 OS << "\"MOTargetFlag2\" ";
1132 if (getFlags() & MachineMemOperand::MOTargetFlag3)
15
Assuming the condition is false
1133 OS << "\"MOTargetFlag3\" ";
1134 }
1135
1136 assert((isLoad() || isStore()) &&(static_cast <bool> ((isLoad() || isStore()) &&
"machine memory operand must be a load or store (or both)") ?
void (0) : __assert_fail ("(isLoad() || isStore()) && \"machine memory operand must be a load or store (or both)\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1137, __extension__ __PRETTY_FUNCTION__
))
16
Taking false branch
17
Assuming the condition is false
18
Assuming the condition is true
19
'?' condition is true
1137 "machine memory operand must be a load or store (or both)")(static_cast <bool> ((isLoad() || isStore()) &&
"machine memory operand must be a load or store (or both)") ?
void (0) : __assert_fail ("(isLoad() || isStore()) && \"machine memory operand must be a load or store (or both)\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1137, __extension__ __PRETTY_FUNCTION__
))
;
1138 if (isLoad())
20
Taking false branch
1139 OS << "load ";
1140 if (isStore())
21
Taking true branch
1141 OS << "store ";
1142
1143 printSyncScope(OS, Context, getSyncScopeID(), SSNs);
1144
1145 if (getSuccessOrdering() != AtomicOrdering::NotAtomic)
22
Assuming the condition is false
23
Taking false branch
1146 OS << toIRString(getSuccessOrdering()) << ' ';
1147 if (getFailureOrdering() != AtomicOrdering::NotAtomic)
24
Assuming the condition is false
25
Taking false branch
1148 OS << toIRString(getFailureOrdering()) << ' ';
1149
1150 if (getMemoryType().isValid())
26
Taking false branch
1151 OS << '(' << getMemoryType() << ')';
1152 else
1153 OS << "unknown-size";
1154
1155 if (const Value *Val
43.1
'Val' is null
43.1
'Val' is null
43.1
'Val' is null
43.1
'Val' is null
= getValue()) {
27
Calling 'MachineMemOperand::getValue'
43
Returning from 'MachineMemOperand::getValue'
44
Taking false branch
1156 OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
1157 MIRFormatter::printIRValue(OS, *Val, MST);
1158 } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
45
Calling 'MachineMemOperand::getPseudoValue'
69
Returning from 'MachineMemOperand::getPseudoValue'
70
Assuming 'PVal' is non-null
71
Taking true branch
1159 OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
72
'?' condition is false
1160 assert(PVal && "Expected a pseudo source value")(static_cast <bool> (PVal && "Expected a pseudo source value"
) ? void (0) : __assert_fail ("PVal && \"Expected a pseudo source value\""
, "llvm/lib/CodeGen/MachineOperand.cpp", 1160, __extension__ __PRETTY_FUNCTION__
))
;
73
'?' condition is true
1161 switch (PVal->kind()) {
74
Control jumps to the 'default' case at line 1190
1162 case PseudoSourceValue::Stack:
1163 OS << "stack";
1164 break;
1165 case PseudoSourceValue::GOT:
1166 OS << "got";
1167 break;
1168 case PseudoSourceValue::JumpTable:
1169 OS << "jump-table";
1170 break;
1171 case PseudoSourceValue::ConstantPool:
1172 OS << "constant-pool";
1173 break;
1174 case PseudoSourceValue::FixedStack: {
1175 int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
1176 bool IsFixed = true;
1177 printFrameIndex(OS, FrameIndex, IsFixed, MFI);
1178 break;
1179 }
1180 case PseudoSourceValue::GlobalValueCallEntry:
1181 OS << "call-entry ";
1182 cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
1183 OS, /*PrintType=*/false, MST);
1184 break;
1185 case PseudoSourceValue::ExternalSymbolCallEntry:
1186 OS << "call-entry &";
1187 printLLVMNameWithoutPrefix(
1188 OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
1189 break;
1190 default: {
1191 const MIRFormatter *Formatter = TII->getMIRFormatter();
75
Called C++ object pointer is null
1192 // FIXME: This is not necessarily the correct MIR serialization format for
1193 // a custom pseudo source value, but at least it allows
1194 // MIR printing to work on a target with custom pseudo source
1195 // values.
1196 OS << "custom \"";
1197 Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
1198 OS << '\"';
1199 break;
1200 }
1201 }
1202 } else if (getOpaqueValue() == nullptr && getOffset() != 0) {
1203 OS << ((isLoad() && isStore()) ? " on "
1204 : isLoad() ? " from "
1205 : " into ")
1206 << "unknown-address";
1207 }
1208 MachineOperand::printOperandOffset(OS, getOffset());
1209 if (getSize() > 0 && getAlign() != getSize())
1210 OS << ", align " << getAlign().value();
1211 if (getAlign() != getBaseAlign())
1212 OS << ", basealign " << getBaseAlign().value();
1213 auto AAInfo = getAAInfo();
1214 if (AAInfo.TBAA) {
1215 OS << ", !tbaa ";
1216 AAInfo.TBAA->printAsOperand(OS, MST);
1217 }
1218 if (AAInfo.Scope) {
1219 OS << ", !alias.scope ";
1220 AAInfo.Scope->printAsOperand(OS, MST);
1221 }
1222 if (AAInfo.NoAlias) {
1223 OS << ", !noalias ";
1224 AAInfo.NoAlias->printAsOperand(OS, MST);
1225 }
1226 if (getRanges()) {
1227 OS << ", !range ";
1228 getRanges()->printAsOperand(OS, MST);
1229 }
1230 // FIXME: Implement addrspace printing/parsing in MIR.
1231 // For now, print this even though parsing it is not available in MIR.
1232 if (unsigned AS = getAddrSpace())
1233 OS << ", addrspace " << AS;
1234
1235 OS << ')';
1236}

/build/source/llvm/include/llvm/CodeGen/MachineMemOperand.h

1//==- llvm/CodeGen/MachineMemOperand.h - MachineMemOperand class -*- 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 contains the declaration of the MachineMemOperand class, which is a
10// description of a memory reference. It is used to help track dependencies
11// in the backend.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_MACHINEMEMOPERAND_H
16#define LLVM_CODEGEN_MACHINEMEMOPERAND_H
17
18#include "llvm/ADT/BitmaskEnum.h"
19#include "llvm/ADT/PointerUnion.h"
20#include "llvm/CodeGen/PseudoSourceValue.h"
21#include "llvm/IR/DerivedTypes.h"
22#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
23#include "llvm/Support/AtomicOrdering.h"
24#include "llvm/Support/DataTypes.h"
25#include "llvm/Support/LowLevelTypeImpl.h"
26
27namespace llvm {
28
29class FoldingSetNodeID;
30class MDNode;
31class raw_ostream;
32class MachineFunction;
33class ModuleSlotTracker;
34class TargetInstrInfo;
35
36/// This class contains a discriminated union of information about pointers in
37/// memory operands, relating them back to LLVM IR or to virtual locations (such
38/// as frame indices) that are exposed during codegen.
39struct MachinePointerInfo {
40 /// This is the IR pointer value for the access, or it is null if unknown.
41 PointerUnion<const Value *, const PseudoSourceValue *> V;
42
43 /// Offset - This is an offset from the base Value*.
44 int64_t Offset;
45
46 unsigned AddrSpace = 0;
47
48 uint8_t StackID;
49
50 explicit MachinePointerInfo(const Value *v, int64_t offset = 0,
51 uint8_t ID = 0)
52 : V(v), Offset(offset), StackID(ID) {
53 AddrSpace = v ? v->getType()->getPointerAddressSpace() : 0;
54 }
55
56 explicit MachinePointerInfo(const PseudoSourceValue *v, int64_t offset = 0,
57 uint8_t ID = 0)
58 : V(v), Offset(offset), StackID(ID) {
59 AddrSpace = v ? v->getAddressSpace() : 0;
60 }
61
62 explicit MachinePointerInfo(unsigned AddressSpace = 0, int64_t offset = 0)
63 : V((const Value *)nullptr), Offset(offset), AddrSpace(AddressSpace),
64 StackID(0) {}
65
66 explicit MachinePointerInfo(
67 PointerUnion<const Value *, const PseudoSourceValue *> v,
68 int64_t offset = 0,
69 uint8_t ID = 0)
70 : V(v), Offset(offset), StackID(ID) {
71 if (V) {
72 if (const auto *ValPtr = V.dyn_cast<const Value*>())
73 AddrSpace = ValPtr->getType()->getPointerAddressSpace();
74 else
75 AddrSpace = V.get<const PseudoSourceValue*>()->getAddressSpace();
76 }
77 }
78
79 MachinePointerInfo getWithOffset(int64_t O) const {
80 if (V.isNull())
81 return MachinePointerInfo(AddrSpace, Offset + O);
82 if (V.is<const Value*>())
83 return MachinePointerInfo(V.get<const Value*>(), Offset + O, StackID);
84 return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset + O,
85 StackID);
86 }
87
88 /// Return true if memory region [V, V+Offset+Size) is known to be
89 /// dereferenceable.
90 bool isDereferenceable(unsigned Size, LLVMContext &C,
91 const DataLayout &DL) const;
92
93 /// Return the LLVM IR address space number that this pointer points into.
94 unsigned getAddrSpace() const;
95
96 /// Return a MachinePointerInfo record that refers to the constant pool.
97 static MachinePointerInfo getConstantPool(MachineFunction &MF);
98
99 /// Return a MachinePointerInfo record that refers to the specified
100 /// FrameIndex.
101 static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI,
102 int64_t Offset = 0);
103
104 /// Return a MachinePointerInfo record that refers to a jump table entry.
105 static MachinePointerInfo getJumpTable(MachineFunction &MF);
106
107 /// Return a MachinePointerInfo record that refers to a GOT entry.
108 static MachinePointerInfo getGOT(MachineFunction &MF);
109
110 /// Stack pointer relative access.
111 static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset,
112 uint8_t ID = 0);
113
114 /// Stack memory without other information.
115 static MachinePointerInfo getUnknownStack(MachineFunction &MF);
116};
117
118
119//===----------------------------------------------------------------------===//
120/// A description of a memory reference used in the backend.
121/// Instead of holding a StoreInst or LoadInst, this class holds the address
122/// Value of the reference along with a byte size and offset. This allows it
123/// to describe lowered loads and stores. Also, the special PseudoSourceValue
124/// objects can be used to represent loads and stores to memory locations
125/// that aren't explicit in the regular LLVM IR.
126///
127class MachineMemOperand {
128public:
129 /// Flags values. These may be or'd together.
130 enum Flags : uint16_t {
131 // No flags set.
132 MONone = 0,
133 /// The memory access reads data.
134 MOLoad = 1u << 0,
135 /// The memory access writes data.
136 MOStore = 1u << 1,
137 /// The memory access is volatile.
138 MOVolatile = 1u << 2,
139 /// The memory access is non-temporal.
140 MONonTemporal = 1u << 3,
141 /// The memory access is dereferenceable (i.e., doesn't trap).
142 MODereferenceable = 1u << 4,
143 /// The memory access always returns the same value (or traps).
144 MOInvariant = 1u << 5,
145
146 // Reserved for use by target-specific passes.
147 // Targets may override getSerializableMachineMemOperandTargetFlags() to
148 // enable MIR serialization/parsing of these flags. If more of these flags
149 // are added, the MIR printing/parsing code will need to be updated as well.
150 MOTargetFlag1 = 1u << 6,
151 MOTargetFlag2 = 1u << 7,
152 MOTargetFlag3 = 1u << 8,
153
154 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ MOTargetFlag3)LLVM_BITMASK_LARGEST_ENUMERATOR = MOTargetFlag3
155 };
156
157private:
158 /// Atomic information for this memory operation.
159 struct MachineAtomicInfo {
160 /// Synchronization scope ID for this memory operation.
161 unsigned SSID : 8; // SyncScope::ID
162 /// Atomic ordering requirements for this memory operation. For cmpxchg
163 /// atomic operations, atomic ordering requirements when store occurs.
164 unsigned Ordering : 4; // enum AtomicOrdering
165 /// For cmpxchg atomic operations, atomic ordering requirements when store
166 /// does not occur.
167 unsigned FailureOrdering : 4; // enum AtomicOrdering
168 };
169
170 MachinePointerInfo PtrInfo;
171
172 /// Track the memory type of the access. An access size which is unknown or
173 /// too large to be represented by LLT should use the invalid LLT.
174 LLT MemoryType;
175
176 Flags FlagVals;
177 Align BaseAlign;
178 MachineAtomicInfo AtomicInfo;
179 AAMDNodes AAInfo;
180 const MDNode *Ranges;
181
182public:
183 /// Construct a MachineMemOperand object with the specified PtrInfo, flags,
184 /// size, and base alignment. For atomic operations the synchronization scope
185 /// and atomic ordering requirements must also be specified. For cmpxchg
186 /// atomic operations the atomic ordering requirements when store does not
187 /// occur must also be specified.
188 MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, uint64_t s,
189 Align a, const AAMDNodes &AAInfo = AAMDNodes(),
190 const MDNode *Ranges = nullptr,
191 SyncScope::ID SSID = SyncScope::System,
192 AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
193 AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
194 MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, LLT type, Align a,
195 const AAMDNodes &AAInfo = AAMDNodes(),
196 const MDNode *Ranges = nullptr,
197 SyncScope::ID SSID = SyncScope::System,
198 AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
199 AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
200
201 const MachinePointerInfo &getPointerInfo() const { return PtrInfo; }
202
203 /// Return the base address of the memory access. This may either be a normal
204 /// LLVM IR Value, or one of the special values used in CodeGen.
205 /// Special values are those obtained via
206 /// PseudoSourceValue::getFixedStack(int), PseudoSourceValue::getStack, and
207 /// other PseudoSourceValue member functions which return objects which stand
208 /// for frame/stack pointer relative references and other special references
209 /// which are not representable in the high-level IR.
210 const Value *getValue() const { return PtrInfo.V.dyn_cast<const Value*>(); }
28
Calling 'PointerUnion::dyn_cast'
41
Returning from 'PointerUnion::dyn_cast'
42
Returning null pointer, which participates in a condition later
211
212 const PseudoSourceValue *getPseudoValue() const {
213 return PtrInfo.V.dyn_cast<const PseudoSourceValue*>();
46
Calling 'PointerUnion::dyn_cast'
67
Returning from 'PointerUnion::dyn_cast'
68
Returning pointer, which participates in a condition later
214 }
215
216 const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); }
217
218 /// Return the raw flags of the source value, \see Flags.
219 Flags getFlags() const { return FlagVals; }
220
221 /// Bitwise OR the current flags with the given flags.
222 void setFlags(Flags f) { FlagVals |= f; }
223
224 /// For normal values, this is a byte offset added to the base address.
225 /// For PseudoSourceValue::FPRel values, this is the FrameIndex number.
226 int64_t getOffset() const { return PtrInfo.Offset; }
227
228 unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
229
230 /// Return the memory type of the memory reference. This should only be relied
231 /// on for GlobalISel G_* operation legalization.
232 LLT getMemoryType() const { return MemoryType; }
233
234 /// Return the size in bytes of the memory reference.
235 uint64_t getSize() const {
236 return MemoryType.isValid() ? MemoryType.getSizeInBytes() : ~UINT64_C(0)0UL;
237 }
238
239 /// Return the size in bits of the memory reference.
240 uint64_t getSizeInBits() const {
241 return MemoryType.isValid() ? MemoryType.getSizeInBits() : ~UINT64_C(0)0UL;
242 }
243
244 LLT getType() const {
245 return MemoryType;
246 }
247
248 /// Return the minimum known alignment in bytes of the actual memory
249 /// reference.
250 Align getAlign() const;
251
252 /// Return the minimum known alignment in bytes of the base address, without
253 /// the offset.
254 Align getBaseAlign() const { return BaseAlign; }
255
256 /// Return the AA tags for the memory reference.
257 AAMDNodes getAAInfo() const { return AAInfo; }
258
259 /// Return the range tag for the memory reference.
260 const MDNode *getRanges() const { return Ranges; }
261
262 /// Returns the synchronization scope ID for this memory operation.
263 SyncScope::ID getSyncScopeID() const {
264 return static_cast<SyncScope::ID>(AtomicInfo.SSID);
265 }
266
267 /// Return the atomic ordering requirements for this memory operation. For
268 /// cmpxchg atomic operations, return the atomic ordering requirements when
269 /// store occurs.
270 AtomicOrdering getSuccessOrdering() const {
271 return static_cast<AtomicOrdering>(AtomicInfo.Ordering);
272 }
273
274 /// For cmpxchg atomic operations, return the atomic ordering requirements
275 /// when store does not occur.
276 AtomicOrdering getFailureOrdering() const {
277 return static_cast<AtomicOrdering>(AtomicInfo.FailureOrdering);
278 }
279
280 /// Return a single atomic ordering that is at least as strong as both the
281 /// success and failure orderings for an atomic operation. (For operations
282 /// other than cmpxchg, this is equivalent to getSuccessOrdering().)
283 AtomicOrdering getMergedOrdering() const {
284 return getMergedAtomicOrdering(getSuccessOrdering(), getFailureOrdering());
285 }
286
287 bool isLoad() const { return FlagVals & MOLoad; }
288 bool isStore() const { return FlagVals & MOStore; }
289 bool isVolatile() const { return FlagVals & MOVolatile; }
290 bool isNonTemporal() const { return FlagVals & MONonTemporal; }
291 bool isDereferenceable() const { return FlagVals & MODereferenceable; }
292 bool isInvariant() const { return FlagVals & MOInvariant; }
293
294 /// Returns true if this operation has an atomic ordering requirement of
295 /// unordered or higher, false otherwise.
296 bool isAtomic() const {
297 return getSuccessOrdering() != AtomicOrdering::NotAtomic;
298 }
299
300 /// Returns true if this memory operation doesn't have any ordering
301 /// constraints other than normal aliasing. Volatile and (ordered) atomic
302 /// memory operations can't be reordered.
303 bool isUnordered() const {
304 return (getSuccessOrdering() == AtomicOrdering::NotAtomic ||
305 getSuccessOrdering() == AtomicOrdering::Unordered) &&
306 !isVolatile();
307 }
308
309 /// Update this MachineMemOperand to reflect the alignment of MMO, if it has a
310 /// greater alignment. This must only be used when the new alignment applies
311 /// to all users of this MachineMemOperand.
312 void refineAlignment(const MachineMemOperand *MMO);
313
314 /// Change the SourceValue for this MachineMemOperand. This should only be
315 /// used when an object is being relocated and all references to it are being
316 /// updated.
317 void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
318 void setValue(const PseudoSourceValue *NewSV) { PtrInfo.V = NewSV; }
319 void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
320
321 /// Reset the tracked memory type.
322 void setType(LLT NewTy) {
323 MemoryType = NewTy;
324 }
325
326 /// Profile - Gather unique data for the object.
327 ///
328 void Profile(FoldingSetNodeID &ID) const;
329
330 /// Support for operator<<.
331 /// @{
332 void print(raw_ostream &OS, ModuleSlotTracker &MST,
333 SmallVectorImpl<StringRef> &SSNs, const LLVMContext &Context,
334 const MachineFrameInfo *MFI, const TargetInstrInfo *TII) const;
335 /// @}
336
337 friend bool operator==(const MachineMemOperand &LHS,
338 const MachineMemOperand &RHS) {
339 return LHS.getValue() == RHS.getValue() &&
340 LHS.getPseudoValue() == RHS.getPseudoValue() &&
341 LHS.getSize() == RHS.getSize() &&
342 LHS.getOffset() == RHS.getOffset() &&
343 LHS.getFlags() == RHS.getFlags() &&
344 LHS.getAAInfo() == RHS.getAAInfo() &&
345 LHS.getRanges() == RHS.getRanges() &&
346 LHS.getAlign() == RHS.getAlign() &&
347 LHS.getAddrSpace() == RHS.getAddrSpace();
348 }
349
350 friend bool operator!=(const MachineMemOperand &LHS,
351 const MachineMemOperand &RHS) {
352 return !(LHS == RHS);
353 }
354};
355
356} // End llvm namespace
357
358#endif

/build/source/llvm/include/llvm/ADT/PointerUnion.h

1//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- 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/// \file
10/// This file defines the PointerUnion class, which is a discriminated union of
11/// pointer types.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_POINTERUNION_H
16#define LLVM_ADT_POINTERUNION_H
17
18#include "llvm/ADT/DenseMapInfo.h"
19#include "llvm/ADT/PointerIntPair.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/PointerLikeTypeTraits.h"
23#include <algorithm>
24#include <cassert>
25#include <cstddef>
26#include <cstdint>
27
28namespace llvm {
29
30namespace pointer_union_detail {
31 /// Determine the number of bits required to store integers with values < n.
32 /// This is ceil(log2(n)).
33 constexpr int bitsRequired(unsigned n) {
34 return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0;
35 }
36
37 template <typename... Ts> constexpr int lowBitsAvailable() {
38 return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...});
39 }
40
41 /// Find the first type in a list of types.
42 template <typename T, typename...> struct GetFirstType {
43 using type = T;
44 };
45
46 /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
47 /// for the template arguments.
48 template <typename ...PTs> class PointerUnionUIntTraits {
49 public:
50 static inline void *getAsVoidPointer(void *P) { return P; }
51 static inline void *getFromVoidPointer(void *P) { return P; }
52 static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>();
53 };
54
55 template <typename Derived, typename ValTy, int I, typename ...Types>
56 class PointerUnionMembers;
57
58 template <typename Derived, typename ValTy, int I>
59 class PointerUnionMembers<Derived, ValTy, I> {
60 protected:
61 ValTy Val;
62 PointerUnionMembers() = default;
63 PointerUnionMembers(ValTy Val) : Val(Val) {}
64
65 friend struct PointerLikeTypeTraits<Derived>;
66 };
67
68 template <typename Derived, typename ValTy, int I, typename Type,
69 typename ...Types>
70 class PointerUnionMembers<Derived, ValTy, I, Type, Types...>
71 : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> {
72 using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>;
73 public:
74 using Base::Base;
75 PointerUnionMembers() = default;
76 PointerUnionMembers(Type V)
77 : Base(ValTy(const_cast<void *>(
78 PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
79 I)) {}
80
81 using Base::operator=;
82 Derived &operator=(Type V) {
83 this->Val = ValTy(
84 const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
85 I);
86 return static_cast<Derived &>(*this);
87 };
88 };
89}
90
91// This is a forward declaration of CastInfoPointerUnionImpl
92// Refer to its definition below for further details
93template <typename... PTs> struct CastInfoPointerUnionImpl;
94/// A discriminated union of two or more pointer types, with the discriminator
95/// in the low bit of the pointer.
96///
97/// This implementation is extremely efficient in space due to leveraging the
98/// low bits of the pointer, while exposing a natural and type-safe API.
99///
100/// Common use patterns would be something like this:
101/// PointerUnion<int*, float*> P;
102/// P = (int*)0;
103/// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
104/// X = P.get<int*>(); // ok.
105/// Y = P.get<float*>(); // runtime assertion failure.
106/// Z = P.get<double*>(); // compile time failure.
107/// P = (float*)0;
108/// Y = P.get<float*>(); // ok.
109/// X = P.get<int*>(); // runtime assertion failure.
110/// PointerUnion<int*, int*> Q; // compile time failure.
111template <typename... PTs>
112class PointerUnion
113 : public pointer_union_detail::PointerUnionMembers<
114 PointerUnion<PTs...>,
115 PointerIntPair<
116 void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
117 pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
118 0, PTs...> {
119 static_assert(TypesAreDistinct<PTs...>::value,
120 "PointerUnion alternative types cannot be repeated");
121 // The first type is special because we want to directly cast a pointer to a
122 // default-initialized union to a pointer to the first type. But we don't
123 // want PointerUnion to be a 'template <typename First, typename ...Rest>'
124 // because it's much more convenient to have a name for the whole pack. So
125 // split off the first type here.
126 using First = TypeAtIndex<0, PTs...>;
127 using Base = typename PointerUnion::PointerUnionMembers;
128
129 /// This is needed to give the CastInfo implementation below access
130 /// to protected members.
131 /// Refer to its definition for further details.
132 friend struct CastInfoPointerUnionImpl<PTs...>;
133
134public:
135 PointerUnion() = default;
136
137 PointerUnion(std::nullptr_t) : PointerUnion() {}
138 using Base::Base;
139
140 /// Test if the pointer held in the union is null, regardless of
141 /// which type it is.
142 bool isNull() const { return !this->Val.getPointer(); }
143
144 explicit operator bool() const { return !isNull(); }
145
146 // FIXME: Replace the uses of is(), get() and dyn_cast() with
147 // isa<T>, cast<T> and the llvm::dyn_cast<T>
148
149 /// Test if the Union currently holds the type matching T.
150 template <typename T> inline bool is() const { return isa<T>(*this); }
151
152 /// Returns the value of the specified pointer type.
153 ///
154 /// If the specified pointer type is incorrect, assert.
155 template <typename T> inline T get() const {
156 assert(isa<T>(*this) && "Invalid accessor called")(static_cast <bool> (isa<T>(*this) && "Invalid accessor called"
) ? void (0) : __assert_fail ("isa<T>(*this) && \"Invalid accessor called\""
, "llvm/include/llvm/ADT/PointerUnion.h", 156, __extension__ __PRETTY_FUNCTION__
))
;
157 return cast<T>(*this);
158 }
159
160 /// Returns the current pointer if it is of the specified pointer type,
161 /// otherwise returns null.
162 template <typename T> inline T dyn_cast() const {
163 return llvm::dyn_cast_if_present<T>(*this);
29
Calling 'dyn_cast_if_present<const llvm::Value *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
39
Returning from 'dyn_cast_if_present<const llvm::Value *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
40
Returning null pointer, which participates in a condition later
47
Calling 'dyn_cast_if_present<const llvm::PseudoSourceValue *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
65
Returning from 'dyn_cast_if_present<const llvm::PseudoSourceValue *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
66
Returning pointer, which participates in a condition later
164 }
165
166 /// If the union is set to the first pointer type get an address pointing to
167 /// it.
168 First const *getAddrOfPtr1() const {
169 return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
170 }
171
172 /// If the union is set to the first pointer type get an address pointing to
173 /// it.
174 First *getAddrOfPtr1() {
175 assert(is<First>() && "Val is not the first pointer")(static_cast <bool> (is<First>() && "Val is not the first pointer"
) ? void (0) : __assert_fail ("is<First>() && \"Val is not the first pointer\""
, "llvm/include/llvm/ADT/PointerUnion.h", 175, __extension__ __PRETTY_FUNCTION__
))
;
176 assert((static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(get<First>()) == this->Val.getPointer
() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\""
, "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__
))
177 PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) ==(static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(get<First>()) == this->Val.getPointer
() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\""
, "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__
))
178 this->Val.getPointer() &&(static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(get<First>()) == this->Val.getPointer
() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\""
, "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__
))
179 "Can't get the address because PointerLikeTypeTraits changes the ptr")(static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(get<First>()) == this->Val.getPointer
() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == this->Val.getPointer() && \"Can't get the address because PointerLikeTypeTraits changes the ptr\""
, "llvm/include/llvm/ADT/PointerUnion.h", 179, __extension__ __PRETTY_FUNCTION__
))
;
180 return const_cast<First *>(
181 reinterpret_cast<const First *>(this->Val.getAddrOfPointer()));
182 }
183
184 /// Assignment from nullptr which just clears the union.
185 const PointerUnion &operator=(std::nullptr_t) {
186 this->Val.initWithPointer(nullptr);
187 return *this;
188 }
189
190 /// Assignment from elements of the union.
191 using Base::operator=;
192
193 void *getOpaqueValue() const { return this->Val.getOpaqueValue(); }
194 static inline PointerUnion getFromOpaqueValue(void *VP) {
195 PointerUnion V;
196 V.Val = decltype(V.Val)::getFromOpaqueValue(VP);
197 return V;
198 }
199};
200
201template <typename ...PTs>
202bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
203 return lhs.getOpaqueValue() == rhs.getOpaqueValue();
204}
205
206template <typename ...PTs>
207bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
208 return lhs.getOpaqueValue() != rhs.getOpaqueValue();
209}
210
211template <typename ...PTs>
212bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
213 return lhs.getOpaqueValue() < rhs.getOpaqueValue();
214}
215
216/// We can't (at least, at this moment with C++14) declare CastInfo
217/// as a friend of PointerUnion like this:
218/// ```
219/// template<typename To>
220/// friend struct CastInfo<To, PointerUnion<PTs...>>;
221/// ```
222/// The compiler complains 'Partial specialization cannot be declared as a
223/// friend'.
224/// So we define this struct to be a bridge between CastInfo and
225/// PointerUnion.
226template <typename... PTs> struct CastInfoPointerUnionImpl {
227 using From = PointerUnion<PTs...>;
228
229 template <typename To> static inline bool isPossible(From &F) {
230 return F.Val.getInt() == FirstIndexOfType<To, PTs...>::value;
231 }
232
233 template <typename To> static To doCast(From &F) {
234 assert(isPossible<To>(F) && "cast to an incompatible type !")(static_cast <bool> (isPossible<To>(F) &&
"cast to an incompatible type !") ? void (0) : __assert_fail
("isPossible<To>(F) && \"cast to an incompatible type !\""
, "llvm/include/llvm/ADT/PointerUnion.h", 234, __extension__ __PRETTY_FUNCTION__
))
;
55
'?' condition is true
235 return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer());
56
Returning pointer, which participates in a condition later
236 }
237};
238
239// Specialization of CastInfo for PointerUnion
240template <typename To, typename... PTs>
241struct CastInfo<To, PointerUnion<PTs...>>
242 : public DefaultDoCastIfPossible<To, PointerUnion<PTs...>,
243 CastInfo<To, PointerUnion<PTs...>>> {
244 using From = PointerUnion<PTs...>;
245 using Impl = CastInfoPointerUnionImpl<PTs...>;
246
247 static inline bool isPossible(From &f) {
248 return Impl::template isPossible<To>(f);
249 }
250
251 static To doCast(From &f) { return Impl::template doCast<To>(f); }
54
Calling 'CastInfoPointerUnionImpl::doCast'
57
Returning from 'CastInfoPointerUnionImpl::doCast'
58
Returning pointer, which participates in a condition later
252
253 static inline To castFailed() { return To(); }
34
Returning null pointer, which participates in a condition later
254};
255
256template <typename To, typename... PTs>
257struct CastInfo<To, const PointerUnion<PTs...>>
258 : public ConstStrippingForwardingCast<To, const PointerUnion<PTs...>,
259 CastInfo<To, PointerUnion<PTs...>>> {
260};
261
262// Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
263// # low bits available = min(PT1bits,PT2bits)-1.
264template <typename ...PTs>
265struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
266 static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) {
267 return P.getOpaqueValue();
268 }
269
270 static inline PointerUnion<PTs...> getFromVoidPointer(void *P) {
271 return PointerUnion<PTs...>::getFromOpaqueValue(P);
272 }
273
274 // The number of bits available are the min of the pointer types minus the
275 // bits needed for the discriminator.
276 static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype(
277 PointerUnion<PTs...>::Val)>::NumLowBitsAvailable;
278};
279
280// Teach DenseMap how to use PointerUnions as keys.
281template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
282 using Union = PointerUnion<PTs...>;
283 using FirstInfo =
284 DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
285
286 static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
287
288 static inline Union getTombstoneKey() {
289 return Union(FirstInfo::getTombstoneKey());
290 }
291
292 static unsigned getHashValue(const Union &UnionVal) {
293 intptr_t key = (intptr_t)UnionVal.getOpaqueValue();
294 return DenseMapInfo<intptr_t>::getHashValue(key);
295 }
296
297 static bool isEqual(const Union &LHS, const Union &RHS) {
298 return LHS == RHS;
299 }
300};
301
302} // end namespace llvm
303
304#endif // LLVM_ADT_POINTERUNION_H

/build/source/llvm/include/llvm/Support/Casting.h

1//===- llvm/Support/Casting.h - Allow flexible, checked, casts --*- 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 defines the isa<X>(), cast<X>(), dyn_cast<X>(),
10// cast_if_present<X>(), and dyn_cast_if_present<X>() templates.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_CASTING_H
15#define LLVM_SUPPORT_CASTING_H
16
17#include "llvm/ADT/Optional.h"
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/type_traits.h"
20#include <cassert>
21#include <memory>
22#include <type_traits>
23
24namespace llvm {
25
26//===----------------------------------------------------------------------===//
27// simplify_type
28//===----------------------------------------------------------------------===//
29
30/// Define a template that can be specialized by smart pointers to reflect the
31/// fact that they are automatically dereferenced, and are not involved with the
32/// template selection process... the default implementation is a noop.
33// TODO: rename this and/or replace it with other cast traits.
34template <typename From> struct simplify_type {
35 using SimpleType = From; // The real type this represents...
36
37 // An accessor to get the real value...
38 static SimpleType &getSimplifiedValue(From &Val) { return Val; }
39};
40
41template <typename From> struct simplify_type<const From> {
42 using NonConstSimpleType = typename simplify_type<From>::SimpleType;
43 using SimpleType = typename add_const_past_pointer<NonConstSimpleType>::type;
44 using RetType =
45 typename add_lvalue_reference_if_not_pointer<SimpleType>::type;
46
47 static RetType getSimplifiedValue(const From &Val) {
48 return simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val));
49 }
50};
51
52// TODO: add this namespace once everyone is switched to using the new
53// interface.
54// namespace detail {
55
56//===----------------------------------------------------------------------===//
57// isa_impl
58//===----------------------------------------------------------------------===//
59
60// The core of the implementation of isa<X> is here; To and From should be
61// the names of classes. This template can be specialized to customize the
62// implementation of isa<> without rewriting it from scratch.
63template <typename To, typename From, typename Enabler = void> struct isa_impl {
64 static inline bool doit(const From &Val) { return To::classof(&Val); }
65};
66
67// Always allow upcasts, and perform no dynamic check for them.
68template <typename To, typename From>
69struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> {
70 static inline bool doit(const From &) { return true; }
71};
72
73template <typename To, typename From> struct isa_impl_cl {
74 static inline bool doit(const From &Val) {
75 return isa_impl<To, From>::doit(Val);
76 }
77};
78
79template <typename To, typename From> struct isa_impl_cl<To, const From> {
80 static inline bool doit(const From &Val) {
81 return isa_impl<To, From>::doit(Val);
82 }
83};
84
85template <typename To, typename From>
86struct isa_impl_cl<To, const std::unique_ptr<From>> {
87 static inline bool doit(const std::unique_ptr<From> &Val) {
88 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "llvm/include/llvm/Support/Casting.h", 88, __extension__ __PRETTY_FUNCTION__
))
;
89 return isa_impl_cl<To, From>::doit(*Val);
90 }
91};
92
93template <typename To, typename From> struct isa_impl_cl<To, From *> {
94 static inline bool doit(const From *Val) {
95 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "llvm/include/llvm/Support/Casting.h", 95, __extension__ __PRETTY_FUNCTION__
))
;
96 return isa_impl<To, From>::doit(*Val);
97 }
98};
99
100template <typename To, typename From> struct isa_impl_cl<To, From *const> {
101 static inline bool doit(const From *Val) {
102 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "llvm/include/llvm/Support/Casting.h", 102, __extension__ __PRETTY_FUNCTION__
))
;
103 return isa_impl<To, From>::doit(*Val);
104 }
105};
106
107template <typename To, typename From> struct isa_impl_cl<To, const From *> {
108 static inline bool doit(const From *Val) {
109 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "llvm/include/llvm/Support/Casting.h", 109, __extension__ __PRETTY_FUNCTION__
))
;
110 return isa_impl<To, From>::doit(*Val);
111 }
112};
113
114template <typename To, typename From>
115struct isa_impl_cl<To, const From *const> {
116 static inline bool doit(const From *Val) {
117 assert(Val && "isa<> used on a null pointer")(static_cast <bool> (Val && "isa<> used on a null pointer"
) ? void (0) : __assert_fail ("Val && \"isa<> used on a null pointer\""
, "llvm/include/llvm/Support/Casting.h", 117, __extension__ __PRETTY_FUNCTION__
))
;
118 return isa_impl<To, From>::doit(*Val);
119 }
120};
121
122template <typename To, typename From, typename SimpleFrom>
123struct isa_impl_wrap {
124 // When From != SimplifiedType, we can simplify the type some more by using
125 // the simplify_type template.
126 static bool doit(const From &Val) {
127 return isa_impl_wrap<To, SimpleFrom,
128 typename simplify_type<SimpleFrom>::SimpleType>::
129 doit(simplify_type<const From>::getSimplifiedValue(Val));
130 }
131};
132
133template <typename To, typename FromTy>
134struct isa_impl_wrap<To, FromTy, FromTy> {
135 // When From == SimpleType, we are as simple as we are going to get.
136 static bool doit(const FromTy &Val) {
137 return isa_impl_cl<To, FromTy>::doit(Val);
138 }
139};
140
141//===----------------------------------------------------------------------===//
142// cast_retty + cast_retty_impl
143//===----------------------------------------------------------------------===//
144
145template <class To, class From> struct cast_retty;
146
147// Calculate what type the 'cast' function should return, based on a requested
148// type of To and a source type of From.
149template <class To, class From> struct cast_retty_impl {
150 using ret_type = To &; // Normal case, return Ty&
151};
152template <class To, class From> struct cast_retty_impl<To, const From> {
153 using ret_type = const To &; // Normal case, return Ty&
154};
155
156template <class To, class From> struct cast_retty_impl<To, From *> {
157 using ret_type = To *; // Pointer arg case, return Ty*
158};
159
160template <class To, class From> struct cast_retty_impl<To, const From *> {
161 using ret_type = const To *; // Constant pointer arg case, return const Ty*
162};
163
164template <class To, class From> struct cast_retty_impl<To, const From *const> {
165 using ret_type = const To *; // Constant pointer arg case, return const Ty*
166};
167
168template <class To, class From>
169struct cast_retty_impl<To, std::unique_ptr<From>> {
170private:
171 using PointerType = typename cast_retty_impl<To, From *>::ret_type;
172 using ResultType = std::remove_pointer_t<PointerType>;
173
174public:
175 using ret_type = std::unique_ptr<ResultType>;
176};
177
178template <class To, class From, class SimpleFrom> struct cast_retty_wrap {
179 // When the simplified type and the from type are not the same, use the type
180 // simplifier to reduce the type, then reuse cast_retty_impl to get the
181 // resultant type.
182 using ret_type = typename cast_retty<To, SimpleFrom>::ret_type;
183};
184
185template <class To, class FromTy> struct cast_retty_wrap<To, FromTy, FromTy> {
186 // When the simplified type is equal to the from type, use it directly.
187 using ret_type = typename cast_retty_impl<To, FromTy>::ret_type;
188};
189
190template <class To, class From> struct cast_retty {
191 using ret_type = typename cast_retty_wrap<
192 To, From, typename simplify_type<From>::SimpleType>::ret_type;
193};
194
195//===----------------------------------------------------------------------===//
196// cast_convert_val
197//===----------------------------------------------------------------------===//
198
199// Ensure the non-simple values are converted using the simplify_type template
200// that may be specialized by smart pointers...
201//
202template <class To, class From, class SimpleFrom> struct cast_convert_val {
203 // This is not a simple type, use the template to simplify it...
204 static typename cast_retty<To, From>::ret_type doit(const From &Val) {
205 return cast_convert_val<To, SimpleFrom,
206 typename simplify_type<SimpleFrom>::SimpleType>::
207 doit(simplify_type<From>::getSimplifiedValue(const_cast<From &>(Val)));
208 }
209};
210
211template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> {
212 // If it's a reference, switch to a pointer to do the cast and then deref it.
213 static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
214 return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
215 *)&const_cast<FromTy &>(Val);
216 }
217};
218
219template <class To, class FromTy>
220struct cast_convert_val<To, FromTy *, FromTy *> {
221 // If it's a pointer, we can use c-style casting directly.
222 static typename cast_retty<To, FromTy *>::ret_type doit(const FromTy *Val) {
223 return (typename cast_retty<To, FromTy *>::ret_type) const_cast<FromTy *>(
224 Val);
225 }
226};
227
228//===----------------------------------------------------------------------===//
229// is_simple_type
230//===----------------------------------------------------------------------===//
231
232template <class X> struct is_simple_type {
233 static const bool value =
234 std::is_same<X, typename simplify_type<X>::SimpleType>::value;
235};
236
237// } // namespace detail
238
239//===----------------------------------------------------------------------===//
240// CastIsPossible
241//===----------------------------------------------------------------------===//
242
243/// This struct provides a way to check if a given cast is possible. It provides
244/// a static function called isPossible that is used to check if a cast can be
245/// performed. It should be overridden like this:
246///
247/// template<> struct CastIsPossible<foo, bar> {
248/// static inline bool isPossible(const bar &b) {
249/// return bar.isFoo();
250/// }
251/// };
252template <typename To, typename From, typename Enable = void>
253struct CastIsPossible {
254 static inline bool isPossible(const From &f) {
255 return isa_impl_wrap<
256 To, const From,
257 typename simplify_type<const From>::SimpleType>::doit(f);
258 }
259};
260
261// Needed for optional unwrapping. This could be implemented with isa_impl, but
262// we want to implement things in the new method and move old implementations
263// over. In fact, some of the isa_impl templates should be moved over to
264// CastIsPossible.
265template <typename To, typename From>
266struct CastIsPossible<To, Optional<From>> {
267 static inline bool isPossible(const Optional<From> &f) {
268 assert(f && "CastIsPossible::isPossible called on a nullopt!")(static_cast <bool> (f && "CastIsPossible::isPossible called on a nullopt!"
) ? void (0) : __assert_fail ("f && \"CastIsPossible::isPossible called on a nullopt!\""
, "llvm/include/llvm/Support/Casting.h", 268, __extension__ __PRETTY_FUNCTION__
))
;
269 return isa_impl_wrap<
270 To, const From,
271 typename simplify_type<const From>::SimpleType>::doit(*f);
272 }
273};
274
275/// Upcasting (from derived to base) and casting from a type to itself should
276/// always be possible.
277template <typename To, typename From>
278struct CastIsPossible<To, From,
279 std::enable_if_t<std::is_base_of<To, From>::value>> {
280 static inline bool isPossible(const From &f) { return true; }
281};
282
283//===----------------------------------------------------------------------===//
284// Cast traits
285//===----------------------------------------------------------------------===//
286
287/// All of these cast traits are meant to be implementations for useful casts
288/// that users may want to use that are outside the standard behavior. An
289/// example of how to use a special cast called `CastTrait` is:
290///
291/// template<> struct CastInfo<foo, bar> : public CastTrait<foo, bar> {};
292///
293/// Essentially, if your use case falls directly into one of the use cases
294/// supported by a given cast trait, simply inherit your special CastInfo
295/// directly from one of these to avoid having to reimplement the boilerplate
296/// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also
297/// provide a subset of those functions.
298
299/// This cast trait just provides castFailed for the specified `To` type to make
300/// CastInfo specializations more declarative. In order to use this, the target
301/// result type must be `To` and `To` must be constructible from `nullptr`.
302template <typename To> struct NullableValueCastFailed {
303 static To castFailed() { return To(nullptr); }
304};
305
306/// This cast trait just provides the default implementation of doCastIfPossible
307/// to make CastInfo specializations more declarative. The `Derived` template
308/// parameter *must* be provided for forwarding castFailed and doCast.
309template <typename To, typename From, typename Derived>
310struct DefaultDoCastIfPossible {
311 static To doCastIfPossible(From f) {
312 if (!Derived::isPossible(f))
52
Taking false branch
313 return Derived::castFailed();
314 return Derived::doCast(f);
53
Calling 'CastInfo::doCast'
59
Returning from 'CastInfo::doCast'
60
Returning pointer, which participates in a condition later
315 }
316};
317
318namespace detail {
319/// A helper to derive the type to use with `Self` for cast traits, when the
320/// provided CRTP derived type is allowed to be void.
321template <typename OptionalDerived, typename Default>
322using SelfType = std::conditional_t<std::is_same<OptionalDerived, void>::value,
323 Default, OptionalDerived>;
324} // namespace detail
325
326/// This cast trait provides casting for the specific case of casting to a
327/// value-typed object from a pointer-typed object. Note that `To` must be
328/// nullable/constructible from a pointer to `From` to use this cast.
329template <typename To, typename From, typename Derived = void>
330struct ValueFromPointerCast
331 : public CastIsPossible<To, From *>,
332 public NullableValueCastFailed<To>,
333 public DefaultDoCastIfPossible<
334 To, From *,
335 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
336 static inline To doCast(From *f) { return To(f); }
337};
338
339/// This cast trait provides std::unique_ptr casting. It has the semantics of
340/// moving the contents of the input unique_ptr into the output unique_ptr
341/// during the cast. It's also a good example of how to implement a move-only
342/// cast.
343template <typename To, typename From, typename Derived = void>
344struct UniquePtrCast : public CastIsPossible<To, From *> {
345 using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>;
346 using CastResultType = std::unique_ptr<
347 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
348
349 static inline CastResultType doCast(std::unique_ptr<From> &&f) {
350 return CastResultType((typename CastResultType::element_type *)f.release());
351 }
352
353 static inline CastResultType castFailed() { return CastResultType(nullptr); }
354
355 static inline CastResultType doCastIfPossible(std::unique_ptr<From> &&f) {
356 if (!Self::isPossible(f))
357 return castFailed();
358 return doCast(f);
359 }
360};
361
362/// This cast trait provides Optional<T> casting. This means that if you have a
363/// value type, you can cast it to another value type and have dyn_cast return
364/// an Optional<T>.
365template <typename To, typename From, typename Derived = void>
366struct OptionalValueCast
367 : public CastIsPossible<To, From>,
368 public DefaultDoCastIfPossible<
369 Optional<To>, From,
370 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
371 static inline Optional<To> castFailed() { return Optional<To>{}; }
372
373 static inline Optional<To> doCast(const From &f) { return To(f); }
374};
375
376/// Provides a cast trait that strips `const` from types to make it easier to
377/// implement a const-version of a non-const cast. It just removes boilerplate
378/// and reduces the amount of code you as the user need to implement. You can
379/// use it like this:
380///
381/// template<> struct CastInfo<foo, bar> {
382/// ...verbose implementation...
383/// };
384///
385/// template<> struct CastInfo<foo, const bar> : public
386/// ConstStrippingForwardingCast<foo, const bar, CastInfo<foo, bar>> {};
387///
388template <typename To, typename From, typename ForwardTo>
389struct ConstStrippingForwardingCast {
390 // Remove the pointer if it exists, then we can get rid of consts/volatiles.
391 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
392 // Now if it's a pointer, add it back. Otherwise, we want a ref.
393 using NonConstFrom = std::conditional_t<std::is_pointer<From>::value,
394 DecayedFrom *, DecayedFrom &>;
395
396 static inline bool isPossible(const From &f) {
397 return ForwardTo::isPossible(const_cast<NonConstFrom>(f));
398 }
399
400 static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); }
33
Calling 'CastInfo::castFailed'
35
Returning from 'CastInfo::castFailed'
36
Returning null pointer, which participates in a condition later
401
402 static inline decltype(auto) doCast(const From &f) {
403 return ForwardTo::doCast(const_cast<NonConstFrom>(f));
404 }
405
406 static inline decltype(auto) doCastIfPossible(const From &f) {
407 return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));
51
Calling 'DefaultDoCastIfPossible::doCastIfPossible'
61
Returning from 'DefaultDoCastIfPossible::doCastIfPossible'
62
Returning pointer, which participates in a condition later
408 }
409};
410
411/// Provides a cast trait that uses a defined pointer to pointer cast as a base
412/// for reference-to-reference casts. Note that it does not provide castFailed
413/// and doCastIfPossible because a pointer-to-pointer cast would likely just
414/// return `nullptr` which could cause nullptr dereference. You can use it like
415/// this:
416///
417/// template <> struct CastInfo<foo, bar *> { ... verbose implementation... };
418///
419/// template <>
420/// struct CastInfo<foo, bar>
421/// : public ForwardToPointerCast<foo, bar, CastInfo<foo, bar *>> {};
422///
423template <typename To, typename From, typename ForwardTo>
424struct ForwardToPointerCast {
425 static inline bool isPossible(const From &f) {
426 return ForwardTo::isPossible(&f);
427 }
428
429 static inline decltype(auto) doCast(const From &f) {
430 return *ForwardTo::doCast(&f);
431 }
432};
433
434//===----------------------------------------------------------------------===//
435// CastInfo
436//===----------------------------------------------------------------------===//
437
438/// This struct provides a method for customizing the way a cast is performed.
439/// It inherits from CastIsPossible, to support the case of declaring many
440/// CastIsPossible specializations without having to specialize the full
441/// CastInfo.
442///
443/// In order to specialize different behaviors, specify different functions in
444/// your CastInfo specialization.
445/// For isa<> customization, provide:
446///
447/// `static bool isPossible(const From &f)`
448///
449/// For cast<> customization, provide:
450///
451/// `static To doCast(const From &f)`
452///
453/// For dyn_cast<> and the *_if_present<> variants' customization, provide:
454///
455/// `static To castFailed()` and `static To doCastIfPossible(const From &f)`
456///
457/// Your specialization might look something like this:
458///
459/// template<> struct CastInfo<foo, bar> : public CastIsPossible<foo, bar> {
460/// static inline foo doCast(const bar &b) {
461/// return foo(const_cast<bar &>(b));
462/// }
463/// static inline foo castFailed() { return foo(); }
464/// static inline foo doCastIfPossible(const bar &b) {
465/// if (!CastInfo<foo, bar>::isPossible(b))
466/// return castFailed();
467/// return doCast(b);
468/// }
469/// };
470
471// The default implementations of CastInfo don't use cast traits for now because
472// we need to specify types all over the place due to the current expected
473// casting behavior and the way cast_retty works. New use cases can and should
474// take advantage of the cast traits whenever possible!
475
476template <typename To, typename From, typename Enable = void>
477struct CastInfo : public CastIsPossible<To, From> {
478 using Self = CastInfo<To, From, Enable>;
479
480 using CastReturnType = typename cast_retty<To, From>::ret_type;
481
482 static inline CastReturnType doCast(const From &f) {
483 return cast_convert_val<
484 To, From,
485 typename simplify_type<From>::SimpleType>::doit(const_cast<From &>(f));
486 }
487
488 // This assumes that you can construct the cast return type from `nullptr`.
489 // This is largely to support legacy use cases - if you don't want this
490 // behavior you should specialize CastInfo for your use case.
491 static inline CastReturnType castFailed() { return CastReturnType(nullptr); }
492
493 static inline CastReturnType doCastIfPossible(const From &f) {
494 if (!Self::isPossible(f))
495 return castFailed();
496 return doCast(f);
497 }
498};
499
500/// This struct provides an overload for CastInfo where From has simplify_type
501/// defined. This simply forwards to the appropriate CastInfo with the
502/// simplified type/value, so you don't have to implement both.
503template <typename To, typename From>
504struct CastInfo<To, From, std::enable_if_t<!is_simple_type<From>::value>> {
505 using Self = CastInfo<To, From>;
506 using SimpleFrom = typename simplify_type<From>::SimpleType;
507 using SimplifiedSelf = CastInfo<To, SimpleFrom>;
508
509 static inline bool isPossible(From &f) {
510 return SimplifiedSelf::isPossible(
511 simplify_type<From>::getSimplifiedValue(f));
512 }
513
514 static inline decltype(auto) doCast(From &f) {
515 return SimplifiedSelf::doCast(simplify_type<From>::getSimplifiedValue(f));
516 }
517
518 static inline decltype(auto) castFailed() {
519 return SimplifiedSelf::castFailed();
520 }
521
522 static inline decltype(auto) doCastIfPossible(From &f) {
523 return SimplifiedSelf::doCastIfPossible(
524 simplify_type<From>::getSimplifiedValue(f));
525 }
526};
527
528//===----------------------------------------------------------------------===//
529// Pre-specialized CastInfo
530//===----------------------------------------------------------------------===//
531
532/// Provide a CastInfo specialized for std::unique_ptr.
533template <typename To, typename From>
534struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {};
535
536/// Provide a CastInfo specialized for Optional<From>. It's assumed that if the
537/// input is Optional<From> that the output can be Optional<To>. If that's not
538/// the case, specialize CastInfo for your use case.
539template <typename To, typename From>
540struct CastInfo<To, Optional<From>> : public OptionalValueCast<To, From> {};
541
542/// isa<X> - Return true if the parameter to the template is an instance of one
543/// of the template type arguments. Used like this:
544///
545/// if (isa<Type>(myVal)) { ... }
546/// if (isa<Type0, Type1, Type2>(myVal)) { ... }
547template <typename To, typename From>
548[[nodiscard]] inline bool isa(const From &Val) {
549 return CastInfo<To, const From>::isPossible(Val);
550}
551
552template <typename First, typename Second, typename... Rest, typename From>
553[[nodiscard]] inline bool isa(const From &Val) {
554 return isa<First>(Val) || isa<Second, Rest...>(Val);
555}
556
557/// cast<X> - Return the argument parameter cast to the specified type. This
558/// casting operator asserts that the type is correct, so it does not return
559/// null on failure. It does not allow a null argument (use cast_if_present for
560/// that). It is typically used like this:
561///
562/// cast<Instruction>(myVal)->getParent()
563
564template <typename To, typename From>
565[[nodiscard]] inline decltype(auto) cast(const From &Val) {
566 assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 566, __extension__ __PRETTY_FUNCTION__
))
;
567 return CastInfo<To, const From>::doCast(Val);
568}
569
570template <typename To, typename From>
571[[nodiscard]] inline decltype(auto) cast(From &Val) {
572 assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 572, __extension__ __PRETTY_FUNCTION__
))
;
573 return CastInfo<To, From>::doCast(Val);
574}
575
576template <typename To, typename From>
577[[nodiscard]] inline decltype(auto) cast(From *Val) {
578 assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 578, __extension__ __PRETTY_FUNCTION__
))
;
579 return CastInfo<To, From *>::doCast(Val);
580}
581
582template <typename To, typename From>
583[[nodiscard]] inline decltype(auto) cast(std::unique_ptr<From> &&Val) {
584 assert(isa<To>(Val) && "cast<Ty>() argument of incompatible type!")(static_cast <bool> (isa<To>(Val) && "cast<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<To>(Val) && \"cast<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 584, __extension__ __PRETTY_FUNCTION__
))
;
585 return CastInfo<To, std::unique_ptr<From>>::doCast(std::move(Val));
586}
587
588//===----------------------------------------------------------------------===//
589// ValueIsPresent
590//===----------------------------------------------------------------------===//
591
592template <typename T>
593constexpr bool IsNullable =
594 std::is_pointer_v<T> || std::is_constructible_v<T, std::nullptr_t>;
595
596/// ValueIsPresent provides a way to check if a value is, well, present. For
597/// pointers, this is the equivalent of checking against nullptr, for Optionals
598/// this is the equivalent of checking hasValue(). It also provides a method for
599/// unwrapping a value (think calling .value() on an optional).
600
601// Generic values can't *not* be present.
602template <typename T, typename Enable = void> struct ValueIsPresent {
603 using UnwrappedType = T;
604 static inline bool isPresent(const T &t) { return true; }
605 static inline decltype(auto) unwrapValue(T &t) { return t; }
606};
607
608// Optional provides its own way to check if something is present.
609template <typename T> struct ValueIsPresent<Optional<T>> {
610 using UnwrappedType = T;
611 static inline bool isPresent(const Optional<T> &t) { return t.has_value(); }
612 static inline decltype(auto) unwrapValue(Optional<T> &t) { return t.value(); }
613};
614
615// If something is "nullable" then we just compare it to nullptr to see if it
616// exists.
617template <typename T>
618struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> {
619 using UnwrappedType = T;
620 static inline bool isPresent(const T &t) { return t != T(nullptr); }
621 static inline decltype(auto) unwrapValue(T &t) { return t; }
622};
623
624namespace detail {
625// Convenience function we can use to check if a value is present. Because of
626// simplify_type, we have to call it on the simplified type for now.
627template <typename T> inline bool isPresent(const T &t) {
628 return ValueIsPresent<typename simplify_type<T>::SimpleType>::isPresent(
629 simplify_type<T>::getSimplifiedValue(const_cast<T &>(t)));
630}
631
632// Convenience function we can use to unwrap a value.
633template <typename T> inline decltype(auto) unwrapValue(T &t) {
634 return ValueIsPresent<T>::unwrapValue(t);
635}
636} // namespace detail
637
638/// dyn_cast<X> - Return the argument parameter cast to the specified type. This
639/// casting operator returns null if the argument is of the wrong type, so it
640/// can be used to test for a type as well as cast if successful. The value
641/// passed in must be present, if not, use dyn_cast_if_present. This should be
642/// used in the context of an if statement like this:
643///
644/// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
645
646template <typename To, typename From>
647[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) {
648 assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value"
) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\""
, "llvm/include/llvm/Support/Casting.h", 648, __extension__ __PRETTY_FUNCTION__
))
;
649 return CastInfo<To, const From>::doCastIfPossible(Val);
650}
651
652template <typename To, typename From>
653[[nodiscard]] inline decltype(auto) dyn_cast(From &Val) {
654 assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value"
) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\""
, "llvm/include/llvm/Support/Casting.h", 654, __extension__ __PRETTY_FUNCTION__
))
;
655 return CastInfo<To, From>::doCastIfPossible(Val);
656}
657
658template <typename To, typename From>
659[[nodiscard]] inline decltype(auto) dyn_cast(From *Val) {
660 assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value"
) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\""
, "llvm/include/llvm/Support/Casting.h", 660, __extension__ __PRETTY_FUNCTION__
))
;
661 return CastInfo<To, From *>::doCastIfPossible(Val);
662}
663
664template <typename To, typename From>
665[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) {
666 assert(detail::isPresent(Val) && "dyn_cast on a non-existent value")(static_cast <bool> (detail::isPresent(Val) && "dyn_cast on a non-existent value"
) ? void (0) : __assert_fail ("detail::isPresent(Val) && \"dyn_cast on a non-existent value\""
, "llvm/include/llvm/Support/Casting.h", 666, __extension__ __PRETTY_FUNCTION__
))
;
667 return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible(
668 std::forward<std::unique_ptr<From> &&>(Val));
669}
670
671/// isa_and_present<X> - Functionally identical to isa, except that a null value
672/// is accepted.
673template <typename... X, class Y>
674[[nodiscard]] inline bool isa_and_present(const Y &Val) {
675 if (!detail::isPresent(Val))
676 return false;
677 return isa<X...>(Val);
678}
679
680template <typename... X, class Y>
681[[nodiscard]] inline bool isa_and_nonnull(const Y &Val) {
682 return isa_and_present<X...>(Val);
683}
684
685/// cast_if_present<X> - Functionally identical to cast, except that a null
686/// value is accepted.
687template <class X, class Y>
688[[nodiscard]] inline auto cast_if_present(const Y &Val) {
689 if (!detail::isPresent(Val))
690 return CastInfo<X, const Y>::castFailed();
691 assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 691, __extension__ __PRETTY_FUNCTION__
))
;
692 return cast<X>(detail::unwrapValue(Val));
693}
694
695template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) {
696 if (!detail::isPresent(Val))
697 return CastInfo<X, Y>::castFailed();
698 assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 698, __extension__ __PRETTY_FUNCTION__
))
;
699 return cast<X>(detail::unwrapValue(Val));
700}
701
702template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) {
703 if (!detail::isPresent(Val))
704 return CastInfo<X, Y *>::castFailed();
705 assert(isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!")(static_cast <bool> (isa<X>(Val) && "cast_if_present<Ty>() argument of incompatible type!"
) ? void (0) : __assert_fail ("isa<X>(Val) && \"cast_if_present<Ty>() argument of incompatible type!\""
, "llvm/include/llvm/Support/Casting.h", 705, __extension__ __PRETTY_FUNCTION__
))
;
706 return cast<X>(detail::unwrapValue(Val));
707}
708
709template <class X, class Y>
710[[nodiscard]] inline auto cast_if_present(std::unique_ptr<Y> &&Val) {
711 if (!detail::isPresent(Val))
712 return UniquePtrCast<X, Y>::castFailed();
713 return UniquePtrCast<X, Y>::doCast(std::move(Val));
714}
715
716// Provide a forwarding from cast_or_null to cast_if_present for current
717// users. This is deprecated and will be removed in a future patch, use
718// cast_if_present instead.
719template <class X, class Y> auto cast_or_null(const Y &Val) {
720 return cast_if_present<X>(Val);
721}
722
723template <class X, class Y> auto cast_or_null(Y &Val) {
724 return cast_if_present<X>(Val);
725}
726
727template <class X, class Y> auto cast_or_null(Y *Val) {
728 return cast_if_present<X>(Val);
729}
730
731template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) {
732 return cast_if_present<X>(std::move(Val));
733}
734
735/// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a
736/// null (or none in the case of optionals) value is accepted.
737template <class X, class Y> auto dyn_cast_if_present(const Y &Val) {
738 if (!detail::isPresent(Val))
30
Assuming the condition is true
31
Taking true branch
48
Assuming the condition is false
49
Taking false branch
739 return CastInfo<X, const Y>::castFailed();
32
Calling 'ConstStrippingForwardingCast::castFailed'
37
Returning from 'ConstStrippingForwardingCast::castFailed'
38
Returning null pointer, which participates in a condition later
740 return CastInfo<X, const Y>::doCastIfPossible(detail::unwrapValue(Val));
50
Calling 'ConstStrippingForwardingCast::doCastIfPossible'
63
Returning from 'ConstStrippingForwardingCast::doCastIfPossible'
64
Returning pointer, which participates in a condition later
741}
742
743template <class X, class Y> auto dyn_cast_if_present(Y &Val) {
744 if (!detail::isPresent(Val))
745 return CastInfo<X, Y>::castFailed();
746 return CastInfo<X, Y>::doCastIfPossible(detail::unwrapValue(Val));
747}
748
749template <class X, class Y> auto dyn_cast_if_present(Y *Val) {
750 if (!detail::isPresent(Val))
751 return CastInfo<X, Y *>::castFailed();
752 return CastInfo<X, Y *>::doCastIfPossible(detail::unwrapValue(Val));
753}
754
755// Forwards to dyn_cast_if_present to avoid breaking current users. This is
756// deprecated and will be removed in a future patch, use
757// cast_if_present instead.
758template <class X, class Y> auto dyn_cast_or_null(const Y &Val) {
759 return dyn_cast_if_present<X>(Val);
760}
761
762template <class X, class Y> auto dyn_cast_or_null(Y &Val) {
763 return dyn_cast_if_present<X>(Val);
764}
765
766template <class X, class Y> auto dyn_cast_or_null(Y *Val) {
767 return dyn_cast_if_present<X>(Val);
768}
769
770/// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
771/// taking ownership of the input pointer iff isa<X>(Val) is true. If the
772/// cast is successful, From refers to nullptr on exit and the casted value
773/// is returned. If the cast is unsuccessful, the function returns nullptr
774/// and From is unchanged.
775template <class X, class Y>
776[[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
777unique_dyn_cast(std::unique_ptr<Y> &Val) {
778 if (!isa<X>(Val))
779 return nullptr;
780 return cast<X>(std::move(Val));
781}
782
783template <class X, class Y>
784[[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) {
785 return unique_dyn_cast<X, Y>(Val);
786}
787
788// unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast,
789// except that a null value is accepted.
790template <class X, class Y>
791[[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
792unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) {
793 if (!Val)
794 return nullptr;
795 return unique_dyn_cast<X, Y>(Val);
796}
797
798template <class X, class Y>
799[[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) {
800 return unique_dyn_cast_or_null<X, Y>(Val);
801}
802
803} // end namespace llvm
804
805#endif // LLVM_SUPPORT_CASTING_H