| ... | @@ -10,27 +10,374 @@ | ... | @@ -10,27 +10,374 @@ |
| 10 | #include "ir_print.hpp" | 10 | #include "ir_print.hpp" |
| 11 | #include "os.hpp" | 11 | #include "os.hpp" |
| 12 | | 12 | |
| | 13 | static uint32_t hash_instruction_ptr(IrInstruction* instruction) { |
| | 14 | return (uint32_t)(uintptr_t)instruction; |
| | 15 | } |
| | 16 | |
| | 17 | static bool instruction_ptr_equal(IrInstruction* a, IrInstruction* b) { |
| | 18 | return a == b; |
| | 19 | } |
| | 20 | |
| | 21 | using InstructionSet = HashMap<IrInstruction*, uint8_t, hash_instruction_ptr, instruction_ptr_equal>; |
| | 22 | using InstructionList = ZigList<IrInstruction*>; |
| | 23 | |
| 13 | struct IrPrint { | 24 | struct IrPrint { |
| | 25 | size_t pass_num; |
| 14 | CodeGen *codegen; | 26 | CodeGen *codegen; |
| 15 | FILE *f; | 27 | FILE *f; |
| 16 | int indent; | 28 | int indent; |
| 17 | int indent_size; | 29 | int indent_size; |
| | 30 | |
| | 31 | // When printing pass 2 instructions referenced var instructions are not |
| | 32 | // present in the instruction list. Thus we track which instructions |
| | 33 | // are printed (per executable) and after each pass 2 instruction those |
| | 34 | // var instructions are rendered in a trailing fashion. |
| | 35 | InstructionSet printed; |
| | 36 | InstructionList pending; |
| 18 | }; | 37 | }; |
| 19 | | 38 | |
| 20 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction); | 39 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction); |
| 21 | | 40 | |
| | 41 | static const char* ir_instruction_type_str(IrInstruction* instruction) { |
| | 42 | switch (instruction->id) { |
| | 43 | case IrInstructionIdInvalid: |
| | 44 | return "Invalid"; |
| | 45 | case IrInstructionIdDeclVarSrc: |
| | 46 | return "DeclVarSrc"; |
| | 47 | case IrInstructionIdDeclVarGen: |
| | 48 | return "DeclVarGen"; |
| | 49 | case IrInstructionIdBr: |
| | 50 | return "Br"; |
| | 51 | case IrInstructionIdCondBr: |
| | 52 | return "CondBr"; |
| | 53 | case IrInstructionIdSwitchBr: |
| | 54 | return "SwitchBr"; |
| | 55 | case IrInstructionIdSwitchVar: |
| | 56 | return "SwitchVar"; |
| | 57 | case IrInstructionIdSwitchElseVar: |
| | 58 | return "SwitchElseVar"; |
| | 59 | case IrInstructionIdSwitchTarget: |
| | 60 | return "SwitchTarget"; |
| | 61 | case IrInstructionIdPhi: |
| | 62 | return "Phi"; |
| | 63 | case IrInstructionIdUnOp: |
| | 64 | return "UnOp"; |
| | 65 | case IrInstructionIdBinOp: |
| | 66 | return "BinOp"; |
| | 67 | case IrInstructionIdLoadPtr: |
| | 68 | return "LoadPtr"; |
| | 69 | case IrInstructionIdLoadPtrGen: |
| | 70 | return "LoadPtrGen"; |
| | 71 | case IrInstructionIdStorePtr: |
| | 72 | return "StorePtr"; |
| | 73 | case IrInstructionIdFieldPtr: |
| | 74 | return "FieldPtr"; |
| | 75 | case IrInstructionIdStructFieldPtr: |
| | 76 | return "StructFieldPtr"; |
| | 77 | case IrInstructionIdUnionFieldPtr: |
| | 78 | return "UnionFieldPtr"; |
| | 79 | case IrInstructionIdElemPtr: |
| | 80 | return "ElemPtr"; |
| | 81 | case IrInstructionIdVarPtr: |
| | 82 | return "VarPtr"; |
| | 83 | case IrInstructionIdReturnPtr: |
| | 84 | return "ReturnPtr"; |
| | 85 | case IrInstructionIdCallSrc: |
| | 86 | return "CallSrc"; |
| | 87 | case IrInstructionIdCallGen: |
| | 88 | return "CallGen"; |
| | 89 | case IrInstructionIdConst: |
| | 90 | return "Const"; |
| | 91 | case IrInstructionIdReturn: |
| | 92 | return "Return"; |
| | 93 | case IrInstructionIdCast: |
| | 94 | return "Cast"; |
| | 95 | case IrInstructionIdResizeSlice: |
| | 96 | return "ResizeSlice"; |
| | 97 | case IrInstructionIdContainerInitList: |
| | 98 | return "ContainerInitList"; |
| | 99 | case IrInstructionIdContainerInitFields: |
| | 100 | return "ContainerInitFields"; |
| | 101 | case IrInstructionIdUnreachable: |
| | 102 | return "Unreachable"; |
| | 103 | case IrInstructionIdTypeOf: |
| | 104 | return "TypeOf"; |
| | 105 | case IrInstructionIdSetCold: |
| | 106 | return "SetCold"; |
| | 107 | case IrInstructionIdSetRuntimeSafety: |
| | 108 | return "SetRuntimeSafety"; |
| | 109 | case IrInstructionIdSetFloatMode: |
| | 110 | return "SetFloatMode"; |
| | 111 | case IrInstructionIdArrayType: |
| | 112 | return "ArrayType"; |
| | 113 | case IrInstructionIdAnyFrameType: |
| | 114 | return "AnyFrameType"; |
| | 115 | case IrInstructionIdSliceType: |
| | 116 | return "SliceType"; |
| | 117 | case IrInstructionIdGlobalAsm: |
| | 118 | return "GlobalAsm"; |
| | 119 | case IrInstructionIdAsm: |
| | 120 | return "Asm"; |
| | 121 | case IrInstructionIdSizeOf: |
| | 122 | return "SizeOf"; |
| | 123 | case IrInstructionIdTestNonNull: |
| | 124 | return "TestNonNull"; |
| | 125 | case IrInstructionIdOptionalUnwrapPtr: |
| | 126 | return "OptionalUnwrapPtr"; |
| | 127 | case IrInstructionIdOptionalWrap: |
| | 128 | return "OptionalWrap"; |
| | 129 | case IrInstructionIdUnionTag: |
| | 130 | return "UnionTag"; |
| | 131 | case IrInstructionIdClz: |
| | 132 | return "Clz"; |
| | 133 | case IrInstructionIdCtz: |
| | 134 | return "Ctz"; |
| | 135 | case IrInstructionIdPopCount: |
| | 136 | return "PopCount"; |
| | 137 | case IrInstructionIdBswap: |
| | 138 | return "Bswap"; |
| | 139 | case IrInstructionIdBitReverse: |
| | 140 | return "BitReverse"; |
| | 141 | case IrInstructionIdImport: |
| | 142 | return "Import"; |
| | 143 | case IrInstructionIdCImport: |
| | 144 | return "CImport"; |
| | 145 | case IrInstructionIdCInclude: |
| | 146 | return "CInclude"; |
| | 147 | case IrInstructionIdCDefine: |
| | 148 | return "CDefine"; |
| | 149 | case IrInstructionIdCUndef: |
| | 150 | return "CUndef"; |
| | 151 | case IrInstructionIdRef: |
| | 152 | return "Ref"; |
| | 153 | case IrInstructionIdRefGen: |
| | 154 | return "RefGen"; |
| | 155 | case IrInstructionIdCompileErr: |
| | 156 | return "CompileErr"; |
| | 157 | case IrInstructionIdCompileLog: |
| | 158 | return "CompileLog"; |
| | 159 | case IrInstructionIdErrName: |
| | 160 | return "ErrName"; |
| | 161 | case IrInstructionIdEmbedFile: |
| | 162 | return "EmbedFile"; |
| | 163 | case IrInstructionIdCmpxchgSrc: |
| | 164 | return "CmpxchgSrc"; |
| | 165 | case IrInstructionIdCmpxchgGen: |
| | 166 | return "CmpxchgGen"; |
| | 167 | case IrInstructionIdFence: |
| | 168 | return "Fence"; |
| | 169 | case IrInstructionIdTruncate: |
| | 170 | return "Truncate"; |
| | 171 | case IrInstructionIdIntCast: |
| | 172 | return "IntCast"; |
| | 173 | case IrInstructionIdFloatCast: |
| | 174 | return "FloatCast"; |
| | 175 | case IrInstructionIdIntToFloat: |
| | 176 | return "IntToFloat"; |
| | 177 | case IrInstructionIdFloatToInt: |
| | 178 | return "FloatToInt"; |
| | 179 | case IrInstructionIdBoolToInt: |
| | 180 | return "BoolToInt"; |
| | 181 | case IrInstructionIdIntType: |
| | 182 | return "IntType"; |
| | 183 | case IrInstructionIdVectorType: |
| | 184 | return "VectorType"; |
| | 185 | case IrInstructionIdBoolNot: |
| | 186 | return "BoolNot"; |
| | 187 | case IrInstructionIdMemset: |
| | 188 | return "Memset"; |
| | 189 | case IrInstructionIdMemcpy: |
| | 190 | return "Memcpy"; |
| | 191 | case IrInstructionIdSliceSrc: |
| | 192 | return "SliceSrc"; |
| | 193 | case IrInstructionIdSliceGen: |
| | 194 | return "SliceGen"; |
| | 195 | case IrInstructionIdMemberCount: |
| | 196 | return "MemberCount"; |
| | 197 | case IrInstructionIdMemberType: |
| | 198 | return "MemberType"; |
| | 199 | case IrInstructionIdMemberName: |
| | 200 | return "MemberName"; |
| | 201 | case IrInstructionIdBreakpoint: |
| | 202 | return "Breakpoint"; |
| | 203 | case IrInstructionIdReturnAddress: |
| | 204 | return "ReturnAddress"; |
| | 205 | case IrInstructionIdFrameAddress: |
| | 206 | return "FrameAddress"; |
| | 207 | case IrInstructionIdFrameHandle: |
| | 208 | return "FrameHandle"; |
| | 209 | case IrInstructionIdFrameType: |
| | 210 | return "FrameType"; |
| | 211 | case IrInstructionIdFrameSizeSrc: |
| | 212 | return "FrameSizeSrc"; |
| | 213 | case IrInstructionIdFrameSizeGen: |
| | 214 | return "FrameSizeGen"; |
| | 215 | case IrInstructionIdAlignOf: |
| | 216 | return "AlignOf"; |
| | 217 | case IrInstructionIdOverflowOp: |
| | 218 | return "OverflowOp"; |
| | 219 | case IrInstructionIdTestErrSrc: |
| | 220 | return "TestErrSrc"; |
| | 221 | case IrInstructionIdTestErrGen: |
| | 222 | return "TestErrGen"; |
| | 223 | case IrInstructionIdMulAdd: |
| | 224 | return "MulAdd"; |
| | 225 | case IrInstructionIdFloatOp: |
| | 226 | return "FloatOp"; |
| | 227 | case IrInstructionIdUnwrapErrCode: |
| | 228 | return "UnwrapErrCode"; |
| | 229 | case IrInstructionIdUnwrapErrPayload: |
| | 230 | return "UnwrapErrPayload"; |
| | 231 | case IrInstructionIdErrWrapCode: |
| | 232 | return "ErrWrapCode"; |
| | 233 | case IrInstructionIdErrWrapPayload: |
| | 234 | return "ErrWrapPayload"; |
| | 235 | case IrInstructionIdFnProto: |
| | 236 | return "FnProto"; |
| | 237 | case IrInstructionIdTestComptime: |
| | 238 | return "TestComptime"; |
| | 239 | case IrInstructionIdPtrCastSrc: |
| | 240 | return "PtrCastSrc"; |
| | 241 | case IrInstructionIdPtrCastGen: |
| | 242 | return "PtrCastGen"; |
| | 243 | case IrInstructionIdBitCastSrc: |
| | 244 | return "BitCastSrc"; |
| | 245 | case IrInstructionIdBitCastGen: |
| | 246 | return "BitCastGen"; |
| | 247 | case IrInstructionIdWidenOrShorten: |
| | 248 | return "WidenOrShorten"; |
| | 249 | case IrInstructionIdIntToPtr: |
| | 250 | return "IntToPtr"; |
| | 251 | case IrInstructionIdPtrToInt: |
| | 252 | return "PtrToInt"; |
| | 253 | case IrInstructionIdIntToEnum: |
| | 254 | return "IntToEnum"; |
| | 255 | case IrInstructionIdEnumToInt: |
| | 256 | return "EnumToInt"; |
| | 257 | case IrInstructionIdIntToErr: |
| | 258 | return "IntToErr"; |
| | 259 | case IrInstructionIdErrToInt: |
| | 260 | return "ErrToInt"; |
| | 261 | case IrInstructionIdCheckSwitchProngs: |
| | 262 | return "CheckSwitchProngs"; |
| | 263 | case IrInstructionIdCheckStatementIsVoid: |
| | 264 | return "CheckStatementIsVoid"; |
| | 265 | case IrInstructionIdTypeName: |
| | 266 | return "TypeName"; |
| | 267 | case IrInstructionIdDeclRef: |
| | 268 | return "DeclRef"; |
| | 269 | case IrInstructionIdPanic: |
| | 270 | return "Panic"; |
| | 271 | case IrInstructionIdTagName: |
| | 272 | return "TagName"; |
| | 273 | case IrInstructionIdTagType: |
| | 274 | return "TagType"; |
| | 275 | case IrInstructionIdFieldParentPtr: |
| | 276 | return "FieldParentPtr"; |
| | 277 | case IrInstructionIdByteOffsetOf: |
| | 278 | return "ByteOffsetOf"; |
| | 279 | case IrInstructionIdBitOffsetOf: |
| | 280 | return "BitOffsetOf"; |
| | 281 | case IrInstructionIdTypeInfo: |
| | 282 | return "TypeInfo"; |
| | 283 | case IrInstructionIdHasField: |
| | 284 | return "HasField"; |
| | 285 | case IrInstructionIdTypeId: |
| | 286 | return "TypeId"; |
| | 287 | case IrInstructionIdSetEvalBranchQuota: |
| | 288 | return "SetEvalBranchQuota"; |
| | 289 | case IrInstructionIdPtrType: |
| | 290 | return "PtrType"; |
| | 291 | case IrInstructionIdAlignCast: |
| | 292 | return "AlignCast"; |
| | 293 | case IrInstructionIdImplicitCast: |
| | 294 | return "ImplicitCast"; |
| | 295 | case IrInstructionIdResolveResult: |
| | 296 | return "ResolveResult"; |
| | 297 | case IrInstructionIdResetResult: |
| | 298 | return "ResetResult"; |
| | 299 | case IrInstructionIdOpaqueType: |
| | 300 | return "OpaqueType"; |
| | 301 | case IrInstructionIdSetAlignStack: |
| | 302 | return "SetAlignStack"; |
| | 303 | case IrInstructionIdArgType: |
| | 304 | return "ArgType"; |
| | 305 | case IrInstructionIdExport: |
| | 306 | return "Export"; |
| | 307 | case IrInstructionIdErrorReturnTrace: |
| | 308 | return "ErrorReturnTrace"; |
| | 309 | case IrInstructionIdErrorUnion: |
| | 310 | return "ErrorUnion"; |
| | 311 | case IrInstructionIdAtomicRmw: |
| | 312 | return "AtomicRmw"; |
| | 313 | case IrInstructionIdAtomicLoad: |
| | 314 | return "AtomicLoad"; |
| | 315 | case IrInstructionIdSaveErrRetAddr: |
| | 316 | return "SaveErrRetAddr"; |
| | 317 | case IrInstructionIdAddImplicitReturnType: |
| | 318 | return "AddImplicitReturnType"; |
| | 319 | case IrInstructionIdErrSetCast: |
| | 320 | return "ErrSetCast"; |
| | 321 | case IrInstructionIdToBytes: |
| | 322 | return "ToBytes"; |
| | 323 | case IrInstructionIdFromBytes: |
| | 324 | return "FromBytes"; |
| | 325 | case IrInstructionIdCheckRuntimeScope: |
| | 326 | return "CheckRuntimeScope"; |
| | 327 | case IrInstructionIdVectorToArray: |
| | 328 | return "VectorToArray"; |
| | 329 | case IrInstructionIdArrayToVector: |
| | 330 | return "ArrayToVector"; |
| | 331 | case IrInstructionIdAssertZero: |
| | 332 | return "AssertZero"; |
| | 333 | case IrInstructionIdAssertNonNull: |
| | 334 | return "AssertNonNull"; |
| | 335 | case IrInstructionIdHasDecl: |
| | 336 | return "HasDecl"; |
| | 337 | case IrInstructionIdUndeclaredIdent: |
| | 338 | return "UndeclaredIdent"; |
| | 339 | case IrInstructionIdAllocaSrc: |
| | 340 | return "AllocaSrc"; |
| | 341 | case IrInstructionIdAllocaGen: |
| | 342 | return "AllocaGen"; |
| | 343 | case IrInstructionIdEndExpr: |
| | 344 | return "EndExpr"; |
| | 345 | case IrInstructionIdPtrOfArrayToSlice: |
| | 346 | return "PtrOfArrayToSlice"; |
| | 347 | case IrInstructionIdUnionInitNamedField: |
| | 348 | return "UnionInitNamedField"; |
| | 349 | case IrInstructionIdSuspendBegin: |
| | 350 | return "SuspendBegin"; |
| | 351 | case IrInstructionIdSuspendFinish: |
| | 352 | return "SuspendFinish"; |
| | 353 | case IrInstructionIdAwaitSrc: |
| | 354 | return "AwaitSrc"; |
| | 355 | case IrInstructionIdAwaitGen: |
| | 356 | return "AwaitGen"; |
| | 357 | case IrInstructionIdResume: |
| | 358 | return "Resume"; |
| | 359 | case IrInstructionIdSpillBegin: |
| | 360 | return "SpillBegin"; |
| | 361 | case IrInstructionIdSpillEnd: |
| | 362 | return "SpillEnd"; |
| | 363 | } |
| | 364 | zig_unreachable(); |
| | 365 | } |
| | 366 | |
| 22 | static void ir_print_indent(IrPrint *irp) { | 367 | static void ir_print_indent(IrPrint *irp) { |
| 23 | for (int i = 0; i < irp->indent; i += 1) { | 368 | for (int i = 0; i < irp->indent; i += 1) { |
| 24 | fprintf(irp->f, " "); | 369 | fprintf(irp->f, " "); |
| 25 | } | 370 | } |
| 26 | } | 371 | } |
| 27 | | 372 | |
| 28 | static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) { | 373 | static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction, bool trailing) { |
| 29 | ir_print_indent(irp); | 374 | ir_print_indent(irp); |
| | 375 | const char mark = trailing ? ':' : '#'; |
| 30 | const char *type_name = instruction->value.type ? buf_ptr(&instruction->value.type->name) : "(unknown)"; | 376 | const char *type_name = instruction->value.type ? buf_ptr(&instruction->value.type->name) : "(unknown)"; |
| 31 | const char *ref_count = ir_has_side_effects(instruction) ? | 377 | const char *ref_count = ir_has_side_effects(instruction) ? |
| 32 | "-" : buf_ptr(buf_sprintf("%" ZIG_PRI_usize "", instruction->ref_count)); | 378 | "-" : buf_ptr(buf_sprintf("%" ZIG_PRI_usize "", instruction->ref_count)); |
| 33 | fprintf(irp->f, "#%-3zu| %-12s| %-2s| ", instruction->debug_id, type_name, ref_count); | 379 | fprintf(irp->f, "%c%-3zu| %-22s| %-12s| %-2s| ", mark, instruction->debug_id, |
| | 380 | ir_instruction_type_str(instruction), type_name, ref_count); |
| 34 | } | 381 | } |
| 35 | | 382 | |
| 36 | static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { | 383 | static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { |
| ... | @@ -42,6 +389,10 @@ static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { | ... | @@ -42,6 +389,10 @@ static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { |
| 42 | | 389 | |
| 43 | static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) { | 390 | static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 44 | fprintf(irp->f, "#%" ZIG_PRI_usize "", instruction->debug_id); | 391 | fprintf(irp->f, "#%" ZIG_PRI_usize "", instruction->debug_id); |
| | 392 | if (irp->pass_num == 2 && irp->printed.maybe_get(instruction) == nullptr) { |
| | 393 | irp->printed.put(instruction, 0); |
| | 394 | irp->pending.append(instruction); |
| | 395 | } |
| 45 | } | 396 | } |
| 46 | | 397 | |
| 47 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) { | 398 | static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) { |
| ... | @@ -49,6 +400,7 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) | ... | @@ -49,6 +400,7 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) |
| 49 | fprintf(irp->f, "(null)"); | 400 | fprintf(irp->f, "(null)"); |
| 50 | return; | 401 | return; |
| 51 | } | 402 | } |
| | 403 | |
| 52 | if (instruction->value.special != ConstValSpecialRuntime) { | 404 | if (instruction->value.special != ConstValSpecialRuntime) { |
| 53 | ir_print_const_value(irp, &instruction->value); | 405 | ir_print_const_value(irp, &instruction->value); |
| 54 | } else { | 406 | } else { |
| ... | @@ -1550,8 +1902,8 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction) | ... | @@ -1550,8 +1902,8 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction) |
| 1550 | fprintf(irp->f, ")"); | 1902 | fprintf(irp->f, ")"); |
| 1551 | } | 1903 | } |
| 1552 | | 1904 | |
| 1553 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 1905 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool trailing) { |
| 1554 | ir_print_prefix(irp, instruction); | 1906 | ir_print_prefix(irp, instruction, trailing); |
| 1555 | switch (instruction->id) { | 1907 | switch (instruction->id) { |
| 1556 | case IrInstructionIdInvalid: | 1908 | case IrInstructionIdInvalid: |
| 1557 | zig_unreachable(); | 1909 | zig_unreachable(); |
| ... | @@ -2036,31 +2388,48 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -2036,31 +2388,48 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 2036 | fprintf(irp->f, "\n"); | 2388 | fprintf(irp->f, "\n"); |
| 2037 | } | 2389 | } |
| 2038 | | 2390 | |
| 2039 | void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size) { | 2391 | void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, size_t pass_num) { |
| 2040 | IrPrint ir_print = {}; | 2392 | IrPrint ir_print = {}; |
| 2041 | IrPrint *irp = &ir_print; | 2393 | IrPrint *irp = &ir_print; |
| | 2394 | irp->pass_num = pass_num; |
| 2042 | irp->codegen = codegen; | 2395 | irp->codegen = codegen; |
| 2043 | irp->f = f; | 2396 | irp->f = f; |
| 2044 | irp->indent = indent_size; | 2397 | irp->indent = indent_size; |
| 2045 | irp->indent_size = indent_size; | 2398 | irp->indent_size = indent_size; |
| | 2399 | irp->printed = {}; |
| | 2400 | irp->printed.init(64); |
| | 2401 | irp->pending = {}; |
| 2046 | | 2402 | |
| 2047 | for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) { | 2403 | for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) { |
| 2048 | IrBasicBlock *current_block = executable->basic_block_list.at(bb_i); | 2404 | IrBasicBlock *current_block = executable->basic_block_list.at(bb_i); |
| 2049 | fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id); | 2405 | fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id); |
| 2050 | for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { | 2406 | for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { |
| 2051 | IrInstruction *instruction = current_block->instruction_list.at(instr_i); | 2407 | IrInstruction *instruction = current_block->instruction_list.at(instr_i); |
| 2052 | ir_print_instruction(irp, instruction); | 2408 | if (irp->pass_num == 2) { |
| | 2409 | irp->printed.put(instruction, 0); |
| | 2410 | irp->pending.clear(); |
| | 2411 | } |
| | 2412 | ir_print_instruction(irp, instruction, false); |
| | 2413 | for (size_t j = 0; j < irp->pending.length; ++j) |
| | 2414 | ir_print_instruction(irp, irp->pending.at(j), true); |
| 2053 | } | 2415 | } |
| 2054 | } | 2416 | } |
| | 2417 | |
| | 2418 | irp->pending.deinit(); |
| | 2419 | irp->printed.deinit(); |
| 2055 | } | 2420 | } |
| 2056 | | 2421 | |
| 2057 | void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size) { | 2422 | void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, size_t pass_num) { |
| 2058 | IrPrint ir_print = {}; | 2423 | IrPrint ir_print = {}; |
| 2059 | IrPrint *irp = &ir_print; | 2424 | IrPrint *irp = &ir_print; |
| | 2425 | irp->pass_num = pass_num; |
| 2060 | irp->codegen = codegen; | 2426 | irp->codegen = codegen; |
| 2061 | irp->f = f; | 2427 | irp->f = f; |
| 2062 | irp->indent = indent_size; | 2428 | irp->indent = indent_size; |
| 2063 | irp->indent_size = indent_size; | 2429 | irp->indent_size = indent_size; |
| | 2430 | irp->printed = {}; |
| | 2431 | irp->printed.init(4); |
| | 2432 | irp->pending = {}; |
| 2064 | | 2433 | |
| 2065 | ir_print_instruction(irp, instruction); | 2434 | ir_print_instruction(irp, instruction, false); |
| 2066 | } | 2435 | } |