authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-06 22:04:55-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-06 22:04:55-05:00
log7d9fa01ed54e99368f7351dbf1193e4f79ddf806
tree4f2789735a05170bb9ad83bb7fc13a22bd63f6ea
parent6ed202ab16f42d73975e8a4508698857300c1b6f

IR: implement compile time eval unwrap maybe


4 files changed, 35 insertions(+), 6 deletions(-)

src/analyze.cpp+3-1
...@@ -875,7 +875,9 @@ TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) {...@@ -875,7 +875,9 @@ TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) {
875875
876static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry) {876static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry) {
877 size_t backward_branch_count = 0;877 size_t backward_branch_count = 0;
878 return ir_eval_const_value(g, scope, node, type_entry, &backward_branch_count, default_backward_branch_quota);878 return ir_eval_const_value(g, scope, node, type_entry,
879 &backward_branch_count, default_backward_branch_quota,
880 nullptr);
879}881}
880882
881TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {883TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
src/ir.cpp+20-4
...@@ -3379,10 +3379,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value) {...@@ -3379,10 +3379,12 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value) {
3379}3379}
33803380
3381IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,3381IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
3382 TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota)3382 TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
3383 FnTableEntry *fn_entry)
3383{3384{
3384 IrExecutable ir_executable = {0};3385 IrExecutable ir_executable = {0};
3385 ir_executable.is_inline = true;3386 ir_executable.is_inline = true;
3387 ir_executable.fn_entry = fn_entry;
3386 ir_gen(codegen, node, scope, &ir_executable);3388 ir_gen(codegen, node, scope, &ir_executable);
33873389
3388 if (ir_executable.invalid)3390 if (ir_executable.invalid)
...@@ -3397,6 +3399,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node...@@ -3397,6 +3399,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
3397 }3399 }
3398 IrExecutable analyzed_executable = {0};3400 IrExecutable analyzed_executable = {0};
3399 analyzed_executable.is_inline = true;3401 analyzed_executable.is_inline = true;
3402 analyzed_executable.fn_entry = fn_entry;
3400 analyzed_executable.backward_branch_count = backward_branch_count;3403 analyzed_executable.backward_branch_count = backward_branch_count;
3401 analyzed_executable.backward_branch_quota = backward_branch_quota;3404 analyzed_executable.backward_branch_quota = backward_branch_quota;
3402 TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node);3405 TypeTableEntry *result_type = ir_analyze(codegen, &ir_executable, &analyzed_executable, expected_type, node);
...@@ -4501,7 +4504,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -4501,7 +4504,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
4501 // Analyze the fn body block like any other constant expression.4504 // Analyze the fn body block like any other constant expression.
4502 AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body;4505 AstNode *body_node = fn_entry->fn_def_node->data.fn_def.body;
4503 IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,4506 IrInstruction *result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
4504 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota);4507 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry);
4505 if (result->type_entry->id == TypeTableEntryIdInvalid)4508 if (result->type_entry->id == TypeTableEntryIdInvalid)
4506 return ira->codegen->builtin_types.entry_invalid;4509 return ira->codegen->builtin_types.entry_invalid;
45074510
...@@ -4926,7 +4929,16 @@ static TypeTableEntry *ir_analyze_unwrap_maybe(IrAnalyze *ira, IrInstructionUnOp...@@ -4926,7 +4929,16 @@ static TypeTableEntry *ir_analyze_unwrap_maybe(IrAnalyze *ira, IrInstructionUnOp
4926 return type_entry;4929 return type_entry;
4927 } else if (type_entry->id == TypeTableEntryIdMaybe) {4930 } else if (type_entry->id == TypeTableEntryIdMaybe) {
4928 if (value->static_value.special != ConstValSpecialRuntime) {4931 if (value->static_value.special != ConstValSpecialRuntime) {
4929 zig_panic("TODO compile time eval unwrap maybe");4932 bool depends_on_compile_var = value->static_value.depends_on_compile_var;
4933 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, depends_on_compile_var);
4934 ConstExprValue *child_val = value->static_value.data.x_maybe;
4935 if (!child_val) {
4936 ir_add_error(ira, &un_op_instruction->base,
4937 buf_sprintf("unable to unwrap null"));
4938 return ira->codegen->builtin_types.entry_invalid;
4939 }
4940 *out_val = *child_val;
4941 return type_entry->data.maybe.child_type;
4930 }4942 }
4931 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, IrUnOpUnwrapMaybe, value);4943 ir_build_un_op_from(&ira->new_irb, &un_op_instruction->base, IrUnOpUnwrapMaybe, value);
4932 return type_entry->data.maybe.child_type;4944 return type_entry->data.maybe.child_type;
...@@ -6102,10 +6114,14 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,...@@ -6102,10 +6114,14 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
6102 assert(value->static_value.data.x_ptr.index == SIZE_MAX);6114 assert(value->static_value.data.x_ptr.index == SIZE_MAX);
61036115
6104 if (maybe_val->special != ConstValSpecialRuntime) {6116 if (maybe_val->special != ConstValSpecialRuntime) {
6117 if (!maybe_val->data.x_maybe) {
6118 ir_add_error(ira, &unwrap_maybe_instruction->base, buf_sprintf("unable to unwrap null"));
6119 return ira->codegen->builtin_types.entry_invalid;
6120 }
6105 bool depends_on_compile_var = maybe_val->depends_on_compile_var;6121 bool depends_on_compile_var = maybe_val->depends_on_compile_var;
6106 ConstExprValue *out_val = ir_build_const_from(ira, &unwrap_maybe_instruction->base,6122 ConstExprValue *out_val = ir_build_const_from(ira, &unwrap_maybe_instruction->base,
6107 depends_on_compile_var);6123 depends_on_compile_var);
6108 out_val->data.x_ptr.base_ptr = maybe_val;6124 out_val->data.x_ptr.base_ptr = maybe_val->data.x_maybe;
6109 out_val->data.x_ptr.index = SIZE_MAX;6125 out_val->data.x_ptr.index = SIZE_MAX;
6110 return result_type;6126 return result_type;
6111 }6127 }
src/ir.hpp+2-1
...@@ -14,7 +14,8 @@ IrInstruction *ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_...@@ -14,7 +14,8 @@ IrInstruction *ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_
14IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);14IrInstruction *ir_gen_fn(CodeGen *g, FnTableEntry *fn_entry);
1515
16IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,16IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
17 TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota);17 TypeTableEntry *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
18 FnTableEntry *fn_entry);
1819
19TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,20TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
20 TypeTableEntry *expected_type, AstNode *expected_type_source_node);21 TypeTableEntry *expected_type, AstNode *expected_type_source_node);
test/self_hosted2.zig+10
...@@ -194,6 +194,15 @@ entry:...@@ -194,6 +194,15 @@ entry:
194 if (b) goto exit;194 if (b) goto exit;
195}195}
196196
197fn unwrapAndAddOne(blah: ?i32) -> i32 {
198 return ??blah + 1;
199}
200
201const should_be_1235 = unwrapAndAddOne(1234);
202
203fn testStaticAddOne() {
204 assert(should_be_1235 == 1235);
205}
197206
198207
199fn assert(ok: bool) {208fn assert(ok: bool) {
...@@ -218,6 +227,7 @@ fn runAllTests() {...@@ -218,6 +227,7 @@ fn runAllTests() {
218 testContinueInForLoop();227 testContinueInForLoop();
219 shortCircuit();228 shortCircuit();
220 testGotoLeaveDeferScope(true);229 testGotoLeaveDeferScope(true);
230 testStaticAddOne();
221}231}
222232
223export nakedcc fn _start() -> unreachable {233export nakedcc fn _start() -> unreachable {