mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-17 19:32:23 -07:00
115 lines
2.9 KiB
C++
115 lines
2.9 KiB
C++
void ssa_begin_procedure_body(ssaProcedure *proc) {
|
|
array_init(&proc->blocks, heap_allocator());
|
|
array_init(&proc->defer_stmts, heap_allocator());
|
|
array_init(&proc->children, heap_allocator());
|
|
|
|
proc->decl_block = ssa_add_block(proc, proc->type_expr, "decls");
|
|
proc->entry_block = ssa_add_block(proc, proc->type_expr, "entry");
|
|
proc->curr_block = proc->entry_block;
|
|
|
|
if (proc->type->Proc.params != NULL) {
|
|
auto *params = &proc->type->Proc.params->Tuple;
|
|
for (isize i = 0; i < params->variable_count; i++) {
|
|
Entity *e = params->variables[i];
|
|
ssaValue *param = ssa_add_param(proc, e);
|
|
array_add(&proc->params, param);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ssa_end_procedure_body(ssaProcedure *proc) {
|
|
if (proc->type->Proc.result_count == 0) {
|
|
ssa_emit_return(proc, NULL);
|
|
}
|
|
|
|
if (proc->curr_block->instrs.count == 0) {
|
|
ssa_emit_unreachable(proc);
|
|
}
|
|
|
|
proc->curr_block = proc->decl_block;
|
|
ssa_emit_jump(proc, proc->entry_block);
|
|
|
|
ssa_opt_proc(proc);
|
|
|
|
// Number registers
|
|
i32 reg_index = 0;
|
|
for_array(i, proc->blocks) {
|
|
ssaBlock *b = proc->blocks[i];
|
|
b->index = i;
|
|
for_array(j, b->instrs) {
|
|
ssaValue *value = b->instrs[j];
|
|
GB_ASSERT(value->kind == ssaValue_Instr);
|
|
ssaInstr *instr = &value->Instr;
|
|
if (ssa_instr_type(instr) == NULL) { // NOTE(bill): Ignore non-returning instructions
|
|
continue;
|
|
}
|
|
value->index = reg_index;
|
|
reg_index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) {
|
|
if (parent == NULL) {
|
|
if (proc->name == "main") {
|
|
ssa_emit_startup_runtime(proc);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
|
|
ssaProcedure *proc = &value->Proc;
|
|
|
|
proc->parent = parent;
|
|
|
|
if (proc->entity != NULL) {
|
|
ssaModule *m = proc->module;
|
|
CheckerInfo *info = m->info;
|
|
Entity *e = proc->entity;
|
|
String filename = e->token.pos.file;
|
|
AstFile **found = map_get(&info->files, hash_string(filename));
|
|
GB_ASSERT(found != NULL);
|
|
AstFile *f = *found;
|
|
ssaDebugInfo *di_file = NULL;
|
|
|
|
ssaDebugInfo **di_file_found = map_get(&m->debug_info, hash_pointer(f));
|
|
if (di_file_found) {
|
|
di_file = *di_file_found;
|
|
GB_ASSERT(di_file->kind == ssaDebugInfo_File);
|
|
} else {
|
|
di_file = ssa_add_debug_info_file(proc, f);
|
|
}
|
|
|
|
ssa_add_debug_info_proc(proc, e, proc->name, di_file);
|
|
}
|
|
|
|
if (proc->body != NULL) {
|
|
u32 prev_stmt_state_flags = proc->module->stmt_state_flags;
|
|
defer (proc->module->stmt_state_flags = prev_stmt_state_flags);
|
|
|
|
if (proc->tags != 0) {
|
|
u32 in = proc->tags;
|
|
u32 out = proc->module->stmt_state_flags;
|
|
defer (proc->module->stmt_state_flags = out);
|
|
|
|
if (in & ProcTag_bounds_check) {
|
|
out |= StmtStateFlag_bounds_check;
|
|
out &= ~StmtStateFlag_no_bounds_check;
|
|
} else if (in & ProcTag_no_bounds_check) {
|
|
out |= StmtStateFlag_no_bounds_check;
|
|
out &= ~StmtStateFlag_bounds_check;
|
|
}
|
|
}
|
|
|
|
|
|
ssa_begin_procedure_body(proc);
|
|
ssa_insert_code_before_proc(proc, parent);
|
|
ssa_build_stmt(proc, proc->body);
|
|
ssa_end_procedure_body(proc);
|
|
}
|
|
}
|
|
|
|
|