Commit 4ea421f8cb

Andrew Kelley <andrew@ziglang.org>
2021-05-28 06:01:03
stage1: move the ZigFn from Stage1Zir to Stage1AstGen
Part of an effort to make Stage1Zir immutable.
1 parent 42f4ee0
src/stage1/all_types.hpp
@@ -114,7 +114,6 @@ struct Stage1Zir {
     ZigList<IrBasicBlockSrc *> basic_block_list;
     Buf *name;
     ZigFn *name_fn;
-    ZigFn *fn_entry;
     Buf *c_import_buf;
     AstNode *source_node;
     Scope *begin_scope;
@@ -135,7 +134,6 @@ struct Stage1Air {
     ZigFn *name_fn;
     size_t mem_slot_count;
     size_t next_debug_id;
-    ZigFn *fn_entry;
     Buf *c_import_buf;
     AstNode *source_node;
     Stage1Air *parent_exec;
src/stage1/analyze.cpp
@@ -3654,9 +3654,6 @@ static void get_fully_qualified_decl_name(CodeGen *g, Buf *buf, Tld *tld, bool i
 static ZigFn *create_fn_raw(CodeGen *g, bool is_noinline) {
     ZigFn *fn_entry = heap::c_allocator.create<ZigFn>();
     fn_entry->ir_executable = heap::c_allocator.create<Stage1Zir>();
-
-    fn_entry->analyzed_executable.fn_entry = fn_entry;
-    fn_entry->ir_executable->fn_entry = fn_entry;
     fn_entry->is_noinline = is_noinline;
 
     return fn_entry;
@@ -5134,7 +5131,7 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
     size_t backward_branch_quota = max(fn->branch_quota, default_backward_branch_quota);
     ZigType *block_return_type = ir_analyze(g, fn->ir_executable, &fn->analyzed_executable,
             &backward_branch_count, &backward_branch_quota,
-            fn_type_id->return_type, return_type_node, nullptr);
+            fn_type_id->return_type, return_type_node, nullptr, fn);
     fn->src_implicit_return_type = block_return_type;
 
     if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {
@@ -5231,7 +5228,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
     ZigType *fn_type = fn_table_entry->type_entry;
     assert(!fn_type->data.fn.is_generic);
 
-    if (!ir_gen_fn(g, fn_table_entry)) {
+    if (!stage1_astgen_fn(g, fn_table_entry)) {
         fn_table_entry->anal_state = FnAnalStateInvalid;
         return;
     }
src/stage1/astgen.cpp
@@ -17,6 +17,7 @@ struct Stage1AstGen {
     IrBasicBlockSrc *current_basic_block;
     AstNode *main_block_node;
     size_t next_debug_id;
+    ZigFn *fn;
 };
 
 static IrInstSrc *ir_gen_node(Stage1AstGen *ag, AstNode *node, Scope *scope);
@@ -368,10 +369,6 @@ static size_t irb_next_debug_id(Stage1AstGen *ag) {
     return result;
 }
 
-static ZigFn *exec_fn_entry(Stage1Zir *exec) {
-    return exec->fn_entry;
-}
-
 static Buf *exec_c_import_buf(Stage1Zir *exec) {
     return exec->c_import_buf;
 }
@@ -3043,7 +3040,7 @@ static IrInstSrc *ir_gen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, L
                 if (expr_node) {
                     // Temporarily set this so that if we return a type it gets the name of the function
                     ZigFn *prev_name_fn = ag->exec->name_fn;
-                    ag->exec->name_fn = exec_fn_entry(ag->exec);
+                    ag->exec->name_fn = ag->fn;
                     return_value = ir_gen_node_extra(ag, expr_node, scope, LValNone, &result_loc_ret->base);
                     ag->exec->name_fn = prev_name_fn;
                     if (return_value == ag->codegen->invalid_inst_src)
@@ -4771,8 +4768,9 @@ static IrInstSrc *ir_gen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, AstNode
         case BuiltinFnIdFrameAddress:
             return ir_lval_wrap(ag, scope, ir_build_frame_address_src(ag, scope, node), lval, result_loc);
         case BuiltinFnIdFrameHandle:
-            if (!ag->exec->fn_entry) {
-                add_node_error(ag->codegen, node, buf_sprintf("@frame() called outside of function definition"));
+            if (ag->fn == nullptr) {
+                add_node_error(ag->codegen, node,
+                        buf_sprintf("@frame() called outside of function definition"));
                 return ag->codegen->invalid_inst_src;
             }
             return ir_lval_wrap(ag, scope, ir_build_handle_src(ag, scope, node), lval, result_loc);
@@ -7700,8 +7698,7 @@ static IrInstSrc *ir_gen_await_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
         }
     }
 
-    ZigFn *fn_entry = exec_fn_entry(ag->exec);
-    if (!fn_entry) {
+    if (!ag->fn) {
         add_node_error(ag->codegen, node, buf_sprintf("await outside function definition"));
         return ag->codegen->invalid_inst_src;
     }
@@ -7726,8 +7723,7 @@ static IrInstSrc *ir_gen_await_expr(Stage1AstGen *ag, Scope *scope, AstNode *nod
 static IrInstSrc *ir_gen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
     assert(node->type == NodeTypeSuspend);
 
-    ZigFn *fn_entry = exec_fn_entry(ag->exec);
-    if (!fn_entry) {
+    if (!ag->fn) {
         add_node_error(ag->codegen, node, buf_sprintf("suspend outside function definition"));
         return ag->codegen->invalid_inst_src;
     }
@@ -8019,7 +8015,7 @@ static IrInstSrc *ir_gen_node_extra(Stage1AstGen *ag, AstNode *node, Scope *scop
     }
     Scope *child_scope;
     if (ag->exec->is_inline ||
-        (ag->exec->fn_entry != nullptr && ag->exec->fn_entry->child_scope == scope))
+        (ag->fn != nullptr && ag->fn->child_scope == scope))
     {
         child_scope = scope;
     } else {
@@ -8038,13 +8034,16 @@ static IrInstSrc *ir_gen_node(Stage1AstGen *ag, AstNode *node, Scope *scope) {
     return ir_gen_node_extra(ag, node, scope, LValNone, nullptr);
 }
 
-bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *ir_executable) {
+bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *ir_executable,
+        ZigFn *fn)
+{
     assert(node->owner);
 
     Stage1AstGen ir_builder = {0};
     Stage1AstGen *ag = &ir_builder;
 
     ag->codegen = codegen;
+    ag->fn = fn;
     ag->exec = ir_executable;
     ag->main_block_node = node;
 
@@ -8076,15 +8075,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *ir_executa
     return true;
 }
 
-bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
-    assert(fn_entry);
-
-    Stage1Zir *ir_executable = fn_entry->ir_executable;
-    AstNode *body_node = fn_entry->body_node;
-
-    assert(fn_entry->child_scope);
-
-    return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
+bool stage1_astgen_fn(CodeGen *codegen, ZigFn *fn) {
+    assert(fn != nullptr);
+    assert(fn->child_scope != nullptr);
+    return stage1_astgen(codegen, fn->body_node, fn->child_scope, fn->ir_executable, fn);
 }
 
 void invalidate_exec(Stage1Zir *exec, ErrorMsg *msg) {
src/stage1/astgen.hpp
@@ -10,8 +10,8 @@
 
 #include "all_types.hpp"
 
-bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, Stage1Zir *ir_executable);
-bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
+bool stage1_astgen(CodeGen *g, AstNode *node, Scope *scope, Stage1Zir *ir_executable, ZigFn *fn);
+bool stage1_astgen_fn(CodeGen *g, ZigFn *fn_entry);
 
 bool ir_inst_src_has_side_effects(IrInstSrc *inst);
 
src/stage1/ir.cpp
@@ -49,6 +49,7 @@ struct IrAnalyze {
     Stage1Air *parent_exec;
     size_t *backward_branch_count;
     size_t *backward_branch_quota;
+    ZigFn *fn;
 
     // For the purpose of using in a debugger
     void dump();
@@ -4259,7 +4260,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
                     continue;
                 }
                 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
-                        cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                    cur_type->data.error_set.infer_fn == ira->fn;
                 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
                     return ira->codegen->builtin_types.entry_invalid;
                 }
@@ -4327,7 +4328,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
                 }
                 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
                 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
-                    cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                    cur_err_set_type->data.error_set.infer_fn == ira->fn;
                 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
                     return ira->codegen->builtin_types.entry_invalid;
                 }
@@ -4382,7 +4383,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
 
         if (cur_type->id == ZigTypeIdErrorSet) {
             bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
-                    cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                    cur_type->data.error_set.infer_fn == ira->fn;
             if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
                 return ira->codegen->builtin_types.entry_invalid;
             }
@@ -4401,7 +4402,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
                 if (prev_type->id == ZigTypeIdErrorUnion) {
                     err_set_type = prev_type->data.error_union.err_set_type;
                     allow_infer = err_set_type->data.error_set.infer_fn != nullptr &&
-                        err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                        err_set_type->data.error_set.infer_fn == ira->fn;
                 } else {
                     err_set_type = cur_type;
                 }
@@ -4465,9 +4466,9 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
                     continue;
 
                 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr &&
-                        prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                        prev_err_set_type->data.error_set.infer_fn == ira->fn;
                 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr &&
-                        cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                        cur_err_set_type->data.error_set.infer_fn == ira->fn;
 
                 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) {
                     return ira->codegen->builtin_types.entry_invalid;
@@ -4651,7 +4652,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
             if (err_set_type != nullptr) {
                 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
                 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
-                    cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
+                    cur_err_set_type->data.error_set.infer_fn == ira->fn;
                 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
                     return ira->codegen->builtin_types.entry_invalid;
                 }
@@ -5595,11 +5596,10 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
     ir_executable->source_node = source_node;
     ir_executable->name = exec_name;
     ir_executable->is_inline = true;
-    ir_executable->fn_entry = fn_entry;
     ir_executable->c_import_buf = c_import_buf;
     ir_executable->begin_scope = scope;
 
-    if (!ir_gen(codegen, node, scope, ir_executable))
+    if (!stage1_astgen(codegen, node, scope, ir_executable, fn_entry))
         return ErrorSemanticAnalyzeFail;
 
     if (ir_executable->first_err_trace_msg != nullptr) {
@@ -5618,12 +5618,12 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
     analyzed_executable->source_exec = ir_executable;
     analyzed_executable->name = exec_name;
     analyzed_executable->is_inline = true;
-    analyzed_executable->fn_entry = fn_entry;
     analyzed_executable->c_import_buf = c_import_buf;
     analyzed_executable->begin_scope = scope;
     ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable,
             backward_branch_count, backward_branch_quota,
-            return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr);
+            return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr,
+            fn_entry);
     if (type_is_invalid(result_type)) {
         return ErrorSemanticAnalyzeFail;
     }
@@ -11025,7 +11025,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
         return ira->codegen->invalid_inst_gen;
     }
 
-    ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *fn_entry = ira->fn;
     if (fn_entry)
         fn_entry->variable_list.append(var);
 
@@ -11421,9 +11421,9 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern
             is_thread_local, expr_type);
 }
 
