diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-06-16 17:35:24 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-06-16 17:35:24 -0400 |
commit | e327fd94f3be22d9129b252102e73b5bfb3b3276 (patch) | |
tree | 4e2f178bd467fda1ffce236e40bb112db94dd133 | |
parent | 15e96a558baf007966f80d565f50f18cd2ecd75d (diff) |
Remove redundant loads
Do breadth first of the entire program when marking variables used/unused
Don't optimize away unused function parameters
-rw-r--r-- | ast.h | 5 | ||||
-rw-r--r-- | interpret.c | 2 | ||||
-rw-r--r-- | offsets.c | 28 | ||||
-rw-r--r-- | optimize.c | 27 | ||||
-rw-r--r-- | prepare.c | 2 | ||||
-rw-r--r-- | util.c | 12 |
6 files changed, 62 insertions, 14 deletions
@@ -935,6 +935,7 @@ struct ast_variable_definition_t int level; gboolean field; + gboolean parameter; gboolean used; }; @@ -1451,6 +1452,10 @@ gboolean ast_encloses (ast_t *outer, ast_t *inner); void ast_ensure_ast (ast_t *ast); +void program_breadth_first (ast_program_t *program, + node_callback_t callback, + gpointer data); + /* Garbage Collector */ void gc_init (void); void *gc_alloc (int n_bytes); diff --git a/interpret.c b/interpret.c index 2b8a07a..d5b261d 100644 --- a/interpret.c +++ b/interpret.c @@ -217,6 +217,8 @@ interpret (ast_t *ast) env = gc_alloc (program->env_size); + g_print ("size of env: %d\n", program->env_size); + current = program->enter; while (current) { @@ -59,18 +59,21 @@ assign_offsets (symbol_table_t *symbols, int offset, int *max) { ast_definition_t *definition = definitions->pdata[i]; - if (definition->common.type == AST_VARIABLE_DEFINITION && - definition->variable.used) + if (definition->common.type == AST_VARIABLE_DEFINITION) { - int size = ast_type_spec_get_size (definition->variable.type_spec); - - /* Align to size */ - if (offset % size != 0) - offset += (size - offset % size); - - definition->variable.offset = offset; - - offset += size; + ast_variable_definition_t *variable = &definition->variable; + + if (variable->used || variable->parameter) + { + int size = ast_type_spec_get_size (variable->type_spec); + + /* Align to size */ + if (offset % size != 0) + offset += (size - offset % size); + + variable->offset = offset; + offset += size; + } } } @@ -145,8 +148,7 @@ do_offsets (ast_t *ast, int offset, int *max) gboolean offsets (ast_t *ast) { - node_breadth_first (ast->program.enter, mark_used, NULL); - + program_breadth_first (&ast->program, mark_used, NULL); do_offsets (ast, 0, NULL); /* The offsets pass can never fail */ @@ -416,6 +416,30 @@ peephole (node_t *node, *changed = TRUE; } + else if (node_is (node0, NODE_STORE) && + node_is (node1, NODE_LOAD) && + node0->store.definition == node1->load.definition) + { + node_t *n; + + n = node_new_dup (node1, NULL); + node_new_store ( + node0->store.definition, node0->store.expression, + n, node0->common.ast); + + nop_node (node0, 0); + nop_node (node1, 0); + + *changed = TRUE; + } + else if (node_is (node0, NODE_DUP) && + node_is (node1, NODE_POP)) + { + nop_node (node0, 0); + nop_node (node1, 0); + + *changed = TRUE; + } node->common.next = peephole (node->common.next, changed); @@ -504,7 +528,8 @@ optimize (ast_t *ast) changed = FALSE; mark_variables_unused (ast); - node_breadth_first (ast->program.enter, mark_used, NULL); + + program_breadth_first (&ast->program, mark_used, NULL); do_optimize (ast, &changed); } while (changed); @@ -139,6 +139,8 @@ prepare_function (ast_function_definition_t *function, parameter = function->parameters[i]; + parameter->parameter = TRUE; + if (!prepare_definition ((ast_definition_t *)parameter, parent, info)) return FALSE; } @@ -455,3 +455,15 @@ report_error (const char *fmt, ...) return FALSE; } + +void +program_breadth_first (ast_program_t *program, + node_callback_t callback, + gpointer data) +{ + int i; + + node_breadth_first (program->enter, callback, data); + for (i = 0; program->functions[i]; ++i) + node_breadth_first (program->functions[i]->enter, callback, data); +} |