Browse Source

Fix minimal dependency for nested entities

Ginger Bill 9 years ago
parent
commit
f6bbd8a4c2
5 changed files with 66 additions and 93 deletions
  1. 3 0
      code/demo.odin
  2. 4 1
      src/checker/checker.cpp
  3. 9 6
      src/checker/stmt.cpp
  4. 3 1
      src/checker/type.cpp
  5. 47 85
      src/codegen/ssa.cpp

+ 3 - 0
code/demo.odin

@@ -1,5 +1,8 @@
 #import "fmt.odin"
+#import "game.odin"
 
 main :: proc() {
 	fmt.println("Hello")
+	game.run()
+
 }

+ 4 - 1
src/checker/checker.cpp

@@ -447,7 +447,10 @@ void add_dependency(DeclInfo *d, Entity *e) {
 }
 
 void add_declaration_dependency(Checker *c, Entity *e) {
-	if (c->context.decl) {
+	if (e == NULL) {
+		return;
+	}
+	if (c->context.decl != NULL) {
 		auto found = map_get(&c->info.entities, hash_pointer(e));
 		if (found) {
 			add_dependency(c->context.decl, e);

+ 9 - 6
src/checker/stmt.cpp

@@ -33,13 +33,14 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
 
 				Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
 				e->identifier = name;
-				add_entity(c, e->scope, name, e);
 
-				DeclInfo *di = make_declaration_info(c->allocator, e->scope);
-				di->type_expr = cd->type;
-				di->init_expr = value;
+				DeclInfo *d = make_declaration_info(c->allocator, e->scope);
+				d->type_expr = cd->type;
+				d->init_expr = value;
 
-				Delay delay = {e, di};
+				add_entity_and_decl_info(c, name, e, d);
+
+				Delay delay = {e, d};
 				gb_array_append(delayed_const, delay);
 			}
 
@@ -61,6 +62,8 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
 			DeclInfo *d = make_declaration_info(c->allocator, e->scope);
 			d->type_expr = td->type;
 
+			add_entity_and_decl_info(c, td->name, e, d);
+
 			Delay delay = {e, d};
 			gb_array_append(delayed_type, delay);
 		case_end;
@@ -1531,11 +1534,11 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		// e.g. using
 		Entity *e = make_entity_procedure(c->allocator, c->context.scope, pd->name->Ident, NULL);
 		e->identifier = pd->name;
-		add_entity(c, c->context.scope, pd->name, e);
 
 		DeclInfo *d = make_declaration_info(c->allocator, e->scope);
 		d->proc_decl = node;
 
+		add_entity_and_decl_info(c, pd->name, e, d);
 		check_entity_decl(c, e, d, NULL);
 	case_end;
 

+ 3 - 1
src/checker/type.cpp

@@ -499,6 +499,7 @@ b32 is_type_u8_slice(Type *t) {
 	return false;
 }
 b32 is_type_vector(Type *t) {
+	t = base_type(t);
 	return t->kind == Type_Vector;
 }
 b32 is_type_proc(Type *t) {
@@ -507,7 +508,8 @@ b32 is_type_proc(Type *t) {
 }
 Type *base_vector_type(Type *t) {
 	if (is_type_vector(t)) {
-		return base_type(t)->Vector.elem;
+		t = base_type(t);
+		return t->Vector.elem;
 	}
 	return t;
 }

+ 47 - 85
src/codegen/ssa.cpp

@@ -1023,9 +1023,7 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *b
 	isize i = count;
 	while (i --> 0) {
 		ssaDefer d = proc->defer_stmts[i];
-		if (kind == ssaDeferExit_Return) {
-			ssa_build_defer_stmt(proc, d);
-		} else if (kind == ssaDeferExit_Default) {
+		if (kind == ssaDeferExit_Default) {
 			if (proc->scope_index == d.scope_index &&
 			    d.scope_index > 1) {
 				ssa_build_defer_stmt(proc, d);
@@ -1034,6 +1032,8 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *b
 			} else {
 				break;
 			}
+		} else if (kind == ssaDeferExit_Return) {
+			ssa_build_defer_stmt(proc, d);
 		} else if (kind == ssaDeferExit_Branch) {
 			GB_ASSERT(block != NULL);
 			isize lower_limit = block->scope_index+1;
@@ -1044,6 +1044,17 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *b
 	}
 }
 
+void ssa_open_scope(ssaProcedure *proc) {
+	proc->scope_index++;
+}
+
+
+void ssa_close_scope(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *block) {
+	ssa_emit_defer_stmts(proc, kind, block);
+	GB_ASSERT(proc->scope_index > 0);
+	proc->scope_index--;
+}
+
 
 
 
@@ -2985,8 +2996,9 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
 
 void ssa_build_assign_op(ssaProcedure *proc, ssaAddr lhs, ssaValue *value, Token op) {
 	ssaValue *old_value = ssa_lvalue_load(proc, lhs);
-	ssaValue *change = ssa_emit_conv(proc, value, ssa_type(old_value));
-	ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, ssa_type(old_value));
+	Type *type = ssa_type(old_value);
+	ssaValue *change = ssa_emit_conv(proc, value, type);
+	ssaValue *new_value = ssa_emit_arith(proc, op, old_value, change, type);
 	ssa_lvalue_store(proc, lhs, new_value);
 }
 
@@ -3112,35 +3124,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
 		defer (gb_temp_arena_memory_end(tmp));
 
-		if (gb_array_count(vd->names) == gb_array_count(vd->values)) { // 1:1 assigment
-			gbArray(ssaAddr)  lvals;
-			gbArray(ssaValue *) inits;
-			gb_array_init_reserve(lvals, m->tmp_allocator, gb_array_count(vd->names));
-			gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(vd->names));
-
-			gb_for_array(i, vd->names) {
-				AstNode *name = vd->names[i];
-				ssaAddr lval = ssa_make_addr(NULL, NULL);
-				if (!ssa_is_blank_ident(name)) {
-					ssa_add_local_for_identifier(proc, name, false);
-					lval = ssa_build_addr(proc, name);
-					GB_ASSERT(lval.addr != NULL);
-				}
-
-				gb_array_append(lvals, lval);
-			}
-			gb_for_array(i, vd->values) {
-				ssaValue *init = ssa_build_expr(proc, vd->values[i]);
-				gb_array_append(inits, init);
-			}
-
-
-			gb_for_array(i, inits) {
-				ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_addr_type(lvals[i]));
-				ssa_lvalue_store(proc, lvals[i], v);
-			}
-
-		} else if (gb_array_count(vd->values) == 0) { // declared and zero-initialized
+		if (gb_array_count(vd->values) == 0) { // declared and zero-initialized
 			gb_for_array(i, vd->names) {
 				AstNode *name = vd->names[i];
 				if (!ssa_is_blank_ident(name)) {
@@ -3372,17 +3356,17 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 	case_end;
 
 	case_ast_node(bs, BlockStmt, node);
-		proc->scope_index++;
+		ssa_open_scope(proc);
 		ssa_build_stmt_list(proc, bs->stmts);
-		ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
-		proc->scope_index--;
+		ssa_close_scope(proc, ssaDeferExit_Default, NULL);
 	case_end;
 
 	case_ast_node(ds, DeferStmt, node);
 		ssa_emit_comment(proc, make_string("DeferStmt"));
 		isize scope_index = proc->scope_index;
-		if (ds->stmt->kind == AstNode_BlockStmt)
+		if (ds->stmt->kind == AstNode_BlockStmt) {
 			scope_index--;
+		}
 		ssa_add_defer_node(proc, scope_index, ds->stmt);
 	case_end;
 
@@ -3391,7 +3375,12 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		ssaValue *v = NULL;
 		auto *return_type_tuple  = &proc->type->Proc.results->Tuple;
 		isize return_count = proc->type->Proc.result_count;
-		if (gb_array_count(rs->results) < return_count) {
+		if (return_count == 0) {
+			// No return values
+		} else if (return_count == 1) {
+			Entity *e = return_type_tuple->variables[0];
+			v = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[0]), e->type);
+		} else {
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 			defer (gb_temp_arena_memory_end(tmp));
 
@@ -3423,22 +3412,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 			v = ssa_emit_load(proc, v);
 
-		} else if (return_count == 1) {
-			Entity *e = return_type_tuple->variables[0];
-			v = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[0]), e->type);
-		} else if (return_count == 0) {
-			// No return values
-		} else {
-			// 1:1 multiple return values
-			Type *ret_type = proc->type->Proc.results;
-			v = ssa_add_local_generated(proc, ret_type);
-			gb_for_array(i, rs->results) {
-				Entity *e = return_type_tuple->variables[i];
-				ssaValue *res = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[i]), e->type);
-				ssaValue *field = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, e->type));
-				ssa_emit_store(proc, field, res);
-			}
-			v = ssa_emit_load(proc, v);
 		}
 		ssa_emit_ret(proc, v);
 