-static bool exec_has_err_ret_trace(CodeGen *g, Stage1Zir *exec) {
-    ZigFn *fn_entry = exec->fn_entry;
-    return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing;
+static bool ira_has_err_ret_trace(IrAnalyze *ira) {
+    ZigFn *fn = ira->fn;
+    return fn != nullptr && fn->calls_or_awaits_errorable_fn && ira->codegen->have_err_ret_tracing;
 }
 
 static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
@@ -11432,7 +11432,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
     ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false);
     if (instruction->optional == IrInstErrorReturnTraceNull) {
         ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type);
-        if (!exec_has_err_ret_trace(ira->codegen, ira->zir)) {
+        if (!ira_has_err_ret_trace(ira)) {
             IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type);
             ZigValue *out_val = result->value;
             assert(get_src_ptr_type(optional_type) != nullptr);
@@ -11504,7 +11504,7 @@ static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType
             PtrLenSingle, align, 0, 0, false);
 
     if (!force_comptime) {
-        ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+        ZigFn *fn_entry = ira->fn;
         if (fn_entry != nullptr) {
             fn_entry->alloca_gen_list.append(result);
         }
@@ -11603,7 +11603,7 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
     alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
             PtrLenSingle, 0, 0, 0, false);
     set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base);
-    ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *fn_entry = ira->fn;
     if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
         fn_entry->alloca_gen_list.append(alloca_gen);
     }
@@ -12131,7 +12131,7 @@ static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSr
     if (result_loc != nullptr)
         return result_loc;
 
-    ZigFn *fn = ira->new_irb.exec->fn_entry;
+    ZigFn *fn = ira->fn;
     if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync &&
             instruction->result_loc->id == ResultLocIdReturn)
     {
@@ -12849,7 +12849,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
             }
         }
 
-        ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;
+        ZigFn *parent_fn_entry = ira->fn;
         assert(parent_fn_entry);
         for (size_t call_i = 0; call_i < args_len; call_i += 1) {
             IrInstGen *arg = args_ptr[call_i];
@@ -13017,7 +13017,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
         return ir_finish_anal(ira, &new_call_instruction->base);
     }
 
-    ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *parent_fn_entry = ira->fn;
     assert(fn_type_id->return_type != nullptr);
     assert(parent_fn_entry != nullptr);
     if (fn_type_can_fail(fn_type_id)) {
@@ -21069,7 +21069,7 @@ static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrc
 }
 
 static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) {
-    ZigFn *fn = ira->new_irb.exec->fn_entry;
+    ZigFn *fn = ira->fn;
     ir_assert(fn != nullptr, &instruction->base.base);
 
     if (fn->inferred_async_node == nullptr) {
@@ -22932,7 +22932,7 @@ static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstS
         return ira->codegen->invalid_inst_gen;
     }
 
-    ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *fn_entry = ira->fn;
     if (fn_entry == nullptr) {
         ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function"));
         return ira->codegen->invalid_inst_gen;
@@ -23952,7 +23952,7 @@ static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSr
     ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base);
     IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base);
 
