From 2e942f12fc94626f884ba38192b530122a5f0e43 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 12 Mar 2019 19:28:15 +0100 Subject: Turn ast resolve/ssa generation thread work to generic workflow - better for future steps --- src/compiler.c | 155 ++++++++++++++++++--------------------------------------- 1 file changed, 48 insertions(+), 107 deletions(-) (limited to 'src/compiler.c') diff --git a/src/compiler.c b/src/compiler.c index f464005..dc703f8 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -38,8 +38,7 @@ int amal_compiler_init(amal_compiler *self) { am_memset(&self->allocator, 0, sizeof(self->allocator)); 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; + self->generic_work_object_index = 0; amal_mutex_init(&self->mutex); return_if_error(scoped_allocator_init(&self->allocator)); @@ -77,6 +76,12 @@ int amal_compiler_deinit(amal_compiler *self) { return result; } +typedef enum { + THREAD_WORK_PARSE, + THREAD_WORK_RESOLVE_AST, + THREAD_WORK_GENERATE_SSA +} ThreadWorkType; + typedef struct { amal_compiler *compiler; ParserThreadData *parser_thread_data; @@ -87,19 +92,8 @@ typedef struct { amal_compiler *compiler; ParserThreadData *parser_thread_data; 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_GENERATE_SSA -} ThreadWorkType; + ThreadWorkType work_type; +} CompilerGenericThreadUserData; typedef struct { union { @@ -156,79 +150,52 @@ static void* thread_callback_parse_file(void *userdata) { return result; } -/* TODO: Handle errors (stop resolving ast in all other threads and report errors/warnings) */ -static void* thread_callback_resolve_ast(void *userdata) { - CompilerAstResolverThreadUserData compiler_ast_resolver_userdata; +/* TODO: Handle errors (stop work in all other threads and report errors/warnings) */ +static void* thread_callback_generic(void *userdata) { + CompilerGenericThreadUserData compiler_userdata; Parser *parser; AstCompilerContext compiler_context; void *result; assert(!amal_thread_is_main()); - am_memcpy(&compiler_ast_resolver_userdata, userdata, sizeof(compiler_ast_resolver_userdata)); + am_memcpy(&compiler_userdata, userdata, sizeof(compiler_userdata)); am_free(userdata); - parser = compiler_ast_resolver_userdata.parser; + parser = compiler_userdata.parser; compiler_context.parser = parser; result = (void*)AMAL_COMPILER_ERR; for(;;) { int result; - amal_log_debug("Resolving AST for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data); result = setjmp(compiler_context.env); - if(result == 0) - scope_resolve(&parser->scope, &compiler_context); - else { - /* TODO: stop resolving ast in all other threads */ - break; - } - cleanup_if_error(amal_mutex_lock(&compiler_ast_resolver_userdata.compiler->mutex, "thread_callback_resolve_ast")); - if(compiler_ast_resolver_userdata.compiler->resolve_ast_index + 1 >= (int)buffer_get_size(&compiler_ast_resolver_userdata.compiler->parsers, Parser)) - break; - ++compiler_ast_resolver_userdata.compiler->resolve_ast_index; - parser = buffer_get(&compiler_ast_resolver_userdata.compiler->parsers, compiler_ast_resolver_userdata.compiler->resolve_ast_index, sizeof(Parser)); - amal_mutex_tryunlock(&compiler_ast_resolver_userdata.compiler->mutex); - } - result = NULL; - - cleanup: - compiler_ast_resolver_userdata.parser_thread_data->status = PARSER_THREAD_STATUS_IDLE; - amal_mutex_tryunlock(&compiler_ast_resolver_userdata.compiler->mutex); - 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 */ + if(result == 0) { + switch(compiler_userdata.work_type) { + case THREAD_WORK_PARSE: + assert(bool_false && "Thread work type can't ge 'parse' for generic work"); + break; + case THREAD_WORK_RESOLVE_AST: + amal_log_debug("Resolving AST for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data); + scope_resolve(&parser->scope, &compiler_context); + break; + case THREAD_WORK_GENERATE_SSA: + amal_log_debug("Generating SSA for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data); + scope_generate_ssa(&parser->scope, &compiler_context); + break; + } + } else { + /* TODO: stop work 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)) + cleanup_if_error(amal_mutex_lock(&compiler_userdata.compiler->mutex, "thread_callback_generic")); + if(compiler_userdata.compiler->generic_work_object_index + 1 >= (int)buffer_get_size(&compiler_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); + ++compiler_userdata.compiler->generic_work_object_index; + parser = buffer_get(&compiler_userdata.compiler->parsers, compiler_userdata.compiler->generic_work_object_index, sizeof(Parser)); + amal_mutex_tryunlock(&compiler_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); + compiler_userdata.parser_thread_data->status = PARSER_THREAD_STATUS_IDLE; + amal_mutex_tryunlock(&compiler_userdata.compiler->mutex); return result; } @@ -258,26 +225,17 @@ static CHECK_RESULT int amal_compiler_select_thread_for_work(amal_compiler *self result = parser_thread_data_start(parser_thread_data, thread_callback_parse_file, userdata); break; } - case THREAD_WORK_RESOLVE_AST: { - CompilerAstResolverThreadUserData *userdata; - cleanup_if_error(am_malloc(sizeof(CompilerAstResolverThreadUserData), (void**)&userdata)); - thread_user_data = userdata; - userdata->compiler = self; - userdata->parser_thread_data = parser_thread_data; - userdata->parser = work_data.value.parser; - ++self->resolve_ast_index; - result = parser_thread_data_start(parser_thread_data, thread_callback_resolve_ast, userdata); - break; - } + case THREAD_WORK_RESOLVE_AST: case THREAD_WORK_GENERATE_SSA: { - CompilerSsaGeneratorThreadUserData *userdata; - cleanup_if_error(am_malloc(sizeof(CompilerSsaGeneratorThreadUserData), (void**)&userdata)); + CompilerGenericThreadUserData *userdata; + cleanup_if_error(am_malloc(sizeof(CompilerGenericThreadUserData), (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); + userdata->work_type = work_data.type; + ++self->generic_work_object_index; + result = parser_thread_data_start(parser_thread_data, thread_callback_generic, userdata); break; } } @@ -358,33 +316,16 @@ static CHECK_RESULT int amal_compiler_load_file_join_threads(amal_compiler *self return result; } -static CHECK_RESULT int amal_compiler_resolve_ast(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_RESOLVE_AST; - 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); -} - -static CHECK_RESULT int amal_compiler_generate_ssa(amal_compiler *self) { +static CHECK_RESULT int amal_compiler_dispatch_generic(amal_compiler *self, ThreadWorkType work_type) { Parser *parser; Parser *parser_end; parser = buffer_start(&self->parsers); parser_end = buffer_end(&self->parsers); + self->generic_work_object_index = 0; for(; parser != parser_end; ++parser) { ParserThreadData *thread_selected; ThreadWorkData thread_work_data; - thread_work_data.type = THREAD_WORK_GENERATE_SSA; + thread_work_data.type = work_type; 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 */ @@ -414,9 +355,9 @@ int amal_compiler_load_file(amal_compiler *self, BufferView filepath) { /*return_if_error(amal_compiler_load_first_this_thread(self, filepath, &self->main_thread_allocator));*/ 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)); + return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_RESOLVE_AST)); amal_log_debug("Finished resolving AST, generating SSA"); - return_if_error(amal_compiler_generate_ssa(self)); + return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_SSA)); return AMAL_COMPILER_OK; } -- cgit v1.2.3