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;...@@ -32,8 +32,8 @@ struct IrInstruction;
32struct IrBasicBlock;32struct IrBasicBlock;
3333
34struct IrExecutable {34struct IrExecutable {
35 IrBasicBlock **basic_block_list;35 ZigList<IrBasicBlock *> basic_block_list;
36 size_t basic_block_count;36 size_t var_slot_count;
37 size_t next_debug_id;37 size_t next_debug_id;
38};38};
3939
...@@ -1114,6 +1114,7 @@ struct FnTableEntry {...@@ -1114,6 +1114,7 @@ struct FnTableEntry {
1114 FnInline fn_inline;1114 FnInline fn_inline;
1115 FnAnalState anal_state;1115 FnAnalState anal_state;
1116 IrExecutable ir_executable;1116 IrExecutable ir_executable;
1117 IrExecutable analyzed_executable;
11171118
1118 AstNode *fn_no_inline_set_node;1119 AstNode *fn_no_inline_set_node;
1119 AstNode *fn_export_set_node;1120 AstNode *fn_export_set_node;
...@@ -1347,6 +1348,7 @@ struct VariableTableEntry {...@@ -1347,6 +1348,7 @@ struct VariableTableEntry {
1347 bool force_depends_on_compile_var;1348 bool force_depends_on_compile_var;
1348 ImportTableEntry *import;1349 ImportTableEntry *import;
1349 bool shadowable;1350 bool shadowable;
1351 size_t slot_index;
1350};1352};
13511353
1352struct ErrorTableEntry {1354struct ErrorTableEntry {
...@@ -1404,8 +1406,8 @@ enum AtomicOrder {...@@ -1404,8 +1406,8 @@ enum AtomicOrder {
1404// Phi instructions must be first in a basic block.1406// Phi instructions must be first in a basic block.
1405// The last instruction in a basic block must be an expression of type unreachable.1407// The last instruction in a basic block must be an expression of type unreachable.
1406struct IrBasicBlock {1408struct IrBasicBlock {
1407 IrInstruction *first;1409 ZigList<IrInstruction *> instruction_list;
1408 IrInstruction *last;1410 IrBasicBlock *other;
1409};1411};
14101412
1411enum IrInstructionId {1413enum IrInstructionId {
...@@ -1424,23 +1426,23 @@ enum IrInstructionId {...@@ -1424,23 +1426,23 @@ enum IrInstructionId {
1424};1426};
14251427
1426struct IrInstruction {1428struct IrInstruction {
1427 IrInstruction *prev;
1428 IrInstruction *next;
1429
1430 IrInstructionId id;1429 IrInstructionId id;
1431 AstNode *source_node;1430 AstNode *source_node;
1432 ConstExprValue static_value;1431 ConstExprValue static_value;
1433 TypeTableEntry *type_entry;1432 TypeTableEntry *type_entry;
1434 size_t debug_id;1433 size_t debug_id;
1435 LLVMValueRef llvm_value;1434 LLVMValueRef llvm_value;
1435 // if ref_count is zero, instruction can be omitted in codegen
1436 size_t ref_count;
1437 IrInstruction *other;
1436};1438};
14371439
1438struct IrInstructionCondBr {1440struct IrInstructionCondBr {
1439 IrInstruction base;1441 IrInstruction base;
14401442
1441 // If the condition is null, then this is an unconditional branch.1443 // If cond_inst_index == SIZE_MAX, then this is an unconditional branch.
1442 IrInstruction *cond;1444 size_t cond_inst_index;
1443 IrBasicBlock *dest;1445 size_t dest_basic_block_index;
1444};1446};
14451447
1446struct IrInstructionSwitchBrCase {1448struct IrInstructionSwitchBrCase {
src/analyze.cpp+8-1
...@@ -7088,9 +7088,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -7088,9 +7088,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
7088 fprintf(stderr, "}\n");7088 fprintf(stderr, "}\n");
7089 }7089 }
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);
7092 node->data.fn_def.implicit_return_type = block_return_type;7093 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
7094 fn_table_entry->anal_state = FnAnalStateComplete;7101 fn_table_entry->anal_state = FnAnalStateComplete;
7095}7102}
70967103
src/codegen.cpp+6-7
...@@ -2921,13 +2921,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2921,13 +2921,12 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
29212921
2922static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {2922static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
2923 assert(fn_entry);2923 assert(fn_entry);
2924 IrExecutable *executable = &fn_entry->ir_executable;2924 IrExecutable *executable = &fn_entry->analyzed_executable;
2925 assert(executable->basic_block_count > 0);2925 assert(executable->basic_block_list.length > 0);
2926 for (size_t i = 0; i < executable->basic_block_count; i += 1) {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[i];2927 IrBasicBlock *current_block = executable->basic_block_list.at(block_i);
2928 for (IrInstruction *instruction = current_block->first; instruction != nullptr;2928 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
2929 instruction = instruction->next)2929 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
2930 {
2931 instruction->llvm_value = ir_render_instruction(g, executable, instruction);2930 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
2932 }2931 }
2933 }2932 }
src/ir.cpp+209-225
...@@ -2,57 +2,35 @@...@@ -2,57 +2,35 @@
2#include "ir.hpp"2#include "ir.hpp"
3#include "error.hpp"3#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 {
6 CodeGen *codegen;16 CodeGen *codegen;
7 AstNode *node;
8 IrBasicBlock *current_basic_block;
9 IrExecutable *exec;17 IrExecutable *exec;
18 IrBasicBlock *current_basic_block;
10};19};
1120
12struct IrAnalyze {21struct IrAnalyze {
13 CodeGen *codegen;22 CodeGen *codegen;
14 IrExecutable *exec;23 IrBuilder old_irb;
15 IrBasicBlock *current_basic_block;24 IrBuilder new_irb;
25 IrExecContext exec_context;
16};26};
1727
18static IrInstruction *ir_gen_node(IrGen *irg, AstNode *node, BlockContext *scope);28static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
1929
20static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {30static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {
21 if (!basic_block->last) {31 assert(basic_block);
22 basic_block->first = instruction;32 assert(instruction);
23 basic_block->last = instruction;33 basic_block->instruction_list.append(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 }
56}34}
5735
58static size_t exec_next_debug_id(IrExecutable *exec) {36static size_t exec_next_debug_id(IrExecutable *exec) {
...@@ -115,97 +93,82 @@ static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {...@@ -115,97 +93,82 @@ static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
115}93}
11694
117template<typename T>95template<typename T>
118static T *ir_build_instruction(IrGen *irg, AstNode *source_node) {96static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {
119 T *special_instruction = ir_create_instruction<T>(irg->exec, source_node);97 T *special_instruction = ir_create_instruction<T>(irb->exec, source_node);
120 ir_instruction_append(irg->current_basic_block, &special_instruction->base);98 ir_instruction_append(irb->current_basic_block, &special_instruction->base);
121 return special_instruction;99 return special_instruction;
122}100}
123101
124static IrInstruction *ir_insert_const_type(IrAnalyze *ira, IrInstruction *before_instruction,102static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInstruction *dest_type,
125 IrInstruction *after_instruction, TypeTableEntry *type_entry)103 IrInstruction *value, bool is_implicit)
126{104{
127 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->exec,105 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);
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);
142 cast_instruction->dest_type = dest_type;106 cast_instruction->dest_type = dest_type;
143 cast_instruction->value = value;107 cast_instruction->value = value;
144 cast_instruction->is_implicit = is_implicit;108 cast_instruction->is_implicit = is_implicit;
145 ir_instruction_insert(ira->current_basic_block, before_instruction, after_instruction, &cast_instruction->base);
146 return &cast_instruction->base;109 return &cast_instruction->base;
147}110}
148111
149static IrInstruction *ir_build_return(IrGen *irg, AstNode *source_node, IrInstruction *return_value) {112static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrInstruction *return_value) {
150 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irg, source_node);113 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, source_node);
151 return_instruction->base.type_entry = irg->codegen->builtin_types.entry_unreachable;114 return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
152 return_instruction->base.static_value.ok = true;115 return_instruction->base.static_value.ok = true;
153 return_instruction->value = return_value;116 return_instruction->value = return_value;
154 return &return_instruction->base;117 return &return_instruction->base;
155}118}
156119
157static IrInstruction *ir_build_const_void(IrGen *irg, AstNode *source_node) {120static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) {
158 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);121 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
159 const_instruction->base.type_entry = irg->codegen->builtin_types.entry_void;122 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
160 const_instruction->base.static_value.ok = true;123 const_instruction->base.static_value.ok = true;
161 return &const_instruction->base;124 return &const_instruction->base;
162}125}
163126
164static IrInstruction *ir_build_const_bignum(IrGen *irg, AstNode *source_node, BigNum *bignum) {127static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node, BigNum *bignum) {
165 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);128 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
166 const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ?129 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;
168 const_instruction->base.static_value.ok = true;131 const_instruction->base.static_value.ok = true;
169 const_instruction->base.static_value.data.x_bignum = *bignum;132 const_instruction->base.static_value.data.x_bignum = *bignum;
170 return &const_instruction->base;133 return &const_instruction->base;
171}134}
172135
173static IrInstruction *ir_build_const_type(IrGen *irg, AstNode *source_node, TypeTableEntry *type_entry) {136static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {
174 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);137 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
175 const_instruction->base.type_entry = irg->codegen->builtin_types.entry_type;138 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type;
176 const_instruction->base.static_value.ok = true;139 const_instruction->base.static_value.ok = true;
177 const_instruction->base.static_value.data.x_type = type_entry;140 const_instruction->base.static_value.data.x_type = type_entry;
178 return &const_instruction->base;141 return &const_instruction->base;
179}142}
180143
181static IrInstruction *ir_build_const_fn(IrGen *irg, AstNode *source_node, FnTableEntry *fn_entry) {144static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) {
182 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);145 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
183 const_instruction->base.type_entry = fn_entry->type_entry;146 const_instruction->base.type_entry = fn_entry->type_entry;
184 const_instruction->base.static_value.ok = true;147 const_instruction->base.static_value.ok = true;
185 const_instruction->base.static_value.data.x_fn = fn_entry;148 const_instruction->base.static_value.data.x_fn = fn_entry;
186 return &const_instruction->base;149 return &const_instruction->base;
187}150}
188151
189static IrInstruction *ir_build_const_generic_fn(IrGen *irg, AstNode *source_node, TypeTableEntry *fn_type) {152static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_node, TypeTableEntry *fn_type) {
190 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irg, source_node);153 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
191 const_instruction->base.type_entry = fn_type;154 const_instruction->base.type_entry = fn_type;
192 const_instruction->base.static_value.ok = true;155 const_instruction->base.static_value.ok = true;
193 const_instruction->base.static_value.data.x_type = fn_type;156 const_instruction->base.static_value.data.x_type = fn_type;
194 return &const_instruction->base;157 return &const_instruction->base;
195}158}
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,
198 IrInstruction *op1, IrInstruction *op2)161 IrInstruction *op1, IrInstruction *op2)
199{162{
200 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irg, source_node);163 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, source_node);
201 bin_op_instruction->op_id = op_id;164 bin_op_instruction->op_id = op_id;
202 bin_op_instruction->op1 = op1;165 bin_op_instruction->op1 = op1;
203 bin_op_instruction->op2 = op2;166 bin_op_instruction->op2 = op2;
204 return &bin_op_instruction->base;167 return &bin_op_instruction->base;
205}168}
206169
207static IrInstruction *ir_build_load_var(IrGen *irg, AstNode *source_node, VariableTableEntry *var) {170static IrInstruction *ir_build_load_var(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) {
208 IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irg, source_node);171 IrInstructionLoadVar *load_var_instruction = ir_build_instruction<IrInstructionLoadVar>(irb, source_node);
209 load_var_instruction->base.type_entry = var->type;172 load_var_instruction->base.type_entry = var->type;
210 load_var_instruction->var = var;173 load_var_instruction->var = var;
211 return &load_var_instruction->base;174 return &load_var_instruction->base;
...@@ -226,7 +189,7 @@ static IrInstruction *ir_build_load_var(IrGen *irg, AstNode *source_node, Variab...@@ -226,7 +189,7 @@ static IrInstruction *ir_build_load_var(IrGen *irg, AstNode *source_node, Variab
226// return result;189// return result;
227//}190//}
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,
230 bool gen_error_defers, bool gen_maybe_defers)193 bool gen_error_defers, bool gen_maybe_defers)
231{194{
232 while (inner_block != outer_block) {195 while (inner_block != outer_block) {
...@@ -236,15 +199,15 @@ static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, Block...@@ -236,15 +199,15 @@ static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, Block
236 (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe)))199 (gen_maybe_defers && inner_block->node->data.defer.kind == ReturnKindMaybe)))
237 {200 {
238 AstNode *defer_expr_node = inner_block->node->data.defer.expr;201 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);
240 }203 }
241 inner_block = inner_block->parent;204 inner_block = inner_block->parent;
242 }205 }
243}206}
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) {
246// BlockContext *defer_inner_block = source_node->block_context;209// 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;
248// if (rk == ReturnKnowledgeUnknown) {211// if (rk == ReturnKnowledgeUnknown) {
249// if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) {212// if (get_conditional_defer_count(defer_inner_block, defer_outer_block) > 0) {
250// // generate branching code that checks the return value and generates defers213// // 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...@@ -252,14 +215,14 @@ static void ir_gen_defers_for_block(IrGen *irg, BlockContext *inner_block, Block
252// zig_panic("TODO");215// zig_panic("TODO");
253// }216// }
254// } else if (rk != ReturnKnowledgeSkipDefers) {217// } 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,
256// rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull);219// rk == ReturnKnowledgeKnownError, rk == ReturnKnowledgeKnownNull);
257// }220// }
258//221//
259// return ir_build_return(irg, source_node, value);222// return ir_build_return(irb, source_node, value);
260//}223//}
261224
262static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {225static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
263 assert(block_node->type == NodeTypeBlock);226 assert(block_node->type == NodeTypeBlock);
264227
265 BlockContext *parent_context = block_node->block_context;228 BlockContext *parent_context = block_node->block_context;
...@@ -269,8 +232,8 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {...@@ -269,8 +232,8 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {
269 IrInstruction *return_value = nullptr;232 IrInstruction *return_value = nullptr;
270 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {233 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
271 AstNode *statement_node = block_node->data.block.statements.at(i);234 AstNode *statement_node = block_node->data.block.statements.at(i);
272 return_value = ir_gen_node(irg, statement_node, child_context);235 return_value = ir_gen_node(irb, statement_node, child_context);
273 if (statement_node->type == NodeTypeDefer && return_value != irg->codegen->invalid_instruction) {236 if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) {
274 // defer starts a new block context237 // defer starts a new block context
275 child_context = statement_node->data.defer.child_block;238 child_context = statement_node->data.defer.child_block;
276 assert(child_context);239 assert(child_context);
...@@ -278,20 +241,20 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {...@@ -278,20 +241,20 @@ static IrInstruction *ir_gen_block(IrGen *irg, AstNode *block_node) {
278 }241 }
279242
280 if (!return_value)243 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
285 return return_value;248 return return_value;
286}249}
287250
288static IrInstruction *ir_gen_bin_op_id(IrGen *irg, AstNode *node, IrBinOp op_id) {251static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) {
289 IrInstruction *op1 = ir_gen_node(irg, node->data.bin_op_expr.op1, node->block_context);252 IrInstruction *op1 = ir_gen_node(irb, 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);253 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->block_context);
291 return ir_build_bin_op(irg, node, op_id, op1, op2);254 return ir_build_bin_op(irb, node, op_id, op1, op2);
292}255}
293256
294static IrInstruction *ir_gen_bin_op(IrGen *irg, AstNode *node) {257static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {
295 assert(node->type == NodeTypeBinOpExpr);258 assert(node->type == NodeTypeBinOpExpr);
296259
297 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;260 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) {...@@ -322,144 +285,144 @@ static IrInstruction *ir_gen_bin_op(IrGen *irg, AstNode *node) {
322 // because of the control flow285 // because of the control flow
323 zig_panic("TODO gen IR for bool or/and");286 zig_panic("TODO gen IR for bool or/and");
324 case BinOpTypeCmpEq:287 case BinOpTypeCmpEq:
325 return ir_gen_bin_op_id(irg, node, IrBinOpCmpEq);288 return ir_gen_bin_op_id(irb, node, IrBinOpCmpEq);
326 case BinOpTypeCmpNotEq:289 case BinOpTypeCmpNotEq:
327 return ir_gen_bin_op_id(irg, node, IrBinOpCmpNotEq);290 return ir_gen_bin_op_id(irb, node, IrBinOpCmpNotEq);
328 case BinOpTypeCmpLessThan:291 case BinOpTypeCmpLessThan:
329 return ir_gen_bin_op_id(irg, node, IrBinOpCmpLessThan);292 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessThan);
330 case BinOpTypeCmpGreaterThan:293 case BinOpTypeCmpGreaterThan:
331 return ir_gen_bin_op_id(irg, node, IrBinOpCmpGreaterThan);294 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterThan);
332 case BinOpTypeCmpLessOrEq:295 case BinOpTypeCmpLessOrEq:
333 return ir_gen_bin_op_id(irg, node, IrBinOpCmpLessOrEq);296 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessOrEq);
334 case BinOpTypeCmpGreaterOrEq:297 case BinOpTypeCmpGreaterOrEq:
335 return ir_gen_bin_op_id(irg, node, IrBinOpCmpGreaterOrEq);298 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterOrEq);
336 case BinOpTypeBinOr:299 case BinOpTypeBinOr:
337 return ir_gen_bin_op_id(irg, node, IrBinOpBinOr);300 return ir_gen_bin_op_id(irb, node, IrBinOpBinOr);
338 case BinOpTypeBinXor:301 case BinOpTypeBinXor:
339 return ir_gen_bin_op_id(irg, node, IrBinOpBinXor);302 return ir_gen_bin_op_id(irb, node, IrBinOpBinXor);
340 case BinOpTypeBinAnd:303 case BinOpTypeBinAnd:
341 return ir_gen_bin_op_id(irg, node, IrBinOpBinAnd);304 return ir_gen_bin_op_id(irb, node, IrBinOpBinAnd);
342 case BinOpTypeBitShiftLeft:305 case BinOpTypeBitShiftLeft:
343 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftLeft);306 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeft);
344 case BinOpTypeBitShiftLeftWrap:307 case BinOpTypeBitShiftLeftWrap:
345 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftLeftWrap);308 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeftWrap);
346 case BinOpTypeBitShiftRight:309 case BinOpTypeBitShiftRight:
347 return ir_gen_bin_op_id(irg, node, IrBinOpBitShiftRight);310 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftRight);
348 case BinOpTypeAdd:311 case BinOpTypeAdd:
349 return ir_gen_bin_op_id(irg, node, IrBinOpAdd);312 return ir_gen_bin_op_id(irb, node, IrBinOpAdd);
350 case BinOpTypeAddWrap:313 case BinOpTypeAddWrap:
351 return ir_gen_bin_op_id(irg, node, IrBinOpAddWrap);314 return ir_gen_bin_op_id(irb, node, IrBinOpAddWrap);
352 case BinOpTypeSub:315 case BinOpTypeSub:
353 return ir_gen_bin_op_id(irg, node, IrBinOpSub);316 return ir_gen_bin_op_id(irb, node, IrBinOpSub);
354 case BinOpTypeSubWrap:317 case BinOpTypeSubWrap:
355 return ir_gen_bin_op_id(irg, node, IrBinOpSubWrap);318 return ir_gen_bin_op_id(irb, node, IrBinOpSubWrap);
356 case BinOpTypeMult:319 case BinOpTypeMult:
357 return ir_gen_bin_op_id(irg, node, IrBinOpMult);320 return ir_gen_bin_op_id(irb, node, IrBinOpMult);
358 case BinOpTypeMultWrap:321 case BinOpTypeMultWrap:
359 return ir_gen_bin_op_id(irg, node, IrBinOpMultWrap);322 return ir_gen_bin_op_id(irb, node, IrBinOpMultWrap);
360 case BinOpTypeDiv:323 case BinOpTypeDiv:
361 return ir_gen_bin_op_id(irg, node, IrBinOpDiv);324 return ir_gen_bin_op_id(irb, node, IrBinOpDiv);
362 case BinOpTypeMod:325 case BinOpTypeMod:
363 return ir_gen_bin_op_id(irg, node, IrBinOpMod);326 return ir_gen_bin_op_id(irb, node, IrBinOpMod);
364 case BinOpTypeArrayCat:327 case BinOpTypeArrayCat:
365 return ir_gen_bin_op_id(irg, node, IrBinOpArrayCat);328 return ir_gen_bin_op_id(irb, node, IrBinOpArrayCat);
366 case BinOpTypeArrayMult:329 case BinOpTypeArrayMult:
367 return ir_gen_bin_op_id(irg, node, IrBinOpArrayMult);330 return ir_gen_bin_op_id(irb, node, IrBinOpArrayMult);
368 case BinOpTypeUnwrapMaybe:331 case BinOpTypeUnwrapMaybe:
369 zig_panic("TODO gen IR for unwrap maybe");332 zig_panic("TODO gen IR for unwrap maybe");
370 }333 }
371 zig_unreachable();334 zig_unreachable();
372}335}
373336
374static IrInstruction *ir_gen_num_lit(IrGen *irg, AstNode *node) {337static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {
375 assert(node->type == NodeTypeNumberLiteral);338 assert(node->type == NodeTypeNumberLiteral);
376339
377 if (node->data.number_literal.overflow) {340 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"));341 add_node_error(irb->codegen, node, buf_sprintf("number literal too large to be represented in any type"));
379 return irg->codegen->invalid_instruction;342 return irb->codegen->invalid_instruction;
380 }343 }
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);
383}346}
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,
386 bool pointer_only, BlockContext *scope)349 bool pointer_only, BlockContext *scope)
387{350{
388 resolve_top_level_decl(irg->codegen, decl_node, pointer_only);351 resolve_top_level_decl(irb->codegen, decl_node, pointer_only);
389 TopLevelDecl *tld = get_as_top_level_decl(decl_node);352 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
390 if (tld->resolution == TldResolutionInvalid)353 if (tld->resolution == TldResolutionInvalid)
391 return irg->codegen->invalid_instruction;354 return irb->codegen->invalid_instruction;
392355
393 if (decl_node->type == NodeTypeVariableDeclaration) {356 if (decl_node->type == NodeTypeVariableDeclaration) {
394 VariableTableEntry *var = decl_node->data.variable_declaration.variable;357 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);
396 } else if (decl_node->type == NodeTypeFnProto) {359 } else if (decl_node->type == NodeTypeFnProto) {
397 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;360 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
398 assert(fn_entry->type_entry);361 assert(fn_entry->type_entry);
399 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {362 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);
401 } else {364 } else {
402 return ir_build_const_fn(irg, source_node, fn_entry);365 return ir_build_const_fn(irb, source_node, fn_entry);
403 }366 }
404 } else if (decl_node->type == NodeTypeContainerDecl) {367 } else if (decl_node->type == NodeTypeContainerDecl) {
405 if (decl_node->data.struct_decl.generic_params.length > 0) {368 if (decl_node->data.struct_decl.generic_params.length > 0) {
406 TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;369 TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
407 assert(type_entry);370 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);
409 } else {372 } 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);
411 }374 }
412 } else if (decl_node->type == NodeTypeTypeDecl) {375 } 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);
414 } else {377 } else {
415 zig_unreachable();378 zig_unreachable();
416 }379 }
417}380}
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) {
420 assert(node->type == NodeTypeSymbol);383 assert(node->type == NodeTypeSymbol);
421384
422 if (node->data.symbol_expr.override_type_entry)385 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
425 Buf *variable_name = node->data.symbol_expr.symbol;388 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);
428 if (primitive_table_entry)391 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);
432 if (var)395 if (var)
433 return ir_build_load_var(irg, node, var);396 return ir_build_load_var(irb, node, var);
434397
435 AstNode *decl_node = find_decl(node->block_context, variable_name);398 AstNode *decl_node = find_decl(node->block_context, variable_name);
436 if (decl_node)399 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
439 if (node->owner->any_imports_failed) {402 if (node->owner->any_imports_failed) {
440 // skip the error message since we had a failing import in this file403 // skip the error message since we had a failing import in this file
441 // if an import breaks we don't need redundant undeclared identifier errors404 // if an import breaks we don't need redundant undeclared identifier errors
442 return irg->codegen->invalid_instruction;405 return irb->codegen->invalid_instruction;
443 }406 }
444407
445 add_node_error(irg->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));408 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
446 return irg->codegen->invalid_instruction;409 return irb->codegen->invalid_instruction;
447}410}
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,
450 bool pointer_only)413 bool pointer_only)
451{414{
452 node->block_context = block_context;415 node->block_context = block_context;
453416
454 switch (node->type) {417 switch (node->type) {
455 case NodeTypeBlock:418 case NodeTypeBlock:
456 return ir_gen_block(irg, node);419 return ir_gen_block(irb, node);
457 case NodeTypeBinOpExpr:420 case NodeTypeBinOpExpr:
458 return ir_gen_bin_op(irg, node);421 return ir_gen_bin_op(irb, node);
459 case NodeTypeNumberLiteral:422 case NodeTypeNumberLiteral:
460 return ir_gen_num_lit(irg, node);423 return ir_gen_num_lit(irb, node);
461 case NodeTypeSymbol:424 case NodeTypeSymbol:
462 return ir_gen_symbol(irg, node, pointer_only);425 return ir_gen_symbol(irb, node, pointer_only);
463 case NodeTypeUnwrapErrorExpr:426 case NodeTypeUnwrapErrorExpr:
464 case NodeTypeReturnExpr:427 case NodeTypeReturnExpr:
465 case NodeTypeDefer:428 case NodeTypeDefer:
...@@ -509,9 +472,9 @@ static IrInstruction *ir_gen_node_extra(IrGen *irg, AstNode *node, BlockContext...@@ -509,9 +472,9 @@ static IrInstruction *ir_gen_node_extra(IrGen *irg, AstNode *node, BlockContext
509 zig_unreachable();472 zig_unreachable();
510}473}
511474
512static IrInstruction *ir_gen_node(IrGen *irg, AstNode *node, BlockContext *scope) {475static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope) {
513 bool pointer_only_no = false;476 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);
515}478}
516479
517static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext *scope,480static 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...@@ -519,28 +482,23 @@ static IrInstruction *ir_gen_add_return(CodeGen *g, AstNode *node, BlockContext
519{482{
520 assert(node->owner);483 assert(node->owner);
521484
522 IrGen ir_gen = {0};485 IrBuilder ir_gen = {0};
523 IrGen *irg = &ir_gen;486 IrBuilder *irb = &ir_gen;
524487
525 irg->codegen = g;488 irb->codegen = g;
526 irg->node = node;489 irb->exec = ir_executable;
527 irg->exec = ir_executable;
528490
529 irg->exec->basic_block_list = allocate<IrBasicBlock*>(1);491 irb->current_basic_block = allocate<IrBasicBlock>(1);
530 irg->exec->basic_block_count = 1;492 irb->exec->basic_block_list.append(irb->current_basic_block);
531493
532 IrBasicBlock *entry_basic_block = allocate<IrBasicBlock>(1);494 IrInstruction *result = ir_gen_node_extra(irb, node, scope, pointer_only);
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);
537 assert(result);495 assert(result);
538496
539 if (result == g->invalid_instruction)497 if (result == g->invalid_instruction)
540 return result;498 return result;
541499
542 if (add_return)500 if (add_return)
543 return ir_build_return(irg, result->source_node, result);501 return ir_build_return(irb, result->source_node, result);
544502
545 return result;503 return result;
546}504}
...@@ -566,6 +524,11 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {...@@ -566,6 +524,11 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
566 return ir_gen_add_return(codegn, body_node, scope, ir_executable, add_return_yes, pointer_only_no);524 return ir_gen_add_return(codegn, body_node, scope, ir_executable, add_return_yes, pointer_only_no);
567}525}
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
569/*532/*
570static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) {533static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *node) {
571 assert(node->type == NodeTypeGoto);534 assert(node->type == NodeTypeGoto);
...@@ -640,7 +603,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -640,7 +603,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
640603
641 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";604 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,
644 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",607 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",
645 num_lit_str,608 num_lit_str,
646 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),609 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),
...@@ -654,7 +617,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa...@@ -654,7 +617,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
654 assert(instruction_count >= 1);617 assert(instruction_count >= 1);
655 IrInstruction *prev_inst = instructions[0];618 IrInstruction *prev_inst = instructions[0];
656 if (prev_inst->type_entry->id == TypeTableEntryIdInvalid) {619 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;
658 }621 }
659 for (size_t i = 1; i < instruction_count; i += 1) {622 for (size_t i = 1; i < instruction_count; i += 1) {
660 IrInstruction *cur_inst = instructions[i];623 IrInstruction *cur_inst = instructions[i];
...@@ -701,7 +664,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa...@@ -701,7 +664,7 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
701 prev_inst = cur_inst;664 prev_inst = cur_inst;
702 continue;665 continue;
703 } else {666 } else {
704 return ira->codegen->builtin_types.entry_invalid;667 return ira->old_irb.codegen->builtin_types.entry_invalid;
705 }668 }
706 } else if (cur_type->id == TypeTableEntryIdNumLitInt ||669 } else if (cur_type->id == TypeTableEntryIdNumLitInt ||
707 cur_type->id == TypeTableEntryIdNumLitFloat)670 cur_type->id == TypeTableEntryIdNumLitFloat)
...@@ -709,14 +672,14 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa...@@ -709,14 +672,14 @@ static TypeTableEntry *ir_determine_peer_types(IrAnalyze *ira, IrInstruction *pa
709 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type)) {672 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type)) {
710 continue;673 continue;
711 } else {674 } else {
712 return ira->codegen->builtin_types.entry_invalid;675 return ira->old_irb.codegen->builtin_types.entry_invalid;
713 }676 }
714 } else {677 } else {
715 add_node_error(ira->codegen, parent_instruction->source_node,678 add_node_error(ira->old_irb.codegen, parent_instruction->source_node,
716 buf_sprintf("incompatible types: '%s' and '%s'",679 buf_sprintf("incompatible types: '%s' and '%s'",
717 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name)));680 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;
720 }683 }
721 }684 }
722 return prev_inst->type_entry;685 return prev_inst->type_entry;
...@@ -819,14 +782,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, IrInstruction *pare...@@ -819,14 +782,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, IrInstruction *pare
819 return ir_determine_peer_types(ira, parent_instruction, instructions, instruction_count);782 return ir_determine_peer_types(ira, parent_instruction, instructions, instruction_count);
820}783}
821784
822static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,785static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type) {
823 TypeTableEntry *expected_type,
824 IrInstruction *before_instruction, IrInstruction *after_instruction)
825{
826 assert(value);786 assert(value);
827 assert(before_instruction || after_instruction);787 assert(value != ira->old_irb.codegen->invalid_instruction);
828 assert(!before_instruction || !after_instruction);
829 assert(value != ira->codegen->invalid_instruction);
830 assert(!expected_type || expected_type->id != TypeTableEntryIdInvalid);788 assert(!expected_type || expected_type->id != TypeTableEntryIdInvalid);
831 assert(value->type_entry);789 assert(value->type_entry);
832 assert(value->type_entry->id != TypeTableEntryIdInvalid);790 assert(value->type_entry->id != TypeTableEntryIdInvalid);
...@@ -840,23 +798,22 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,...@@ -840,23 +798,22 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
840 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->type_entry, value);798 ImplicitCastMatchResult result = ir_types_match_with_implicit_cast(ira, expected_type, value->type_entry, value);
841 switch (result) {799 switch (result) {
842 case ImplicitCastMatchResultNo:800 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),
844 buf_sprintf("expected type '%s', got '%s'",802 buf_sprintf("expected type '%s', got '%s'",
845 buf_ptr(&expected_type->name),803 buf_ptr(&expected_type->name),
846 buf_ptr(&value->type_entry->name)));804 buf_ptr(&value->type_entry->name)));
847 return ira->codegen->invalid_instruction;805 return ira->old_irb.codegen->invalid_instruction;
848806
849 case ImplicitCastMatchResultYes:807 case ImplicitCastMatchResultYes:
850 {808 {
851 IrInstruction *dest_type = ir_insert_const_type(ira, before_instruction,809 IrInstruction *dest_type = ir_build_const_type(&ira->new_irb, value->source_node, expected_type);
852 after_instruction, expected_type);
853 bool is_implicit = true;810 bool is_implicit = true;
854 IrInstruction *cast_instruction = ir_insert_cast(ira, nullptr, dest_type,811 IrInstruction *cast_instruction = ir_build_cast(&ira->new_irb, value->source_node, dest_type,
855 dest_type, value, is_implicit);812 value, is_implicit);
856 return cast_instruction;813 return cast_instruction;
857 }814 }
858 case ImplicitCastMatchResultReportedError:815 case ImplicitCastMatchResultReportedError:
859 return ira->codegen->invalid_instruction;816 return ira->old_irb.codegen->invalid_instruction;
860 }817 }
861818
862 zig_unreachable();819 zig_unreachable();
...@@ -871,19 +828,20 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructi...@@ -871,19 +828,20 @@ static TypeTableEntry *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructi
871 }828 }
872829
873 TypeTableEntry *expected_return_type = scope->fn_entry->type_entry->data.fn.fn_type_id.return_type;830 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,832 IrInstruction *value = ir_get_casted_value(ira, return_instruction->value->other, expected_return_type);
879 return_instruction->value, expected_return_type, &return_instruction->base, nullptr);833 if (value == ira->codegen->invalid_instruction) {
880 if (return_instruction->value == ira->codegen->invalid_instruction) {
881 return ira->codegen->builtin_types.entry_invalid;834 return ira->codegen->builtin_types.entry_invalid;
882 }835 }
836
837 ir_link_new(ir_build_return(&ira->new_irb, return_instruction->base.source_node, value),
838 &return_instruction->base);
839
883 return ira->codegen->builtin_types.entry_unreachable;840 return ira->codegen->builtin_types.entry_unreachable;
884}841}
885842
886static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {843static TypeTableEntry *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *const_instruction) {
844 const_instruction->base.other = &const_instruction->base;
887 return const_instruction->base.type_entry;845 return const_instruction->base.type_entry;
888}846}
889847
...@@ -891,17 +849,18 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp...@@ -891,17 +849,18 @@ static TypeTableEntry *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp
891 IrInstruction *op1 = bin_op_instruction->op1;849 IrInstruction *op1 = bin_op_instruction->op1;
892 IrInstruction *op2 = bin_op_instruction->op2;850 IrInstruction *op2 = bin_op_instruction->op2;
893851
894 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1, ira->codegen->builtin_types.entry_bool,852 IrInstruction *casted_op1 = ir_get_casted_value(ira, op1->other, ira->old_irb.codegen->builtin_types.entry_bool);
895 &bin_op_instruction->base, nullptr);853 if (casted_op1 == ira->old_irb.codegen->invalid_instruction)
896 if (casted_op1 == ira->codegen->invalid_instruction)854 return ira->old_irb.codegen->builtin_types.entry_invalid;
897 return ira->codegen->builtin_types.entry_invalid;
898855
899 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2, ira->codegen->builtin_types.entry_bool,856 IrInstruction *casted_op2 = ir_get_casted_value(ira, op2->other, ira->old_irb.codegen->builtin_types.entry_bool);
900 &bin_op_instruction->base, nullptr);857 if (casted_op2 == ira->old_irb.codegen->invalid_instruction)
901 if (casted_op2 == ira->codegen->invalid_instruction)858 return ira->old_irb.codegen->builtin_types.entry_invalid;
902 return ira->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;
905}864}
906865
907static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {866static 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...@@ -917,7 +876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
917 AstNode *source_node = bin_op_instruction->base.source_node;876 AstNode *source_node = bin_op_instruction->base.source_node;
918 switch (resolved_type->id) {877 switch (resolved_type->id) {
919 case TypeTableEntryIdInvalid:878 case TypeTableEntryIdInvalid:
920 return ira->codegen->builtin_types.entry_invalid;879 return ira->old_irb.codegen->builtin_types.entry_invalid;
921880
922 case TypeTableEntryIdNumLitFloat:881 case TypeTableEntryIdNumLitFloat:
923 case TypeTableEntryIdNumLitInt:882 case TypeTableEntryIdNumLitInt:
...@@ -936,17 +895,17 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -936,17 +895,17 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
936 case TypeTableEntryIdBlock:895 case TypeTableEntryIdBlock:
937 case TypeTableEntryIdGenericFn:896 case TypeTableEntryIdGenericFn:
938 if (!is_equality_cmp) {897 if (!is_equality_cmp) {
939 add_node_error(ira->codegen, source_node,898 add_node_error(ira->old_irb.codegen, source_node,
940 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));899 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;
942 }901 }
943 break;902 break;
944903
945 case TypeTableEntryIdEnum:904 case TypeTableEntryIdEnum:
946 if (!is_equality_cmp || resolved_type->data.enumeration.gen_field_count != 0) {905 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,
948 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));907 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;
950 }909 }
951 break;910 break;
952911
...@@ -958,15 +917,18 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -958,15 +917,18 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
958 case TypeTableEntryIdMaybe:917 case TypeTableEntryIdMaybe:
959 case TypeTableEntryIdErrorUnion:918 case TypeTableEntryIdErrorUnion:
960 case TypeTableEntryIdUnion:919 case TypeTableEntryIdUnion:
961 add_node_error(ira->codegen, source_node,920 add_node_error(ira->old_irb.codegen, source_node,
962 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));921 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
965 case TypeTableEntryIdVar:924 case TypeTableEntryIdVar:
966 zig_unreachable();925 zig_unreachable();
967 }926 }
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;
970}932}
971933
972static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {934static 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...@@ -993,12 +955,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
993 // float955 // float
994 } else {956 } else {
995 AstNode *source_node = bin_op_instruction->base.source_node;957 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'",
997 buf_ptr(&op1->type_entry->name),959 buf_ptr(&op1->type_entry->name),
998 buf_ptr(&op2->type_entry->name)));960 buf_ptr(&op2->type_entry->name)));
999 return ira->codegen->builtin_types.entry_invalid;961 return ira->old_irb.codegen->builtin_types.entry_invalid;
1000 }962 }
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
1002 return resolved_type;967 return resolved_type;
1003}968}
1004969
...@@ -1041,6 +1006,8 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi...@@ -1041,6 +1006,8 @@ static TypeTableEntry *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructi
1041}1006}
10421007
1043static TypeTableEntry *ir_analyze_instruction_load_var(IrAnalyze *ira, IrInstructionLoadVar *load_var_instruction) {1008static 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);
1044 return load_var_instruction->var->type;1011 return load_var_instruction->var->type;
1045}1012}
10461013
...@@ -1073,35 +1040,52 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins...@@ -1073,35 +1040,52 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins
1073{1040{
1074 TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction);1041 TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction);
1075 instruction->type_entry = instruction_type;1042 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,1046 IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type);
1078 nullptr, instruction);
1079 return casted_instruction->type_entry;1047 return casted_instruction->type_entry;
1080}1048}
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{
1083 IrAnalyze ir_analyze_data = {};1055 IrAnalyze ir_analyze_data = {};
1084 IrAnalyze *ira = &ir_analyze_data;1056 IrAnalyze *ira = &ir_analyze_data;
1085 ira->codegen = codegen;1057 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
1088 TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void;1068 TypeTableEntry *return_type = ira->codegen->builtin_types.entry_void;
10891069
1090 for (size_t i = 0; i < executable->basic_block_count; i += 1) {1070 ira->new_irb.current_basic_block = allocate<IrBasicBlock>(1);
1091 ira->current_basic_block = executable->basic_block_list[i];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;1073 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(0);
1094 instruction = instruction->next)1074
1095 {1075 ira->new_irb.current_basic_block->other = ira->old_irb.current_basic_block;
1096 if (return_type->id == TypeTableEntryIdUnreachable) {1076 ira->old_irb.current_basic_block->other = ira->new_irb.current_basic_block;
1097 add_node_error(ira->codegen, first_executing_node(instruction->source_node),1077
1098 buf_sprintf("unreachable code"));1078
1099 break;1079 for (size_t i = 0; i < ira->old_irb.current_basic_block->instruction_list.length; i += 1) {
1100 }1080 IrInstruction *instruction = ira->old_irb.current_basic_block->instruction_list.at(i);
1101 bool is_last = (instruction == ira->current_basic_block->last);1081 if (return_type->id == TypeTableEntryIdUnreachable) {
1102 TypeTableEntry *passed_expected_type = is_last ? expected_type : nullptr;1082 add_node_error(ira->codegen, first_executing_node(instruction->source_node),
1103 return_type = ir_analyze_instruction(ira, instruction, passed_expected_type);1083 buf_sprintf("unreachable code"));
1084 break;
1104 }1085 }
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);
1105 }1089 }
11061090
1107 return return_type;1091 return return_type;
src/ir.hpp+2-1
...@@ -13,6 +13,7 @@...@@ -13,6 +13,7 @@
13IrInstruction *ir_gen(CodeGen *g, AstNode *node, BlockContext *scope, IrExecutable *ir_executable);13IrInstruction *ir_gen(CodeGen *g, AstNode *node, BlockContext *scope, IrExecutable *ir_executable);
14IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);14IrInstruction *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
18#endif19#endif
src/ir_print.cpp+4-5
...@@ -173,11 +173,10 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {...@@ -173,11 +173,10 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
173 irp->indent = indent_size;173 irp->indent = indent_size;
174 irp->indent_size = indent_size;174 irp->indent_size = indent_size;
175175
176 for (size_t i = 0; i < executable->basic_block_count; i += 1) {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[i];177 IrBasicBlock *current_block = executable->basic_block_list.at(bb_i);
178 for (IrInstruction *instruction = current_block->first; instruction != nullptr;178 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
179 instruction = instruction->next)179 IrInstruction *instruction = current_block->instruction_list.at(instr_i);
180 {
181 ir_print_instruction(irp, instruction);180 ir_print_instruction(irp, instruction);
182 }181 }
183 }182 }