mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-20 18:52:28 +00:00
[qfcc] Create du-chains from ud-chains
I'm not certain this is correct, but it seems to me that du-chains are the same information as ud-chains, but from the defining statement's point of view instead of that of the using statement.
This commit is contained in:
parent
7149a092f6
commit
e2c1da9b6a
5 changed files with 58 additions and 7 deletions
|
@ -44,7 +44,8 @@ typedef struct flowvar_s {
|
|||
struct flowvar_s *next; ///< for ALLOC
|
||||
struct set_s *use; ///< set of statements that use this var
|
||||
struct set_s *define; ///< set of statements that define this var
|
||||
struct set_s *udchains; ///< set of ud chains for this var
|
||||
struct set_s *udchains; ///< set of ud-chains for this var
|
||||
struct set_s *duchains; ///< set of du-chains for this var
|
||||
struct operand_s *op; ///< an operand using this var
|
||||
int number; ///< number of variable in func's ref list
|
||||
int flowaddr; ///< psuedo address for local and temp vars
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef struct function_s {
|
|||
int num_statements;
|
||||
int num_ud_chains;
|
||||
struct udchain_s *ud_chains;
|
||||
struct udchain_s *du_chains;
|
||||
int pseudo_addr;///< pseudo address space for flow analysis
|
||||
struct pseudoop_s *pseudo_ops;///< pseudo operands used by this function
|
||||
} function_t;
|
||||
|
|
|
@ -119,6 +119,8 @@ typedef struct statement_s {
|
|||
operand_t *kill; ///< list of auxiliary operands killed
|
||||
int first_use;
|
||||
int num_use;
|
||||
int first_def;
|
||||
int num_def;
|
||||
} statement_t;
|
||||
|
||||
typedef struct sblock_s {
|
||||
|
|
|
@ -204,11 +204,11 @@ print_flow_vars (dstring_t *dstr, flowgraph_t *graph, int level)
|
|||
dasprintf (dstr, "%*sfv_%p [shape=none,label=<\n", indent, "", graph);
|
||||
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
|
||||
"cellspacing=\"0\">\n", indent + 2, "");
|
||||
dasprintf (dstr, "%*s<tr><td colspan=\"6\">flow vars</td></tr>\n",
|
||||
dasprintf (dstr, "%*s<tr><td colspan=\"7\">flow vars</td></tr>\n",
|
||||
indent + 4, "");
|
||||
dasprintf (dstr, "%*s<tr><td>#</td><td>name</td>"
|
||||
"<td>addr</td><td>define</td><td>use</td><td>ud</td></tr>\n",
|
||||
indent + 4, "");
|
||||
"<td>addr</td><td>define</td><td>use</td><td>ud</td><td>du</td>"
|
||||
"</tr>\n", indent + 4, "");
|
||||
for (i = 0; i < graph->func->num_vars; i++) {
|
||||
var = graph->func->vars[i];
|
||||
dasprintf (dstr, "%*s<tr><td>%d</td><td>%s</td><td>%d</td><td>%s</td>",
|
||||
|
@ -218,6 +218,7 @@ print_flow_vars (dstring_t *dstr, flowgraph_t *graph, int level)
|
|||
set_as_string (var->define));
|
||||
dasprintf (dstr, "<td>%s</td>", set_as_string (var->use));
|
||||
dasprintf (dstr, "<td>%s</td>", set_as_string (var->udchains));
|
||||
dasprintf (dstr, "<td>%s</td>", set_as_string (var->duchains));
|
||||
dasprintf (dstr, "</tr>\n");
|
||||
}
|
||||
dasprintf (dstr, "%*s</table>>];\n", indent + 2, "");
|
||||
|
@ -237,6 +238,22 @@ print_flow_vars (dstring_t *dstr, flowgraph_t *graph, int level)
|
|||
indent + 4, "", i, ud.var, ud.usest, ud.defst);
|
||||
}
|
||||
dasprintf (dstr, "%*s</table>>];\n", indent + 2, "");
|
||||
|
||||
dasprintf (dstr, "%*sdu_%p [shape=none,label=<\n", indent, "", graph);
|
||||
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
|
||||
"cellspacing=\"0\">\n", indent + 2, "");
|
||||
dasprintf (dstr, "%*s<tr><td colspan=\"4\">du chains</td></tr>\n",
|
||||
indent + 4, "");
|
||||
dasprintf (dstr, "%*s<tr><td>#</td><td>var</td>"
|
||||
"<td>def</td><td>use</td></tr>\n",
|
||||
indent + 4, "");
|
||||
for (i = 0; i < graph->func->num_ud_chains; i++) {
|
||||
udchain_t du = graph->func->du_chains[i];
|
||||
dasprintf (dstr, "%*s<tr><td>%d</td><td>%d</td>"
|
||||
"<td>%d</td><td>%d</td></tr>",
|
||||
indent + 4, "", i, du.var, du.defst, du.usest);
|
||||
}
|
||||
dasprintf (dstr, "%*s</table>>];\n", indent + 2, "");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/heapsort.h"
|
||||
#include "QF/set.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
|
@ -87,7 +87,7 @@ ALLOC_STATE (flowgraph_t, graphs); ///< flow graph pool
|
|||
|
||||
/** Allocate a new flow var.
|
||||
*
|
||||
* The var's use, define and udchain sets are initialized to empty.
|
||||
* The var's use, define, udchain and duchain sets are initialized to empty.
|
||||
*/
|
||||
static flowvar_t *
|
||||
new_flowvar (void)
|
||||
|
@ -97,6 +97,7 @@ new_flowvar (void)
|
|||
var->use = set_new ();
|
||||
var->define = set_new ();
|
||||
var->udchains = set_new ();
|
||||
var->duchains = set_new ();
|
||||
return var;
|
||||
}
|
||||
|
||||
|
@ -108,6 +109,7 @@ delete_flowvar (flowvar_t *var)
|
|||
set_delete (var->use);
|
||||
set_delete (var->define);
|
||||
set_delete (var->udchains);
|
||||
set_delete (var->duchains);
|
||||
FREE (vars, var);
|
||||
}
|
||||
|
||||
|
@ -1078,6 +1080,14 @@ live_set_def (set_t *stdef, set_t *use, set_t *def)
|
|||
set_union (def, stdef);
|
||||
}
|
||||
|
||||
static int
|
||||
duchain_cmp (const void *_a, const void *_b)
|
||||
{
|
||||
const udchain_t *a = _a;
|
||||
const udchain_t *b = _b;
|
||||
return a->defst - b->defst;
|
||||
}
|
||||
|
||||
static void
|
||||
flow_build_chains (flowgraph_t *graph)
|
||||
{
|
||||
|
@ -1100,9 +1110,10 @@ flow_build_chains (flowgraph_t *graph)
|
|||
for (int i = 0; i < graph->func->num_vars; i++) {
|
||||
udchains[i] = set_new ();
|
||||
}
|
||||
int num_ud_chains;
|
||||
while (1) {
|
||||
udchain_t *ud_chains = 0;
|
||||
int num_ud_chains = 0;
|
||||
num_ud_chains = 0;
|
||||
|
||||
// count use-def chain elements
|
||||
for (int i = 0; i < graph->num_nodes; i++) {
|
||||
|
@ -1189,6 +1200,25 @@ flow_build_chains (flowgraph_t *graph)
|
|||
set_delete (reach.gen);
|
||||
set_delete (reach.kill);
|
||||
set_delete (reach.stdef);
|
||||
|
||||
graph->func->du_chains = malloc (num_ud_chains * sizeof (udchain_t));
|
||||
memcpy (graph->func->du_chains, graph->func->ud_chains,
|
||||
num_ud_chains * sizeof (udchain_t));
|
||||
heapsort (graph->func->du_chains, num_ud_chains, sizeof (udchain_t),
|
||||
duchain_cmp);
|
||||
for (int i = 0; i < num_ud_chains; i++) {
|
||||
udchain_t du = graph->func->du_chains[i];
|
||||
|
||||
flowvar_t *var = graph->func->vars[du.var];
|
||||
set_add (var->duchains, i);
|
||||
|
||||
if (du.defst < graph->func->num_statements) {
|
||||
statement_t *st = graph->func->statements[du.defst];
|
||||
if (!st->num_def++) {
|
||||
st->first_def = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue