Browse Source

Expose `runtime._startup_runtime` to allow for freestanding targets in the future

gingerBill 4 years ago
parent
commit
0cd681e6b7
4 changed files with 47 additions and 45 deletions
  1. 14 0
      core/runtime/core.odin
  2. 30 11
      src/ir.cpp
  3. 3 31
      src/llvm_backend.cpp
  4. 0 3
      src/llvm_backend.hpp

+ 14 - 0
core/runtime/core.odin

@@ -391,7 +391,21 @@ Map_Header :: struct {
 	value_size:    int,
 	value_size:    int,
 }
 }
 
 
+/////////////////////////////
+// Init Startup Procedures //
+/////////////////////////////
 
 
+// IMPORTANT NOTE(bill): Do not call this unless you want to explicitly set up the entry point and how it gets called
+// This is probably only useful for freestanding targets
+foreign {
+	@(link_name="__$startup_runtime")
+	_startup_runtime :: proc "contextless" () ---
+}
+
+
+/////////////////////////////
+/////////////////////////////
+/////////////////////////////
 
 
 
 
 type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
 type_info_base :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {

+ 30 - 11
src/ir.cpp

@@ -33,8 +33,6 @@ struct irModule {
 	i32                   global_array_index; // For ConstantSlice
 	i32                   global_array_index; // For ConstantSlice
 	i32                   global_generated_index;
 	i32                   global_generated_index;
 
 
-	irValue *             global_default_context;
-
 	// NOTE(bill): To prevent strings from being copied a lot
 	// NOTE(bill): To prevent strings from being copied a lot
 	// Mainly used for file names
 	// Mainly used for file names
 	StringMap<irValue *>  const_strings;
 	StringMap<irValue *>  const_strings;
@@ -179,6 +177,7 @@ gbAllocator ir_allocator(void) {
 }
 }
 
 
 
 
+#define IR_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
 #define IR_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
 #define IR_STARTUP_RUNTIME_PROC_NAME "__$startup_runtime"
 #define IR_TYPE_INFO_DATA_NAME       "__$type_info_data"
 #define IR_TYPE_INFO_DATA_NAME       "__$type_info_data"
 #define IR_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"
 #define IR_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"
@@ -3170,11 +3169,12 @@ irValue *ir_emit_comment(irProcedure *p, String text) {
 	return ir_emit(p, ir_instr_comment(p, text));
 	return ir_emit(p, ir_instr_comment(p, text));
 }
 }
 
 
-void ir_emit_init_context(irProcedure *proc, irValue *c = nullptr) {
+void ir_emit_init_context(irProcedure *proc, irValue *c) {
+	GB_ASSERT(c != nullptr);
 	irModule *m = proc->module;
 	irModule *m = proc->module;
 	gbAllocator a = ir_allocator();
 	gbAllocator a = ir_allocator();
 	auto args = array_make<irValue *>(a, 1);
 	auto args = array_make<irValue *>(a, 1);
-	args[0] = c ? c : m->global_default_context;
+	args[0] = c;
 	ir_emit_runtime_call(proc, "__init_context", args);
 	ir_emit_runtime_call(proc, "__init_context", args);
 }
 }
 
 
@@ -12442,9 +12442,6 @@ void ir_gen_tree(irGen *s) {
 		}
 		}
 	}
 	}
 
 