@@ -3462,20 +3435,18 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		ssa_build_cond(proc, is->cond, then, else_);
 		proc->curr_block = then;
 
-		proc->scope_index++;
+		ssa_open_scope(proc);
 		ssa_build_stmt(proc, is->body);
-		ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
-		proc->scope_index--;
+		ssa_close_scope(proc, ssaDeferExit_Default, NULL);
 
 		ssa_emit_jump(proc, done);
 
 		if (is->else_stmt != NULL) {
 			proc->curr_block = else_;
 
-			proc->scope_index++;
+			ssa_open_scope(proc);
 			ssa_build_stmt(proc, is->else_stmt);
-			ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
-			proc->scope_index--;
+			ssa_close_scope(proc, ssaDeferExit_Default, NULL);
 
 			ssa_emit_jump(proc, done);
 		}
@@ -3513,10 +3484,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 		ssa_push_target_list(proc, done, cont, NULL);
 
-		proc->scope_index++;
+		ssa_open_scope(proc);
 		ssa_build_stmt(proc, fs->body);
-		ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
-		proc->scope_index--;
+		ssa_close_scope(proc, ssaDeferExit_Default, NULL);
 
 		ssa_pop_target_list(proc);
 		ssa_emit_jump(proc, cont);
@@ -3606,13 +3576,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			}
 			proc->curr_block = body;
 
