aboutsummaryrefslogtreecommitdiff
path: root/src/compiler.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-03-12 01:27:54 +0100
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commitb35b3e1bf70bf764940498247b1db5bb02761160 (patch)
tree07ad41028fd3d162e9e681a03b75df1cfc740606 /src/compiler.c
parent79bf40f909cefdc611bfa13f70ae55b52ac41d23 (diff)
Starting on ssa
Diffstat (limited to 'src/compiler.c')
-rw-r--r--src/compiler.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/src/compiler.c b/src/compiler.c
index 6988b20..f464005 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -39,6 +39,7 @@ int amal_compiler_init(amal_compiler *self) {
am_memset(&self->main_thread_allocator, 0, sizeof(self->main_thread_allocator));
self->started = bool_false;
self->resolve_ast_index = 0;
+ self->generate_ssa_index = 0;
amal_mutex_init(&self->mutex);
return_if_error(scoped_allocator_init(&self->allocator));
@@ -88,9 +89,16 @@ typedef struct {
Parser *parser;
} CompilerAstResolverThreadUserData;
+typedef struct {
+ amal_compiler *compiler;
+ ParserThreadData *parser_thread_data;
+ Parser *parser;
+} CompilerSsaGeneratorThreadUserData;
+
typedef enum {
THREAD_WORK_PARSE,
- THREAD_WORK_RESOLVE_AST
+ THREAD_WORK_RESOLVE_AST,
+ THREAD_WORK_GENERATE_SSA
} ThreadWorkType;
typedef struct {
@@ -186,6 +194,44 @@ static void* thread_callback_resolve_ast(void *userdata) {
return result;
}
+/* TODO: Handle errors (stop generating ssa in all other threads and report errors/warnings) */
+static void* thread_callback_generate_ssa(void *userdata) {
+ CompilerSsaGeneratorThreadUserData compiler_ssa_generator_userdata;
+ Parser *parser;
+ AstCompilerContext compiler_context;
+ void *result;
+ assert(!amal_thread_is_main());
+
+ am_memcpy(&compiler_ssa_generator_userdata, userdata, sizeof(compiler_ssa_generator_userdata));
+ am_free(userdata);
+ parser = compiler_ssa_generator_userdata.parser;
+ compiler_context.parser = parser;
+ result = (void*)AMAL_COMPILER_ERR;
+ for(;;) {
+ int result;
+ amal_log_debug("Generating SSA for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data);
+ result = setjmp(compiler_context.env);
+ if(result == 0)
+ scope_generate_ssa(&parser->scope, &compiler_context);
+ else {
+ /* TODO: stop generating ssa in all other threads */
+ break;
+ }
+ cleanup_if_error(amal_mutex_lock(&compiler_ssa_generator_userdata.compiler->mutex, "thread_callback_generate_ssa"));
+ if(compiler_ssa_generator_userdata.compiler->generate_ssa_index + 1 >= (int)buffer_get_size(&compiler_ssa_generator_userdata.compiler->parsers, Parser))
+ break;
+ ++compiler_ssa_generator_userdata.compiler->generate_ssa_index;
+ parser = buffer_get(&compiler_ssa_generator_userdata.compiler->parsers, compiler_ssa_generator_userdata.compiler->generate_ssa_index, sizeof(Parser));
+ amal_mutex_tryunlock(&compiler_ssa_generator_userdata.compiler->mutex);
+ }
+ result = NULL;
+
+ cleanup:
+ compiler_ssa_generator_userdata.parser_thread_data->status = PARSER_THREAD_STATUS_IDLE;
+ amal_mutex_tryunlock(&compiler_ssa_generator_userdata.compiler->mutex);
+ return result;
+}
+
static CHECK_RESULT int amal_compiler_select_thread_for_work(amal_compiler *self, ThreadWorkData work_data, ParserThreadData **thread_selected) {
int i;
int result;
@@ -223,6 +269,17 @@ static CHECK_RESULT int amal_compiler_select_thread_for_work(amal_compiler *self
result = parser_thread_data_start(parser_thread_data, thread_callback_resolve_ast, userdata);
break;
}
+ case THREAD_WORK_GENERATE_SSA: {
+ CompilerSsaGeneratorThreadUserData *userdata;
+ cleanup_if_error(am_malloc(sizeof(CompilerSsaGeneratorThreadUserData), (void**)&userdata));
+ thread_user_data = userdata;
+ userdata->compiler = self;
+ userdata->parser_thread_data = parser_thread_data;
+ userdata->parser = work_data.value.parser;
+ ++self->generate_ssa_index;
+ result = parser_thread_data_start(parser_thread_data, thread_callback_generate_ssa, userdata);
+ break;
+ }
}
*thread_selected = parser_thread_data;
break;
@@ -319,6 +376,24 @@ static CHECK_RESULT int amal_compiler_resolve_ast(amal_compiler *self) {
return amal_compiler_load_file_join_threads(self);
}
+static CHECK_RESULT int amal_compiler_generate_ssa(amal_compiler *self) {
+ Parser *parser;
+ Parser *parser_end;
+ parser = buffer_start(&self->parsers);
+ parser_end = buffer_end(&self->parsers);
+ for(; parser != parser_end; ++parser) {
+ ParserThreadData *thread_selected;
+ ThreadWorkData thread_work_data;
+ thread_work_data.type = THREAD_WORK_GENERATE_SSA;
+ thread_work_data.value.parser = parser;
+ return_if_error(amal_compiler_select_thread_for_work(self, thread_work_data, &thread_selected));
+ /* After all threads have been used, they will handle using the remaining parsers or stop if there is an error */
+ if(!thread_selected)
+ break;
+ }
+ return amal_compiler_load_file_join_threads(self);
+}
+
int amal_compiler_load_file(amal_compiler *self, BufferView filepath) {
int result;
ParserThreadData *parser_thread_data;
@@ -340,6 +415,8 @@ int amal_compiler_load_file(amal_compiler *self, BufferView filepath) {
return_if_error(amal_compiler_load_file_join_threads(self));
amal_log_debug("Finished parsing all files, resolving AST");
return_if_error(amal_compiler_resolve_ast(self));
+ amal_log_debug("Finished resolving AST, generating SSA");
+ return_if_error(amal_compiler_generate_ssa(self));
return AMAL_COMPILER_OK;
}