mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 23:32:09 +00:00
Handle jumpb statements in dot_sblock and flow graphs.
This commit is contained in:
parent
ffa08a99c2
commit
acde6ca0a0
3 changed files with 57 additions and 4 deletions
|
@ -76,8 +76,10 @@ typedef struct flowgraph_s {
|
|||
|
||||
int flow_is_cond (struct statement_s *s);
|
||||
int flow_is_goto (struct statement_s *s);
|
||||
int flow_is_jumpb (struct statement_s *s);
|
||||
int flow_is_return (struct statement_s *s);
|
||||
struct sblock_s *flow_get_target (struct statement_s *s);
|
||||
struct sblock_s **flow_get_targetlist (struct statement_s *s);
|
||||
void flow_build_vars (struct function_s *func);
|
||||
flowgraph_t *flow_build_graph (struct sblock_s *func);
|
||||
void flow_del_graph (flowgraph_t *graph);
|
||||
|
|
|
@ -66,7 +66,8 @@ static void
|
|||
flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno)
|
||||
{
|
||||
statement_t *s;
|
||||
sblock_t *target;
|
||||
sblock_t **target;
|
||||
sblock_t **target_list;
|
||||
ex_label_t *l;
|
||||
|
||||
if (sblock->dag) {
|
||||
|
@ -94,11 +95,15 @@ flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno)
|
|||
dasprintf (dstr, " </tr>\n");
|
||||
dasprintf (dstr, " </table>>];\n");
|
||||
if (sblock->next && !flow_is_goto ((statement_t *) sblock->tail)
|
||||
&& !flow_is_jumpb ((statement_t *) sblock->tail)
|
||||
&& !flow_is_return ((statement_t *) sblock->tail))
|
||||
dasprintf (dstr, " sb_%p:e -> sb_%p:s;\n", sblock, sblock->next);
|
||||
if ((target = flow_get_target ((statement_t *) sblock->tail)))
|
||||
dasprintf (dstr, " sb_%p:e -> sb_%p:s [label=\"%s\"];\n", sblock,
|
||||
target, ((statement_t *) sblock->tail)->opcode);
|
||||
if ((target_list = flow_get_targetlist ((statement_t *) sblock->tail))) {
|
||||
for (target = target_list; *target; target++)
|
||||
dasprintf (dstr, " sb_%p:e -> sb_%p:s [label=\"%s\"];\n", sblock,
|
||||
*target, ((statement_t *) sblock->tail)->opcode);
|
||||
free (target_list);
|
||||
}
|
||||
dasprintf (dstr, "\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -42,12 +42,14 @@
|
|||
#include "QF/dstring.h"
|
||||
|
||||
#include "dags.h"
|
||||
#include "def.h"
|
||||
#include "flow.h"
|
||||
#include "function.h"
|
||||
#include "qfcc.h"
|
||||
#include "set.h"
|
||||
#include "statements.h"
|
||||
#include "symtab.h"
|
||||
#include "type.h"
|
||||
|
||||
static flowloop_t *free_loops;
|
||||
static flownode_t *free_nodes;
|
||||
|
@ -229,6 +231,14 @@ flow_is_goto (statement_t *s)
|
|||
return !strcmp (s->opcode, "<GOTO>");
|
||||
}
|
||||
|
||||
int
|
||||
flow_is_jumpb (statement_t *s)
|
||||
{
|
||||
if (!s)
|
||||
return 0;
|
||||
return !strcmp (s->opcode, "<JUMPB>");
|
||||
}
|
||||
|
||||
int
|
||||
flow_is_return (statement_t *s)
|
||||
{
|
||||
|
@ -247,6 +257,36 @@ flow_get_target (statement_t *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
sblock_t **
|
||||
flow_get_targetlist (statement_t *s)
|
||||
{
|
||||
sblock_t **target_list;
|
||||
int count, i;
|
||||
def_t *table = 0;
|
||||
expr_t *e;
|
||||
|
||||
if (flow_is_cond (s)) {
|
||||
count = 1;
|
||||
} else if (flow_is_goto (s)) {
|
||||
count = 1;
|
||||
} else if (flow_is_jumpb (s)) {
|
||||
table = s->opa->o.alias->o.symbol->s.def; //FIXME check!!!
|
||||
count = table->type->t.array.size;
|
||||
}
|
||||
target_list = malloc ((count + 1) * sizeof (sblock_t *));
|
||||
target_list[count] = 0;
|
||||
if (flow_is_cond (s)) {
|
||||
target_list[0] = flow_get_target (s);
|
||||
} else if (flow_is_goto (s)) {
|
||||
target_list[0] = flow_get_target (s);
|
||||
} else if (flow_is_jumpb (s)) {
|
||||
e = table->initializer->e.block.head; //FIXME check!!!
|
||||
for (i = 0; i < count; e = e->next, i++)
|
||||
target_list[i] = e->e.labelref.label->dest;
|
||||
}
|
||||
return target_list;
|
||||
}
|
||||
|
||||
static void
|
||||
flow_find_predecessors (flowgraph_t *graph)
|
||||
{
|
||||
|
@ -413,6 +453,7 @@ flow_build_graph (sblock_t *sblock)
|
|||
flowgraph_t *graph;
|
||||
flownode_t *node;
|
||||
sblock_t *sb;
|
||||
sblock_t **target_list, **target;
|
||||
statement_t *st;
|
||||
set_iter_t *succ;
|
||||
int i, j;
|
||||
|
@ -445,6 +486,11 @@ flow_build_graph (sblock_t *sblock)
|
|||
if (flow_is_goto (st)) {
|
||||
// sb's next is never followed.
|
||||
set_add (node->successors, flow_get_target (st)->number);
|
||||
} else if (flow_is_jumpb (st)) {
|
||||
target_list = flow_get_targetlist (st);
|
||||
for (target = target_list; *target; target++)
|
||||
set_add (node->successors, (*target)->number);
|
||||
free (target_list);
|
||||
} else if (flow_is_cond (st)) {
|
||||
// branch: either sb's next or the conditional statment's
|
||||
// target will be followed.
|
||||
|
|
Loading…
Reference in a new issue