Files
Odin/src/ssa/proc.cpp
T
2016-10-30 17:49:30 +00:00

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);
}
}