Bug Summary

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

/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/LowLevelType.h"
21#include "llvm/CodeGen/PseudoSourceValue.h"
22#include "llvm/IR/DerivedTypes.h"
23#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
24#include "llvm/Support/AtomicOrdering.h"
25#include "llvm/Support/DataTypes.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 = dyn_cast_if_present<const Value *>(V))
73 AddrSpace = ValPtr->getType()->getPointerAddressSpace();
74 else
75 AddrSpace = cast<const PseudoSourceValue *>(V)->getAddressSpace();
76 }
77 }
78
79 MachinePointerInfo getWithOffset(int64_t O) const {
80 if (V.isNull())
81 return MachinePointerInfo(AddrSpace, Offset + O);
82 if (isa<const Value *>(V))
83 return MachinePointerInfo(cast<const Value *>(V), Offset + O, StackID);
84 return MachinePointerInfo(cast<const PseudoSourceValue *>(V), 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 {
211 return dyn_cast_if_present<const Value *>(PtrInfo.V);
28
Calling 'dyn_cast_if_present<const llvm::Value *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
38
Returning from 'dyn_cast_if_present<const llvm::Value *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
39
Returning null pointer, which participates in a condition later
212 }
213
214 const PseudoSourceValue *getPseudoValue() const {
215 return dyn_cast_if_present<const PseudoSourceValue *>(PtrInfo.V);
43
Calling 'dyn_cast_if_present<const llvm::PseudoSourceValue *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
61
Returning from 'dyn_cast_if_present<const llvm::PseudoSourceValue *, llvm::PointerUnion<const llvm::Value *, const llvm::PseudoSourceValue *>>'
62
Returning pointer, which participates in a condition later
216 }
217
218 const void *getOpaqueValue() const { return PtrInfo.V.getOpaqueValue(); }
219
220 /// Return the raw flags of the source value, \see Flags.
221 Flags getFlags() const { return FlagVals; }
222
223 /// Bitwise OR the current flags with the given flags.
224 void setFlags(Flags f) { FlagVals |= f; }
225
226 /// For normal values, this is a byte offset added to the base address.
227 /// For PseudoSourceValue::FPRel values, this is the FrameIndex number.
228 int64_t getOffset() const { return PtrInfo.Offset; }
229
230 unsigned getAddrSpace() const { return PtrInfo.getAddrSpace(); }
231
232 /// Return the memory type of the memory reference. This should only be relied
233 /// on for GlobalISel G_* operation legalization.
234 LLT getMemoryType() const { return MemoryType; }
235
236 /// Return the size in bytes of the memory reference.
237 uint64_t getSize() const {
238 return MemoryType.isValid() ? MemoryType.getSizeInBytes() : ~UINT64_C(0)0UL;
239 }
240
241 /// Return the size in bits of the memory reference.
242 uint64_t getSizeInBits() const {
243 return MemoryType.isValid() ? MemoryType.getSizeInBits() : ~UINT64_C(0)0UL;
244 }
245
246 LLT getType() const {
247 return MemoryType;
248 }
249
250 /// Return the minimum known alignment in bytes of the actual memory
251 /// reference.
252 Align getAlign() const;
253
254 /// Return the minimum known alignment in bytes of the base address, without
255 /// the offset.
256 Align getBaseAlign() const { return BaseAlign; }
257
258 /// Return the AA tags for the memory reference.
259 AAMDNodes getAAInfo() const { return AAInfo; }
260
261 /// Return the range tag for the memory reference.
262 const MDNode *getRanges() const { return Ranges; }
263
264 /// Returns the synchronization scope ID for this memory operation.
265 SyncScope::ID getSyncScopeID() const {
266 return static_cast<SyncScope::ID>(AtomicInfo.SSID);
267 }
268
269 /// Return the atomic ordering requirements for this memory operation. For
270 /// cmpxchg atomic operations, return the atomic ordering requirements when
271 /// store occurs.
272 AtomicOrdering getSuccessOrdering() const {
273 return static_cast<AtomicOrdering>(AtomicInfo.Ordering);
274 }
275
276 /// For cmpxchg atomic operations, return the atomic ordering requirements
277 /// when store does not occur.
278 AtomicOrdering getFailureOrdering() const {
279 return static_cast<AtomicOrdering>(AtomicInfo.FailureOrdering);
280 }
281
282 /// Return a single atomic ordering that is at least as strong as both the
283 /// success and failure orderings for an atomic operation. (For operations
284 /// other than cmpxchg, this is equivalent to getSuccessOrdering().)
285 AtomicOrdering getMergedOrdering() const {
286 return getMergedAtomicOrdering(getSuccessOrdering(), getFailureOrdering());
287 }
288
289 bool isLoad() const { return FlagVals & MOLoad; }
290 bool isStore() const { return FlagVals & MOStore; }
291 bool isVolatile() const { return FlagVals & MOVolatile; }
292 bool isNonTemporal() const { return FlagVals & MONonTemporal; }
293 bool isDereferenceable() const { return FlagVals & MODereferenceable; }
294 bool isInvariant() const { return FlagVals & MOInvariant; }
295
296 /// Returns true if this operation has an atomic ordering requirement of
297 /// unordered or higher, false otherwise.
298 bool isAtomic() const {
299 return getSuccessOrdering() != AtomicOrdering::NotAtomic;
300 }
301
302 /// Returns true if this memory operation doesn't have any ordering
303 /// constraints other than normal aliasing. Volatile and (ordered) atomic
304 /// memory operations can't be reordered.
305 bool isUnordered() const {
306 return (getSuccessOrdering() == AtomicOrdering::NotAtomic ||
307 getSuccessOrdering() == AtomicOrdering::Unordered) &&
308 !isVolatile();
309 }
310
311 /// Update this MachineMemOperand to reflect the alignment of MMO, if it has a
312 /// greater alignment. This must only be used when the new alignment applies
313 /// to all users of this MachineMemOperand.
314 void refineAlignment(const MachineMemOperand *MMO);
315
316 /// Change the SourceValue for this MachineMemOperand. This should only be
317 /// used when an object is being relocated and all references to it are being
318 /// updated.
319 void setValue(const Value *NewSV) { PtrInfo.V = NewSV; }
320 void setValue(const PseudoSourceValue *NewSV) { PtrInfo.V = NewSV; }
321 void setOffset(int64_t NewOffset) { PtrInfo.Offset = NewOffset; }
322
323 /// Reset the tracked memory type.
324 void setType(LLT NewTy) {
325 MemoryType = NewTy;
326 }
327
328 /// Profile - Gather unique data for the object.
329 ///
330 void Profile(FoldingSetNodeID &ID) const;
331
332 /// Support for operator<<.
333 /// @{
334 void print(raw_ostream &OS, ModuleSlotTracker &MST,
335 SmallVectorImpl<StringRef> &SSNs, const LLVMContext &Context,
336 const MachineFrameInfo *MFI, const TargetInstrInfo *TII) const;
337 /// @}
338
339 friend bool operator==(const MachineMemOperand &LHS,
340 const MachineMemOperand &RHS) {
341 return LHS.getValue() == RHS.getValue() &&
342 LHS.getPseudoValue() == RHS.getPseudoValue() &&
343 LHS.getSize() == RHS.getSize() &&
344 LHS.getOffset() == RHS.getOffset() &&
345 LHS.getFlags() == RHS.getFlags() &&
346 LHS.getAAInfo() == RHS.getAAInfo() &&
347 LHS.getRanges() == RHS.getRanges() &&
348 LHS.getAlign() == RHS.getAlign() &&
349 LHS.getAddrSpace() == RHS.getAddrSpace();
350 }
351
352 friend bool operator!=(const MachineMemOperand &LHS,
353 const MachineMemOperand &RHS) {
354 return !(LHS == RHS);
355 }
356};
357
358} // End llvm namespace
359
360#endif

