diff --git a/include/ravi_compiler.h b/include/ravi_compiler.h index 9cd3b60..cc1d6b4 100644 --- a/include/ravi_compiler.h +++ b/include/ravi_compiler.h @@ -248,6 +248,14 @@ RAVICOMP_EXPORT LinearizerState *raviX_init_linearizer(CompilerState *compiler_s * Returns 0 on success. */ RAVICOMP_EXPORT int raviX_ast_linearize(LinearizerState *linearizer); + +/* + * Attempts to replace use of upvalues with constants where the upvalue + * points to a local that was initialized with a literal and the local + * has no other assignments. + */ +RAVICOMP_EXPORT void raviX_optimize_upvalues(LinearizerState *linearizer); + /* Prints out the content of the linear IR */ RAVICOMP_EXPORT void raviX_output_linearizer(LinearizerState *linearizer, FILE *fp); /* Cleanup the linearizer */ diff --git a/src/linearizer.c b/src/linearizer.c index ffe7ef8..791d853 100644 --- a/src/linearizer.c +++ b/src/linearizer.c @@ -3001,6 +3001,10 @@ static void replace_literal_upvalues(Proc *proc) END_FOR_EACH_PTR(childproc) } +void raviX_optimize_upvalues(LinearizerState *linearizer) { + replace_literal_upvalues(linearizer->main_proc); +} + ////////////// end of optimization of upvalues static const char *op_codenames[] = { diff --git a/src/ravi_binding.c b/src/ravi_binding.c index 25f5134..4e758b0 100644 --- a/src/ravi_binding.c +++ b/src/ravi_binding.c @@ -68,6 +68,7 @@ int raviX_compile(struct Ravi_CompilerInterface *compiler_interface) } raviX_construct_cfg(linearizer->main_proc); raviX_remove_unreachable_blocks(linearizer); + raviX_optimize_upvalues(linearizer); TextBuffer buf; raviX_buffer_init(&buf, 4096); diff --git a/tests/tcommon.c b/tests/tcommon.c index cb2a29e..9c95f78 100644 --- a/tests/tcommon.c +++ b/tests/tcommon.c @@ -40,6 +40,7 @@ void parse_arguments(struct arguments *args, int argc, const char *argv[]) args->simplify_ast = 0; args->remove_unreachable_blocks = 0; args->gen_C = 0; + args->opt_upvalue = 0; args->mainfunc = "setup"; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--notypecheck") == 0) { @@ -60,6 +61,8 @@ void parse_arguments(struct arguments *args, int argc, const char *argv[]) args->remove_unreachable_blocks = 1; } else if (strcmp(argv[i], "--gen-C") == 0) { args->gen_C = 1; + } else if (strcmp(argv[i], "--opt-upvalues") == 0) { + args->opt_upvalue = 1; } else if (strcmp(argv[i], "-main") == 0) { if (i < argc - 1) { i++; diff --git a/tests/tcommon.h b/tests/tcommon.h index 57040ee..5f582d1 100644 --- a/tests/tcommon.h +++ b/tests/tcommon.h @@ -30,7 +30,7 @@ struct arguments { const char *filename; const char *code; unsigned typecheck : 1, linearize : 1, astdump : 1, irdump : 1, cfgdump : 1, codump : 1, simplify_ast : 1, - remove_unreachable_blocks: 1, gen_C: 1; + remove_unreachable_blocks: 1, gen_C: 1, opt_upvalue: 1; const char *mainfunc; /* name of the main function in generated code, only applies if gen_C is on */ }; extern void parse_arguments(struct arguments *args, int argc, const char *argv[]); diff --git a/tests/trun.c b/tests/trun.c index d580da6..6b9fdf5 100644 --- a/tests/trun.c +++ b/tests/trun.c @@ -179,6 +179,12 @@ static int do_code(C_MemoryAllocator *allocator, const char *code, const struct raviX_output_cfg(linearizer->main_proc, stdout); } } + if (args->opt_upvalue) { + raviX_optimize_upvalues(linearizer); + if (args->irdump) { + raviX_output_linearizer(linearizer, stdout); + } + } if (args->gen_C) { fprintf(stdout, "\n#endif\n"); raviX_generate_C_tofile(linearizer, args->mainfunc, stdout);