mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-13 01:21:38 -07:00
Separate ini global var stuff
This commit is contained in:
+76
-63
@@ -1924,6 +1924,74 @@ gb_internal WORKER_TASK_PROC(lb_llvm_module_verification_worker_proc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
gb_internal bool lb_init_global_var(lbModule *m, lbProcedure *p, Entity *e, Ast *init_expr, lbGlobalVariable &var) {
|
||||
if (init_expr != nullptr) {
|
||||
lbValue init = lb_build_expr(p, init_expr);
|
||||
if (init.value == nullptr) {
|
||||
LLVMTypeRef global_type = llvm_addr_type(p->module, var.var);
|
||||
if (is_type_untyped_nil(init.type)) {
|
||||
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
||||
var.is_initialized = true;
|
||||
|
||||
if (e->Variable.is_rodata) {
|
||||
LLVMSetGlobalConstant(var.var.value, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
|
||||
}
|
||||
|
||||
if (is_type_any(e->type) || is_type_union(e->type)) {
|
||||
var.init = init;
|
||||
} else if (lb_is_const_or_global(init)) {
|
||||
if (!var.is_initialized) {
|
||||
if (is_type_proc(init.type)) {
|
||||
init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
|
||||
}
|
||||
LLVMSetInitializer(var.var.value, init.value);
|
||||
var.is_initialized = true;
|
||||
|
||||
if (e->Variable.is_rodata) {
|
||||
LLVMSetGlobalConstant(var.var.value, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
var.init = init;
|
||||
}
|
||||
}
|
||||
|
||||
if (var.init.value != nullptr) {
|
||||
GB_ASSERT(!var.is_initialized);
|
||||
Type *t = type_deref(var.var.type);
|
||||
|
||||
if (is_type_any(t)) {
|
||||
// NOTE(bill): Edge case for 'any' type
|
||||
Type *var_type = default_type(var.init.type);
|
||||
gbString var_name = gb_string_make(permanent_allocator(), "__$global_any::");
|
||||
gbString e_str = string_canonical_entity_name(temporary_allocator(), e);
|
||||
var_name = gb_string_append_length(var_name, e_str, gb_strlen(e_str));
|
||||
lbAddr g = lb_add_global_generated_with_name(m, var_type, {}, make_string_c(var_name));
|
||||
lb_addr_store(p, g, var.init);
|
||||
lbValue gp = lb_addr_get_ptr(p, g);
|
||||
|
||||
lbValue data = lb_emit_struct_ep(p, var.var, 0);
|
||||
lbValue ti = lb_emit_struct_ep(p, var.var, 1);
|
||||
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
|
||||
lb_emit_store(p, ti, lb_typeid(p->module, var_type));
|
||||
} else {
|
||||
LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
|
||||
lbValue src0 = lb_emit_conv(p, var.init, t);
|
||||
LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
|
||||
LLVMValueRef dst = var.var.value;
|
||||
LLVMBuildStore(p->builder, src, dst);
|
||||
}
|
||||
|
||||
var.is_initialized = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedure *p) {
|
||||
lb_begin_procedure_body(p);
|
||||
@@ -1944,73 +2012,13 @@ gb_internal void lb_create_startup_runtime_generate_body(lbModule *m, lbProcedur
|
||||
Entity *e = var.decl->entity;
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
e->code_gen_module = entity_module;
|
||||
|
||||
Ast *init_expr = var.decl->init_expr;
|
||||
if (init_expr != nullptr) {
|
||||
lbValue init = lb_build_expr(p, init_expr);
|
||||
if (init.value == nullptr) {
|
||||
LLVMTypeRef global_type = llvm_addr_type(p->module, var.var);
|
||||
if (is_type_untyped_nil(init.type)) {
|
||||
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
||||
var.is_initialized = true;
|
||||
|
||||
if (e->Variable.is_rodata) {
|
||||
LLVMSetGlobalConstant(var.var.value, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
|
||||
}
|
||||
|
||||
if (is_type_any(e->type) || is_type_union(e->type)) {
|
||||
var.init = init;
|
||||
} else if (lb_is_const_or_global(init)) {
|
||||
if (!var.is_initialized) {
|
||||
if (is_type_proc(init.type)) {
|
||||
init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
|
||||
}
|
||||
LLVMSetInitializer(var.var.value, init.value);
|
||||
var.is_initialized = true;
|
||||
|
||||
if (e->Variable.is_rodata) {
|
||||
LLVMSetGlobalConstant(var.var.value, true);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
var.init = init;
|
||||
}
|
||||
}
|
||||
|
||||
if (var.init.value != nullptr) {
|
||||
GB_ASSERT(!var.is_initialized);
|
||||
Type *t = type_deref(var.var.type);
|
||||
|
||||
if (is_type_any(t)) {
|
||||
// NOTE(bill): Edge case for 'any' type
|
||||
Type *var_type = default_type(var.init.type);
|
||||
gbString var_name = gb_string_make(permanent_allocator(), "__$global_any::");
|
||||
gbString e_str = string_canonical_entity_name(temporary_allocator(), e);
|
||||
var_name = gb_string_append_length(var_name, e_str, gb_strlen(e_str));
|
||||
lbAddr g = lb_add_global_generated_with_name(m, var_type, {}, make_string_c(var_name));
|
||||
lb_addr_store(p, g, var.init);
|
||||
lbValue gp = lb_addr_get_ptr(p, g);
|
||||
|
||||
lbValue data = lb_emit_struct_ep(p, var.var, 0);
|
||||
lbValue ti = lb_emit_struct_ep(p, var.var, 1);
|
||||
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
|
||||
lb_emit_store(p, ti, lb_typeid(p->module, var_type));
|
||||
} else {
|
||||
LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
|
||||
lbValue src0 = lb_emit_conv(p, var.init, t);
|
||||
LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
|
||||
LLVMValueRef dst = var.var.value;
|
||||
LLVMBuildStore(p->builder, src, dst);
|
||||
}
|
||||
|
||||
var.is_initialized = true;
|
||||
if (init_expr == nullptr && var.init.value == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lb_init_global_var(m, p, e, init_expr, var);
|
||||
|
||||
}
|
||||
CheckerInfo *info = m->gen->info;
|
||||
@@ -2448,7 +2456,12 @@ gb_internal WORKER_TASK_PROC(lb_generate_missing_procedures_to_check_worker_proc
|
||||
for (isize i = 0; i < m->missing_procedures_to_check.count; i++) {
|
||||
lbProcedure *p = m->missing_procedures_to_check[i];
|
||||
debugf("Generate missing procedure: %.*s module %p\n", LIT(p->name), m);
|
||||
isize count = m->procedures_to_generate.count;
|
||||
lb_generate_procedure(m, p);
|
||||
isize new_count = m->procedures_to_generate.count;
|
||||
if (count != new_count) {
|
||||
gb_printf_err("NEW STUFF!\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user