1 | //===- SelectionDAGDumper.cpp - Implement SelectionDAG::dump() ------------===// |
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 implements the SelectionDAG::dump method and friends. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "SDNodeDbgValue.h" |
14 | #include "llvm/ADT/APFloat.h" |
15 | #include "llvm/ADT/APInt.h" |
16 | #include "llvm/ADT/SmallPtrSet.h" |
17 | #include "llvm/ADT/StringExtras.h" |
18 | #include "llvm/CodeGen/ISDOpcodes.h" |
19 | #include "llvm/CodeGen/MachineBasicBlock.h" |
20 | #include "llvm/CodeGen/MachineConstantPool.h" |
21 | #include "llvm/CodeGen/MachineMemOperand.h" |
22 | #include "llvm/CodeGen/SelectionDAG.h" |
23 | #include "llvm/CodeGen/SelectionDAGNodes.h" |
24 | #include "llvm/CodeGen/SelectionDAGTargetInfo.h" |
25 | #include "llvm/CodeGen/TargetInstrInfo.h" |
26 | #include "llvm/CodeGen/TargetLowering.h" |
27 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
28 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
29 | #include "llvm/CodeGen/ValueTypes.h" |
30 | #include "llvm/CodeGenTypes/MachineValueType.h" |
31 | #include "llvm/Config/llvm-config.h" |
32 | #include "llvm/IR/BasicBlock.h" |
33 | #include "llvm/IR/Constants.h" |
34 | #include "llvm/IR/DebugInfoMetadata.h" |
35 | #include "llvm/IR/DebugLoc.h" |
36 | #include "llvm/IR/Function.h" |
37 | #include "llvm/IR/Intrinsics.h" |
38 | #include "llvm/IR/ModuleSlotTracker.h" |
39 | #include "llvm/IR/Value.h" |
40 | #include "llvm/Support/Casting.h" |
41 | #include "llvm/Support/CommandLine.h" |
42 | #include "llvm/Support/Compiler.h" |
43 | #include "llvm/Support/Debug.h" |
44 | #include "llvm/Support/ErrorHandling.h" |
45 | #include "llvm/Support/Printable.h" |
46 | #include "llvm/Support/raw_ostream.h" |
47 | #include "llvm/Target/TargetMachine.h" |
48 | #include <cstdint> |
49 | #include <iterator> |
50 | |
51 | using namespace llvm; |
52 | |
53 | static cl::opt<bool> |
54 | VerboseDAGDumping("dag-dump-verbose" , cl::Hidden, |
55 | cl::desc("Display more information when dumping selection " |
56 | "DAG nodes." )); |
57 | |
58 | std::string SDNode::getOperationName(const SelectionDAG *G) const { |
59 | switch (getOpcode()) { |
60 | default: |
61 | if (getOpcode() < ISD::BUILTIN_OP_END) |
62 | return "<<Unknown DAG Node>>" ; |
63 | if (isMachineOpcode()) { |
64 | if (G) |
65 | if (const TargetInstrInfo *TII = G->getSubtarget().getInstrInfo()) |
66 | if (getMachineOpcode() < TII->getNumOpcodes()) |
67 | return std::string(TII->getName(Opcode: getMachineOpcode())); |
68 | return "<<Unknown Machine Node #" + utostr(X: getOpcode()) + ">>" ; |
69 | } |
70 | if (G) { |
71 | const SelectionDAGTargetInfo &TSI = G->getSelectionDAGInfo(); |
72 | if (const char *Name = TSI.getTargetNodeName(Opcode: getOpcode())) |
73 | return Name; |
74 | const TargetLowering &TLI = G->getTargetLoweringInfo(); |
75 | const char *Name = TLI.getTargetNodeName(Opcode: getOpcode()); |
76 | if (Name) return Name; |
77 | return "<<Unknown Target Node #" + utostr(X: getOpcode()) + ">>" ; |
78 | } |
79 | return "<<Unknown Node #" + utostr(X: getOpcode()) + ">>" ; |
80 | |
81 | // clang-format off |
82 | #ifndef NDEBUG |
83 | case ISD::DELETED_NODE: return "<<Deleted Node!>>" ; |
84 | #endif |
85 | case ISD::PREFETCH: return "Prefetch" ; |
86 | case ISD::MEMBARRIER: return "MemBarrier" ; |
87 | case ISD::ATOMIC_FENCE: return "AtomicFence" ; |
88 | case ISD::ATOMIC_CMP_SWAP: return "AtomicCmpSwap" ; |
89 | case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: return "AtomicCmpSwapWithSuccess" ; |
90 | case ISD::ATOMIC_SWAP: return "AtomicSwap" ; |
91 | case ISD::ATOMIC_LOAD_ADD: return "AtomicLoadAdd" ; |
92 | case ISD::ATOMIC_LOAD_SUB: return "AtomicLoadSub" ; |
93 | case ISD::ATOMIC_LOAD_AND: return "AtomicLoadAnd" ; |
94 | case ISD::ATOMIC_LOAD_CLR: return "AtomicLoadClr" ; |
95 | case ISD::ATOMIC_LOAD_OR: return "AtomicLoadOr" ; |
96 | case ISD::ATOMIC_LOAD_XOR: return "AtomicLoadXor" ; |
97 | case ISD::ATOMIC_LOAD_NAND: return "AtomicLoadNand" ; |
98 | case ISD::ATOMIC_LOAD_MIN: return "AtomicLoadMin" ; |
99 | case ISD::ATOMIC_LOAD_MAX: return "AtomicLoadMax" ; |
100 | case ISD::ATOMIC_LOAD_UMIN: return "AtomicLoadUMin" ; |
101 | case ISD::ATOMIC_LOAD_UMAX: return "AtomicLoadUMax" ; |
102 | case ISD::ATOMIC_LOAD_FADD: return "AtomicLoadFAdd" ; |
103 | case ISD::ATOMIC_LOAD_FSUB: return "AtomicLoadFSub" ; |
104 | case ISD::ATOMIC_LOAD_FMIN: return "AtomicLoadFMin" ; |
105 | case ISD::ATOMIC_LOAD_FMAX: return "AtomicLoadFMax" ; |
106 | case ISD::ATOMIC_LOAD_FMINIMUM: return "AtomicLoadFMinimum" ; |
107 | case ISD::ATOMIC_LOAD_FMAXIMUM: return "AtomicLoadFMaximum" ; |
108 | case ISD::ATOMIC_LOAD_UINC_WRAP: |
109 | return "AtomicLoadUIncWrap" ; |
110 | case ISD::ATOMIC_LOAD_UDEC_WRAP: |
111 | return "AtomicLoadUDecWrap" ; |
112 | case ISD::ATOMIC_LOAD_USUB_COND: |
113 | return "AtomicLoadUSubCond" ; |
114 | case ISD::ATOMIC_LOAD_USUB_SAT: |
115 | return "AtomicLoadUSubSat" ; |
116 | case ISD::ATOMIC_LOAD: return "AtomicLoad" ; |
117 | case ISD::ATOMIC_STORE: return "AtomicStore" ; |
118 | case ISD::PCMARKER: return "PCMarker" ; |
119 | case ISD::READCYCLECOUNTER: return "ReadCycleCounter" ; |
120 | case ISD::READSTEADYCOUNTER: return "ReadSteadyCounter" ; |
121 | case ISD::SRCVALUE: return "SrcValue" ; |
122 | case ISD::MDNODE_SDNODE: return "MDNode" ; |
123 | case ISD::EntryToken: return "EntryToken" ; |
124 | case ISD::TokenFactor: return "TokenFactor" ; |
125 | case ISD::AssertSext: return "AssertSext" ; |
126 | case ISD::AssertZext: return "AssertZext" ; |
127 | case ISD::AssertNoFPClass: return "AssertNoFPClass" ; |
128 | case ISD::AssertAlign: return "AssertAlign" ; |
129 | |
130 | case ISD::BasicBlock: return "BasicBlock" ; |
131 | case ISD::VALUETYPE: return "ValueType" ; |
132 | case ISD::Register: return "Register" ; |
133 | case ISD::RegisterMask: return "RegisterMask" ; |
134 | case ISD::Constant: |
135 | if (cast<ConstantSDNode>(Val: this)->isOpaque()) |
136 | return "OpaqueConstant" ; |
137 | return "Constant" ; |
138 | case ISD::ConstantFP: return "ConstantFP" ; |
139 | case ISD::GlobalAddress: return "GlobalAddress" ; |
140 | case ISD::GlobalTLSAddress: return "GlobalTLSAddress" ; |
141 | case ISD::PtrAuthGlobalAddress: return "PtrAuthGlobalAddress" ; |
142 | case ISD::FrameIndex: return "FrameIndex" ; |
143 | case ISD::JumpTable: return "JumpTable" ; |
144 | case ISD::JUMP_TABLE_DEBUG_INFO: |
145 | return "JUMP_TABLE_DEBUG_INFO" ; |
146 | case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE" ; |
147 | case ISD::RETURNADDR: return "RETURNADDR" ; |
148 | case ISD::ADDROFRETURNADDR: return "ADDROFRETURNADDR" ; |
149 | case ISD::FRAMEADDR: return "FRAMEADDR" ; |
150 | case ISD::SPONENTRY: return "SPONENTRY" ; |
151 | case ISD::LOCAL_RECOVER: return "LOCAL_RECOVER" ; |
152 | case ISD::READ_REGISTER: return "READ_REGISTER" ; |
153 | case ISD::WRITE_REGISTER: return "WRITE_REGISTER" ; |
154 | case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET" ; |
155 | case ISD::EH_DWARF_CFA: return "EH_DWARF_CFA" ; |
156 | case ISD::EH_RETURN: return "EH_RETURN" ; |
157 | case ISD::EH_SJLJ_SETJMP: return "EH_SJLJ_SETJMP" ; |
158 | case ISD::EH_SJLJ_LONGJMP: return "EH_SJLJ_LONGJMP" ; |
159 | case ISD::EH_SJLJ_SETUP_DISPATCH: return "EH_SJLJ_SETUP_DISPATCH" ; |
160 | case ISD::ConstantPool: return "ConstantPool" ; |
161 | case ISD::TargetIndex: return "TargetIndex" ; |
162 | case ISD::ExternalSymbol: return "ExternalSymbol" ; |
163 | case ISD::BlockAddress: return "BlockAddress" ; |
164 | case ISD::INTRINSIC_WO_CHAIN: |
165 | case ISD::INTRINSIC_VOID: |
166 | case ISD::INTRINSIC_W_CHAIN: { |
167 | unsigned OpNo = getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1; |
168 | unsigned IID = getOperand(Num: OpNo)->getAsZExtVal(); |
169 | if (IID < Intrinsic::num_intrinsics) |
170 | return Intrinsic::getBaseName(id: (Intrinsic::ID)IID).str(); |
171 | if (!G) |
172 | return "Unknown intrinsic" ; |
173 | llvm_unreachable("Invalid intrinsic ID" ); |
174 | } |
175 | |
176 | case ISD::BUILD_VECTOR: return "BUILD_VECTOR" ; |
177 | case ISD::TargetConstant: |
178 | if (cast<ConstantSDNode>(Val: this)->isOpaque()) |
179 | return "OpaqueTargetConstant" ; |
180 | return "TargetConstant" ; |
181 | |
182 | case ISD::TargetConstantFP: return "TargetConstantFP" ; |
183 | case ISD::TargetGlobalAddress: return "TargetGlobalAddress" ; |
184 | case ISD::TargetGlobalTLSAddress: return "TargetGlobalTLSAddress" ; |
185 | case ISD::TargetFrameIndex: return "TargetFrameIndex" ; |
186 | case ISD::TargetJumpTable: return "TargetJumpTable" ; |
187 | case ISD::TargetConstantPool: return "TargetConstantPool" ; |
188 | case ISD::TargetExternalSymbol: return "TargetExternalSymbol" ; |
189 | case ISD::MCSymbol: return "MCSymbol" ; |
190 | case ISD::TargetBlockAddress: return "TargetBlockAddress" ; |
191 | |
192 | case ISD::CopyToReg: return "CopyToReg" ; |
193 | case ISD::CopyFromReg: return "CopyFromReg" ; |
194 | case ISD::UNDEF: return "undef" ; |
195 | case ISD::POISON: return "poison" ; |
196 | case ISD::VSCALE: return "vscale" ; |
197 | case ISD::MERGE_VALUES: return "merge_values" ; |
198 | case ISD::INLINEASM: return "inlineasm" ; |
199 | case ISD::INLINEASM_BR: return "inlineasm_br" ; |
200 | case ISD::EH_LABEL: return "eh_label" ; |
201 | case ISD::ANNOTATION_LABEL: return "annotation_label" ; |
202 | case ISD::HANDLENODE: return "handlenode" ; |
203 | |
204 | // Unary operators |
205 | case ISD::FABS: return "fabs" ; |
206 | case ISD::FMINNUM: return "fminnum" ; |
207 | case ISD::STRICT_FMINNUM: return "strict_fminnum" ; |
208 | case ISD::FMAXNUM: return "fmaxnum" ; |
209 | case ISD::STRICT_FMAXNUM: return "strict_fmaxnum" ; |
210 | case ISD::FMINNUM_IEEE: return "fminnum_ieee" ; |
211 | case ISD::FMAXNUM_IEEE: return "fmaxnum_ieee" ; |
212 | case ISD::FMINIMUM: return "fminimum" ; |
213 | case ISD::STRICT_FMINIMUM: return "strict_fminimum" ; |
214 | case ISD::FMAXIMUM: return "fmaximum" ; |
215 | case ISD::STRICT_FMAXIMUM: return "strict_fmaximum" ; |
216 | case ISD::FMINIMUMNUM: return "fminimumnum" ; |
217 | case ISD::FMAXIMUMNUM: return "fmaximumnum" ; |
218 | case ISD::FNEG: return "fneg" ; |
219 | case ISD::FSQRT: return "fsqrt" ; |
220 | case ISD::STRICT_FSQRT: return "strict_fsqrt" ; |
221 | case ISD::FCBRT: return "fcbrt" ; |
222 | case ISD::FSIN: return "fsin" ; |
223 | case ISD::STRICT_FSIN: return "strict_fsin" ; |
224 | case ISD::FCOS: return "fcos" ; |
225 | case ISD::STRICT_FCOS: return "strict_fcos" ; |
226 | case ISD::FSINCOS: return "fsincos" ; |
227 | case ISD::FSINCOSPI: return "fsincospi" ; |
228 | case ISD::FMODF: return "fmodf" ; |
229 | case ISD::FTAN: return "ftan" ; |
230 | case ISD::STRICT_FTAN: return "strict_ftan" ; |
231 | case ISD::FASIN: return "fasin" ; |
232 | case ISD::STRICT_FASIN: return "strict_fasin" ; |
233 | case ISD::FACOS: return "facos" ; |
234 | case ISD::STRICT_FACOS: return "strict_facos" ; |
235 | case ISD::FATAN: return "fatan" ; |
236 | case ISD::STRICT_FATAN: return "strict_fatan" ; |
237 | case ISD::FATAN2: return "fatan2" ; |
238 | case ISD::STRICT_FATAN2: return "strict_fatan2" ; |
239 | case ISD::FSINH: return "fsinh" ; |
240 | case ISD::STRICT_FSINH: return "strict_fsinh" ; |
241 | case ISD::FCOSH: return "fcosh" ; |
242 | case ISD::STRICT_FCOSH: return "strict_fcosh" ; |
243 | case ISD::FTANH: return "ftanh" ; |
244 | case ISD::STRICT_FTANH: return "strict_ftanh" ; |
245 | case ISD::FTRUNC: return "ftrunc" ; |
246 | case ISD::STRICT_FTRUNC: return "strict_ftrunc" ; |
247 | case ISD::FFLOOR: return "ffloor" ; |
248 | case ISD::STRICT_FFLOOR: return "strict_ffloor" ; |
249 | case ISD::FCEIL: return "fceil" ; |
250 | case ISD::STRICT_FCEIL: return "strict_fceil" ; |
251 | case ISD::FRINT: return "frint" ; |
252 | case ISD::STRICT_FRINT: return "strict_frint" ; |
253 | case ISD::FNEARBYINT: return "fnearbyint" ; |
254 | case ISD::STRICT_FNEARBYINT: return "strict_fnearbyint" ; |
255 | case ISD::FROUND: return "fround" ; |
256 | case ISD::STRICT_FROUND: return "strict_fround" ; |
257 | case ISD::FROUNDEVEN: return "froundeven" ; |
258 | case ISD::STRICT_FROUNDEVEN: return "strict_froundeven" ; |
259 | case ISD::FEXP: return "fexp" ; |
260 | case ISD::STRICT_FEXP: return "strict_fexp" ; |
261 | case ISD::FEXP2: return "fexp2" ; |
262 | case ISD::STRICT_FEXP2: return "strict_fexp2" ; |
263 | case ISD::FEXP10: return "fexp10" ; |
264 | case ISD::FLOG: return "flog" ; |
265 | case ISD::STRICT_FLOG: return "strict_flog" ; |
266 | case ISD::FLOG2: return "flog2" ; |
267 | case ISD::STRICT_FLOG2: return "strict_flog2" ; |
268 | case ISD::FLOG10: return "flog10" ; |
269 | case ISD::STRICT_FLOG10: return "strict_flog10" ; |
270 | |
271 | // Binary operators |
272 | case ISD::ADD: return "add" ; |
273 | case ISD::PTRADD: return "ptradd" ; |
274 | case ISD::SUB: return "sub" ; |
275 | case ISD::MUL: return "mul" ; |
276 | case ISD::MULHU: return "mulhu" ; |
277 | case ISD::MULHS: return "mulhs" ; |
278 | case ISD::AVGFLOORU: return "avgflooru" ; |
279 | case ISD::AVGFLOORS: return "avgfloors" ; |
280 | case ISD::AVGCEILU: return "avgceilu" ; |
281 | case ISD::AVGCEILS: return "avgceils" ; |
282 | case ISD::ABDS: return "abds" ; |
283 | case ISD::ABDU: return "abdu" ; |
284 | case ISD::SDIV: return "sdiv" ; |
285 | case ISD::UDIV: return "udiv" ; |
286 | case ISD::SREM: return "srem" ; |
287 | case ISD::UREM: return "urem" ; |
288 | case ISD::SMUL_LOHI: return "smul_lohi" ; |
289 | case ISD::UMUL_LOHI: return "umul_lohi" ; |
290 | case ISD::SDIVREM: return "sdivrem" ; |
291 | case ISD::UDIVREM: return "udivrem" ; |
292 | case ISD::AND: return "and" ; |
293 | case ISD::OR: return "or" ; |
294 | case ISD::XOR: return "xor" ; |
295 | case ISD::SHL: return "shl" ; |
296 | case ISD::SRA: return "sra" ; |
297 | case ISD::SRL: return "srl" ; |
298 | case ISD::ROTL: return "rotl" ; |
299 | case ISD::ROTR: return "rotr" ; |
300 | case ISD::FSHL: return "fshl" ; |
301 | case ISD::FSHR: return "fshr" ; |
302 | case ISD::FADD: return "fadd" ; |
303 | case ISD::STRICT_FADD: return "strict_fadd" ; |
304 | case ISD::FSUB: return "fsub" ; |
305 | case ISD::STRICT_FSUB: return "strict_fsub" ; |
306 | case ISD::FMUL: return "fmul" ; |
307 | case ISD::STRICT_FMUL: return "strict_fmul" ; |
308 | case ISD::FDIV: return "fdiv" ; |
309 | case ISD::STRICT_FDIV: return "strict_fdiv" ; |
310 | case ISD::FMA: return "fma" ; |
311 | case ISD::STRICT_FMA: return "strict_fma" ; |
312 | case ISD::FMAD: return "fmad" ; |
313 | case ISD::FREM: return "frem" ; |
314 | case ISD::STRICT_FREM: return "strict_frem" ; |
315 | case ISD::FCOPYSIGN: return "fcopysign" ; |
316 | case ISD::FGETSIGN: return "fgetsign" ; |
317 | case ISD::FCANONICALIZE: return "fcanonicalize" ; |
318 | case ISD::IS_FPCLASS: return "is_fpclass" ; |
319 | case ISD::FPOW: return "fpow" ; |
320 | case ISD::STRICT_FPOW: return "strict_fpow" ; |
321 | case ISD::SMIN: return "smin" ; |
322 | case ISD::SMAX: return "smax" ; |
323 | case ISD::UMIN: return "umin" ; |
324 | case ISD::UMAX: return "umax" ; |
325 | case ISD::SCMP: return "scmp" ; |
326 | case ISD::UCMP: return "ucmp" ; |
327 | |
328 | case ISD::FLDEXP: return "fldexp" ; |
329 | case ISD::STRICT_FLDEXP: return "strict_fldexp" ; |
330 | case ISD::FFREXP: return "ffrexp" ; |
331 | case ISD::FPOWI: return "fpowi" ; |
332 | case ISD::STRICT_FPOWI: return "strict_fpowi" ; |
333 | case ISD::SETCC: return "setcc" ; |
334 | case ISD::SETCCCARRY: return "setcccarry" ; |
335 | case ISD::STRICT_FSETCC: return "strict_fsetcc" ; |
336 | case ISD::STRICT_FSETCCS: return "strict_fsetccs" ; |
337 | case ISD::FPTRUNC_ROUND: return "fptrunc_round" ; |
338 | case ISD::SELECT: return "select" ; |
339 | case ISD::VSELECT: return "vselect" ; |
340 | case ISD::SELECT_CC: return "select_cc" ; |
341 | case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt" ; |
342 | case ISD::EXTRACT_VECTOR_ELT: return "extract_vector_elt" ; |
343 | case ISD::CONCAT_VECTORS: return "concat_vectors" ; |
344 | case ISD::INSERT_SUBVECTOR: return "insert_subvector" ; |
345 | case ISD::EXTRACT_SUBVECTOR: return "extract_subvector" ; |
346 | case ISD::VECTOR_DEINTERLEAVE: return "vector_deinterleave" ; |
347 | case ISD::VECTOR_INTERLEAVE: return "vector_interleave" ; |
348 | case ISD::SCALAR_TO_VECTOR: return "scalar_to_vector" ; |
349 | case ISD::VECTOR_SHUFFLE: return "vector_shuffle" ; |
350 | case ISD::VECTOR_SPLICE: return "vector_splice" ; |
351 | case ISD::SPLAT_VECTOR: return "splat_vector" ; |
352 | case ISD::SPLAT_VECTOR_PARTS: return "splat_vector_parts" ; |
353 | case ISD::VECTOR_REVERSE: return "vector_reverse" ; |
354 | case ISD::STEP_VECTOR: return "step_vector" ; |
355 | case ISD::CARRY_FALSE: return "carry_false" ; |
356 | case ISD::ADDC: return "addc" ; |
357 | case ISD::ADDE: return "adde" ; |
358 | case ISD::UADDO_CARRY: return "uaddo_carry" ; |
359 | case ISD::SADDO_CARRY: return "saddo_carry" ; |
360 | case ISD::SADDO: return "saddo" ; |
361 | case ISD::UADDO: return "uaddo" ; |
362 | case ISD::SSUBO: return "ssubo" ; |
363 | case ISD::USUBO: return "usubo" ; |
364 | case ISD::SMULO: return "smulo" ; |
365 | case ISD::UMULO: return "umulo" ; |
366 | case ISD::SUBC: return "subc" ; |
367 | case ISD::SUBE: return "sube" ; |
368 | case ISD::USUBO_CARRY: return "usubo_carry" ; |
369 | case ISD::SSUBO_CARRY: return "ssubo_carry" ; |
370 | case ISD::SHL_PARTS: return "shl_parts" ; |
371 | case ISD::SRA_PARTS: return "sra_parts" ; |
372 | case ISD::SRL_PARTS: return "srl_parts" ; |
373 | |
374 | case ISD::SADDSAT: return "saddsat" ; |
375 | case ISD::UADDSAT: return "uaddsat" ; |
376 | case ISD::SSUBSAT: return "ssubsat" ; |
377 | case ISD::USUBSAT: return "usubsat" ; |
378 | case ISD::SSHLSAT: return "sshlsat" ; |
379 | case ISD::USHLSAT: return "ushlsat" ; |
380 | |
381 | case ISD::SMULFIX: return "smulfix" ; |
382 | case ISD::SMULFIXSAT: return "smulfixsat" ; |
383 | case ISD::UMULFIX: return "umulfix" ; |
384 | case ISD::UMULFIXSAT: return "umulfixsat" ; |
385 | |
386 | case ISD::SDIVFIX: return "sdivfix" ; |
387 | case ISD::SDIVFIXSAT: return "sdivfixsat" ; |
388 | case ISD::UDIVFIX: return "udivfix" ; |
389 | case ISD::UDIVFIXSAT: return "udivfixsat" ; |
390 | |
391 | // Conversion operators. |
392 | case ISD::SIGN_EXTEND: return "sign_extend" ; |
393 | case ISD::ZERO_EXTEND: return "zero_extend" ; |
394 | case ISD::ANY_EXTEND: return "any_extend" ; |
395 | case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg" ; |
396 | case ISD::ANY_EXTEND_VECTOR_INREG: return "any_extend_vector_inreg" ; |
397 | case ISD::SIGN_EXTEND_VECTOR_INREG: return "sign_extend_vector_inreg" ; |
398 | case ISD::ZERO_EXTEND_VECTOR_INREG: return "zero_extend_vector_inreg" ; |
399 | case ISD::TRUNCATE: return "truncate" ; |
400 | case ISD::TRUNCATE_SSAT_S: return "truncate_ssat_s" ; |
401 | case ISD::TRUNCATE_SSAT_U: return "truncate_ssat_u" ; |
402 | case ISD::TRUNCATE_USAT_U: return "truncate_usat_u" ; |
403 | case ISD::FP_ROUND: return "fp_round" ; |
404 | case ISD::STRICT_FP_ROUND: return "strict_fp_round" ; |
405 | case ISD::FP_EXTEND: return "fp_extend" ; |
406 | case ISD::STRICT_FP_EXTEND: return "strict_fp_extend" ; |
407 | |
408 | case ISD::SINT_TO_FP: return "sint_to_fp" ; |
409 | case ISD::STRICT_SINT_TO_FP: return "strict_sint_to_fp" ; |
410 | case ISD::UINT_TO_FP: return "uint_to_fp" ; |
411 | case ISD::STRICT_UINT_TO_FP: return "strict_uint_to_fp" ; |
412 | case ISD::FP_TO_SINT: return "fp_to_sint" ; |
413 | case ISD::STRICT_FP_TO_SINT: return "strict_fp_to_sint" ; |
414 | case ISD::FP_TO_UINT: return "fp_to_uint" ; |
415 | case ISD::STRICT_FP_TO_UINT: return "strict_fp_to_uint" ; |
416 | case ISD::FP_TO_SINT_SAT: return "fp_to_sint_sat" ; |
417 | case ISD::FP_TO_UINT_SAT: return "fp_to_uint_sat" ; |
418 | case ISD::BITCAST: return "bitcast" ; |
419 | case ISD::ADDRSPACECAST: return "addrspacecast" ; |
420 | case ISD::FP16_TO_FP: return "fp16_to_fp" ; |
421 | case ISD::STRICT_FP16_TO_FP: return "strict_fp16_to_fp" ; |
422 | case ISD::FP_TO_FP16: return "fp_to_fp16" ; |
423 | case ISD::STRICT_FP_TO_FP16: return "strict_fp_to_fp16" ; |
424 | case ISD::BF16_TO_FP: return "bf16_to_fp" ; |
425 | case ISD::STRICT_BF16_TO_FP: return "strict_bf16_to_fp" ; |
426 | case ISD::FP_TO_BF16: return "fp_to_bf16" ; |
427 | case ISD::STRICT_FP_TO_BF16: return "strict_fp_to_bf16" ; |
428 | case ISD::LROUND: return "lround" ; |
429 | case ISD::STRICT_LROUND: return "strict_lround" ; |
430 | case ISD::LLROUND: return "llround" ; |
431 | case ISD::STRICT_LLROUND: return "strict_llround" ; |
432 | case ISD::LRINT: return "lrint" ; |
433 | case ISD::STRICT_LRINT: return "strict_lrint" ; |
434 | case ISD::LLRINT: return "llrint" ; |
435 | case ISD::STRICT_LLRINT: return "strict_llrint" ; |
436 | |
437 | // Control flow instructions |
438 | case ISD::BR: return "br" ; |
439 | case ISD::BRIND: return "brind" ; |
440 | case ISD::BR_JT: return "br_jt" ; |
441 | case ISD::BRCOND: return "brcond" ; |
442 | case ISD::BR_CC: return "br_cc" ; |
443 | case ISD::CALLSEQ_START: return "callseq_start" ; |
444 | case ISD::CALLSEQ_END: return "callseq_end" ; |
445 | |
446 | // EH instructions |
447 | case ISD::CATCHRET: return "catchret" ; |
448 | case ISD::CLEANUPRET: return "cleanupret" ; |
449 | |
450 | // Other operators |
451 | case ISD::LOAD: return "load" ; |
452 | case ISD::STORE: return "store" ; |
453 | case ISD::MLOAD: return "masked_load" ; |
454 | case ISD::MSTORE: return "masked_store" ; |
455 | case ISD::MGATHER: return "masked_gather" ; |
456 | case ISD::MSCATTER: return "masked_scatter" ; |
457 | case ISD::VECTOR_COMPRESS: return "vector_compress" ; |
458 | case ISD::VAARG: return "vaarg" ; |
459 | case ISD::VACOPY: return "vacopy" ; |
460 | case ISD::VAEND: return "vaend" ; |
461 | case ISD::VASTART: return "vastart" ; |
462 | case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc" ; |
463 | case ISD::EXTRACT_ELEMENT: return "extract_element" ; |
464 | case ISD::BUILD_PAIR: return "build_pair" ; |
465 | case ISD::STACKSAVE: return "stacksave" ; |
466 | case ISD::STACKRESTORE: return "stackrestore" ; |
467 | case ISD::TRAP: return "trap" ; |
468 | case ISD::DEBUGTRAP: return "debugtrap" ; |
469 | case ISD::UBSANTRAP: return "ubsantrap" ; |
470 | case ISD::LIFETIME_START: return "lifetime.start" ; |
471 | case ISD::LIFETIME_END: return "lifetime.end" ; |
472 | case ISD::FAKE_USE: |
473 | return "fake_use" ; |
474 | case ISD::PSEUDO_PROBE: |
475 | return "pseudoprobe" ; |
476 | case ISD::GC_TRANSITION_START: return "gc_transition.start" ; |
477 | case ISD::GC_TRANSITION_END: return "gc_transition.end" ; |
478 | case ISD::GET_DYNAMIC_AREA_OFFSET: return "get.dynamic.area.offset" ; |
479 | case ISD::FREEZE: return "freeze" ; |
480 | case ISD::PREALLOCATED_SETUP: |
481 | return "call_setup" ; |
482 | case ISD::PREALLOCATED_ARG: |
483 | return "call_alloc" ; |
484 | |
485 | // Floating point environment manipulation |
486 | case ISD::GET_ROUNDING: return "get_rounding" ; |
487 | case ISD::SET_ROUNDING: return "set_rounding" ; |
488 | case ISD::GET_FPENV: return "get_fpenv" ; |
489 | case ISD::SET_FPENV: return "set_fpenv" ; |
490 | case ISD::RESET_FPENV: return "reset_fpenv" ; |
491 | case ISD::GET_FPENV_MEM: return "get_fpenv_mem" ; |
492 | case ISD::SET_FPENV_MEM: return "set_fpenv_mem" ; |
493 | case ISD::GET_FPMODE: return "get_fpmode" ; |
494 | case ISD::SET_FPMODE: return "set_fpmode" ; |
495 | case ISD::RESET_FPMODE: return "reset_fpmode" ; |
496 | |
497 | // Convergence control instructions |
498 | case ISD::CONVERGENCECTRL_ANCHOR: return "convergencectrl_anchor" ; |
499 | case ISD::CONVERGENCECTRL_ENTRY: return "convergencectrl_entry" ; |
500 | case ISD::CONVERGENCECTRL_LOOP: return "convergencectrl_loop" ; |
501 | case ISD::CONVERGENCECTRL_GLUE: return "convergencectrl_glue" ; |
502 | |
503 | // Bit manipulation |
504 | case ISD::ABS: return "abs" ; |
505 | case ISD::BITREVERSE: return "bitreverse" ; |
506 | case ISD::BSWAP: return "bswap" ; |
507 | case ISD::CTPOP: return "ctpop" ; |
508 | case ISD::CTTZ: return "cttz" ; |
509 | case ISD::CTTZ_ZERO_UNDEF: return "cttz_zero_undef" ; |
510 | case ISD::CTLZ: return "ctlz" ; |
511 | case ISD::CTLZ_ZERO_UNDEF: return "ctlz_zero_undef" ; |
512 | case ISD::PARITY: return "parity" ; |
513 | |
514 | // Trampolines |
515 | case ISD::INIT_TRAMPOLINE: return "init_trampoline" ; |
516 | case ISD::ADJUST_TRAMPOLINE: return "adjust_trampoline" ; |
517 | |
518 | // clang-format on |
519 | |
520 | case ISD::CONDCODE: |
521 | switch (cast<CondCodeSDNode>(Val: this)->get()) { |
522 | default: llvm_unreachable("Unknown setcc condition!" ); |
523 | case ISD::SETOEQ: return "setoeq" ; |
524 | case ISD::SETOGT: return "setogt" ; |
525 | case ISD::SETOGE: return "setoge" ; |
526 | case ISD::SETOLT: return "setolt" ; |
527 | case ISD::SETOLE: return "setole" ; |
528 | case ISD::SETONE: return "setone" ; |
529 | |
530 | case ISD::SETO: return "seto" ; |
531 | case ISD::SETUO: return "setuo" ; |
532 | case ISD::SETUEQ: return "setueq" ; |
533 | case ISD::SETUGT: return "setugt" ; |
534 | case ISD::SETUGE: return "setuge" ; |
535 | case ISD::SETULT: return "setult" ; |
536 | case ISD::SETULE: return "setule" ; |
537 | case ISD::SETUNE: return "setune" ; |
538 | |
539 | case ISD::SETEQ: return "seteq" ; |
540 | case ISD::SETGT: return "setgt" ; |
541 | case ISD::SETGE: return "setge" ; |
542 | case ISD::SETLT: return "setlt" ; |
543 | case ISD::SETLE: return "setle" ; |
544 | case ISD::SETNE: return "setne" ; |
545 | |
546 | case ISD::SETTRUE: return "settrue" ; |
547 | case ISD::SETTRUE2: return "settrue2" ; |
548 | case ISD::SETFALSE: return "setfalse" ; |
549 | case ISD::SETFALSE2: return "setfalse2" ; |
550 | } |
551 | case ISD::VECREDUCE_FADD: return "vecreduce_fadd" ; |
552 | case ISD::VECREDUCE_SEQ_FADD: return "vecreduce_seq_fadd" ; |
553 | case ISD::VECREDUCE_FMUL: return "vecreduce_fmul" ; |
554 | case ISD::VECREDUCE_SEQ_FMUL: return "vecreduce_seq_fmul" ; |
555 | case ISD::VECREDUCE_ADD: return "vecreduce_add" ; |
556 | case ISD::VECREDUCE_MUL: return "vecreduce_mul" ; |
557 | case ISD::VECREDUCE_AND: return "vecreduce_and" ; |
558 | case ISD::VECREDUCE_OR: return "vecreduce_or" ; |
559 | case ISD::VECREDUCE_XOR: return "vecreduce_xor" ; |
560 | case ISD::VECREDUCE_SMAX: return "vecreduce_smax" ; |
561 | case ISD::VECREDUCE_SMIN: return "vecreduce_smin" ; |
562 | case ISD::VECREDUCE_UMAX: return "vecreduce_umax" ; |
563 | case ISD::VECREDUCE_UMIN: return "vecreduce_umin" ; |
564 | case ISD::VECREDUCE_FMAX: return "vecreduce_fmax" ; |
565 | case ISD::VECREDUCE_FMIN: return "vecreduce_fmin" ; |
566 | case ISD::VECREDUCE_FMAXIMUM: return "vecreduce_fmaximum" ; |
567 | case ISD::VECREDUCE_FMINIMUM: return "vecreduce_fminimum" ; |
568 | case ISD::STACKMAP: |
569 | return "stackmap" ; |
570 | case ISD::PATCHPOINT: |
571 | return "patchpoint" ; |
572 | case ISD::CLEAR_CACHE: |
573 | return "clear_cache" ; |
574 | |
575 | case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM: |
576 | return "histogram" ; |
577 | |
578 | case ISD::VECTOR_FIND_LAST_ACTIVE: |
579 | return "find_last_active" ; |
580 | |
581 | case ISD::GET_ACTIVE_LANE_MASK: |
582 | return "get_active_lane_mask" ; |
583 | |
584 | case ISD::PARTIAL_REDUCE_UMLA: |
585 | return "partial_reduce_umla" ; |
586 | case ISD::PARTIAL_REDUCE_SMLA: |
587 | return "partial_reduce_smla" ; |
588 | case ISD::PARTIAL_REDUCE_SUMLA: |
589 | return "partial_reduce_sumla" ; |
590 | |
591 | // Vector Predication |
592 | #define BEGIN_REGISTER_VP_SDNODE(SDID, LEGALARG, NAME, ...) \ |
593 | case ISD::SDID: \ |
594 | return #NAME; |
595 | #include "llvm/IR/VPIntrinsics.def" |
596 | } |
597 | } |
598 | |
599 | const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) { |
600 | switch (AM) { |
601 | default: return "" ; |
602 | case ISD::PRE_INC: return "<pre-inc>" ; |
603 | case ISD::PRE_DEC: return "<pre-dec>" ; |
604 | case ISD::POST_INC: return "<post-inc>" ; |
605 | case ISD::POST_DEC: return "<post-dec>" ; |
606 | } |
607 | } |
608 | |
609 | static Printable PrintNodeId(const SDNode &Node) { |
610 | return Printable([&Node](raw_ostream &OS) { |
611 | #ifndef NDEBUG |
612 | static const raw_ostream::Colors Color[] = { |
613 | raw_ostream::BLACK, raw_ostream::RED, raw_ostream::GREEN, |
614 | raw_ostream::YELLOW, raw_ostream::BLUE, raw_ostream::MAGENTA, |
615 | raw_ostream::CYAN, |
616 | }; |
617 | OS.changeColor(Color[Node.PersistentId % std::size(Color)]); |
618 | OS << 't' << Node.PersistentId; |
619 | OS.resetColor(); |
620 | #else |
621 | OS << (const void*)&Node; |
622 | #endif |
623 | }); |
624 | } |
625 | |
626 | // Print the MMO with more information from the SelectionDAG. |
627 | static void printMemOperand(raw_ostream &OS, const MachineMemOperand &MMO, |
628 | const MachineFunction *MF, const Module *M, |
629 | const MachineFrameInfo *MFI, |
630 | const TargetInstrInfo *TII, LLVMContext &Ctx) { |
631 | ModuleSlotTracker MST(M); |
632 | if (MF) |
633 | MST.incorporateFunction(F: MF->getFunction()); |
634 | SmallVector<StringRef, 0> SSNs; |
635 | MMO.print(OS, MST, SSNs, Context: Ctx, MFI, TII); |
636 | } |
637 | |
638 | static void printMemOperand(raw_ostream &OS, const MachineMemOperand &MMO, |
639 | const SelectionDAG *G) { |
640 | if (G) { |
641 | const MachineFunction *MF = &G->getMachineFunction(); |
642 | return printMemOperand(OS, MMO, MF, M: MF->getFunction().getParent(), |
643 | MFI: &MF->getFrameInfo(), |
644 | TII: G->getSubtarget().getInstrInfo(), Ctx&: *G->getContext()); |
645 | } |
646 | |
647 | LLVMContext Ctx; |
648 | return printMemOperand(OS, MMO, /*MF=*/nullptr, /*M=*/nullptr, |
649 | /*MFI=*/nullptr, /*TII=*/nullptr, Ctx); |
650 | } |
651 | |
652 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
653 | LLVM_DUMP_METHOD void SDNode::dump() const { dump(nullptr); } |
654 | |
655 | LLVM_DUMP_METHOD void SDNode::dump(const SelectionDAG *G) const { |
656 | print(dbgs(), G); |
657 | dbgs() << '\n'; |
658 | } |
659 | #endif |
660 | |
661 | void SDNode::print_types(raw_ostream &OS, const SelectionDAG *G) const { |
662 | for (unsigned i = 0, e = getNumValues(); i != e; ++i) { |
663 | if (i) OS << "," ; |
664 | if (getValueType(ResNo: i) == MVT::Other) |
665 | OS << "ch" ; |
666 | else |
667 | OS << getValueType(ResNo: i).getEVTString(); |
668 | } |
669 | } |
670 | |
671 | void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const { |
672 | if (getFlags().hasNoUnsignedWrap()) |
673 | OS << " nuw" ; |
674 | |
675 | if (getFlags().hasNoSignedWrap()) |
676 | OS << " nsw" ; |
677 | |
678 | if (getFlags().hasExact()) |
679 | OS << " exact" ; |
680 | |
681 | if (getFlags().hasDisjoint()) |
682 | OS << " disjoint" ; |
683 | |
684 | if (getFlags().hasSameSign()) |
685 | OS << " samesign" ; |
686 | |
687 | if (getFlags().hasNonNeg()) |
688 | OS << " nneg" ; |
689 | |
690 | if (getFlags().hasNoNaNs()) |
691 | OS << " nnan" ; |
692 | |
693 | if (getFlags().hasNoInfs()) |
694 | OS << " ninf" ; |
695 | |
696 | if (getFlags().hasNoSignedZeros()) |
697 | OS << " nsz" ; |
698 | |
699 | if (getFlags().hasAllowReciprocal()) |
700 | OS << " arcp" ; |
701 | |
702 | if (getFlags().hasAllowContract()) |
703 | OS << " contract" ; |
704 | |
705 | if (getFlags().hasApproximateFuncs()) |
706 | OS << " afn" ; |
707 | |
708 | if (getFlags().hasAllowReassociation()) |
709 | OS << " reassoc" ; |
710 | |
711 | if (getFlags().hasNoFPExcept()) |
712 | OS << " nofpexcept" ; |
713 | |
714 | if (const MachineSDNode *MN = dyn_cast<MachineSDNode>(Val: this)) { |
715 | if (!MN->memoperands_empty()) { |
716 | OS << "<" ; |
717 | OS << "Mem:" ; |
718 | for (MachineSDNode::mmo_iterator i = MN->memoperands_begin(), |
719 | e = MN->memoperands_end(); i != e; ++i) { |
720 | printMemOperand(OS, MMO: **i, G); |
721 | if (std::next(x: i) != e) |
722 | OS << " " ; |
723 | } |
724 | OS << ">" ; |
725 | } |
726 | } else if (const ShuffleVectorSDNode *SVN = |
727 | dyn_cast<ShuffleVectorSDNode>(Val: this)) { |
728 | OS << "<" ; |
729 | for (unsigned i = 0, e = ValueList[0].getVectorNumElements(); i != e; ++i) { |
730 | int Idx = SVN->getMaskElt(Idx: i); |
731 | if (i) OS << "," ; |
732 | if (Idx < 0) |
733 | OS << "u" ; |
734 | else |
735 | OS << Idx; |
736 | } |
737 | OS << ">" ; |
738 | } else if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Val: this)) { |
739 | OS << '<' << CSDN->getAPIntValue() << '>'; |
740 | } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Val: this)) { |
741 | if (&CSDN->getValueAPF().getSemantics() == &APFloat::IEEEsingle()) |
742 | OS << '<' << CSDN->getValueAPF().convertToFloat() << '>'; |
743 | else if (&CSDN->getValueAPF().getSemantics() == &APFloat::IEEEdouble()) |
744 | OS << '<' << CSDN->getValueAPF().convertToDouble() << '>'; |
745 | else { |
746 | OS << "<APFloat(" ; |
747 | CSDN->getValueAPF().bitcastToAPInt().print(OS, isSigned: false); |
748 | OS << ")>" ; |
749 | } |
750 | } else if (const GlobalAddressSDNode *GADN = |
751 | dyn_cast<GlobalAddressSDNode>(Val: this)) { |
752 | int64_t offset = GADN->getOffset(); |
753 | OS << '<'; |
754 | GADN->getGlobal()->printAsOperand(O&: OS); |
755 | OS << '>'; |
756 | if (offset > 0) |
757 | OS << " + " << offset; |
758 | else |
759 | OS << " " << offset; |
760 | if (unsigned int TF = GADN->getTargetFlags()) |
761 | OS << " [TF=" << TF << ']'; |
762 | } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Val: this)) { |
763 | OS << "<" << FIDN->getIndex() << ">" ; |
764 | } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(Val: this)) { |
765 | OS << "<" << JTDN->getIndex() << ">" ; |
766 | if (unsigned int TF = JTDN->getTargetFlags()) |
767 | OS << " [TF=" << TF << ']'; |
768 | } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Val: this)){ |
769 | int offset = CP->getOffset(); |
770 | if (CP->isMachineConstantPoolEntry()) |
771 | OS << "<" << *CP->getMachineCPVal() << ">" ; |
772 | else |
773 | OS << "<" << *CP->getConstVal() << ">" ; |
774 | if (offset > 0) |
775 | OS << " + " << offset; |
776 | else |
777 | OS << " " << offset; |
778 | if (unsigned int TF = CP->getTargetFlags()) |
779 | OS << " [TF=" << TF << ']'; |
780 | } else if (const TargetIndexSDNode *TI = dyn_cast<TargetIndexSDNode>(Val: this)) { |
781 | OS << "<" << TI->getIndex() << '+' << TI->getOffset() << ">" ; |
782 | if (unsigned TF = TI->getTargetFlags()) |
783 | OS << " [TF=" << TF << ']'; |
784 | } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Val: this)) { |
785 | OS << "<" ; |
786 | const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); |
787 | if (LBB) |
788 | OS << LBB->getName() << " " ; |
789 | OS << (const void*)BBDN->getBasicBlock() << ">" ; |
790 | } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Val: this)) { |
791 | OS << ' ' << printReg(Reg: R->getReg(), |
792 | TRI: G ? G->getSubtarget().getRegisterInfo() : nullptr); |
793 | } else if (const ExternalSymbolSDNode *ES = |
794 | dyn_cast<ExternalSymbolSDNode>(Val: this)) { |
795 | OS << "'" << ES->getSymbol() << "'" ; |
796 | if (unsigned int TF = ES->getTargetFlags()) |
797 | OS << " [TF=" << TF << ']'; |
798 | } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Val: this)) { |
799 | if (M->getValue()) |
800 | OS << "<" << M->getValue() << ">" ; |
801 | else |
802 | OS << "<null>" ; |
803 | } else if (const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(Val: this)) { |
804 | if (MD->getMD()) |
805 | OS << "<" << MD->getMD() << ">" ; |
806 | else |
807 | OS << "<null>" ; |
808 | } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Val: this)) { |
809 | OS << ":" << N->getVT(); |
810 | } |
811 | else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(Val: this)) { |
812 | OS << "<" ; |
813 | |
814 | printMemOperand(OS, MMO: *LD->getMemOperand(), G); |
815 | |
816 | bool doExt = true; |
817 | switch (LD->getExtensionType()) { |
818 | default: doExt = false; break; |
819 | case ISD::EXTLOAD: OS << ", anyext" ; break; |
820 | case ISD::SEXTLOAD: OS << ", sext" ; break; |
821 | case ISD::ZEXTLOAD: OS << ", zext" ; break; |
822 | } |
823 | if (doExt) |
824 | OS << " from " << LD->getMemoryVT(); |
825 | |
826 | const char *AM = getIndexedModeName(AM: LD->getAddressingMode()); |
827 | if (*AM) |
828 | OS << ", " << AM; |
829 | |
830 | OS << ">" ; |
831 | } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(Val: this)) { |
832 | OS << "<" ; |
833 | printMemOperand(OS, MMO: *ST->getMemOperand(), G); |
834 | |
835 | if (ST->isTruncatingStore()) |
836 | OS << ", trunc to " << ST->getMemoryVT(); |
837 | |
838 | const char *AM = getIndexedModeName(AM: ST->getAddressingMode()); |
839 | if (*AM) |
840 | OS << ", " << AM; |
841 | |
842 | OS << ">" ; |
843 | } else if (const MaskedLoadSDNode *MLd = dyn_cast<MaskedLoadSDNode>(Val: this)) { |
844 | OS << "<" ; |
845 | |
846 | printMemOperand(OS, MMO: *MLd->getMemOperand(), G); |
847 | |
848 | bool doExt = true; |
849 | switch (MLd->getExtensionType()) { |
850 | default: doExt = false; break; |
851 | case ISD::EXTLOAD: OS << ", anyext" ; break; |
852 | case ISD::SEXTLOAD: OS << ", sext" ; break; |
853 | case ISD::ZEXTLOAD: OS << ", zext" ; break; |
854 | } |
855 | if (doExt) |
856 | OS << " from " << MLd->getMemoryVT(); |
857 | |
858 | const char *AM = getIndexedModeName(AM: MLd->getAddressingMode()); |
859 | if (*AM) |
860 | OS << ", " << AM; |
861 | |
862 | if (MLd->isExpandingLoad()) |
863 | OS << ", expanding" ; |
864 | |
865 | OS << ">" ; |
866 | } else if (const MaskedStoreSDNode *MSt = dyn_cast<MaskedStoreSDNode>(Val: this)) { |
867 | OS << "<" ; |
868 | printMemOperand(OS, MMO: *MSt->getMemOperand(), G); |
869 | |
870 | if (MSt->isTruncatingStore()) |
871 | OS << ", trunc to " << MSt->getMemoryVT(); |
872 | |
873 | const char *AM = getIndexedModeName(AM: MSt->getAddressingMode()); |
874 | if (*AM) |
875 | OS << ", " << AM; |
876 | |
877 | if (MSt->isCompressingStore()) |
878 | OS << ", compressing" ; |
879 | |
880 | OS << ">" ; |
881 | } else if (const auto *MGather = dyn_cast<MaskedGatherSDNode>(Val: this)) { |
882 | OS << "<" ; |
883 | printMemOperand(OS, MMO: *MGather->getMemOperand(), G); |
884 | |
885 | bool doExt = true; |
886 | switch (MGather->getExtensionType()) { |
887 | default: doExt = false; break; |
888 | case ISD::EXTLOAD: OS << ", anyext" ; break; |
889 | case ISD::SEXTLOAD: OS << ", sext" ; break; |
890 | case ISD::ZEXTLOAD: OS << ", zext" ; break; |
891 | } |
892 | if (doExt) |
893 | OS << " from " << MGather->getMemoryVT(); |
894 | |
895 | auto Signed = MGather->isIndexSigned() ? "signed" : "unsigned" ; |
896 | auto Scaled = MGather->isIndexScaled() ? "scaled" : "unscaled" ; |
897 | OS << ", " << Signed << " " << Scaled << " offset" ; |
898 | |
899 | OS << ">" ; |
900 | } else if (const auto *MScatter = dyn_cast<MaskedScatterSDNode>(Val: this)) { |
901 | OS << "<" ; |
902 | printMemOperand(OS, MMO: *MScatter->getMemOperand(), G); |
903 | |
904 | if (MScatter->isTruncatingStore()) |
905 | OS << ", trunc to " << MScatter->getMemoryVT(); |
906 | |
907 | auto Signed = MScatter->isIndexSigned() ? "signed" : "unsigned" ; |
908 | auto Scaled = MScatter->isIndexScaled() ? "scaled" : "unscaled" ; |
909 | OS << ", " << Signed << " " << Scaled << " offset" ; |
910 | |
911 | OS << ">" ; |
912 | } else if (const MemSDNode *M = dyn_cast<MemSDNode>(Val: this)) { |
913 | OS << "<" ; |
914 | printMemOperand(OS, MMO: *M->getMemOperand(), G); |
915 | if (auto *A = dyn_cast<AtomicSDNode>(Val: M)) |
916 | if (A->getOpcode() == ISD::ATOMIC_LOAD) { |
917 | bool doExt = true; |
918 | switch (A->getExtensionType()) { |
919 | default: doExt = false; break; |
920 | case ISD::EXTLOAD: OS << ", anyext" ; break; |
921 | case ISD::SEXTLOAD: OS << ", sext" ; break; |
922 | case ISD::ZEXTLOAD: OS << ", zext" ; break; |
923 | } |
924 | if (doExt) |
925 | OS << " from " << A->getMemoryVT(); |
926 | } |
927 | OS << ">" ; |
928 | } else if (const BlockAddressSDNode *BA = |
929 | dyn_cast<BlockAddressSDNode>(Val: this)) { |
930 | int64_t offset = BA->getOffset(); |
931 | OS << "<" ; |
932 | BA->getBlockAddress()->getFunction()->printAsOperand(O&: OS, PrintType: false); |
933 | OS << ", " ; |
934 | BA->getBlockAddress()->getBasicBlock()->printAsOperand(O&: OS, PrintType: false); |
935 | OS << ">" ; |
936 | if (offset > 0) |
937 | OS << " + " << offset; |
938 | else |
939 | OS << " " << offset; |
940 | if (unsigned int TF = BA->getTargetFlags()) |
941 | OS << " [TF=" << TF << ']'; |
942 | } else if (const AddrSpaceCastSDNode *ASC = |
943 | dyn_cast<AddrSpaceCastSDNode>(Val: this)) { |
944 | OS << '[' |
945 | << ASC->getSrcAddressSpace() |
946 | << " -> " |
947 | << ASC->getDestAddressSpace() |
948 | << ']'; |
949 | } else if (const LifetimeSDNode *LN = dyn_cast<LifetimeSDNode>(Val: this)) { |
950 | if (LN->hasOffset()) |
951 | OS << "<" << LN->getOffset() << " to " << LN->getOffset() + LN->getSize() << ">" ; |
952 | } else if (const auto *AA = dyn_cast<AssertAlignSDNode>(Val: this)) { |
953 | OS << '<' << AA->getAlign().value() << '>'; |
954 | } |
955 | |
956 | if (VerboseDAGDumping) { |
957 | if (unsigned Order = getIROrder()) |
958 | OS << " [ORD=" << Order << ']'; |
959 | |
960 | if (getNodeId() != -1) |
961 | OS << " [ID=" << getNodeId() << ']'; |
962 | if (!(isa<ConstantSDNode>(Val: this) || (isa<ConstantFPSDNode>(Val: this)))) |
963 | OS << " # D:" << isDivergent(); |
964 | |
965 | if (G && !G->GetDbgValues(SD: this).empty()) { |
966 | OS << " [NoOfDbgValues=" << G->GetDbgValues(SD: this).size() << ']'; |
967 | for (SDDbgValue *Dbg : G->GetDbgValues(SD: this)) |
968 | if (!Dbg->isInvalidated()) |
969 | Dbg->print(OS); |
970 | } else if (getHasDebugValue()) |
971 | OS << " [NoOfDbgValues>0]" ; |
972 | |
973 | if (const auto *MD = G ? G->getPCSections(Node: this) : nullptr) { |
974 | OS << " [pcsections " ; |
975 | MD->printAsOperand(OS, M: G->getMachineFunction().getFunction().getParent()); |
976 | OS << ']'; |
977 | } |
978 | |
979 | if (MDNode *MMRA = G ? G->getMMRAMetadata(Node: this) : nullptr) { |
980 | OS << " [mmra " ; |
981 | MMRA->printAsOperand(OS, |
982 | M: G->getMachineFunction().getFunction().getParent()); |
983 | OS << ']'; |
984 | } |
985 | } |
986 | } |
987 | |
988 | LLVM_DUMP_METHOD void SDDbgValue::print(raw_ostream &OS) const { |
989 | OS << " DbgVal(Order=" << getOrder() << ')'; |
990 | if (isInvalidated()) |
991 | OS << "(Invalidated)" ; |
992 | if (isEmitted()) |
993 | OS << "(Emitted)" ; |
994 | OS << "(" ; |
995 | bool Comma = false; |
996 | for (const SDDbgOperand &Op : getLocationOps()) { |
997 | if (Comma) |
998 | OS << ", " ; |
999 | switch (Op.getKind()) { |
1000 | case SDDbgOperand::SDNODE: |
1001 | if (Op.getSDNode()) |
1002 | OS << "SDNODE=" << PrintNodeId(Node: *Op.getSDNode()) << ':' << Op.getResNo(); |
1003 | else |
1004 | OS << "SDNODE" ; |
1005 | break; |
1006 | case SDDbgOperand::CONST: |
1007 | OS << "CONST" ; |
1008 | break; |
1009 | case SDDbgOperand::FRAMEIX: |
1010 | OS << "FRAMEIX=" << Op.getFrameIx(); |
1011 | break; |
1012 | case SDDbgOperand::VREG: |
1013 | OS << "VREG=" << printReg(Reg: Op.getVReg()); |
1014 | break; |
1015 | } |
1016 | Comma = true; |
1017 | } |
1018 | OS << ")" ; |
1019 | if (isIndirect()) OS << "(Indirect)" ; |
1020 | if (isVariadic()) |
1021 | OS << "(Variadic)" ; |
1022 | OS << ":\"" << Var->getName() << '"'; |
1023 | #ifndef NDEBUG |
1024 | if (Expr->getNumElements()) |
1025 | Expr->dump(); |
1026 | #endif |
1027 | } |
1028 | |
1029 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
1030 | LLVM_DUMP_METHOD void SDDbgValue::dump() const { |
1031 | if (isInvalidated()) |
1032 | return; |
1033 | print(dbgs()); |
1034 | dbgs() << "\n" ; |
1035 | } |
1036 | #endif |
1037 | |
1038 | /// Return true if this node is so simple that we should just print it inline |
1039 | /// if it appears as an operand. |
1040 | static bool shouldPrintInline(const SDNode &Node, const SelectionDAG *G) { |
1041 | // Avoid lots of cluttering when inline printing nodes with associated |
1042 | // DbgValues in verbose mode. |
1043 | if (VerboseDAGDumping && G && !G->GetDbgValues(SD: &Node).empty()) |
1044 | return false; |
1045 | if (Node.getOpcode() == ISD::EntryToken) |
1046 | return false; |
1047 | return Node.getNumOperands() == 0; |
1048 | } |
1049 | |
1050 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
1051 | static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) { |
1052 | for (const SDValue &Op : N->op_values()) { |
1053 | if (shouldPrintInline(*Op.getNode(), G)) |
1054 | continue; |
1055 | if (Op.getNode()->hasOneUse()) |
1056 | DumpNodes(Op.getNode(), indent+2, G); |
1057 | } |
1058 | |
1059 | dbgs().indent(indent); |
1060 | N->dump(G); |
1061 | } |
1062 | |
1063 | LLVM_DUMP_METHOD void SelectionDAG::dump() const { |
1064 | dbgs() << "SelectionDAG has " << AllNodes.size() << " nodes:\n" ; |
1065 | |
1066 | for (const SDNode &N : allnodes()) { |
1067 | if (!N.hasOneUse() && &N != getRoot().getNode() && |
1068 | (!shouldPrintInline(N, this) || N.use_empty())) |
1069 | DumpNodes(&N, 2, this); |
1070 | } |
1071 | |
1072 | if (getRoot().getNode()) DumpNodes(getRoot().getNode(), 2, this); |
1073 | dbgs() << "\n" ; |
1074 | |
1075 | if (VerboseDAGDumping) { |
1076 | if (DbgBegin() != DbgEnd()) |
1077 | dbgs() << "SDDbgValues:\n" ; |
1078 | for (auto *Dbg : make_range(DbgBegin(), DbgEnd())) |
1079 | Dbg->dump(); |
1080 | if (ByvalParmDbgBegin() != ByvalParmDbgEnd()) |
1081 | dbgs() << "Byval SDDbgValues:\n" ; |
1082 | for (auto *Dbg : make_range(ByvalParmDbgBegin(), ByvalParmDbgEnd())) |
1083 | Dbg->dump(); |
1084 | } |
1085 | dbgs() << "\n" ; |
1086 | } |
1087 | #endif |
1088 | |
1089 | void SDNode::printr(raw_ostream &OS, const SelectionDAG *G) const { |
1090 | OS << PrintNodeId(Node: *this) << ": " ; |
1091 | print_types(OS, G); |
1092 | OS << " = " << getOperationName(G); |
1093 | print_details(OS, G); |
1094 | } |
1095 | |
1096 | static bool printOperand(raw_ostream &OS, const SelectionDAG *G, |
1097 | const SDValue Value) { |
1098 | if (!Value.getNode()) { |
1099 | OS << "<null>" ; |
1100 | return false; |
1101 | } |
1102 | |
1103 | if (shouldPrintInline(Node: *Value.getNode(), G)) { |
1104 | OS << Value->getOperationName(G) << ':'; |
1105 | Value->print_types(OS, G); |
1106 | Value->print_details(OS, G); |
1107 | return true; |
1108 | } |
1109 | |
1110 | OS << PrintNodeId(Node: *Value.getNode()); |
1111 | if (unsigned RN = Value.getResNo()) |
1112 | OS << ':' << RN; |
1113 | return false; |
1114 | } |
1115 | |
1116 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
1117 | using VisitedSDNodeSet = SmallPtrSet<const SDNode *, 32>; |
1118 | |
1119 | static void DumpNodesr(raw_ostream &OS, const SDNode *N, unsigned indent, |
1120 | const SelectionDAG *G, VisitedSDNodeSet &once) { |
1121 | if (!once.insert(N).second) // If we've been here before, return now. |
1122 | return; |
1123 | |
1124 | // Dump the current SDNode, but don't end the line yet. |
1125 | OS.indent(indent); |
1126 | N->printr(OS, G); |
1127 | |
1128 | // Having printed this SDNode, walk the children: |
1129 | for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { |
1130 | if (i) OS << "," ; |
1131 | OS << " " ; |
1132 | |
1133 | const SDValue Op = N->getOperand(i); |
1134 | bool printedInline = printOperand(OS, G, Op); |
1135 | if (printedInline) |
1136 | once.insert(Op.getNode()); |
1137 | } |
1138 | |
1139 | OS << "\n" ; |
1140 | |
1141 | // Dump children that have grandchildren on their own line(s). |
1142 | for (const SDValue &Op : N->op_values()) |
1143 | DumpNodesr(OS, Op.getNode(), indent+2, G, once); |
1144 | } |
1145 | |
1146 | LLVM_DUMP_METHOD void SDNode::dumpr() const { |
1147 | VisitedSDNodeSet once; |
1148 | DumpNodesr(dbgs(), this, 0, nullptr, once); |
1149 | } |
1150 | |
1151 | LLVM_DUMP_METHOD void SDNode::dumpr(const SelectionDAG *G) const { |
1152 | VisitedSDNodeSet once; |
1153 | DumpNodesr(dbgs(), this, 0, G, once); |
1154 | } |
1155 | #endif |
1156 | |
1157 | static void printrWithDepthHelper(raw_ostream &OS, const SDNode *N, |
1158 | const SelectionDAG *G, unsigned depth, |
1159 | unsigned indent) { |
1160 | if (depth == 0) |
1161 | return; |
1162 | |
1163 | OS.indent(NumSpaces: indent); |
1164 | |
1165 | N->print(OS, G); |
1166 | |
1167 | for (const SDValue &Op : N->op_values()) { |
1168 | // Don't follow chain operands. |
1169 | if (Op.getValueType() == MVT::Other) |
1170 | continue; |
1171 | // Don't print children that were fully rendered inline. |
1172 | if (shouldPrintInline(Node: *Op.getNode(), G)) |
1173 | continue; |
1174 | OS << '\n'; |
1175 | printrWithDepthHelper(OS, N: Op.getNode(), G, depth: depth - 1, indent: indent + 2); |
1176 | } |
1177 | } |
1178 | |
1179 | void SDNode::printrWithDepth(raw_ostream &OS, const SelectionDAG *G, |
1180 | unsigned depth) const { |
1181 | printrWithDepthHelper(OS, N: this, G, depth, indent: 0); |
1182 | } |
1183 | |
1184 | void SDNode::printrFull(raw_ostream &OS, const SelectionDAG *G) const { |
1185 | // Don't print impossibly deep things. |
1186 | printrWithDepth(OS, G, depth: 10); |
1187 | } |
1188 | |
1189 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
1190 | LLVM_DUMP_METHOD |
1191 | void SDNode::dumprWithDepth(const SelectionDAG *G, unsigned depth) const { |
1192 | printrWithDepth(dbgs(), G, depth); |
1193 | } |
1194 | |
1195 | LLVM_DUMP_METHOD void SDNode::dumprFull(const SelectionDAG *G) const { |
1196 | // Don't print impossibly deep things. |
1197 | dumprWithDepth(G, 10); |
1198 | } |
1199 | #endif |
1200 | |
1201 | void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { |
1202 | printr(OS, G); |
1203 | // Under VerboseDAGDumping divergence will be printed always. |
1204 | if (isDivergent() && !VerboseDAGDumping) |
1205 | OS << " # D:1" ; |
1206 | for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { |
1207 | if (i) OS << ", " ; else OS << " " ; |
1208 | printOperand(OS, G, Value: getOperand(Num: i)); |
1209 | } |
1210 | if (DebugLoc DL = getDebugLoc()) { |
1211 | OS << ", " ; |
1212 | DL.print(OS); |
1213 | } |
1214 | } |
1215 | |