-	// Add global default context
-	m->global_default_context = ir_add_global_generated(m, t_context, nullptr);
-
 	struct irGlobalVariable {
 	struct irGlobalVariable {
 		irValue *var, *init;
 		irValue *var, *init;
 		DeclInfo *decl;
 		DeclInfo *decl;
@@ -12819,6 +12816,31 @@ void ir_gen_tree(irGen *s) {
 	}
 	}
 #endif
 #endif
 
 
+	irValue *startup_type_info = nullptr;
+	{  // Startup Type Info
+		// Cleanup(bill): probably better way of doing code insertion
+		String name = str_lit(IR_STARTUP_TYPE_INFO_PROC_NAME);
+		Type *proc_type = alloc_type_proc(gb_alloc_item(a, Scope),
+		                                  nullptr, 0,
+		                                  nullptr, 0, false,
+		                                  ProcCC_Contextless);
+		Ast *body = alloc_ast_node(nullptr, Ast_Invalid);
+		Entity *e = alloc_entity_procedure(nullptr, make_token_ident(name), proc_type, 0);
+		irValue *p = ir_value_procedure(m, e, proc_type, nullptr, body, name);
+		p->Proc.is_startup = true;
+		startup_type_info = p;
+
+		map_set(&m->values, hash_entity(e), p);
+		string_map_set(&m->members, name, p);
+
+		irProcedure *proc = &p->Proc;
+		proc->inlining = ProcInlining_no_inline; // TODO(bill): is no_inline a good idea?
+
+		ir_begin_procedure_body(proc);
+		ir_setup_type_info_data(proc);
+		ir_end_procedure_body(proc);
+	}
+
 	{ // Startup Runtime
 	{ // Startup Runtime
 		// Cleanup(bill): probably better way of doing code insertion
 		// Cleanup(bill): probably better way of doing code insertion
 		String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME);
 		String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME);
@@ -12841,10 +12863,7 @@ void ir_gen_tree(irGen *s) {
 		ir_begin_procedure_body(proc);
 		ir_begin_procedure_body(proc);
 		defer (ir_end_procedure_body(proc));
 		defer (ir_end_procedure_body(proc));
 
 
-		ir_emit_init_context(proc);
-
-		ir_setup_type_info_data(proc);
-
+		ir_emit_call(proc, startup_type_info, {}, ProcInlining_no_inline);
 
 
 		for_array(i, global_variables) {
 		for_array(i, global_variables) {
 			irGlobalVariable *var = &global_variables[i];
 			irGlobalVariable *var = &global_variables[i];

+ 3 - 31
src/llvm_backend.cpp

@@ -11850,9 +11850,6 @@ void lb_generate_code(lbGenerator *gen) {
 	arena_init(&temp_arena, heap_allocator());
 	arena_init(&temp_arena, heap_allocator());
 	gbAllocator temp_allocator = arena_allocator(&temp_arena);
 	gbAllocator temp_allocator = arena_allocator(&temp_arena);
 
 
-	gen->module.global_default_context = lb_add_global_generated(m, t_context, {});
-	gen->module.global_default_context.kind = lbAddr_Context;
-
 	auto *min_dep_set = &info->minimum_dependency_set;
 	auto *min_dep_set = &info->minimum_dependency_set;
 
 
 
 
@@ -12228,7 +12225,6 @@ void lb_generate_code(lbGenerator *gen) {
 	TIME_SECTION("LLVM Runtime Creation");
 	TIME_SECTION("LLVM Runtime Creation");
 
 
 	lbProcedure *startup_type_info = nullptr;
 	lbProcedure *startup_type_info = nullptr;
-	lbProcedure *startup_context = nullptr;
 	lbProcedure *startup_runtime = nullptr;
 	lbProcedure *startup_runtime = nullptr;
 	{ // Startup Type Info
 	{ // Startup Type Info
 		Type *params  = alloc_type_tuple();
 		Type *params  = alloc_type_tuple();
@@ -12255,31 +12251,6 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 		LLVMRunFunctionPassManager(default_function_pass_manager, p->value);
 		LLVMRunFunctionPassManager(default_function_pass_manager, p->value);
 	}
 	}
-	{ // Startup Context
-		Type *params  = alloc_type_tuple();
-		Type *results = alloc_type_tuple();
-
-		Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl);
-
-		lbProcedure *p = lb_create_dummy_procedure(m, str_lit(LB_STARTUP_CONTEXT_PROC_NAME), proc_type);
-		p->is_startup = true;
-		startup_context = p;
-
-		lb_begin_procedure_body(p);
-
-		lb_emit_init_context(p, p->module->global_default_context);
-
-		lb_end_procedure_body(p);
-
-		if (LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
-			gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
-			LLVMDumpValue(p->value);
-			gb_printf_err("\n\n\n\n");
-			LLVMVerifyFunction(p->value, LLVMAbortProcessAction);
-		}
-
-		LLVMRunFunctionPassManager(default_function_pass_manager, p->value);
-	}
 	{ // Startup Runtime
 	{ // Startup Runtime
 		Type *params  = alloc_type_tuple();
 		Type *params  = alloc_type_tuple();
 		Type *results = alloc_type_tuple();
 		Type *results = alloc_type_tuple();
@@ -12292,6 +12263,9 @@ void lb_generate_code(lbGenerator *gen) {
 
 
 		lb_begin_procedure_body(p);
 		lb_begin_procedure_body(p);
 
 
+
+		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
+
 		for_array(i, global_variables) {
 		for_array(i, global_variables) {
 			auto *var = &global_variables[i];
 			auto *var = &global_variables[i];
 			if (var->decl->init_expr != nullptr)  {
 			if (var->decl->init_expr != nullptr)  {
@@ -12396,8 +12370,6 @@ void lb_generate_code(lbGenerator *gen) {
 		lbValue *found = map_get(&m->values, hash_entity(entry_point));
 		lbValue *found = map_get(&m->values, hash_entity(entry_point));
 		GB_ASSERT(found != nullptr);
 		GB_ASSERT(found != nullptr);
 
 
-		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
-		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_context->type)), startup_context->value, nullptr, 0, "");
 		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_runtime->type)), startup_runtime->value, nullptr, 0, "");
 		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_runtime->type)), startup_runtime->value, nullptr, 0, "");
 		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, found->type)), found->value, nullptr, 0, "");
 		LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, found->type)), found->value, nullptr, 0, "");
 		LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false));
 		LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false));

+ 0 - 3
src/llvm_backend.hpp

@@ -84,8 +84,6 @@ struct lbModule {
 
 
 	Map<lbProcedure *> anonymous_proc_lits; // Key: Ast *
 	Map<lbProcedure *> anonymous_proc_lits; // Key: Ast *
 
 
-	lbAddr global_default_context;
-
 	u32 global_array_index;
 	u32 global_array_index;
 	u32 global_generated_index;
 	u32 global_generated_index;
 	u32 nested_type_name_guid;
 	u32 nested_type_name_guid;
@@ -355,7 +353,6 @@ lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value);
 lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
 lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos);
 
 
 #define LB_STARTUP_RUNTIME_PROC_NAME   "__$startup_runtime"
 #define LB_STARTUP_RUNTIME_PROC_NAME   "__$startup_runtime"
-#define LB_STARTUP_CONTEXT_PROC_NAME   "__$startup_context"
 #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
 #define LB_STARTUP_TYPE_INFO_PROC_NAME "__$startup_type_info"
 #define LB_TYPE_INFO_DATA_NAME       "__$type_info_data"
 #define LB_TYPE_INFO_DATA_NAME       "__$type_info_data"
 #define LB_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"
 #define LB_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"