aboutsummaryrefslogtreecommitdiff
path: root/src/ssa
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-04-22 02:34:30 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commita76ba1b33e397638c4209dd77e6073e423ac07a8 (patch)
tree0ef62209546ba91d53a2fabb54f3b8ac9dcfafdf /src/ssa
parent6a9466da5377d0bc73c7e5aa48deca3740d3de6f (diff)
Start on bytecode. Commit before os switch
Diffstat (limited to 'src/ssa')
-rw-r--r--src/ssa/ssa.c83
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, &reg, 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, &reg));
- throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number));
+ throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
+ 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, &reg));
- throw_if_error(ssa_ins_assign_inter(&context->ssa, reg, number));
+ throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
+ 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, &reg));
+ throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
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, &reg));
+ throw_if_error(ssa_ins_call(context->ssa, func_to_call, &reg));
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, &reg));
- throw_if_error(ssa_ins_assign_string(&context->ssa, reg, self->str));
+ throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
+ 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, &reg));
+ throw_if_error(ssa_ins_binop(context->ssa, binop_type_to_ssa_type(self->type), lhs_reg, rhs_reg, &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));