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