/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/Support/Compiler.h"
18#include "llvm/Support/type_traits.h"
19#include <cassert>
20#include <memory>
21#include <optional>
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_v<To, From>>> {
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_v<X, typename simplify_type<X>::SimpleType>;
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, std::optional<From>> {
267 static inline bool isPossible(const std::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, std::enable_if_t<std::is_base_of_v<To, From>>> {
279 static inline bool isPossible(const From &f) { return true; }
280};
281
282//===----------------------------------------------------------------------===//
283// Cast traits
284//===----------------------------------------------------------------------===//
285
286/// All of these cast traits are meant to be implementations for useful casts
287/// that users may want to use that are outside the standard behavior. An
288/// example of how to use a special cast called `CastTrait` is:
289///
290/// template<> struct CastInfo<foo, bar> : public CastTrait<foo, bar> {};
291///
292/// Essentially, if your use case falls directly into one of the use cases
293/// supported by a given cast trait, simply inherit your special CastInfo
294/// directly from one of these to avoid having to reimplement the boilerplate
295/// `isPossible/castFailed/doCast/doCastIfPossible`. A cast trait can also
296/// provide a subset of those functions.
297
298/// This cast trait just provides castFailed for the specified `To` type to make
299/// CastInfo specializations more declarative. In order to use this, the target
300/// result type must be `To` and `To` must be constructible from `nullptr`.
301template <typename To> struct NullableValueCastFailed {
302 static To castFailed() { return To(nullptr); }
303};
304
305/// This cast trait just provides the default implementation of doCastIfPossible
306/// to make CastInfo specializations more declarative. The `Derived` template
307/// parameter *must* be provided for forwarding castFailed and doCast.
308template <typename To, typename From, typename Derived>
309struct DefaultDoCastIfPossible {
310 static To doCastIfPossible(From f) {
311 if (!Derived::isPossible(f))
48
Taking false branch
312 return Derived::castFailed();
313 return Derived::doCast(f);
49
Calling 'CastInfo::doCast'
55
Returning from 'CastInfo::doCast'
56
Returning pointer, which participates in a condition later
314 }
315};
316
317namespace detail {
318/// A helper to derive the type to use with `Self` for cast traits, when the
319/// provided CRTP derived type is allowed to be void.
320template <typename OptionalDerived, typename Default>
321using SelfType = std::conditional_t<std::is_same_v<OptionalDerived, void>,
322 Default, OptionalDerived>;
323} // namespace detail
324
325/// This cast trait provides casting for the specific case of casting to a
326/// value-typed object from a pointer-typed object. Note that `To` must be
327/// nullable/constructible from a pointer to `From` to use this cast.
328template <typename To, typename From, typename Derived = void>
329struct ValueFromPointerCast
330 : public CastIsPossible<To, From *>,
331 public NullableValueCastFailed<To>,
332 public DefaultDoCastIfPossible<
333 To, From *,
334 detail::SelfType<Derived, ValueFromPointerCast<To, From>>> {
335 static inline To doCast(From *f) { return To(f); }
336};
337
338/// This cast trait provides std::unique_ptr casting. It has the semantics of
339/// moving the contents of the input unique_ptr into the output unique_ptr
340/// during the cast. It's also a good example of how to implement a move-only
341/// cast.
342template <typename To, typename From, typename Derived = void>
343struct UniquePtrCast : public CastIsPossible<To, From *> {
344 using Self = detail::SelfType<Derived, UniquePtrCast<To, From>>;
345 using CastResultType = std::unique_ptr<
346 std::remove_reference_t<typename cast_retty<To, From>::ret_type>>;
347
348 static inline CastResultType doCast(std::unique_ptr<From> &&f) {
349 return CastResultType((typename CastResultType::element_type *)f.release());
350 }
351
352 static inline CastResultType castFailed() { return CastResultType(nullptr); }
353
354 static inline CastResultType doCastIfPossible(std::unique_ptr<From> &&f) {
355 if (!Self::isPossible(f))
356 return castFailed();
357 return doCast(f);
358 }
359};
360
361/// This cast trait provides std::optional<T> casting. This means that if you
362/// have a value type, you can cast it to another value type and have dyn_cast
363/// return an std::optional<T>.
364template <typename To, typename From, typename Derived = void>
365struct OptionalValueCast
366 : public CastIsPossible<To, From>,
367 public DefaultDoCastIfPossible<
368 std::optional<To>, From,
369 detail::SelfType<Derived, OptionalValueCast<To, From>>> {
370 static inline std::optional<To> castFailed() { return std::optional<To>{}; }
371
372 static inline std::optional<To> doCast(const From &f) { return To(f); }
373};
374
375/// Provides a cast trait that strips `const` from types to make it easier to
376/// implement a const-version of a non-const cast. It just removes boilerplate
377/// and reduces the amount of code you as the user need to implement. You can
378/// use it like this:
379///
380/// template<> struct CastInfo<foo, bar> {
381/// ...verbose implementation...
382/// };
383///
384/// template<> struct CastInfo<foo, const bar> : public
385/// ConstStrippingForwardingCast<foo, const bar, CastInfo<foo, bar>> {};
386///
387template <typename To, typename From, typename ForwardTo>
388struct ConstStrippingForwardingCast {
389 // Remove the pointer if it exists, then we can get rid of consts/volatiles.
390 using DecayedFrom = std::remove_cv_t<std::remove_pointer_t<From>>;
391 // Now if it's a pointer, add it back. Otherwise, we want a ref.
392 using NonConstFrom =
393 std::conditional_t<std::is_pointer_v<From>, DecayedFrom *, DecayedFrom &>;
394
395 static inline bool isPossible(const From &f) {
396 return ForwardTo::isPossible(const_cast<NonConstFrom>(f));
397 }
398
399 static inline decltype(auto) castFailed() { return ForwardTo::castFailed(); }
32
Calling 'CastInfo::castFailed'
34
Returning from 'CastInfo::castFailed'
35
Returning null pointer, which participates in a condition later
400
401 static inline decltype(auto) doCast(const From &f) {
402 return ForwardTo::doCast(const_cast<NonConstFrom>(f));
403 }
404
405 static inline decltype(auto) doCastIfPossible(const From &f) {
406 return ForwardTo::doCastIfPossible(const_cast<NonConstFrom>(f));
47
Calling 'DefaultDoCastIfPossible::doCastIfPossible'
57
Returning from 'DefaultDoCastIfPossible::doCastIfPossible'
58
Returning pointer, which participates in a condition later
407 }
408};
409
410/// Provides a cast trait that uses a defined pointer to pointer cast as a base
411/// for reference-to-reference casts. Note that it does not provide castFailed
412/// and doCastIfPossible because a pointer-to-pointer cast would likely just
413/// return `nullptr` which could cause nullptr dereference. You can use it like
414/// this:
415///
416/// template <> struct CastInfo<foo, bar *> { ... verbose implementation... };
417///
418/// template <>
419/// struct CastInfo<foo, bar>
420/// : public ForwardToPointerCast<foo, bar, CastInfo<foo, bar *>> {};
421///
422template <typename To, typename From, typename ForwardTo>
423struct ForwardToPointerCast {
424 static inline bool isPossible(const From &f) {
425 return ForwardTo::isPossible(&f);
426 }
427
428 static inline decltype(auto) doCast(const From &f) {
429 return *ForwardTo::doCast(&f);
430 }
431};
432
433//===----------------------------------------------------------------------===//
434// CastInfo
435//===----------------------------------------------------------------------===//
436
437/// This struct provides a method for customizing the way a cast is performed.
438/// It inherits from CastIsPossible, to support the case of declaring many
439/// CastIsPossible specializations without having to specialize the full
440/// CastInfo.
441///
442/// In order to specialize different behaviors, specify different functions in
443/// your CastInfo specialization.
444/// For isa<> customization, provide:
445///
446/// `static bool isPossible(const From &f)`
447///
448/// For cast<> customization, provide:
449///
450/// `static To doCast(const From &f)`
451///
452/// For dyn_cast<> and the *_if_present<> variants' customization, provide:
453///
454/// `static To castFailed()` and `static To doCastIfPossible(const From &f)`
455///
456/// Your specialization might look something like this:
457///
458/// template<> struct CastInfo<foo, bar> : public CastIsPossible<foo, bar> {
459/// static inline foo doCast(const bar &b) {
460/// return foo(const_cast<bar &>(b));
461/// }
462/// static inline foo castFailed() { return foo(); }
463/// static inline foo doCastIfPossible(const bar &b) {
464/// if (!CastInfo<foo, bar>::isPossible(b))
465/// return castFailed();
466/// return doCast(b);
467/// }
468/// };
469
470// The default implementations of CastInfo don't use cast traits for now because
471// we need to specify types all over the place due to the current expected
472// casting behavior and the way cast_retty works. New use cases can and should
473// take advantage of the cast traits whenever possible!
474
475template <typename To, typename From, typename Enable = void>
476struct CastInfo : public CastIsPossible<To, From> {
477 using Self = CastInfo<To, From, Enable>;
478
479 using CastReturnType = typename cast_retty<To, From>::ret_type;
480
481 static inline CastReturnType doCast(const From &f) {
482 return cast_convert_val<
483 To, From,
484 typename simplify_type<From>::SimpleType>::doit(const_cast<From &>(f));
485 }
486
487 // This assumes that you can construct the cast return type from `nullptr`.
488 // This is largely to support legacy use cases - if you don't want this
489 // behavior you should specialize CastInfo for your use case.
490 static inline CastReturnType castFailed() { return CastReturnType(nullptr); }
491
492 static inline CastReturnType doCastIfPossible(const From &f) {
493 if (!Self::isPossible(f))
494 return castFailed();
495 return doCast(f);
496 }
497};
498
499/// This struct provides an overload for CastInfo where From has simplify_type
500/// defined. This simply forwards to the appropriate CastInfo with the
501/// simplified type/value, so you don't have to implement both.
502template <typename To, typename From>
503struct CastInfo<To, From, std::enable_if_t<!is_simple_type<From>::value>> {
504 using Self = CastInfo<To, From>;
505 using SimpleFrom = typename simplify_type<From>::SimpleType;
506 using SimplifiedSelf = CastInfo<To, SimpleFrom>;
507
508 static inline bool isPossible(From &f) {
509 return SimplifiedSelf::isPossible(
510 simplify_type<From>::getSimplifiedValue(f));
511 }
512
513 static inline decltype(auto) doCast(From &f) {
514 return SimplifiedSelf::doCast(simplify_type<From>::getSimplifiedValue(f));
515 }
516
517 static inline decltype(auto) castFailed() {
518 return SimplifiedSelf::castFailed();
519 }
520
521 static inline decltype(auto) doCastIfPossible(From &f) {
522 return SimplifiedSelf::doCastIfPossible(
523 simplify_type<From>::getSimplifiedValue(f));
524 }
525};
526
527//===----------------------------------------------------------------------===//
528// Pre-specialized CastInfo
529//===----------------------------------------------------------------------===//
530
531/// Provide a CastInfo specialized for std::unique_ptr.
532template <typename To, typename From>
533struct CastInfo<To, std::unique_ptr<From>> : public UniquePtrCast<To, From> {};
534
535/// Provide a CastInfo specialized for std::optional<From>. It's assumed that if
536/// the input is std::optional<From> that the output can be std::optional<To>.
537/// If that's not the case, specialize CastInfo for your use case.
538template <typename To, typename From>
539struct CastInfo<To, std::optional<From>> : public OptionalValueCast<To, From> {
540};
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<std::optional<T>> {
610 using UnwrappedType = T;
611 static inline bool isPresent(const std::optional<T> &t) {
612 return t.has_value();
613 }
614 static inline decltype(auto) unwrapValue(std::optional<T> &t) { return *t; }
615};
616
617// If something is "nullable" then we just compare it to nullptr to see if it
618// exists.
619template <typename T>
620struct ValueIsPresent<T, std::enable_if_t<IsNullable<T>>> {
621 using UnwrappedType = T;
622 static inline bool isPresent(const T &t) { return t != T(nullptr); }
623 static inline decltype(auto) unwrapValue(T &t) { return t; }
624};
625
626namespace detail {
627// Convenience function we can use to check if a value is present. Because of
628// simplify_type, we have to call it on the simplified type for now.
629template <typename T> inline bool isPresent(const T &t) {
630 return ValueIsPresent<typename simplify_type<T>::SimpleType>::isPresent(
631 simplify_type<T>::getSimplifiedValue(const_cast<T &>(t)));
632}
633
634// Convenience function we can use to unwrap a value.
635template <typename T> inline decltype(auto) unwrapValue(T &t) {
636 return ValueIsPresent<T>::unwrapValue(t);
637}
638} // namespace detail
639
640/// dyn_cast<X> - Return the argument parameter cast to the specified type. This
641/// casting operator returns null if the argument is of the wrong type, so it
642/// can be used to test for a type as well as cast if successful. The value
643/// passed in must be present, if not, use dyn_cast_if_present. This should be
644/// used in the context of an if statement like this:
645///
646/// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
647
648template <typename To, typename From>
649[[nodiscard]] inline decltype(auto) dyn_cast(const From &Val) {
650 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", 650, __extension__ __PRETTY_FUNCTION__
))
;
651 return CastInfo<To, const From>::doCastIfPossible(Val);
652}
653
654template <typename To, typename From>
655[[nodiscard]] inline decltype(auto) dyn_cast(From &Val) {
656 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", 656, __extension__ __PRETTY_FUNCTION__
))
;
657 return CastInfo<To, From>::doCastIfPossible(Val);
658}
659
660template <typename To, typename From>
661[[nodiscard]] inline decltype(auto) dyn_cast(From *Val) {
662 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", 662, __extension__ __PRETTY_FUNCTION__
))
;
663 return CastInfo<To, From *>::doCastIfPossible(Val);
664}
665
666template <typename To, typename From>
667[[nodiscard]] inline decltype(auto) dyn_cast(std::unique_ptr<From> &&Val) {
668 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", 668, __extension__ __PRETTY_FUNCTION__
))
;
669 return CastInfo<To, std::unique_ptr<From>>::doCastIfPossible(
670 std::forward<std::unique_ptr<From> &&>(Val));
671}
672
673/// isa_and_present<X> - Functionally identical to isa, except that a null value
674/// is accepted.
675template <typename... X, class Y>
676[[nodiscard]] inline bool isa_and_present(const Y &Val) {
677 if (!detail::isPresent(Val))
678 return false;
679 return isa<X...>(Val);
680}
681
682template <typename... X, class Y>
683[[nodiscard]] inline bool isa_and_nonnull(const Y &Val) {
684 return isa_and_present<X...>(Val);
685}
686
687/// cast_if_present<X> - Functionally identical to cast, except that a null
688/// value is accepted.
689template <class X, class Y>
690[[nodiscard]] inline auto cast_if_present(const Y &Val) {
691 if (!detail::isPresent(Val))
692 return CastInfo<X, const Y>::castFailed();
693 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", 693, __extension__ __PRETTY_FUNCTION__
))
;
694 return cast<X>(detail::unwrapValue(Val));
695}
696
697template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y &Val) {
698 if (!detail::isPresent(Val))
699 return CastInfo<X, Y>::castFailed();
700 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", 700, __extension__ __PRETTY_FUNCTION__
))
;
701 return cast<X>(detail::unwrapValue(Val));
702}
703
704template <class X, class Y> [[nodiscard]] inline auto cast_if_present(Y *Val) {
705 if (!detail::isPresent(Val))
706 return CastInfo<X, Y *>::castFailed();
707 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", 707, __extension__ __PRETTY_FUNCTION__
))
;
708 return cast<X>(detail::unwrapValue(Val));
709}
710
711template <class X, class Y>
712[[nodiscard]] inline auto cast_if_present(std::unique_ptr<Y> &&Val) {
713 if (!detail::isPresent(Val))
714 return UniquePtrCast<X, Y>::castFailed();
715 return UniquePtrCast<X, Y>::doCast(std::move(Val));
716}
717
718// Provide a forwarding from cast_or_null to cast_if_present for current
719// users. This is deprecated and will be removed in a future patch, use
720// cast_if_present instead.
721template <class X, class Y> auto cast_or_null(const Y &Val) {
722 return cast_if_present<X>(Val);
723}
724
725template <class X, class Y> auto cast_or_null(Y &Val) {
726 return cast_if_present<X>(Val);
727}
728
729template <class X, class Y> auto cast_or_null(Y *Val) {
730 return cast_if_present<X>(Val);
731}
732
733template <class X, class Y> auto cast_or_null(std::unique_ptr<Y> &&Val) {
734 return cast_if_present<X>(std::move(Val));
735}
736
737/// dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a
738/// null (or none in the case of optionals) value is accepted.
739template <class X, class Y> auto dyn_cast_if_present(const Y &Val) {
740 if (!detail::isPresent(Val))
29
Assuming the condition is true
30
Taking true branch
44
Assuming the condition is false
45
Taking false branch
741 return CastInfo<X, const Y>::castFailed();
31
Calling 'ConstStrippingForwardingCast::castFailed'
36
Returning from 'ConstStrippingForwardingCast::castFailed'
37
Returning null pointer, which participates in a condition later
742 return CastInfo<X, const Y>::doCastIfPossible(detail::unwrapValue(Val));
46
Calling 'ConstStrippingForwardingCast::doCastIfPossible'
59
Returning from 'ConstStrippingForwardingCast::doCastIfPossible'
60
Returning pointer, which participates in a condition later
743}
744
745template <class X, class Y> auto dyn_cast_if_present(Y &Val) {
746 if (!detail::isPresent(Val))
747 return CastInfo<X, Y>::castFailed();
748 return CastInfo<X, Y>::doCastIfPossible(detail::unwrapValue(Val));
749}
750
751template <class X, class Y> auto dyn_cast_if_present(Y *Val) {
752 if (!detail::isPresent(Val))
753 return CastInfo<X, Y *>::castFailed();
754 return CastInfo<X, Y *>::doCastIfPossible(detail::unwrapValue(Val));
755}
756
757// Forwards to dyn_cast_if_present to avoid breaking current users. This is
758// deprecated and will be removed in a future patch, use
759// cast_if_present instead.
760template <class X, class Y> auto dyn_cast_or_null(const Y &Val) {
761 return dyn_cast_if_present<X>(Val);
762}
763
764template <class X, class Y> auto dyn_cast_or_null(Y &Val) {
765 return dyn_cast_if_present<X>(Val);
766}
767
768template <class X, class Y> auto dyn_cast_or_null(Y *Val) {
769 return dyn_cast_if_present<X>(Val);
770}
771
772/// unique_dyn_cast<X> - Given a unique_ptr<Y>, try to return a unique_ptr<X>,
773/// taking ownership of the input pointer iff isa<X>(Val) is true. If the
774/// cast is successful, From refers to nullptr on exit and the casted value
775/// is returned. If the cast is unsuccessful, the function returns nullptr
776/// and From is unchanged.
777template <class X, class Y>
778[[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
779unique_dyn_cast(std::unique_ptr<Y> &Val) {
780 if (!isa<X>(Val))
781 return nullptr;
782 return cast<X>(std::move(Val));
783}
784
785template <class X, class Y>
786[[nodiscard]] inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) {
787 return unique_dyn_cast<X, Y>(Val);
788}
789
790// unique_dyn_cast_or_null<X> - Functionally identical to unique_dyn_cast,
791// except that a null value is accepted.
792template <class X, class Y>
793[[nodiscard]] inline typename CastInfo<X, std::unique_ptr<Y>>::CastResultType
794unique_dyn_cast_or_null(std::unique_ptr<Y> &Val) {
795 if (!Val)
796 return nullptr;
797 return unique_dyn_cast<X, Y>(Val);
798}
799
800template <class X, class Y>
801[[nodiscard]] inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) {
802 return unique_dyn_cast_or_null<X, Y>(Val);
803}
804
805} // end namespace llvm
806
807#endif // LLVM_SUPPORT_CASTING_H

