diff options
author | dec05eba <dec05eba@protonmail.com> | 2019-04-24 21:22:53 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-07-25 14:36:46 +0200 |
commit | 7f524c427597cc998f243769b0e22e4f450c55cf (patch) | |
tree | 0dba782c2214d1ce5309ba71cfd3dddaee4a52a1 /src/ssa | |
parent | 328a9c8310e8bab250b04e9e001ab0d890d33074 (diff) |
Progressing on bytecode (to c), fix ssa resolving multiple times
Diffstat (limited to 'src/ssa')
-rw-r--r-- | src/ssa/ssa.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index e7434f8..c4ed0d3 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -50,7 +50,8 @@ int ssa_init(Ssa *self, ScopedAllocator *allocator) { return_if_error(buffer_init(&self->instructions, allocator)); return_if_error(hash_map_init(&self->intermediates_map, allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number)); return_if_error(buffer_init(&self->intermediates, allocator)); - return_if_error(hash_map_init(&self->strings, allocator, sizeof(SsaStringIndex), hash_compare_string, amal_hash_string)); + return_if_error(hash_map_init(&self->strings_map, allocator, sizeof(SsaStringIndex), hash_compare_string, amal_hash_string)); + return_if_error(buffer_init(&self->strings, allocator)); self->intermediate_counter = 0; self->string_counter = 0; self->reg_counter = 0; @@ -69,7 +70,14 @@ int ssa_get_unique_reg(Ssa *self, SsaRegister *result) { SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index) { SsaNumber result; assert(index < buffer_get_size(&self->intermediates, SsaNumber)); - am_memcpy(&result, buffer_get(&self->intermediates, index, sizeof(SsaNumber)), sizeof(result)); + am_memcpy(&result, buffer_get(&self->intermediates, index, sizeof(SsaNumber)), sizeof(SsaNumber)); + return result; +} + +BufferView ssa_get_string(Ssa *self, SsaStringIndex index) { + BufferView result; + assert(index < buffer_get_size(&self->strings, BufferView)); + am_memcpy(&result, buffer_get(&self->strings, index, sizeof(BufferView)), sizeof(BufferView)); return result; } @@ -109,7 +117,7 @@ static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringI bool exists; assert(result_index); - exists = hash_map_get(&self->strings, str, result_index); + exists = hash_map_get(&self->strings_map, str, result_index); if(exists) return 0; @@ -120,7 +128,8 @@ static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringI *result_index = self->string_counter; ++self->string_counter; amal_log_debug("s%u = \"%.*s\"", *result_index, str.size, str.data); - return hash_map_insert(&self->strings, str, result_index); + return_if_error(buffer_append(&self->strings, &str, sizeof(str))); + return hash_map_insert(&self->strings_map, str, result_index); } static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, u16 rhs) { @@ -157,7 +166,7 @@ static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, Ss return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(SsaRegister) + sizeof(SsaRegister))); *result = self->reg_counter++; self->instructions.data[index + 0] = ins_type; - am_memcpy(self->instructions.data + index + 1, &result, sizeof(*result)); + am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaRegister)); am_memcpy(self->instructions.data + index + 3, &lhs, sizeof(lhs)); am_memcpy(self->instructions.data + index + 5, &rhs, sizeof(rhs)); amal_log_debug("r%u = r%u %s r%u", *result, lhs, binop_type_to_string(ins_type), rhs); @@ -199,7 +208,7 @@ int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result) { return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(u8))); *result = self->func_counter++; self->instructions.data[index + 0] = SSA_FUNC_START; - am_memcpy(self->instructions.data + index + 1, result, sizeof(*result)); + am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaFuncIndex)); self->instructions.data[index + 1 + sizeof(SsaFuncIndex)] = num_args; amal_log_debug("FUNC_START f%u(%u)", *result, num_args); return 0; @@ -234,7 +243,7 @@ int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, SsaRegister *result) { return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(func_decl))); *result = self->reg_counter++; self->instructions.data[index + 0] = SSA_CALL; - am_memcpy(self->instructions.data + index + 1, result, sizeof(*result)); + am_memcpy(self->instructions.data + index + 1, result, sizeof(SsaRegister)); am_memcpy(self->instructions.data + index + 1 + sizeof(SsaRegister), &func_decl, sizeof(func_decl)); amal_log_debug("r%u = CALL %p", *result, func_decl); return 0; @@ -358,7 +367,7 @@ static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerCon } static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) { - /* TODO: Implement */ + /* TODO: Implement, and with cross field references */ (void)self; (void)context; return 0; @@ -399,34 +408,59 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) { assert(self); #ifdef DEBUG - if(self->resolve_data.status != AST_RESOLVED) { + if(self->resolve_data.status != AST_RESOLVED && self->resolve_data.status != AST_SSA_RESOLVED) { amal_log_error("Ast type not resolved: %d", self->type); assert(bool_false); } #endif + + if(self->resolve_data.status == AST_SSA_RESOLVED) + return self->ssa_reg; + switch(self->type) { case AST_NUMBER: - return number_generate_ssa(self->value.number, context); + self->ssa_reg = number_generate_ssa(self->value.number, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_FUNCTION_DECL: - return funcdecl_generate_ssa(self->value.func_decl, context); + self->ssa_reg = funcdecl_generate_ssa(self->value.func_decl, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_FUNCTION_CALL: - return funccall_generate_ssa(self, context); + self->ssa_reg = funccall_generate_ssa(self, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_STRUCT_DECL: - return structdecl_generate_ssa(self->value.struct_decl, context); + self->ssa_reg = structdecl_generate_ssa(self->value.struct_decl, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_STRUCT_FIELD: - return structfield_generate_ssa(self->value.struct_field, context); + self->ssa_reg = structfield_generate_ssa(self->value.struct_field, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_LHS: - return lhsexpr_generate_ssa(self, context); + self->ssa_reg = lhsexpr_generate_ssa(self, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_IMPORT: - /* TODO: When @import(...).data syntax is added, implement the generate ssa for it */ - return 0; + /* TODO: Implement cross file references */ + self->ssa_reg = 0; + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_STRING: - return string_generate_ssa(self->value.string, context); + self->ssa_reg = string_generate_ssa(self->value.string, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_VARIABLE: - return variable_generate_ssa(self->value.variable, context); + self->ssa_reg = variable_generate_ssa(self->value.variable, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; case AST_BINOP: - return binop_generate_ssa(self->value.binop, context); + self->ssa_reg = binop_generate_ssa(self->value.binop, context); + self->resolve_data.status = AST_SSA_RESOLVED; + return self->ssa_reg; } + return 0; } |