summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-06-16 17:35:24 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-06-16 17:35:24 -0400
commite327fd94f3be22d9129b252102e73b5bfb3b3276 (patch)
tree4e2f178bd467fda1ffce236e40bb112db94dd133
parent15e96a558baf007966f80d565f50f18cd2ecd75d (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.h5
-rw-r--r--interpret.c2
-rw-r--r--offsets.c28
-rw-r--r--optimize.c27
-rw-r--r--prepare.c2
-rw-r--r--util.c12
6 files changed, 62 insertions, 14 deletions
diff --git a/ast.h b/ast.h
index d8e8a97..69cc1a8 100644
--- a/ast.h
+++ b/ast.h
@@ -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)
{
diff --git a/offsets.c b/offsets.c
index 32f3614..0504d7f 100644
--- a/offsets.c
+++ b/offsets.c
@@ -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 */
diff --git a/optimize.c b/optimize.c
index 508f5e6..42c2d7d 100644
--- a/optimize.c
+++ b/optimize.c
@@ -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);
diff --git a/prepare.c b/prepare.c
index cc8fa98..9a244c4 100644
--- a/prepare.c
+++ b/prepare.c
@@ -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;
}
diff --git a/util.c b/util.c
index 270f2a3..38ed9b7 100644
--- a/util.c
+++ b/util.c
@@ -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);
+}