-			// TODO(bill): Handle fallthrough scope exit correctly
-			proc->scope_index++;
 			ssa_push_target_list(proc, done, NULL, fall);
+			ssa_open_scope(proc);
 			ssa_build_stmt_list(proc, cc->stmts);
-			ssa_emit_defer_stmts(proc, ssaDeferExit_Default, body);
+			ssa_close_scope(proc, ssaDeferExit_Default, body);
 			ssa_pop_target_list(proc);
-			proc->scope_index--;
 
 			ssa_emit_jump(proc, done);
 			proc->curr_block = next_cond;
@@ -3623,13 +3591,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			gb_array_append(proc->blocks, default_block);
 			proc->curr_block = default_block;
 
-			// TODO(bill): Handle fallthrough scope exit correctly
-			proc->scope_index++;
 			ssa_push_target_list(proc, done, NULL, default_fall);
+			ssa_open_scope(proc);
 			ssa_build_stmt_list(proc, default_stmts);
-			ssa_emit_defer_stmts(proc, ssaDeferExit_Default, default_block);
+			ssa_close_scope(proc, ssaDeferExit_Default, default_block);
 			ssa_pop_target_list(proc);
-			proc->scope_index--;
 		}
 
 		ssa_emit_jump(proc, done);
@@ -3681,7 +3647,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 			ssaBlock *body = ssa__make_block(proc, clause, make_string("type-match.case.body"));
 
-
 			Scope *scope = *map_get(&proc->module->info->scopes, hash_pointer(clause));
 			Entity *tag_var_entity = current_scope_lookup_entity(scope, tag_var_name);
 			GB_ASSERT_MSG(tag_var_entity != NULL, "%.*s", LIT(tag_var_name));
@@ -3714,12 +3679,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			gb_array_append(proc->blocks, body);
 			proc->curr_block = body;
 
-			proc->scope_index++;
 			ssa_push_target_list(proc, done, NULL, NULL);
+			ssa_open_scope(proc);
 			ssa_build_stmt_list(proc, cc->stmts);
-			ssa_emit_defer_stmts(proc, ssaDeferExit_Default, body);
+			ssa_close_scope(proc, ssaDeferExit_Default, body);
 			ssa_pop_target_list(proc);
-			proc->scope_index--;
 
 			ssa_emit_jump(proc, done);
 			proc->curr_block = next_cond;
@@ -3730,12 +3694,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 			gb_array_append(proc->blocks, default_block);
 			proc->curr_block = default_block;
 
-			proc->scope_index++;
 			ssa_push_target_list(proc, done, NULL, NULL);
+			ssa_open_scope(proc);
 			ssa_build_stmt_list(proc, default_stmts);
-			ssa_emit_defer_stmts(proc, ssaDeferExit_Default, default_block);
+			ssa_close_scope(proc, ssaDeferExit_Default, default_block);
 			ssa_pop_target_list(proc);
-			proc->scope_index--;
 		}
 
 		ssa_emit_jump(proc, done);
@@ -3780,8 +3743,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 	case_ast_node(pa, PushAllocator, node);
 		ssa_emit_comment(proc, make_string("PushAllocator"));
-		proc->scope_index++;
-		defer (proc->scope_index--);
+		ssa_open_scope(proc);
+		defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
 
 		ssaValue *context_ptr = *map_get(&proc->module->members, hash_string(make_string("__context")));
 		ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
@@ -3793,14 +3756,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		ssa_emit_store(proc, gep, ssa_build_expr(proc, pa->expr));
 
 		ssa_build_stmt(proc, pa->body);
-		ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
+
 	case_end;
 
 
 	case_ast_node(pa, PushContext, node);
 		ssa_emit_comment(proc, make_string("PushContext"));
-		proc->scope_index++;
-		defer (proc->scope_index--);
+		ssa_open_scope(proc);
+		defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
 
 		ssaValue *context_ptr = *map_get(&proc->module->members, hash_string(make_string("__context")));
 		ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
@@ -3811,7 +3774,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		ssa_emit_store(proc, context_ptr, ssa_build_expr(proc, pa->expr));
 
 		ssa_build_stmt(proc, pa->body);
-		ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
 	case_end;