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