authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-06 01:09:01-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-06 01:09:01-04:00
log07fe60ded1727d528d3ae36b892aa7c84262ed96
tree733a4aa3c8327d0ceb831cf122c84484b6a13d10
parentcd1bd78aa9b4120ee95cd6347b7adce0d460f9d2

IR in 2 passes


6 files changed, 241 insertions(+), 249 deletions(-)

src/all_types.hpp+12-10
......@@ -32,8 +32,8 @@ struct IrInstruction;
3232struct IrBasicBlock;
3333
3434struct IrExecutable {
35 IrBasicBlock **basic_block_list;
36 size_t basic_block_count;
35 ZigList<IrBasicBlock *> basic_block_list;
36 size_t var_slot_count;
3737 size_t next_debug_id;
3838};
3939
......@@ -1114,6 +1114,7 @@ struct FnTableEntry {
11141114 FnInline fn_inline;
11151115 FnAnalState anal_state;
11161116 IrExecutable ir_executable;
1117 IrExecutable analyzed_executable;
11171118
11181119 AstNode *fn_no_inline_set_node;
11191120 AstNode *fn_export_set_node;
......@@ -1347,6 +1348,7 @@ struct VariableTableEntry {
13471348 bool force_depends_on_compile_var;
13481349 ImportTableEntry *import;
13491350 bool shadowable;
1351 size_t slot_index;
13501352};
13511353
13521354struct ErrorTableEntry {
......@@ -1404,8 +1406,8 @@ enum AtomicOrder {
14041406// Phi instructions must be first in a basic block.
14051407// The last instruction in a basic block must be an expression of type unreachable.
14061408struct IrBasicBlock {
1407 IrInstruction *first;
1408 IrInstruction *last;
1409 ZigList<IrInstruction *> instruction_list;
1410 IrBasicBlock *other;
14091411};
14101412
14111413enum IrInstructionId {
......@@ -1424,23 +1426,23 @@ enum IrInstructionId {
14241426};
14251427
14261428struct IrInstruction {
1427 IrInstruction *prev;
1428 IrInstruction *next;
1429
14301429 IrInstructionId id;
14311430 AstNode *source_node;
14321431 ConstExprValue static_value;
14331432 TypeTableEntry *type_entry;
14341433 size_t debug_id;
14351434 LLVMValueRef llvm_value;
1435 // if ref_count is zero, instruction can be omitted in codegen
1436 size_t ref_count;
1437 IrInstruction *other;
14361438};
14371439
14381440struct IrInstructionCondBr {
14391441 IrInstruction base;
14401442
1441 // If the condition is null, then this is an unconditional branch.
1442 IrInstruction *cond;
1443 IrBasicBlock *dest;
1443 // If cond_inst_index == SIZE_MAX, then this is an unconditional branch.
1444 size_t cond_inst_index;
1445 size_t dest_basic_block_index;
14441446};
14451447
14461448struct IrInstructionSwitchBrCase {
src/analyze.cpp+8-1
......@@ -7088,9 +7088,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
70887088 fprintf(stderr, "}\n");
70897089 }
70907090
7091 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable, expected_type);
7091 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable,
7092 &fn_table_entry->analyzed_executable, expected_type);
70927093 node->data.fn_def.implicit_return_type = block_return_type;
70937094
7095 if (g->verbose) {
7096 fprintf(stderr, "fn %s { // (analyzed)\n", buf_ptr(&fn_table_entry->symbol_name));
7097 ir_print(stderr, &fn_table_entry->analyzed_executable, 4);
7098 fprintf(stderr, "}\n");
7099 }
7100
70947101 fn_table_entry->anal_state = FnAnalStateComplete;
70957102}
70967103
src/codegen.cpp+6-7
......@@ -2921,13 +2921,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
29212921
29222922static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
29232923 assert(fn_entry);
2924 IrExecutable *executable = &fn_entry->ir_executable;
2925 assert(executable->basic_block_count > 0);
2926 for (size_t i = 0; i < executable->basic_block_count; i += 1) {
2927 IrBasicBlock *current_block = executable->basic_block_list[i];
2928 for (IrInstruction *instruction = current_block->first; instruction != nullptr;
2929 instruction = instruction->next)
2930 {
2924 IrExecutable *executable = &fn_entry->analyzed_executable;
2925 assert(executable->basic_block_list.length > 0);
2926 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
2927 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
2928 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
2929 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
29312930 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
29322931 }
29332932 }
src/ir.cpp+209-225
......@@ -2,57 +2,35 @@
22#include "ir.hpp"
33#include "error.hpp"
44
5struct IrGen {
5struct IrVarSlot {
6 ConstExprValue value;
7 bool runtime;
8};
9
10struct IrExecContext {
11 IrVarSlot *var_slot_list;
12 size_t var_slot_count;
13};
14
15struct IrBuilder {
616 CodeGen *codegen;
7 AstNode *node;
8 IrBasicBlock *current_basic_block;
917 IrExecutable *exec;
18 IrBasicBlock *current_basic_block;
1019};
1120
1221struct IrAnalyze {
1322 CodeGen *codegen;
14 IrExecutable *exec;
15 IrBasicBlock *current_basic_block;
23 IrBuilder old_irb;
24 IrBuilder new_irb;
25 IrExecContext exec_context;
1626};
1727
18static IrInstruction *ir_gen_node(IrGen *irg, AstNode *node, BlockContext *scope);
28static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
1929
2030static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {
21 if (!basic_block->last) {
22 basic_block->first = instruction;
23 basic_block->last = instruction;
24 instruction->prev = nullptr;
25 instruction->next = nullptr;
26 } else {
27 basic_block->last->next = instruction;
28 instruction->prev = basic_block->last;
29 instruction->next = nullptr;
30 basic_block->last = instruction;
31 }
32}
33
34static void ir_instruction_insert(IrBasicBlock *basic_block,
35 IrInstruction *before_instruction, IrInstruction *after_instruction,
36 IrInstruction *new_instruction)
37{
38 assert(before_instruction || after_instruction);
39 assert(!before_instruction || !after_instruction);
40
41 if (before_instruction) {
42 IrInstruction *displaced_instruction = before_instruction->prev;
43 before_instruction->prev = new_instruction;
44 new_instruction->prev = displaced_instruction;
45 new_instruction->next = before_instruction;
46 if (basic_block->first == before_instruction)
47 basic_block->first = new_instruction;
48 } else {
49 IrInstruction *displaced_instruction = after_instruction->next;
50 after_instruction->next = new_instruction;
51 new_instruction->prev = after_instruction;
52 new_instruction->next = displaced_instruction;
53 if (basic_block->last == after_instruction)
54 basic_block->last = new_instruction;
55 }
31 assert(basic_block);
32 assert(instruction);
33 basic_block->instruction_list.append(instruction);
5634}
5735
5836static size_t exec_next_debug_id(IrExecutable *exec) {
......@@ -115,97 +93,82 @@ static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
11593}
11694
11795template<typename T>
118static T *ir_build_instruction(IrGen *irg, AstNode *source_node) {
119 T *special_instruction = ir_create_instruction<T>(irg->exec, source_node);
120 ir_instruction_append(irg->current_basic_block, &special_instruction->base);
96static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {
97 T *special_instruction = ir_create_instruction<T>(irb->exec, source_node);
98 ir_instruction_append(irb->current_basic_block, &special_instruction->base);
12199 return special_instruction;
122100}
123101
124static IrInstruction *ir_insert_const_type(IrAnalyze *ira, IrInstruction *before_instruction,
125 IrInstruction *after_instruction, TypeTableEntry *type_entry)
102static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInstruction *dest_type,
103 IrInstruction *value, bool is_implicit)
126104{
127 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->exec,
128 before_instruction->source_node);
129 const_instruction->base.type_entry = ira->codegen->builtin_types.entry_type;
130 const_instruction->base.static_value.ok = true;
131 const_instruction->base.static_value.data.x_type = type_entry;
132 ir_instruction_insert(ira->current_basic_block, before_instruction, after_instruction, &const_instruction->base);
133 return &const_instruction->base;
134}
135
136static IrInstruction *ir_insert_cast(IrAnalyze *ira,
137 IrInstruction *before_instruction, IrInstruction *after_instruction,
138 IrInstruction *dest_type, IrInstruction *value, bool is_implicit)
139{
140 IrInstructionCast *cast_instruction = ir_create_instruction<IrInstructionCast>(ira->exec,
141 before_instruction->source_node);
105 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);
142106 cast_instruction->dest_type = dest_type;
143107 cast_instruction->value = value;
144108 cast_instruction->is_implicit = is_implicit;
145 ir_instruction_insert(ira->current_basic_block, before_instruction, after_instruction, &cast_instruction->base);
146109 return &cast_instruction->base;
147110}
148111
149static IrInstruction *ir_build_return(IrGen *irg, AstNode *source_node, IrInstruction *return_value) {
150 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irg, source_node);
151 return_instruction->base.type_entry = irg->codegen->builtin_types.entry_unreachable;
112static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrInstruction *return_value) {
113 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, source_node);
114 return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
152115 return_instruction->base.static_value.ok = true;
153116 return_instruction->value = return_value;
154117 return &return_instruction->base;
155118}
156119
157static IrInstruction *ir_build_const_void(IrGen *irg, AstNode *source_node) {
158 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);
159 const_instruction->base.type_entry = irg->codegen->builtin_types.entry_void;
120static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) {
121 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
122 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
160123 const_instruction->base.static_value.ok = true;
161124 return &const_instruction->base;
162125}
163126
164static IrInstruction *ir_build_const_bignum(IrGen *irg, AstNode *source_node, BigNum *bignum) {
165 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);
127static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node, BigNum *bignum) {
128 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
166129 const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ?
167 irg->codegen->builtin_types.entry_num_lit_int : irg->codegen->builtin_types.entry_num_lit_float;
130 irb->codegen->builtin_types.entry_num_lit_int : irb->codegen->builtin_types.entry_num_lit_float;
168131 const_instruction->base.static_value.ok = true;
169132 const_instruction->base.static_value.data.x_bignum = *bignum;
170133 return &const_instruction->base;
171134}
172135
173static IrInstruction *ir_build_const_type(IrGen *irg, AstNode *source_node, TypeTableEntry *type_entry) {
174 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);
175 const_instruction->base.type_entry = irg->codegen->builtin_types.entry_type;
136static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
137 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
138 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type;
176139 const_instruction->base.static_value.ok = true;
177140 const_instruction->base.static_value.data.x_type = type_entry;
178141 return &const_instruction->base;
179142}
180143
181static IrInstruction *ir_build_const_fn(IrGen *irg, AstNode *source_node, FnTableEntry *fn_entry) {
182 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);
144static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) {
145 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
183146 const_instruction->base.type_entry = fn_entry->type_entry;
184147 const_instruction->base.static_value.ok = true;
185148 const_instruction->base.static_value.data.x_fn = fn_entry;
186149 return &const_instruction->base;
187150}
188151
189static IrInstruction *ir_build_const_generic_fn(IrGen *irg, AstNode *source_node, TypeTableEntry *fn_type) {
190 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);
152static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_node, TypeTableEntry *fn_type) {
153 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
191154 const_instruction->base.type_entry = fn_type;
192155 const_instruction->base.static_value.ok = true;
193156 const_instruction->base.static_value.data.x_type = fn_type;
194157 return &const_instruction->base;
195158}
196159
197static IrInstruction *ir_build_bin_op(IrGen *irg, AstNode *source_node, IrBinOp op_id,
160static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,
198161 IrInstruction *op1, IrInstruction *op2)
199162{
200 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irg, source_node);
163 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, source_node);
201164 bin_op_instruction->op_id = op_id;
202165 bin_op_instruction->op1 = op1;
203166 bin_op_instruction->op2 = op2;
204167 return &bin_op_instruction->base;
205168}
206169
207static IrInstruction *ir_build_load_var(IrGen *irg, AstNode *source_node, VariableTableEntry *var) {
208 IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irg, source_node);
170static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) {
171 IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irb, source_node);
209172 load_var_instruction->base.type_entry = var->type;
210173 load_var_instruction->var = var;
211174 return &load_var_instruction->base;
......@@ -226,7 +189,7 @@ static IrInstruction *ir_build_load_var(IrGen *irg, AstNode *source_node, Variab
226189// return result;
227190//}
228191
229static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, BlockContext *outer_block,
192static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,
230193 bool gen_error_defers, bool gen_maybe_defers)
231194{
232195 while (inner_block != outer_block) {
......@@ -236,15 +199,15 @@ static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, Block
236199 (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe)))
237200 {
238201 AstNode *defer_expr_node = inner_block->node->data.defer.expr;
239 ir_gen_node(irg, defer_expr_node, defer_expr_node->block_context);
202 ir_gen_node(irb, defer_expr_node, defer_expr_node->block_context);
240203 }
241204 inner_block = inner_block->parent;
242205 }
243206}
244207
245//static IrInstruction *ir_gen_return(IrGen *irg, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) {
208//static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *source_node, IrInstruction *value, ReturnKnowledge rk) {
246209// BlockContext *defer_inner_block = source_node->block_context;
247// BlockContext *defer_outer_block = irg->node->block_context;
210// BlockContext *defer_outer_block = irb->node->block_context;
248211// if (rk == ReturnKnowledgeUnknown) {
249212// if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) {
250213// // generate branching code that checks the return value and generates defers
......@@ -252,14 +215,14 @@ static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, Block
252215// zig_panic("TODO");
253216// }
254217// } else if (rk != ReturnKnowledgeSkipDefers) {
255// ir_gen_defers_for_block(irg, defer_inner_block, defer_outer_block,
218// ir_gen_defers_for_block(irb, defer_inner_block, defer_outer_block,
256219// rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull);
257220// }
258221//
259// return ir_build_return(irg, source_node, value);
222// return ir_build_return(irb, source_node, value);
260223//}
261224
262static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {
225static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
263226 assert(block_node->type == NodeTypeBlock);
264227
265228 BlockContext *parent_context = block_node->block_context;
......@@ -269,8 +232,8 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {
269232 IrInstruction *return_value = nullptr;
270233 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
271234 AstNode *statement_node = block_node->data.block.statements.at(i);
272 return_value = ir_gen_node(irg, statement_node, child_context);
273 if (statement_node->type == NodeTypeDefer && return_value != irg->codegen->invalid_instruction) {
235 return_value = ir_gen_node(irb, statement_node, child_context);
236 if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) {
274237 // defer starts a new block context
275238 child_context = statement_node->data.defer.child_block;
276239 assert(child_context);
......@@ -278,20 +241,20 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {
278241 }
279242
280243 if (!return_value)
281 return_value = ir_build_const_void(irg, block_node);
244 return_value = ir_build_const_void(irb, block_node);
282245
283 ir_gen_defers_for_block(irg, child_context, outer_block_context, false, false);
246 ir_gen_defers_for_block(irb, child_context, outer_block_context, false, false);
284247
285248 return return_value;
286249}
287250
288static IrInstruction *ir_gen_bin_op_id(IrGen *irg, AstNode *node, IrBinOp op_id) {
289 IrInstruction *op1 = ir_gen_node(irg, node->data.bin_op_expr.op1, node->block_context);
290 IrInstruction *op2 = ir_gen_node(irg, node->data.bin_op_expr.op2, node->block_context);
291 return ir_build_bin_op(irg, node, op_id, op1, op2);
251static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) {
252 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->block_context);
253 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
254 return ir_build_bin_op(irb, node, op_id, op1, op2);
292255}
293256
294static IrInstruction *ir_gen_bin_op(IrGen *irg, AstNode *node) {
257static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {
295258 assert(node->type == NodeTypeBinOpExpr);
296259
297260 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
......@@ -322,144 +285,144 @@ static IrInstruction *ir_gen_bin_op(IrGen *irg, AstNode *node) {
322285 // because of the control flow
323286 zig_panic("TODO gen IR for bool or/and");
324287 case BinOpTypeCmpEq:
325 return ir_gen_bin_op_id(irg, node, IrBinOpCmpEq);
288 return ir_gen_bin_op_id(irb, node, IrBinOpCmpEq);
326289 case BinOpTypeCmpNotEq:
327 return ir_gen_bin_op_id(irg, node, IrBinOpCmpNotEq);
290 return ir_gen_bin_op_id(irb, node, IrBinOpCmpNotEq);
328291 case BinOpTypeCmpLessThan:
329 return ir_gen_bin_op_id(irg, node, IrBinOpCmpLessThan);
292 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessThan);
330293 case BinOpTypeCmpGreaterThan:
331 return ir_gen_bin_op_id(irg, node, IrBinOpCmpGreaterThan);
294 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterThan);
332295 case BinOpTypeCmpLessOrEq:
333 return ir_gen_bin_op_id(irg, node, IrBinOpCmpLessOrEq);
296 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessOrEq);
334297 case BinOpTypeCmpGreaterOrEq:
335 return ir_gen_bin_op_id(irg, node, IrBinOpCmpGreaterOrEq);
298 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterOrEq);
336299 case BinOpTypeBinOr:
337 return ir_gen_bin_op_id(irg, node, IrBinOpBinOr);
300 return ir_gen_bin_op_id(irb, node, IrBinOpBinOr);
338301 case BinOpTypeBinXor:
339 return ir_gen_bin_op_id(irg, node, IrBinOpBinXor);
302 return ir_gen_bin_op_id(irb, node, IrBinOpBinXor);
340303 case BinOpTypeBinAnd:
341 return ir_gen_bin_op_id(irg, node, IrBinOpBinAnd);
304 return ir_gen_bin_op_id(irb, node, IrBinOpBinAnd);
342305 case BinOpTypeBitShiftLeft:
343 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftLeft);
306 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeft);
344307 case BinOpTypeBitShiftLeftWrap:
345 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftLeftWrap);
308 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeftWrap);
346309 case BinOpTypeBitShiftRight:
347 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftRight);
310 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftRight);
348311 case BinOpTypeAdd:
349 return ir_gen_bin_op_id(irg, node, IrBinOpAdd);
312 return ir_gen_bin_op_id(irb, node, IrBinOpAdd);
350313 case BinOpTypeAddWrap:
351 return ir_gen_bin_op_id(irg, node, IrBinOpAddWrap);
314 return ir_gen_bin_op_id(irb, node, IrBinOpAddWrap);
352315 case BinOpTypeSub:
353 return ir_gen_bin_op_id(irg, node, IrBinOpSub);
316 return ir_gen_bin_op_id(irb, node, IrBinOpSub);
354317 case BinOpTypeSubWrap:
355 return ir_gen_bin_op_id(irg, node, IrBinOpSubWrap);
318 return ir_gen_bin_op_id(irb, node, IrBinOpSubWrap);
356319 case BinOpTypeMult:
357 return ir_gen_bin_op_id(irg, node, IrBinOpMult);
320 return ir_gen_bin_op_id(irb, node, IrBinOpMult);
358321 case BinOpTypeMultWrap:
359 return ir_gen_bin_op_id(irg, node, IrBinOpMultWrap);
322 return ir_gen_bin_op_id(irb, node, IrBinOpMultWrap);
360323 case BinOpTypeDiv:
361 return ir_gen_bin_op_id(irg, node, IrBinOpDiv);
324 return ir_gen_bin_op_id(irb, node, IrBinOpDiv);
362325 case BinOpTypeMod:
363 return ir_gen_bin_op_id(irg, node, IrBinOpMod);
326 return ir_gen_bin_op_id(irb, node, IrBinOpMod);
364327 case BinOpTypeArrayCat:
365 return ir_gen_bin_op_id(irg, node, IrBinOpArrayCat);
328 return ir_gen_bin_op_id(irb, node, IrBinOpArrayCat);
366329 case BinOpTypeArrayMult:
367 return ir_gen_bin_op_id(irg, node, IrBinOpArrayMult);
330 return ir_gen_bin_op_id(irb, node, IrBinOpArrayMult);
368331 case BinOpTypeUnwrapMaybe:
369332 zig_panic("TODO gen IR for unwrap maybe");
370333 }
371334 zig_unreachable();
372335}
373336
374static IrInstruction *ir_gen_num_lit(IrGen *irg, AstNode *node) {
337static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {
375338 assert(node->type == NodeTypeNumberLiteral);
376339
377340 if (node->data.number_literal.overflow) {
378 add_node_error(irg->codegen, node, buf_sprintf("number literal too large to be represented in any type"));
379 return irg->codegen->invalid_instruction;
341 add_node_error(irb->codegen, node, buf_sprintf("number literal too large to be represented in any type"));
342 return irb->codegen->invalid_instruction;
380343 }
381344
382 return ir_build_const_bignum(irg, node, node->data.number_literal.bignum);
345 return ir_build_const_bignum(irb, node, node->data.number_literal.bignum);
383346}
384347
385static IrInstruction *ir_gen_decl_ref(IrGen *irg, AstNode *source_node, AstNode *decl_node,
348static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,
386349 bool pointer_only, BlockContext *scope)
387350{
388 resolve_top_level_decl(irg->codegen, decl_node, pointer_only);
351 resolve_top_level_decl(irb->codegen, decl_node, pointer_only);
389352 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
390353 if (tld->resolution == TldResolutionInvalid)
391 return irg->codegen->invalid_instruction;
354 return irb->codegen->invalid_instruction;
392355
393356 if (decl_node->type == NodeTypeVariableDeclaration) {
394357 VariableTableEntry *var = decl_node->data.variable_declaration.variable;
395 return ir_build_load_var(irg, source_node, var);
358 return ir_build_load_var(irb, source_node, var);
396359 } else if (decl_node->type == NodeTypeFnProto) {
397360 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
398361 assert(fn_entry->type_entry);
399362 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
400 return ir_build_const_generic_fn(irg, source_node, fn_entry->type_entry);
363 return ir_build_const_generic_fn(irb, source_node, fn_entry->type_entry);
401364 } else {
402 return ir_build_const_fn(irg, source_node, fn_entry);
365 return ir_build_const_fn(irb, source_node, fn_entry);
403366 }
404367 } else if (decl_node->type == NodeTypeContainerDecl) {
405368 if (decl_node->data.struct_decl.generic_params.length > 0) {
406369 TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
407370 assert(type_entry);
408 return ir_build_const_generic_fn(irg, source_node, type_entry);
371 return ir_build_const_generic_fn(irb, source_node, type_entry);
409372 } else {
410 return ir_build_const_type(irg, source_node, decl_node->data.struct_decl.type_entry);
373 return ir_build_const_type(irb, source_node, decl_node->data.struct_decl.type_entry);
411374 }
412375 } else if (decl_node->type == NodeTypeTypeDecl) {
413 return ir_build_const_type(irg, source_node, decl_node->data.type_decl.child_type_entry);
376 return ir_build_const_type(irb, source_node, decl_node->data.type_decl.child_type_entry);
414377 } else {
415378 zig_unreachable();
416379 }
417380}
418381
419static IrInstruction *ir_gen_symbol(IrGen *irg, AstNode *node, bool pointer_only) {
382static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, bool pointer_only) {
420383 assert(node->type == NodeTypeSymbol);
421384
422385 if (node->data.symbol_expr.override_type_entry)
423 return ir_build_const_type(irg, node, node->data.symbol_expr.override_type_entry);
386 return ir_build_const_type(irb, node, node->data.symbol_expr.override_type_entry);
424387
425388 Buf *variable_name = node->data.symbol_expr.symbol;
426389
427 auto primitive_table_entry = irg->codegen->primitive_type_table.maybe_get(variable_name);
390 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
428391 if (primitive_table_entry)
429 return ir_build_const_type(irg, node, primitive_table_entry->value);
392 return ir_build_const_type(irb, node, primitive_table_entry->value);
430393
431 VariableTableEntry *var = find_variable(irg->codegen, node->block_context, variable_name);
394 VariableTableEntry *var = find_variable(irb->codegen, node->block_context, variable_name);
432395 if (var)
433 return ir_build_load_var(irg, node, var);
396 return ir_build_load_var(irb, node, var);
434397
435398 AstNode *decl_node = find_decl(node->block_context, variable_name);
436399 if (decl_node)
437 return ir_gen_decl_ref(irg, node, decl_node, pointer_only, node->block_context);
400 return ir_gen_decl_ref(irb, node, decl_node, pointer_only, node->block_context);
438401
439402 if (node->owner->any_imports_failed) {
440403 // skip the error message since we had a failing import in this file
441404 // if an import breaks we don't need redundant undeclared identifier errors
442 return irg->codegen->invalid_instruction;
405 return irb->codegen->invalid_instruction;
443406 }
444407
445 add_node_error(irg->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
446 return irg->codegen->invalid_instruction;
408 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
409 return irb->codegen->invalid_instruction;
447410}
448411
449static IrInstruction *ir_gen_node_extra(IrGen *irg, AstNode *node, BlockContext *block_context,
412static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, BlockContext *block_context,
450413 bool pointer_only)
451414{
452415 node->block_context = block_context;
453416
454417 switch (node->type) {
455418 case NodeTypeBlock:
456 return ir_gen_block(irg, node);
419 return ir_gen_block(irb, node);
457420 case NodeTypeBinOpExpr:
458 return ir_gen_bin_op(irg, node);
421 return ir_gen_bin_op(irb, node);
459422 case NodeTypeNumberLiteral:
460 return ir_gen_num_lit(irg, node);
423 return ir_gen_num_lit(irb, node);
461424 case NodeTypeSymbol:
462 return ir_gen_symbol(irg, node, pointer_only);
425 return ir_gen_symbol(irb, node, pointer_only);
463426 case NodeTypeUnwrapErrorExpr:
464427 case NodeTypeReturnExpr:
465428 case NodeTypeDefer:
......@@ -509,9 +472,9 @@ static IrInstruction *ir_gen_node_extra(IrGen *irg, AstNode *node, BlockContext
509472 zig_unreachable();
510473}
511474
512static IrInstruction *ir_gen_node(IrGen *irg, AstNode *node, BlockContext *scope) {
475static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) {
513476 bool pointer_only_no = false;
514 return ir_gen_node_extra(irg, node, scope, pointer_only_no);
477 return ir_gen_node_extra(irb, node, scope, pointer_only_no);
515478}
516479
517480static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope,
......@@ -519,28 +482,23 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext
519482{
520483 assert(node->owner);
521484
522 IrGen ir_gen = {0};
523 IrGen *irg = &ir_gen;
485 IrBuilder ir_gen = {0};
486 IrBuilder *irb = &ir_gen;
524487
525 irg->codegen = g;
526 irg->node = node;
527 irg->exec = ir_executable;
488 irb->codegen = g;
489 irb->exec = ir_executable;
528490
529 irg->exec->basic_block_list = allocate<IrBasicBlock*>(1);
530 irg->exec->basic_block_count = 1;
491 irb->current_basic_block = allocate<IrBasicBlock>(1);
492 irb->exec->basic_block_list.append(irb->current_basic_block);
531493
532 IrBasicBlock *entry_basic_block = allocate<IrBasicBlock>(1);
533 irg->current_basic_block = entry_basic_block;
534 irg->exec->basic_block_list[0] = entry_basic_block;
535
536 IrInstruction *result = ir_gen_node_extra(irg, node, scope, pointer_only);
494 IrInstruction *result = ir_gen_node_extra(irb, node, scope, pointer_only);
537495 assert(result);
538496
539497 if (result == g->invalid_instruction)
540498 return result;
541499
542500 if (add_return)
543 return ir_build_return(irg, result->source_node, result);
501 return ir_build_return(irb, result->source_node, result);
544502
545503 return result;
546504}
......@@ -566,6 +524,11 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
566524 return ir_gen_add_return(codegn, body_node, scope, ir_executable, add_return_yes, pointer_only_no);
567525}
568526
527static void ir_link_new(IrInstruction *new_instruction, IrInstruction *old_instruction) {
528 new_instruction->other = old_instruction;
529 old_instruction->other = new_instruction;
530}
531
569532/*
570533static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) {
571534 assert(node->type == NodeTypeGoto);
......@@ -640,7 +603,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
640603
641604 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";
642605
643 add_node_error(ira->codegen, instruction->source_node,
606 add_node_error(ira->old_irb.codegen, instruction->source_node,
644607 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",
645608 num_lit_str,
646609 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),
......@@ -654,7 +617,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
654617 assert(instruction_count >= 1);
655618 IrInstruction *prev_inst = instructions[0];
656619 if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) {
657 return ira->codegen->builtin_types.entry_invalid;
620 return ira->old_irb.codegen->builtin_types.entry_invalid;
658621 }
659622 for (size_t i = 1; i < instruction_count; i += 1) {
660623 IrInstruction *cur_inst = instructions[i];
......@@ -701,7 +664,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
701664 prev_inst = cur_inst;
702665 continue;
703666 } else {
704 return ira->codegen->builtin_types.entry_invalid;
667 return ira->old_irb.codegen->builtin_types.entry_invalid;
705668 }
706669 } else if (cur_type->id == TypeTableEntryIdNumLitInt ||
707670 cur_type->id == TypeTableEntryIdNumLitFloat)
......@@ -709,14 +672,14 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
709672 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type)) {
710673 continue;
711674 } else {
712 return ira->codegen->builtin_types.entry_invalid;
675 return ira->old_irb.codegen->builtin_types.entry_invalid;
713676 }
714677 } else {
715 add_node_error(ira->codegen, parent_instruction->source_node,
678 add_node_error(ira->old_irb.codegen, parent_instruction->source_node,
716679 buf_sprintf("incompatible types: '%s' and '%s'",
717680 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name)));
718681
719 return ira->codegen->builtin_types.entry_invalid;
682 return ira->old_irb.codegen->builtin_types.entry_invalid;
720683 }
721684 }
722685 return prev_inst->type_entry;
......@@ -819,14 +782,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, IrInstruction *pare
819782 return ir_determine_peer_types(ira, parent_instruction, instructions, instruction_count);
820783}
821784
822static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
823 TypeTableEntry *expected_type,
824 IrInstruction *before_instruction, IrInstruction *after_instruction)
825{
785static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type) {
826786 assert(value);
827 assert(before_instruction || after_instruction);
828 assert(!before_instruction || !after_instruction);
829 assert(value != ira->codegen->invalid_instruction);
787 assert(value != ira->old_irb.codegen->invalid_instruction);
830788 assert(!expected_type || expected_type->id != TypeTableEntryIdInvalid);
831789 assert(value->type_entry);
832790 assert(value->type_entry->id != TypeTableEntryIdInvalid);
......@@ -840,23 +798,22 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
840798 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->type_entry, value);
841799 switch (result) {
842800 case ImplicitCastMatchResultNo:
843 add_node_error(ira->codegen, first_executing_node(value->source_node),
801 add_node_error(ira->old_irb.codegen, first_executing_node(value->source_node),
844802 buf_sprintf("expected type '%s', got '%s'",
845803 buf_ptr(&expected_type->name),
846804 buf_ptr(&value->type_entry->name)));
847 return ira->codegen->invalid_instruction;
805 return ira->old_irb.codegen->invalid_instruction;
848806
849807 case ImplicitCastMatchResultYes:
850808 {
851 IrInstruction *dest_type = ir_insert_const_type(ira, before_instruction,
852 after_instruction, expected_type);
809 IrInstruction *dest_type = ir_build_const_type(&ira->new_irb, value->source_node, expected_type);
853810 bool is_implicit = true;
854 IrInstruction *cast_instruction = ir_insert_cast(ira, nullptr, dest_type,
855 dest_type, value, is_implicit);
811 IrInstruction *cast_instruction = ir_build_cast(&ira->new_irb, value->source_node, dest_type,
812 value, is_implicit);
856813 return cast_instruction;
857814 }
858815 case ImplicitCastMatchResultReportedError:
859 return ira->codegen->invalid_instruction;
816 return ira->old_irb.codegen->invalid_instruction;
860817 }
861818
862819 zig_unreachable();
......@@ -871,19 +828,20 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructi
871828 }
872829
873830 TypeTableEntry *expected_return_type = scope->fn_entry->type_entry->data.fn.fn_type_id.return_type;
874 if (expected_return_type->id == TypeTableEntryIdVoid && !return_instruction->value) {
875 return ira->codegen->builtin_types.entry_unreachable;
876 }
877831
878 return_instruction->value = ir_get_casted_value(ira,
879 return_instruction->value, expected_return_type, &return_instruction->base, nullptr);
880 if (return_instruction->value == ira->codegen->invalid_instruction) {
832 IrInstruction *value = ir_get_casted_value(ira, return_instruction->value->other, expected_return_type);
833 if (value == ira->codegen->invalid_instruction) {
881834 return ira->codegen->builtin_types.entry_invalid;
882835 }
836
837 ir_link_new(ir_build_return(&ira->new_irb, return_instruction->base.source_node, value),
838 &return_instruction->base);
839
883840 return ira->codegen->builtin_types.entry_unreachable;
884841}
885842
886843static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {
844 const_instruction->base.other = &const_instruction->base;
887845 return const_instruction->base.type_entry;
888846}
889847
......@@ -891,17 +849,18 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp
891849 IrInstruction *op1 = bin_op_instruction->op1;
892850 IrInstruction *op2 = bin_op_instruction->op2;
893851
894 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1, ira->codegen->builtin_types.entry_bool,
895 &bin_op_instruction->base, nullptr);
896 if (casted_op1 == ira->codegen->invalid_instruction)
897 return ira->codegen->builtin_types.entry_invalid;
852 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1->other, ira->old_irb.codegen->builtin_types.entry_bool);
853 if (casted_op1 == ira->old_irb.codegen->invalid_instruction)
854 return ira->old_irb.codegen->builtin_types.entry_invalid;
898855
899 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2, ira->codegen->builtin_types.entry_bool,
900 &bin_op_instruction->base, nullptr);
901 if (casted_op2 == ira->codegen->invalid_instruction)
902 return ira->codegen->builtin_types.entry_invalid;
856 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2->other, ira->old_irb.codegen->builtin_types.entry_bool);
857 if (casted_op2 == ira->old_irb.codegen->invalid_instruction)
858 return ira->old_irb.codegen->builtin_types.entry_invalid;
859
860 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
861 bin_op_instruction->op_id, op1->other, op2->other), &bin_op_instruction->base);
903862
904 return ira->codegen->builtin_types.entry_bool;
863 return ira->old_irb.codegen->builtin_types.entry_bool;
905864}
906865
907866static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
......@@ -917,7 +876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
917876 AstNode *source_node = bin_op_instruction->base.source_node;
918877 switch (resolved_type->id) {
919878 case TypeTableEntryIdInvalid:
920 return ira->codegen->builtin_types.entry_invalid;
879 return ira->old_irb.codegen->builtin_types.entry_invalid;
921880
922881 case TypeTableEntryIdNumLitFloat:
923882 case TypeTableEntryIdNumLitInt:
......@@ -936,17 +895,17 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
936895 case TypeTableEntryIdBlock:
937896 case TypeTableEntryIdGenericFn:
938897 if (!is_equality_cmp) {
939 add_node_error(ira->codegen, source_node,
898 add_node_error(ira->old_irb.codegen, source_node,
940899 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
941 return ira->codegen->builtin_types.entry_invalid;
900 return ira->old_irb.codegen->builtin_types.entry_invalid;
942901 }
943902 break;
944903
945904 case TypeTableEntryIdEnum:
946905 if (!is_equality_cmp || resolved_type->data.enumeration.gen_field_count != 0) {
947 add_node_error(ira->codegen, source_node,
906 add_node_error(ira->old_irb.codegen, source_node,
948907 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
949 return ira->codegen->builtin_types.entry_invalid;
908 return ira->old_irb.codegen->builtin_types.entry_invalid;
950909 }
951910 break;
952911
......@@ -958,15 +917,18 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
958917 case TypeTableEntryIdMaybe:
959918 case TypeTableEntryIdErrorUnion:
960919 case TypeTableEntryIdUnion:
961 add_node_error(ira->codegen, source_node,
920 add_node_error(ira->old_irb.codegen, source_node,
962921 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
963 return ira->codegen->builtin_types.entry_invalid;
922 return ira->old_irb.codegen->builtin_types.entry_invalid;
964923
965924 case TypeTableEntryIdVar:
966925 zig_unreachable();
967926 }
968927
969 return ira->codegen->builtin_types.entry_bool;
928 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
929 op_id, op1->other, op2->other), &bin_op_instruction->base);
930
931 return ira->old_irb.codegen->builtin_types.entry_bool;
970932}
971933
972934static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
......@@ -993,12 +955,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
993955 // float
994956 } else {
995957 AstNode *source_node = bin_op_instruction->base.source_node;
996 add_node_error(ira->codegen, source_node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
958 add_node_error(ira->old_irb.codegen, source_node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
997959 buf_ptr(&op1->type_entry->name),
998960 buf_ptr(&op2->type_entry->name)));
999 return ira->codegen->builtin_types.entry_invalid;
961 return ira->old_irb.codegen->builtin_types.entry_invalid;
1000962 }
1001963
964 ir_link_new(ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.source_node,
965 op_id, op1->other, op2->other), &bin_op_instruction->base);
966
1002967 return resolved_type;
1003968}
1004969
......@@ -1041,6 +1006,8 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi
10411006}
10421007
10431008static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstructionLoadVar *load_var_instruction) {
1009 ir_link_new(ir_build_load_var(&ira->new_irb, load_var_instruction->base.source_node,
1010 load_var_instruction->var), &load_var_instruction->base);
10441011 return load_var_instruction->var->type;
10451012}
10461013
......@@ -1073,35 +1040,52 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins
10731040{
10741041 TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction);
10751042 instruction->type_entry = instruction_type;
1043 if (instruction->other)
1044 instruction->other->type_entry = instruction_type;
10761045
1077 IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type,
1078 nullptr, instruction);
1046 IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type);
10791047 return casted_instruction->type_entry;
10801048}
10811049
1082TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *executable, TypeTableEntry *expected_type) {
1050// This function attempts to evaluate IR code while doing type checking and other analysis.
1051// It emits a new IrExecutable which is partially evaluated IR code.
1052TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec,
1053 TypeTableEntry *expected_type)
1054{
10831055 IrAnalyze ir_analyze_data = {};
10841056 IrAnalyze *ira = &ir_analyze_data;
10851057 ira->codegen = codegen;
1086 ira->exec = executable;
1058
1059 ira->old_irb.codegen = codegen;
1060 ira->old_irb.exec = old_exec;
1061
1062 ira->new_irb.codegen = codegen;
1063 ira->new_irb.exec = new_exec;
1064
1065 ira->exec_context.var_slot_count = ira->old_irb.exec->var_slot_count;
1066 ira->exec_context.var_slot_list = allocate<IrVarSlot>(ira->exec_context.var_slot_count);
10871067
10881068 TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void;
10891069
1090 for (size_t i = 0; i < executable->basic_block_count; i += 1) {
1091 ira->current_basic_block = executable->basic_block_list[i];
1070 ira->new_irb.current_basic_block = allocate<IrBasicBlock>(1);
1071 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10921072
1093 for (IrInstruction *instruction = ira->current_basic_block->first; instruction != nullptr;
1094 instruction = instruction->next)
1095 {
1096 if (return_type->id == TypeTableEntryIdUnreachable) {
1097 add_node_error(ira->codegen, first_executing_node(instruction->source_node),
1098 buf_sprintf("unreachable code"));
1099 break;
1100 }
1101 bool is_last = (instruction == ira->current_basic_block->last);
1102 TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;
1103 return_type = ir_analyze_instruction(ira, instruction, passed_expected_type);
1073 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(0);
1074
1075 ira->new_irb.current_basic_block->other = ira->old_irb.current_basic_block;
1076 ira->old_irb.current_basic_block->other = ira->new_irb.current_basic_block;
1077
1078
1079 for (size_t i = 0; i < ira->old_irb.current_basic_block->instruction_list.length; i += 1) {
1080 IrInstruction *instruction = ira->old_irb.current_basic_block->instruction_list.at(i);
1081 if (return_type->id == TypeTableEntryIdUnreachable) {
1082 add_node_error(ira->codegen, first_executing_node(instruction->source_node),
1083 buf_sprintf("unreachable code"));
1084 break;
11041085 }
1086 bool is_last = (i == ira->old_irb.current_basic_block->instruction_list.length - 1);
1087 TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;
1088 return_type = ir_analyze_instruction(ira, instruction, passed_expected_type);
11051089 }
11061090
11071091 return return_type;
src/ir.hpp+2-1
......@@ -13,6 +13,7 @@
1313IrInstruction *ir_gen(CodeGen *g, AstNode *node, BlockContext *scope, IrExecutable *ir_executable);
1414IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);
1515
16TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *executable, TypeTableEntry *expected_type);
16TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
17 TypeTableEntry *expected_type);
1718
1819#endif
src/ir_print.cpp+4-5
......@@ -173,11 +173,10 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
173173 irp->indent = indent_size;
174174 irp->indent_size = indent_size;
175175
176 for (size_t i = 0; i < executable->basic_block_count; i += 1) {
177 IrBasicBlock *current_block = executable->basic_block_list[i];
178 for (IrInstruction *instruction = current_block->first; instruction != nullptr;
179 instruction = instruction->next)
180 {
176 for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) {
177 IrBasicBlock *current_block = executable->basic_block_list.at(bb_i);
178 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
179 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
181180 ir_print_instruction(irp, instruction);
182181 }
183182 }