From d2f2fdc28e6e5fa06aa608decf52389ac7bdd9e6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 10 Dec 2012 14:41:35 +0900 Subject: [PATCH] Create dummy definitions for local variables. The entry dummy block is setup to provide dummy definitions of local variables so the reaching definitions analysis can be used to detect uninitialized variables (not implemented yet). Fake statement numbers (func->num_statements + X) are used to represent the definitions. Local variables (ie, not temp ops) use their offsets (ie, the offset range they cover) for X. Temp ops use their flowvar number + the size of the function's defspace for X. flow_kill_aliases() should take care of temp op aliasing, while the use of the actual offsets spanned by the variable's def should take care of any wild aliasing so structures and unions should become a non-issue. --- tools/qfcc/source/flow.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/qfcc/source/flow.c b/tools/qfcc/source/flow.c index 7adc82d06..0ea448beb 100644 --- a/tools/qfcc/source/flow.c +++ b/tools/qfcc/source/flow.c @@ -46,6 +46,7 @@ #include "dags.h" #include "def.h" +#include "defspace.h" #include "diagnostic.h" #include "dot.h" #include "flow.h" @@ -178,6 +179,8 @@ flowvar_is_global (flowvar_t *var) if (var->op->op_type != op_def) return 0; def = var->op->o.def; + if (def->alias) + def = def->alias; if (def->local) return 0; return 1; @@ -191,6 +194,8 @@ flowvar_is_param (flowvar_t *var) if (var->op->op_type != op_def) return 0; def = var->op->o.def; + if (def->alias) + def = def->alias; if (!def->local) return 0; if (!def->param) @@ -368,6 +373,23 @@ flow_build_vars (function_t *func) if (flowvar_is_global (func->vars[i])) set_add (func->global_vars, i); } + // create dummy defs for local vars + for (i = 0; i < func->num_vars; i++) { + int offset, size; + int j; + + var = func->vars[i]; + if (flowvar_is_global (var) || flowvar_is_param (var)) + continue; + if (var->op->op_type == op_temp) { + set_add (var->define, func->symtab->space->size + var->number); + } else { + offset = def_offset (var->op->o.def); + size = def_size (var->op->o.def); + for (j = offset; j < offset + size; j++) + set_add (var->define, func->num_statements + j); + } + } set_delete (stuse); set_delete (stdef); @@ -455,6 +477,20 @@ flow_reaching_defs (flowgraph_t *graph) node->reaching_defs.in = set_new (); node->reaching_defs.out = set_new (); } + // Create out for the entry dummy node using fake statement numbers. + kill = set_new (); + for (i = 0; i < graph->func->num_statements; i++) + set_add (kill, i); + out = set_new (); + for (i = 0; i < graph->func->num_vars; i++) { + var = graph->func->vars[i]; + set_union (out, var->define); // do not want alias handling here + set_difference (out, kill); // remove any gens from the function + } + graph->nodes[graph->num_nodes]->reaching_defs.out = out; + graph->nodes[graph->num_nodes]->reaching_defs.in = set_new (); + graph->nodes[graph->num_nodes]->reaching_defs.gen = set_new (); + graph->nodes[graph->num_nodes]->reaching_defs.kill = set_new (); while (changed) { changed = 0;