authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2019-08-31 12:30:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-31 22:42:58-04:00
log1f99899408367a16c13806369f94645c2001e68b
tree0135bed7eda0395f258c3619d906306a42aaf34d
parent5c3a9a1a3eef82ffad17bc295da05ecccd9006a5

stage1 enhance IR print

- pass2 now prints missing instructions in a trailing fashion - instruction struct name added to print as column 2

4 files changed, 383 insertions(+), 14 deletions(-)

src/analyze.cpp+2-2
......@@ -4415,7 +4415,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
44154415
44164416 if (g->verbose_ir) {
44174417 fprintf(stderr, "fn %s() { // (analyzed)\n", buf_ptr(&fn->symbol_name));
4418 ir_print(g, stderr, &fn->analyzed_executable, 4);
4418 ir_print(g, stderr, &fn->analyzed_executable, 4, 2);
44194419 fprintf(stderr, "}\n");
44204420 }
44214421 fn->anal_state = FnAnalStateComplete;
......@@ -4449,7 +4449,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
44494449 fprintf(stderr, "\n");
44504450 ast_render(stderr, fn_table_entry->body_node, 4);
44514451 fprintf(stderr, "\n{ // (IR)\n");
4452 ir_print(g, stderr, &fn_table_entry->ir_executable, 4);
4452 ir_print(g, stderr, &fn_table_entry->ir_executable, 4, 1);
44534453 fprintf(stderr, "}\n");
44544454 }
44554455
src/ir.cpp+2-2
......@@ -10867,7 +10867,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
1086710867 fprintf(stderr, "\nSource: ");
1086810868 ast_render(stderr, node, 4);
1086910869 fprintf(stderr, "\n{ // (IR)\n");
10870 ir_print(codegen, stderr, ir_executable, 2);
10870 ir_print(codegen, stderr, ir_executable, 2, 1);
1087110871 fprintf(stderr, "}\n");
1087210872 }
1087310873 IrExecutable *analyzed_executable = allocate<IrExecutable>(1);
......@@ -10888,7 +10888,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
1088810888
1088910889 if (codegen->verbose_ir) {
1089010890 fprintf(stderr, "{ // (analyzed)\n");
10891 ir_print(codegen, stderr, analyzed_executable, 2);
10891 ir_print(codegen, stderr, analyzed_executable, 2, 2);
1089210892 fprintf(stderr, "}\n");
1089310893 }
1089410894
src/ir_print.cpp+377-8
......@@ -10,27 +10,374 @@
1010#include "ir_print.hpp"
1111#include "os.hpp"
1212
13static uint32_t hash_instruction_ptr(IrInstruction* instruction) {
14 return (uint32_t)(uintptr_t)instruction;
15}
16
17static bool instruction_ptr_equal(IrInstruction* a, IrInstruction* b) {
18 return a == b;
19}
20
21using InstructionSet = HashMap<IrInstruction*, uint8_t, hash_instruction_ptr, instruction_ptr_equal>;
22using InstructionList = ZigList<IrInstruction*>;
23
1324struct IrPrint {
25 size_t pass_num;
1426 CodeGen *codegen;
1527 FILE *f;
1628 int indent;
1729 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;
1837};
1938
2039static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction);
2140
41static 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
22367static void ir_print_indent(IrPrint *irp) {
23368 for (int i = 0; i < irp->indent; i += 1) {
24369 fprintf(irp->f, " ");
25370 }
26371}
27372
28static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) {
373static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction, bool trailing) {
29374 ir_print_indent(irp);
375 const char mark = trailing ? ':' : '#';
30376 const char *type_name = instruction->value.type ? buf_ptr(&instruction->value.type->name) : "(unknown)";
31377 const char *ref_count = ir_has_side_effects(instruction) ?
32378 "-" : 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);
34381}
35382
36383static 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) {
42389
43390static void ir_print_var_instruction(IrPrint *irp, IrInstruction *instruction) {
44391 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 }
45396}
46397
47398static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction) {
......@@ -49,6 +400,7 @@ static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction)
49400 fprintf(irp->f, "(null)");
50401 return;
51402 }
403
52404 if (instruction->value.special != ConstValSpecialRuntime) {
53405 ir_print_const_value(irp, &instruction->value);
54406 } else {
......@@ -1550,8 +1902,8 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction)
15501902 fprintf(irp->f, ")");
15511903}
15521904
1553static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1554 ir_print_prefix(irp, instruction);
1905static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool trailing) {
1906 ir_print_prefix(irp, instruction, trailing);
15551907 switch (instruction->id) {
15561908 case IrInstructionIdInvalid:
15571909 zig_unreachable();
......@@ -2036,31 +2388,48 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
20362388 fprintf(irp->f, "\n");
20372389}
20382390
2039void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size) {
2391void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, size_t pass_num) {
20402392 IrPrint ir_print = {};
20412393 IrPrint *irp = &ir_print;
2394 irp->pass_num = pass_num;
20422395 irp->codegen = codegen;
20432396 irp->f = f;
20442397 irp->indent = indent_size;
20452398 irp->indent_size = indent_size;
2399 irp->printed = {};
2400 irp->printed.init(64);
2401 irp->pending = {};
20462402
20472403 for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) {
20482404 IrBasicBlock *current_block = executable->basic_block_list.at(bb_i);
20492405 fprintf(irp->f, "%s_%" ZIG_PRI_usize ":\n", current_block->name_hint, current_block->debug_id);
20502406 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
20512407 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);
20532415 }
20542416 }
2417
2418 irp->pending.deinit();
2419 irp->printed.deinit();
20552420}
20562421
2057void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size) {
2422void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, size_t pass_num) {
20582423 IrPrint ir_print = {};
20592424 IrPrint *irp = &ir_print;
2425 irp->pass_num = pass_num;
20602426 irp->codegen = codegen;
20612427 irp->f = f;
20622428 irp->indent = indent_size;
20632429 irp->indent_size = indent_size;
2430 irp->printed = {};
2431 irp->printed.init(4);
2432 irp->pending = {};
20642433
2065 ir_print_instruction(irp, instruction);
2434 ir_print_instruction(irp, instruction, false);
20662435}
src/ir_print.hpp+2-2
......@@ -12,7 +12,7 @@
1212
1313#include <stdio.h>
1414
15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size);
16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size);
15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, size_t pass_num);
16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, size_t pass_num);
1717
1818#endif