-    ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *fn_entry = ira->fn;
     ir_assert(fn_entry != nullptr, &instruction->base.base);
 
     if (fn_entry->inferred_async_node == nullptr) {
@@ -24019,7 +24019,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
 
     ZigType *result_type = frame->value->type->data.any_frame.result_type;
 
-    ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
+    ZigFn *fn_entry = ira->fn;
     ir_assert(fn_entry != nullptr, &instruction->base.base);
 
     // If it's not @Frame(func) then it's definitely a suspend point
@@ -24465,16 +24465,17 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
     zig_unreachable();
 }
 
-// This function attempts to evaluate IR code while doing type checking and other analysis.
+// This function attempts to evaluate stage1 ZIR code while doing type checking and other analysis.
 // It emits to a new Stage1Air which is partially evaluated IR code.
 ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
         size_t *backward_branch_count, size_t *backward_branch_quota,
-        ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr)
+        ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr, ZigFn *fn)
 {
     assert(stage1_zir->first_err_trace_msg == nullptr);
     assert(expected_type == nullptr || !type_is_invalid(expected_type));
 
     IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>();
+    ira->fn = fn;
     ira->backward_branch_count = backward_branch_count;
     ira->backward_branch_quota = backward_branch_quota;
     ira->ref_count = 1;
src/stage1/ir.hpp
@@ -22,10 +22,10 @@ Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val);
 
 ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
         size_t *backward_branch_count, size_t *backward_branch_quota,
-        ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr);
+        ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr,
+        ZigFn *fn);
 
 bool ir_inst_gen_has_side_effects(IrInstGen *inst);
-bool ir_inst_src_has_side_effects(IrInstSrc *inst);
 
 struct IrAnalyze;
 ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
src/stage1/ir_print.cpp
@@ -8,6 +8,7 @@
 #include "all_types.hpp"
 #include "analyze.hpp"
 #include "ir.hpp"
+#include "astgen.hpp"
 #include "ir_print.hpp"
 #include "os.hpp"