diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 22f46bb2c..ba8a550b8 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -391,7 +391,21 @@ Map_Header :: struct { 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 { diff --git a/src/ir.cpp b/src/ir.cpp index 7c2e6d0c5..df42df781 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -33,8 +33,6 @@ struct irModule { i32 global_array_index; // For ConstantSlice i32 global_generated_index; - irValue * global_default_context; - // NOTE(bill): To prevent strings from being copied a lot // Mainly used for file names StringMap 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_TYPE_INFO_DATA_NAME "__$type_info_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)); } -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; gbAllocator a = ir_allocator(); auto args = array_make(a, 1); - args[0] = c ? c : m->global_default_context; + args[0] = c; 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 { irValue *var, *init; DeclInfo *decl; @@ -12819,6 +12816,31 @@ void ir_gen_tree(irGen *s) { } #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 // Cleanup(bill): probably better way of doing code insertion String name = str_lit(IR_STARTUP_RUNTIME_PROC_NAME); @@ -12841,10 +12863,7 @@ void ir_gen_tree(irGen *s) { ir_begin_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) { irGlobalVariable *var = &global_variables[i]; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1b3559aa0..40a629d45 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -11850,9 +11850,6 @@ void lb_generate_code(lbGenerator *gen) { arena_init(&temp_arena, heap_allocator()); 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; @@ -12228,7 +12225,6 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Runtime Creation"); lbProcedure *startup_type_info = nullptr; - lbProcedure *startup_context = nullptr; lbProcedure *startup_runtime = nullptr; { // Startup Type Info Type *params = alloc_type_tuple(); @@ -12255,31 +12251,6 @@ void lb_generate_code(lbGenerator *gen) { 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 Type *params = alloc_type_tuple(); Type *results = alloc_type_tuple(); @@ -12292,6 +12263,9 @@ void lb_generate_code(lbGenerator *gen) { 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) { auto *var = &global_variables[i]; 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)); 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, found->type)), found->value, nullptr, 0, ""); LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false)); diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 26b75f05a..e6ba7730d 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -84,8 +84,6 @@ struct lbModule { Map anonymous_proc_lits; // Key: Ast * - lbAddr global_default_context; - u32 global_array_index; u32 global_generated_index; 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); #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_TYPE_INFO_DATA_NAME "__$type_info_data" #define LB_TYPE_INFO_TYPES_NAME "__$type_info_types_data"