/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);
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(isa<First>(*this) && "Val is not the first pointer")(static_cast <bool> (isa<First>(*this) &&
"Val is not the first pointer") ? void (0) : __assert_fail (
"isa<First>(*this) && \"Val is not the first pointer\""
, "llvm/include/llvm/ADT/PointerUnion.h", 175, __extension__ __PRETTY_FUNCTION__
))
;
176 assert((static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(cast<First>(*this)) == this->Val.
getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(cast<First>(*this)) == 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(cast<First>(*this)) ==(static_cast <bool> (PointerLikeTypeTraits<First>
::getAsVoidPointer(cast<First>(*this)) == this->Val.
getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(cast<First>(*this)) == 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(cast<First>(*this)) == this->Val.
getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(cast<First>(*this)) == 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(cast<First>(*this)) == this->Val.
getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"
) ? void (0) : __assert_fail ("PointerLikeTypeTraits<First>::getAsVoidPointer(cast<First>(*this)) == 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__
))
;
51
'?' condition is true
235 return PointerLikeTypeTraits<To>::getFromVoidPointer(F.Val.getPointer());
52
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); }
50
Calling 'CastInfoPointerUnionImpl::doCast'
53
Returning from 'CastInfoPointerUnionImpl::doCast'
54
Returning pointer, which participates in a condition later
252
253 static inline To castFailed() { return To(); }
33
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