Create a function to generalize dot dumping.

Now, any time a graph is wanted, the file can be consistently named without
a lot of messy code.
This commit is contained in:
Bill Currie 2012-11-07 11:00:08 +09:00
parent 5051c922a5
commit c358a0e77e
9 changed files with 113 additions and 24 deletions

View file

@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS= foreign
EXTRA_DIST= class.h codespace.h cpp.h dags.h debug.h def.h defspace.h \
diagnostic.h emit.h expr.h flow.h function.h grab.h idstuff.h \
diagnostic.h dot.h emit.h expr.h flow.h function.h grab.h idstuff.h \
linker.h method.h obj_file.h obj_type.h opcodes.h options.h qfcc.h \
qfprogs.h reloc.h set.h shared.h statements.h strpool.h struct.h \
switch.h symtab.h type.h value.h

37
tools/qfcc/include/dot.h Normal file
View file

@ -0,0 +1,37 @@
/*
dot.h
General dot output support
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/11/07
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifndef dot_h
#define dot_h
void dump_dot (const char *stage, void *data,
void (*dump_func) (void *data, const char *fname));
#endif//dot_h

View file

@ -90,7 +90,6 @@ int find_operands (statement_t *s, operand_t **x, operand_t **y, operand_t **z,
sblock_t *make_statements (struct expr_s *expr);
void print_statement (statement_t *s);
void print_sblock (sblock_t *sblock, const char *filename);
void dump_sblock (sblock_t *sblock, const char *stage);
const char *operand_string (operand_t *op);
#endif//statement_h

View file

@ -40,8 +40,8 @@ bin_SCRIPTS= qfpreqcc
common_src=\
class.c codespace.c constfold.c cpp.c dags.c debug.c def.c defspace.c \
diagnostic.c dot_dag.c dot_expr.c dot_flow.c dot_sblock.c emit.c expr.c \
flow.c function.c grab.c idstuff.c linker.c method.c obj_file.c \
diagnostic.c dot.c dot_dag.c dot_expr.c dot_flow.c dot_sblock.c emit.c \
expr.c flow.c function.c grab.c idstuff.c linker.c method.c obj_file.c \
obj_type.c opcodes.c options.c qfcc.c reloc.c set.c shared.c statements.c \
strpool.c struct.c switch.c symtab.c type.c value.c

53
tools/qfcc/source/dot.c Normal file
View file

@ -0,0 +1,53 @@
/*
dot.c
General dot output support
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/11/07
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "QF/va.h"
#include "dot.h"
#include "function.h"
#include "qfcc.h"
#include "strpool.h"
void
dump_dot (const char *stage, void *data,
void (*dump_func) (void *data, const char *fname))
{
char *fname;
fname = nva ("%s.%s.%s.dot", GETSTR (pr.source_file), current_func->name,
stage);
dump_func (data, fname);
free (fname);
}

View file

@ -134,14 +134,3 @@ print_sblock (sblock_t *sblock, const char *filename)
}
dstring_delete (dstr);
}
void
dump_sblock (sblock_t *sblock, const char *stage)
{
char *fname;
fname = nva ("%s.%s.%s.dot", GETSTR (pr.source_file), current_func->name,
stage);
print_sblock (sblock, fname);
free (fname);
}

View file

@ -43,6 +43,7 @@
#include "dags.h"
#include "def.h"
#include "dot.h"
#include "flow.h"
#include "function.h"
#include "options.h"
@ -57,6 +58,12 @@ static flowloop_t *free_loops;
static flownode_t *free_nodes;
static flowgraph_t *free_graphs;
static void
dump_dot_flow (void *data, const char *fname)
{
print_flowgraph ((flowgraph_t *) data, fname);
}
static flowvar_t *
new_flowvar (void)
{
@ -245,8 +252,6 @@ flow_build_vars (function_t *func)
func->statements[s->number] = s;
sblock->dag = dag_create (sblock);
}
if (options.block_dot.dags)
dump_sblock (func->sblock, "dags");
}
}
@ -339,6 +344,8 @@ flow_data_flow (flowgraph_t *graph)
}
}
flow_live_vars (graph);
if (options.block_dot.flow)
dump_dot ("flow", graph, dump_dot_flow);
}
int

View file

@ -647,9 +647,6 @@ emit_function (function_t *f, expr_t *e)
f->graph = flow_build_graph (f->sblock);
f->graph->func = f;
flow_data_flow (f->graph);
if (options.block_dot.flow)
print_flowgraph (f->graph, nva ("%s.%s.%s.dot", GETSTR (pr.source_file),
f->name, "flow"));
emit_statements (f->sblock);
}

View file

@ -43,6 +43,7 @@
#include "dags.h"
#include "diagnostic.h"
#include "dot.h"
#include "expr.h"
#include "function.h"
#include "options.h"
@ -1433,6 +1434,12 @@ check_final_block (sblock_t *sblock)
sblock_add_statement (sblock, s);
}
static void
dump_dot_sblock (void *data, const char *fname)
{
print_sblock ((sblock_t *) data, fname);
}
sblock_t *
make_statements (expr_t *e)
{
@ -1441,18 +1448,18 @@ make_statements (expr_t *e)
// print_expr (e);
statement_slist (sblock, e);
if (options.block_dot.initial)
dump_sblock (sblock, "initial");
dump_dot ("initial", sblock, dump_dot_sblock);
thread_jumps (sblock);
if (options.block_dot.thread)
dump_sblock (sblock, "thread");
dump_dot ("thread", sblock, dump_dot_sblock);
do {
remove_dead_blocks (sblock);
} while (merge_blocks (sblock));
if (options.block_dot.dead)
dump_sblock (sblock, "dead");
dump_dot ("dead", sblock, dump_dot_sblock);
check_final_block (sblock);
if (options.block_dot.final)
dump_sblock (sblock, "final");
dump_dot ("final", sblock, dump_dot_sblock);
return sblock;
}