summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCHENG Renquan <rqcheng@smu.edu.sg>2010-07-12 16:49:08 +0800
committerCHENG Renquan <rqcheng@smu.edu.sg>2010-07-12 16:49:08 +0800
commit6e10941cc40ffb9d3835521658e5a95d797ca11e (patch)
tree7fe1c82678aab965babade0f015137a6ada409d7
parentfc85c38529fb8c824f616d4ffaf3d1f04badd0a2 (diff)
downloadgcc-dot-gen-plugin-master.tar.gz
gcc-dot-gen-plugin-master.tar.xz
gcc-dot-gen-plugin-master.zip
various improvementsHEADmaster
-rw-r--r--Makefile2
-rw-r--r--pass-dgen.c124
2 files changed, 79 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 453fbeb..cbd24d8 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ PLUGIN_SOURCE_FILES = pass-dgen.c
PLUGIN_OBJECT_FILES = $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
GCCPLUGINS_DIR := $(shell $(GCC) -print-file-name=plugin)
-CFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(with_gmp)/include -Wall -O2
+CFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(with_gmp)/include -Wall -fPIC -O2
all: $(PLUGIN_FILE)
diff --git a/pass-dgen.c b/pass-dgen.c
index 3bf9634..76e36f8 100644
--- a/pass-dgen.c
+++ b/pass-dgen.c
@@ -30,10 +30,16 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-pass.h"
+#include "toplev.h"
int plugin_is_GPL_compatible;
+/* global variables */
static const char *plugin_name;
+static int dot_nr;
+static FILE *dot_file = NULL;
+static bool disabled = false;
+
static struct plugin_info _version_help_info =
{
"0.1", /* version */
@@ -42,23 +48,24 @@ static struct plugin_info _version_help_info =
};
static void
-gimple_cfg2dot (FILE *file)
+gimple_cfg2dot (void)
{
edge e;
edge_iterator ei;
basic_block bb;
+
const char *funcname
= lang_hooks.decl_printable_name (current_function_decl, 2);
/* Write the file header. */
- fprintf (file, "// Function %s\n", funcname);
- fprintf (file, "digraph graph_%s {\n\n", funcname);
- fprintf (file, " graph [ label=%s, labelloc=top ];\n\n", funcname);
+ fprintf (dot_file, "// Function %s\n", funcname);
+ fprintf (dot_file, "digraph graph_%s {\n\n", funcname);
+ fprintf (dot_file, " graph [ label=%s, labelloc=top ];\n\n", funcname);
/* Write blocks and edges. */
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
{
- fprintf (file, " ENTRY -> %d", e->dest->index);
+ fprintf (dot_file, " ENTRY -> %d", e->dest->index);
/* how to represent this in Graphviz dot ??? */
/* if (e->flags & EDGE_FAKE) */
@@ -66,9 +73,9 @@ gimple_cfg2dot (FILE *file)
/* else */
/* fprintf (file, " linestyle: solid priority: 100"); */
- fprintf (file, "\n");
+ fprintf (dot_file, "\n");
}
- fputc ('\n', file);
+ fputc ('\n', dot_file);
FOR_EACH_BB (bb)
{
@@ -97,65 +104,74 @@ gimple_cfg2dot (FILE *file)
else
end_name = "no-statement";
- fprintf (file, " %d [ label=\"#%d\\n%s (%d)\\n%s (%d)\" ]\n",
+ fprintf (dot_file, " %d [ label=\"#%d\\n%s (%d)\\n%s (%d)\" ]\n",
bb->index, bb->index, head_name, head_line, end_name,
end_line);
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->dest == EXIT_BLOCK_PTR)
- fprintf (file, " %d -> EXIT\n", bb->index);
+ fprintf (dot_file, " %d -> EXIT\n", bb->index);
else
- fprintf (file, " %d -> %d", bb->index, e->dest->index);
+ {
+ fprintf (dot_file, " %d -> %d", bb->index, e->dest->index);
- /* if (e->flags & EDGE_FAKE) */
- /* fprintf (file, " priority: 10 linestyle: dotted"); */
- /* else */
- /* fprintf (file, " priority: 100 linestyle: solid"); */
+ /* if (e->flags & EDGE_FAKE) */
+ /* fprintf (file, " priority: 10 linestyle: dotted"); */
+ /* else */
+ /* fprintf (file, " priority: 100 linestyle: solid"); */
- /* fprintf (file, "\n"); */
+ fprintf (dot_file, "\n");
+ }
}
if (bb->next_bb != EXIT_BLOCK_PTR)
- fputc ('\n', file);
+ fputc ('\n', dot_file);
}
- fprintf (file, "}\n\n");
+ fprintf (dot_file, "}\n\n");
}
-static unsigned int
-execute_pass_cfg2dot ()
+static void
+open_dump_file (void)
{
- static int dot_nr;
- FILE *dot_file = NULL;
-
- if (!dot_nr)
+ dot_nr = dump_register (".dot", NULL, NULL, TDF_TREE);
+
+ /* manually set dfi->state to -1 enable it,
+ because the dump_enable is static, cannot be used
+ by plugins.
+ */
+ get_dump_file_info (dot_nr)->state = -1;
+ dot_file = dump_begin (dot_nr, NULL);
+ if (dot_file)
{
- dot_nr = dump_register (".dot", NULL, NULL, TDF_TREE);
- /* manually set dfi->state to -1 enable it,
- because the dump_enable is static, cannot be used
- by plugins.
- */
- get_dump_file_info (dot_nr)->state = -1;
- dot_file = dump_begin (dot_nr, NULL);
- if (dot_file)
- {
- time_t now;
- time (&now);
- fprintf (dot_file,
- "\n// Generated by %s gcc plugin %s at %s\n",
- plugin_name, _version_help_info.version,
- ctime (&now));
- }
+ time_t now;
+ time (&now);
+ fprintf (dot_file,
+ "\n// Generated by %s gcc plugin %s at %s\n",
+ plugin_name, _version_help_info.version,
+ ctime (&now));
}
-
- if (!dot_file)
- dot_file = dump_begin (dot_nr, NULL);
- if (dot_file)
+ else
{
- gimple_cfg2dot (dot_file);
- dump_end (dot_nr, dot_file);
+ warning (0, "dot dump file open failed, diable this pass for following functions.");
+ disabled = true;
}
+}
+
+static bool
+gate_enabled (void)
+{
+ return !disabled;
+}
+
+static unsigned int
+execute_pass_cfg2dot (void)
+{
+ if (!dot_file)
+ open_dump_file ();
+
+ gimple_cfg2dot ();
return 0;
}
@@ -165,7 +181,7 @@ static struct gimple_opt_pass pass_cfg2dot =
{
GIMPLE_PASS,
"*cfg2dot", /* name */
- NULL, /* gate */
+ gate_enabled, /* gate */
execute_pass_cfg2dot, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -179,6 +195,18 @@ static struct gimple_opt_pass pass_cfg2dot =
}
};
+static void
+plugin_finish_unit (void *gcc_data,
+ void *user_data)
+{
+ if (dot_file)
+ {
+ dump_end (dot_nr, dot_file);
+ dot_file = NULL;
+ dot_nr = 0;
+ }
+}
+
int
plugin_init (struct plugin_name_args *plugin_info,
struct plugin_gcc_version *version)
@@ -191,6 +219,10 @@ plugin_init (struct plugin_name_args *plugin_info,
PLUGIN_INFO,
NULL,
&_version_help_info);
+ register_callback (plugin_name,
+ PLUGIN_FINISH_UNIT,
+ plugin_finish_unit,
+ NULL);
regi_info.pass = &pass_cfg2dot.pass;
regi_info.reference_pass_name = "cfg";