diff options
Diffstat (limited to 'src/ssa')
-rw-r--r-- | src/ssa/ssa.c | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/src/ssa/ssa.c b/src/ssa/ssa.c index 2391778..3afe7ed 100644 --- a/src/ssa/ssa.c +++ b/src/ssa/ssa.c @@ -48,7 +48,8 @@ SsaNumber create_ssa_float(f64 value) { int ssa_init(Ssa *self, ScopedAllocator *allocator) { return_if_error(buffer_init(&self->instructions, allocator)); - return_if_error(hash_map_init(&self->intermediates, allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number)); + 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)); self->intermediate_counter = 0; self->string_counter = 0; @@ -65,6 +66,13 @@ int ssa_get_unique_reg(Ssa *self, SsaRegister *result) { return 0; } +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)); + return result; +} + static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, SsaIntermediateIndex *result_index) { bool exists; BufferView key; @@ -72,7 +80,7 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss assert(result_index); key = create_buffer_view((const char*)&number, sizeof(number)); - exists = hash_map_get(&self->intermediates, key, result_index); + exists = hash_map_get(&self->intermediates_map, key, result_index); if(exists) return 0; @@ -92,7 +100,9 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss break; } } - return hash_map_insert(&self->intermediates, key, result_index); + + return_if_error(buffer_append(&self->intermediates, &number, sizeof(number))); + return hash_map_insert(&self->intermediates_map, key, result_index); } static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringIndex *result_index) { @@ -113,18 +123,18 @@ static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringI return hash_map_insert(&self->strings, str, result_index); } -static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstructionType ins_type, SsaRegister lhs, u16 rhs) { +static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, u16 rhs) { usize index; index = self->instructions.size; - return_if_error(buffer_append(&self->instructions, NULL, sizeof(u8) + sizeof(SsaRegister) + sizeof(u16))); + return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister) + sizeof(u16))); self->instructions.data[index + 0] = ins_type; am_memcpy(self->instructions.data + index + 1, &lhs, sizeof(lhs)); am_memcpy(self->instructions.data + index + 3, &rhs, sizeof(rhs)); return 0; } -static const char* binop_type_to_string(SsaInstructionType binop_type) { +static const char* binop_type_to_string(SsaInstruction binop_type) { assert(binop_type >= SSA_ADD && binop_type <= SSA_DIV); switch(binop_type) { case SSA_ADD: return "+"; @@ -135,7 +145,7 @@ static const char* binop_type_to_string(SsaInstructionType binop_type) { } } -static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstructionType ins_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) { +static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) { usize index; index = self->instructions.size; @@ -144,7 +154,7 @@ static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstructionType ins_type return -1; assert(result); - return_if_error(buffer_append(&self->instructions, NULL, sizeof(u8) + sizeof(SsaRegister) + sizeof(SsaRegister) + sizeof(SsaRegister))); + 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)); @@ -173,7 +183,7 @@ int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src) { return ssa_add_ins_form1(self, SSA_ASSIGN_REG, dest, src); } -int ssa_ins_binop(Ssa *self, SsaInstructionType binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) { +int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) { assert(binop_type >= SSA_ADD && binop_type <= SSA_DIV); return ssa_add_ins_form2(self, binop_type, lhs, rhs, result); } @@ -186,11 +196,11 @@ int ssa_ins_func_start(Ssa *self, u8 num_args, SsaFuncIndex *result) { if(self->func_counter + 1 < self->func_counter) return -1; - return_if_error(buffer_append(&self->instructions, NULL, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(u8))); + 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)); - self->instructions.data[index + 3] = num_args; + self->instructions.data[index + 1 + sizeof(SsaFuncIndex)] = num_args; amal_log_debug("FUNC_START f%u(%u)", *result, num_args); return 0; } @@ -206,14 +216,14 @@ int ssa_ins_push(Ssa *self, SsaRegister reg) { usize index; index = self->instructions.size; - return_if_error(buffer_append(&self->instructions, NULL, sizeof(u8) + sizeof(SsaRegister))); + return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(SsaRegister))); self->instructions.data[index + 0] = SSA_PUSH; am_memcpy(self->instructions.data + index + 1, ®, sizeof(reg)); amal_log_debug("PUSH r%u", reg); return 0; } -int ssa_ins_call(Ssa *self, void *func, SsaRegister *result) { +int ssa_ins_call(Ssa *self, FunctionDecl *func_decl, SsaRegister *result) { usize index; index = self->instructions.size; @@ -221,12 +231,12 @@ int ssa_ins_call(Ssa *self, void *func, SsaRegister *result) { if(self->reg_counter + 1 < self->reg_counter) return -1; - return_if_error(buffer_append(&self->instructions, NULL, sizeof(u8) + sizeof(SsaFuncIndex) + sizeof(SsaRegister))); + return_if_error(buffer_append_empty(&self->instructions, sizeof(u8) + sizeof(func_decl) + sizeof(SsaRegister))); *result = self->reg_counter++; self->instructions.data[index + 0] = SSA_CALL; - am_memcpy(self->instructions.data + index + 1, &func, sizeof(func)); - am_memcpy(self->instructions.data + index + 3, result, sizeof(*result)); - amal_log_debug("r%u = CALL %p", *result, func); + am_memcpy(self->instructions.data + index + 1, result, sizeof(*result)); + am_memcpy(self->instructions.data + index + 1 + sizeof(func_decl), &func_decl, sizeof(func_decl)); + amal_log_debug("r%u = CALL %p", *result, func_decl); return 0; } @@ -237,12 +247,12 @@ static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerCon SsaNumber number; if(self->is_integer) { number = create_ssa_integer(self->value.integer); - throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); - throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number)); + throw_if_error(ssa_get_unique_reg(context->ssa, ®)); + throw_if_error(ssa_ins_assign_inter(context->ssa, reg, number)); } else { number = create_ssa_float(self->value.floating); - throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); - throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number)); + throw_if_error(ssa_get_unique_reg(context->ssa, ®)); + throw_if_error(ssa_ins_assign_inter(context->ssa, reg, number)); } return reg; } @@ -266,14 +276,15 @@ static CHECK_RESULT SsaRegister lhsexpr_generate_ssa(Ast *self, SsaCompilerConte */ if(self->resolve_data.type == lhs_expr || lhs_expr->rhs_expr->type == AST_IMPORT) return 0; - throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); + throw_if_error(ssa_get_unique_reg(context->ssa, ®)); if(reg == rhs_reg) { amal_log_error("rhs_expr is same as reg.. rhs type: %d", lhs_expr->rhs_expr->type); } assert(reg != rhs_reg); - throw_if_error(ssa_ins_assign_reg(&context->ssa, reg, rhs_reg)); + throw_if_error(ssa_ins_assign_reg(context->ssa, reg, rhs_reg)); } else { /* TODO: assign default value to reg depending on LhsExpr type */ + reg = 0; } return reg; } @@ -284,10 +295,16 @@ in any order. */ static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) { /* TODO: Implement */ + SsaRegister prev_reg_counter; + prev_reg_counter = context->ssa->reg_counter; + context->ssa->reg_counter = 0; + amal_log_debug("SSA funcdecl %p", self); - throw_if_error(ssa_ins_func_start(&context->ssa, 0, &self->ssa_func_index)); + throw_if_error(ssa_ins_func_start(context->ssa, 0, &self->ssa_func_index)); scope_generate_ssa(&self->body, context); - throw_if_error(ssa_ins_func_end(&context->ssa)); + throw_if_error(ssa_ins_func_end(context->ssa)); + + context->ssa->reg_counter = prev_reg_counter; return 0; } @@ -301,12 +318,12 @@ static CHECK_RESULT SsaRegister funccall_generate_ssa(Ast *self, SsaCompilerCont assert(self->type == AST_FUNCTION_CALL); func_call = self->value.func_call; - ast = buffer_start(&func_call->args); + ast = buffer_begin(&func_call->args); ast_end = buffer_end(&func_call->args); for(; ast != ast_end; ++ast) { SsaRegister arg_reg; arg_reg = ast_generate_ssa(*ast, context); - throw_if_error(ssa_ins_push(&context->ssa, arg_reg)); + throw_if_error(ssa_ins_push(context->ssa, arg_reg)); } assert(self->resolve_data.type->rhs_expr->type == AST_FUNCTION_DECL); @@ -316,7 +333,7 @@ static CHECK_RESULT SsaRegister funccall_generate_ssa(Ast *self, SsaCompilerCont then there is no need for mutex locks. */ amal_log_debug("SSA funccall %.*s, func index ptr: %p", func_call->func.name.size, func_call->func.name.data, func_to_call); - throw_if_error(ssa_ins_call(&context->ssa, func_to_call, ®)); + throw_if_error(ssa_ins_call(context->ssa, func_to_call, ®)); return reg; } @@ -335,8 +352,8 @@ static CHECK_RESULT SsaRegister structfield_generate_ssa(StructField *self, SsaC static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) { SsaRegister reg; - throw_if_error(ssa_get_unique_reg(&context->ssa, ®)); - throw_if_error(ssa_ins_assign_string(&context->ssa, reg, self->str)); + throw_if_error(ssa_get_unique_reg(context->ssa, ®)); + throw_if_error(ssa_ins_assign_string(context->ssa, reg, self->str)); return reg; } @@ -347,7 +364,7 @@ static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompile return 0; } -static SsaInstructionType binop_type_to_ssa_type(BinopType binop_type) { +static SsaInstruction binop_type_to_ssa_type(BinopType binop_type) { switch(binop_type) { case BINOP_ADD: return SSA_ADD; @@ -374,7 +391,7 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte } else { lhs_reg = ast_generate_ssa(self->lhs, context); rhs_reg = ast_generate_ssa(self->rhs, context); - throw_if_error(ssa_ins_binop(&context->ssa, binop_type_to_ssa_type(self->type), lhs_reg, rhs_reg, ®)); + throw_if_error(ssa_ins_binop(context->ssa, binop_type_to_ssa_type(self->type), lhs_reg, rhs_reg, ®)); } return reg; } @@ -416,7 +433,7 @@ CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context void scope_generate_ssa(Scope *self, SsaCompilerContext *context) { Ast **ast; Ast **ast_end; - ast = buffer_start(&self->ast_objects); + ast = buffer_begin(&self->ast_objects); ast_end = buffer_end(&self->ast_objects); for(; ast != ast_end; ++ast) { ignore_result_int(ast_generate_ssa(*ast, context)); |