From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20727 invoked by alias); 5 Mar 2014 22:29:11 -0000 Mailing-List: contact jit-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: Sender: jit-owner@gcc.gnu.org Received: (qmail 20707 invoked by uid 89); 5 Mar 2014 22:29:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.98.1 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com From: David Malcolm To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [jit] New API entrypoint: gcc_jit_function_dump_to_dot Date: Wed, 01 Jan 2014 00:00:00 -0000 Message-Id: <1394058453-7326-1-git-send-email-dmalcolm@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-SW-Source: 2014-q1/txt/msg00064.txt.bz2 Committed to branch dmalcolm/jit: gcc/jit/ * libgccjit.h (gcc_jit_function_dump_to_dot): New. * libgccjit.map (gcc_jit_function_dump_to_dot): New. * libgccjit++.h (gccjit::function::dump_to_dot): New. * libgccjit.c (gcc_jit_function_dump_to_dot): New. * internal-api.h (gcc::jit::recording::function::dump_to_dot): New. (gcc::jit::recording::block::block): Add m_index member. (gcc::jit::recording::block::dump_to_dot): New. (gcc::jit::recording::block::dump_edges_to_dot): New. * internal-api.c (gcc::jit::recording::function::new_block): Give each block an index. (gcc::jit::recording::function::dump_to_dot): New. (gcc::jit::recording::block::dump_to_dot): New. (gcc::jit::recording::block::dump_edges_to_dot): New. --- gcc/jit/ChangeLog.jit | 16 ++++++++++ gcc/jit/internal-api.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++- gcc/jit/internal-api.h | 9 +++++- gcc/jit/libgccjit++.h | 9 ++++++ gcc/jit/libgccjit.c | 11 +++++++ gcc/jit/libgccjit.h | 5 ++++ gcc/jit/libgccjit.map | 1 + 7 files changed, 128 insertions(+), 2 deletions(-) diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index b9172a1..3e2799f 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,3 +1,19 @@ +2014-03-05 David Malcolm + + * libgccjit.h (gcc_jit_function_dump_to_dot): New. + * libgccjit.map (gcc_jit_function_dump_to_dot): New. + * libgccjit++.h (gccjit::function::dump_to_dot): New. + * libgccjit.c (gcc_jit_function_dump_to_dot): New. + * internal-api.h (gcc::jit::recording::function::dump_to_dot): New. + (gcc::jit::recording::block::block): Add m_index member. + (gcc::jit::recording::block::dump_to_dot): New. + (gcc::jit::recording::block::dump_edges_to_dot): New. + * internal-api.c (gcc::jit::recording::function::new_block): Give + each block an index. + (gcc::jit::recording::function::dump_to_dot): New. + (gcc::jit::recording::block::dump_to_dot): New. + (gcc::jit::recording::block::dump_edges_to_dot): New. + 2014-03-04 David Malcolm * internal-api.c (gcc::jit::recording::memento_of_get_pointer:: diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 835aa7f..62301b2 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -1294,7 +1294,7 @@ recording::function::new_block (const char *name) gcc_assert (m_kind != GCC_JIT_FUNCTION_IMPORTED); recording::block *result = - new recording::block (this, new_string (name)); + new recording::block (this, m_blocks.length (), new_string (name)); m_ctxt->record (result); m_blocks.safe_push (result); return result; @@ -1430,6 +1430,42 @@ recording::function::validate () } } +void +recording::function::dump_to_dot (const char *path) +{ + FILE *fp = fopen (path, "w"); + if (!fp) + return; + + pretty_printer the_pp; + the_pp.buffer->stream = fp; + + pretty_printer *pp = &the_pp; + + pp_printf (pp, + "digraph %s {\n", get_debug_string ()); + + /* Blocks: */ + { + int i; + block *b; + FOR_EACH_VEC_ELT (m_blocks, i, b) + b->dump_to_dot (pp); + } + + /* Edges: */ + { + int i; + block *b; + FOR_EACH_VEC_ELT (m_blocks, i, b) + b->dump_edges_to_dot (pp); + } + + pp_printf (pp, "}\n"); + pp_flush (pp); + fclose (fp); +} + recording::string * recording::function::make_debug_string () { @@ -1573,6 +1609,47 @@ recording::block::make_debug_string () (void *)this); } +void +recording::block::dump_to_dot (pretty_printer *pp) +{ + pp_printf (pp, + ("\tblock_%d " + "[shape=record,style=filled,fillcolor=white,label=\"{"), + m_index); + pp_write_text_to_stream (pp); + if (m_name) + { + pp_string (pp, m_name->c_str ()); + pp_string (pp, ":"); + pp_newline (pp); + pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/); + } + + int i; + statement *s; + FOR_EACH_VEC_ELT (m_statements, i, s) + { + pp_string (pp, s->get_debug_string ()); + pp_newline (pp); + pp_write_text_as_dot_label_to_stream (pp, true /*for_record*/); + } + + pp_printf (pp, + "}\"];\n\n"); + pp_flush (pp); +} + +void +recording::block::dump_edges_to_dot (pretty_printer *pp) +{ + block *next[2]; + int num_succs = get_successor_blocks (&next[0], &next[1]); + for (int i = 0; i < num_succs; i++) + pp_printf (pp, + "\tblock_%d:s -> block_%d:n;\n", + m_index, next[i]->m_index); +} + /* gcc::jit::recording::global:: */ void recording::global::replay_into (replayer *r) diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index 5c11085..23352fc 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -889,6 +889,8 @@ public: void validate (); + void dump_to_dot (const char *path); + private: string * make_debug_string (); @@ -907,9 +909,10 @@ private: class block : public memento { public: - block (function *func, string *name) + block (function *func, int index, string *name) : memento (func->m_ctxt), m_func (func), + m_index (index), m_name (name), m_statements (), m_has_been_terminated (false), @@ -974,8 +977,12 @@ private: void replay_into (replayer *r); + void dump_to_dot (pretty_printer *pp); + void dump_edges_to_dot (pretty_printer *pp); + private: function *m_func; + int m_index; string *m_name; vec m_statements; bool m_has_been_terminated; diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index b349ad9..da7471b 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -293,6 +293,8 @@ namespace gccjit gcc_jit_function *get_inner_function () const; + void dump_to_dot (const std::string &path); + param get_param (int index); block new_block (); @@ -1113,6 +1115,13 @@ function::get_inner_function () const return reinterpret_cast (get_inner_object ()); } +inline void +function::dump_to_dot (const std::string &path) +{ + gcc_jit_function_dump_to_dot (get_inner_function (), + path.c_str ()); +} + inline param function::get_param (int index) { diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 75fdfeb..817d1b5 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -578,6 +578,17 @@ gcc_jit_function_get_param (gcc_jit_function *func, int index) return static_cast (func->get_param (index)); } +void +gcc_jit_function_dump_to_dot (gcc_jit_function *func, + const char *path) +{ + RETURN_IF_FAIL (func, NULL, "NULL function"); + gcc::jit::recording::context *ctxt = func->m_ctxt; + RETURN_IF_FAIL (path, ctxt, "NULL path"); + + func->dump_to_dot (path); +} + gcc_jit_block* gcc_jit_function_new_block (gcc_jit_function *func, const char *name) diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 83d4f85..e8f35b9 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -494,6 +494,11 @@ gcc_jit_function_as_object (gcc_jit_function *func); extern gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function *func, int index); +/* Emit the function in graphviz format. */ +extern void +gcc_jit_function_dump_to_dot (gcc_jit_function *func, + const char *path); + /* Create a block. The name can be NULL, or you can give it a meaningful name, which diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index ed51a62..0d9968c 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -47,6 +47,7 @@ gcc_jit_context_zero; gcc_jit_field_as_object; gcc_jit_function_as_object; + gcc_jit_function_dump_to_dot; gcc_jit_function_get_param; gcc_jit_function_new_block; gcc_jit_function_new_local; -- 1.7.11.7