aboutsummaryrefslogtreecommitdiff
path: root/src/ssa/ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssa/ssa.c')
-rw-r--r--src/ssa/ssa.c74
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;
}