authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-27 01:52:06-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-10-27 01:52:06-04:00
log78e6314422bda10440dccf7e7fcfe294193cdca7
tree99fe95b73ebc28bd31e2ff08e06f96ea09919f88
parentbfcd6648e70bfe647b6fea9d6d9a024c4a9169d4

IR: phi instruction works at compile time


1 files changed, 34 insertions(+), 2 deletions(-)

src/ir.cpp+34-2
...@@ -26,6 +26,7 @@ struct IrAnalyze {...@@ -26,6 +26,7 @@ struct IrAnalyze {
26 size_t instruction_index;26 size_t instruction_index;
27 TypeTableEntry *explicit_return_type;27 TypeTableEntry *explicit_return_type;
28 ZigList<IrInstruction *> implicit_return_type_list;28 ZigList<IrInstruction *> implicit_return_type_list;
29 IrBasicBlock *const_predecessor_bb;
29};30};
3031
31static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);32static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, BlockContext *scope);
...@@ -397,6 +398,8 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr...@@ -397,6 +398,8 @@ static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instr
397398
398static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block) {399static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block) {
399 IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node);400 IrInstructionBr *br_instruction = ir_build_instruction<IrInstructionBr>(irb, source_node);
401 br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
402 br_instruction->base.static_value.ok = true;
400 br_instruction->dest_block = dest_block;403 br_instruction->dest_block = dest_block;
401404
402 ir_ref_bb(dest_block);405 ir_ref_bb(dest_block);
...@@ -1618,12 +1621,13 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -1618,12 +1621,13 @@ static void ir_finish_bb(IrAnalyze *ira) {
1618 ira->instruction_index = 0;1621 ira->instruction_index = 0;
1619 ira->new_irb.current_basic_block = ir_get_new_bb(ira, old_bb);1622 ira->new_irb.current_basic_block = ir_get_new_bb(ira, old_bb);
1620 ira->old_irb.current_basic_block = old_bb;1623 ira->old_irb.current_basic_block = old_bb;
1624 ira->const_predecessor_bb = nullptr;
1621 }1625 }
1622}1626}
16231627
1624static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {1628static void ir_inline_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
1625 ira->instruction_index = 0;1629 ira->instruction_index = 0;
16261630 ira->const_predecessor_bb = ira->old_irb.current_basic_block;
1627 ira->old_irb.current_basic_block = old_bb;1631 ira->old_irb.current_basic_block = old_bb;
1628}1632}
16291633
...@@ -2470,7 +2474,10 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -2470,7 +2474,10 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
24702474
2471 ir_build_call_from(&ira->new_irb, &call_instruction->base,2475 ir_build_call_from(&ira->new_irb, &call_instruction->base,
2472 call_instruction->fn, call_instruction->arg_count, call_instruction->args);2476 call_instruction->fn, call_instruction->arg_count, call_instruction->args);
2473 return fn_table_entry->type_entry;2477
2478 TypeTableEntry *fn_type = fn_table_entry->type_entry;
2479 TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;
2480 return return_type;
2474 } else {2481 } else {
2475 zig_panic("TODO analyze more fn call types");2482 zig_panic("TODO analyze more fn call types");
2476 }2483 }
...@@ -3946,6 +3953,24 @@ static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira,...@@ -3946,6 +3953,24 @@ static TypeTableEntry *ir_analyze_instruction_unreachable(IrAnalyze *ira,
3946}3953}
39473954
3948static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {3955static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
3956 if (ira->const_predecessor_bb) {
3957 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
3958 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
3959 if (predecessor != ira->const_predecessor_bb)
3960 continue;
3961 IrInstruction *value = phi_instruction->incoming_values[i]->other;
3962 assert(value->type_entry);
3963 if (value->static_value.ok) {
3964 ConstExprValue *out_val = ir_get_out_val(&phi_instruction->base);
3965 *out_val = value->static_value;
3966 } else {
3967 phi_instruction->base.other = value;
3968 }
3969 return value->type_entry;
3970 }
3971 zig_unreachable();
3972 }
3973
3949 ZigList<IrBasicBlock*> new_incoming_blocks = {0};3974 ZigList<IrBasicBlock*> new_incoming_blocks = {0};
3950 ZigList<IrInstruction*> new_incoming_values = {0};3975 ZigList<IrInstruction*> new_incoming_values = {0};
39513976
...@@ -4094,6 +4119,8 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins...@@ -4094,6 +4119,8 @@ static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *ins
4094{4119{
4095 TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction);4120 TypeTableEntry *instruction_type = ir_analyze_instruction_nocast(ira, instruction);
4096 instruction->type_entry = instruction_type;4121 instruction->type_entry = instruction_type;
4122 if (instruction->other)
4123 instruction->other->type_entry = instruction_type;
40974124
4098 IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type);4125 IrInstruction *casted_instruction = ir_get_casted_value(ira, instruction, expected_type);
4099 return casted_instruction->type_entry;4126 return casted_instruction->type_entry;
...@@ -4128,6 +4155,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl...@@ -4128,6 +4155,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
41284155
4129 while (ira->block_queue_index < ira->block_queue.length) {4156 while (ira->block_queue_index < ira->block_queue.length) {
4130 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);4157 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
4158 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) {
4159 ira->instruction_index += 1;
4160 continue;
4161 }
4162
4131 TypeTableEntry *return_type = ir_analyze_instruction(ira, old_instruction, nullptr);4163 TypeTableEntry *return_type = ir_analyze_instruction(ira, old_instruction, nullptr);
41324164
4133 // unreachable instructions do their own control flow.4165 // unreachable instructions do their own control flow.