diff options
Diffstat (limited to 'src/compiler.c')
-rw-r--r-- | src/compiler.c | 79 |
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; } |