mirror of git://gcc.gnu.org/git/gcc.git
print_rtx_function: integrate dumping of the CFG into the insn chain
gcc/ChangeLog: * function-tests.c: Include "print-rtl.h". (selftest::test_expansion_to_rtl): Call print_rtx_function on the function, and verify what is dumped. * print-rtl-function.c (print_edge): New function. (begin_any_block): New function. (end_any_block): New function. (can_have_basic_block_p): New function. (print_rtx_function): Track the basic blocks of insns in the chain, wrapping those that are within blocks within "(block)" directives. Remove the "(cfg)" directive. From-SVN: r241057
This commit is contained in:
parent
2934018d27
commit
4b77ac40f0
|
|
@ -1,3 +1,16 @@
|
||||||
|
2016-10-12 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
|
* function-tests.c: Include "print-rtl.h".
|
||||||
|
(selftest::test_expansion_to_rtl): Call print_rtx_function on the
|
||||||
|
function, and verify what is dumped.
|
||||||
|
* print-rtl-function.c (print_edge): New function.
|
||||||
|
(begin_any_block): New function.
|
||||||
|
(end_any_block): New function.
|
||||||
|
(can_have_basic_block_p): New function.
|
||||||
|
(print_rtx_function): Track the basic blocks of insns in the
|
||||||
|
chain, wrapping those that are within blocks within "(block)"
|
||||||
|
directives. Remove the "(cfg)" directive.
|
||||||
|
|
||||||
2016-10-12 David Malcolm <dmalcolm@redhat.com>
|
2016-10-12 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
* selftest.c (selftest::read_file): New function.
|
* selftest.c (selftest::read_file): New function.
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "ipa-ref.h"
|
#include "ipa-ref.h"
|
||||||
#include "cgraph.h"
|
#include "cgraph.h"
|
||||||
#include "selftest.h"
|
#include "selftest.h"
|
||||||
|
#include "print-rtl.h"
|
||||||
|
|
||||||
#if CHECKING_P
|
#if CHECKING_P
|
||||||
|
|
||||||
|
|
@ -643,6 +644,27 @@ test_expansion_to_rtl ()
|
||||||
|
|
||||||
/* ...etc; any further checks are likely to over-specify things
|
/* ...etc; any further checks are likely to over-specify things
|
||||||
and run us into target dependencies. */
|
and run us into target dependencies. */
|
||||||
|
|
||||||
|
/* Verify that print_rtl_function is sane. */
|
||||||
|
named_temp_file tmp_out (".rtl");
|
||||||
|
FILE *outfile = fopen (tmp_out.get_filename (), "w");
|
||||||
|
print_rtx_function (outfile, fun);
|
||||||
|
fclose (outfile);
|
||||||
|
|
||||||
|
char *dump = read_file (SELFTEST_LOCATION, tmp_out.get_filename ());
|
||||||
|
ASSERT_STR_CONTAINS (dump, "(function \"test_fn\"\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (insn-chain\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (block 2\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (edge-from entry (flags \"FALLTHRU\"))\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (insn "); /* ...etc. */
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (edge-to exit (flags \"FALLTHRU\"))\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " ) ;; block 2\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " ) ;; insn-chain\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " (crtl\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, " ) ;; crtl\n");
|
||||||
|
ASSERT_STR_CONTAINS (dump, ") ;; function \"test_fn\"\n");
|
||||||
|
|
||||||
|
free (dump);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Run all of the selftests within this file. */
|
/* Run all of the selftests within this file. */
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,106 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "langhooks.h"
|
#include "langhooks.h"
|
||||||
#include "emit-rtl.h"
|
#include "emit-rtl.h"
|
||||||
|
|
||||||
|
/* Print an "(edge-from)" or "(edge-to)" directive describing E
|
||||||
|
to OUTFILE. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_edge (FILE *outfile, edge e, bool from)
|
||||||
|
{
|
||||||
|
fprintf (outfile, " (%s ", from ? "edge-from" : "edge-to");
|
||||||
|
basic_block bb = from ? e->src : e->dest;
|
||||||
|
gcc_assert (bb);
|
||||||
|
switch (bb->index)
|
||||||
|
{
|
||||||
|
case ENTRY_BLOCK:
|
||||||
|
fprintf (outfile, "entry");
|
||||||
|
break;
|
||||||
|
case EXIT_BLOCK:
|
||||||
|
fprintf (outfile, "exit");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf (outfile, "%i", bb->index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Express edge flags as a string with " | " separator.
|
||||||
|
e.g. (flags "FALLTHRU | DFS_BACK"). */
|
||||||
|
fprintf (outfile, " (flags \"");
|
||||||
|
bool seen_flag = false;
|
||||||
|
#define DEF_EDGE_FLAG(NAME,IDX) \
|
||||||
|
do { \
|
||||||
|
if (e->flags & EDGE_##NAME) \
|
||||||
|
{ \
|
||||||
|
if (seen_flag) \
|
||||||
|
fprintf (outfile, " | "); \
|
||||||
|
fprintf (outfile, "%s", (#NAME)); \
|
||||||
|
seen_flag = true; \
|
||||||
|
} \
|
||||||
|
} while (0);
|
||||||
|
#include "cfg-flags.def"
|
||||||
|
#undef DEF_EDGE_FLAG
|
||||||
|
|
||||||
|
fprintf (outfile, "\"))\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If BB is non-NULL, print the start of a "(block)" directive for it
|
||||||
|
to OUTFILE, otherwise do nothing. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
begin_any_block (FILE *outfile, basic_block bb)
|
||||||
|
{
|
||||||
|
if (!bb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
|
fprintf (outfile, " (block %i\n", bb->index);
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
print_edge (outfile, e, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If BB is non-NULL, print the end of a "(block)" directive for it
|
||||||
|
to OUTFILE, otherwise do nothing. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
end_any_block (FILE *outfile, basic_block bb)
|
||||||
|
{
|
||||||
|
if (!bb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
print_edge (outfile, e, false);
|
||||||
|
fprintf (outfile, " ) ;; block %i\n", bb->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine if INSN is of a kind that can have a basic block. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
can_have_basic_block_p (const rtx_insn *insn)
|
||||||
|
{
|
||||||
|
rtx_code code = GET_CODE (insn);
|
||||||
|
if (code == BARRIER)
|
||||||
|
return false;
|
||||||
|
gcc_assert (GET_RTX_FORMAT (code)[2] == 'B');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Write FN to OUTFILE in a form suitable for parsing, with indentation
|
/* Write FN to OUTFILE in a form suitable for parsing, with indentation
|
||||||
and comments to make the structure easy for a human to grok.
|
and comments to make the structure easy for a human to grok. Track
|
||||||
|
the basic blocks of insns in the chain, wrapping those that are within
|
||||||
|
blocks within "(block)" directives.
|
||||||
|
|
||||||
Example output:
|
Example output:
|
||||||
|
|
||||||
(function "times_two"
|
(function "times_two"
|
||||||
(insn-chain
|
(insn-chain
|
||||||
(note 1 0 4 (nil) NOTE_INSN_DELETED)
|
(note 1 0 4 (nil) NOTE_INSN_DELETED)
|
||||||
|
(block 2
|
||||||
|
(edge-from entry (flags "FALLTHRU"))
|
||||||
(note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
|
(note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
|
||||||
(insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
|
(insn 2 4 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
|
||||||
(const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
|
(const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
|
||||||
|
|
@ -69,23 +161,15 @@ along with GCC; see the file COPYING3. If not see
|
||||||
(nil))
|
(nil))
|
||||||
(insn 15 14 0 2 (use (reg/i:SI 0 ax)) t.c:4 -1
|
(insn 15 14 0 2 (use (reg/i:SI 0 ax)) t.c:4 -1
|
||||||
(nil))
|
(nil))
|
||||||
) ;; insn-chain
|
(edge-to exit (flags "FALLTHRU"))
|
||||||
(cfg
|
) ;; block 2
|
||||||
(bb 0
|
) ;; insn-chain
|
||||||
(edge 0 2 (flags 0x1))
|
(crtl
|
||||||
) ;; bb
|
(return_rtx
|
||||||
(bb 2
|
(reg/i:SI 0 ax)
|
||||||
(edge 2 1 (flags 0x1))
|
) ;; return_rtx
|
||||||
) ;; bb
|
) ;; crtl
|
||||||
(bb 1
|
) ;; function "times_two"
|
||||||
) ;; bb
|
|
||||||
) ;; cfg
|
|
||||||
(crtl
|
|
||||||
(return_rtx
|
|
||||||
(reg/i:SI 0 ax)
|
|
||||||
) ;; return_rtx
|
|
||||||
) ;; crtl
|
|
||||||
) ;; function "times_two"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DEBUG_FUNCTION void
|
DEBUG_FUNCTION void
|
||||||
|
|
@ -99,27 +183,25 @@ print_rtx_function (FILE *outfile, function *fn)
|
||||||
|
|
||||||
/* The instruction chain. */
|
/* The instruction chain. */
|
||||||
fprintf (outfile, " (insn-chain\n");
|
fprintf (outfile, " (insn-chain\n");
|
||||||
|
basic_block curr_bb = NULL;
|
||||||
for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
|
||||||
print_rtl_single_with_indent (outfile, insn, 4);
|
{
|
||||||
|
basic_block insn_bb;
|
||||||
|
if (can_have_basic_block_p (insn))
|
||||||
|
insn_bb = BLOCK_FOR_INSN (insn);
|
||||||
|
else
|
||||||
|
insn_bb = NULL;
|
||||||
|
if (curr_bb != insn_bb)
|
||||||
|
{
|
||||||
|
end_any_block (outfile, curr_bb);
|
||||||
|
curr_bb = insn_bb;
|
||||||
|
begin_any_block (outfile, curr_bb);
|
||||||
|
}
|
||||||
|
print_rtl_single_with_indent (outfile, insn, curr_bb ? 6 : 4);
|
||||||
|
}
|
||||||
|
end_any_block (outfile, curr_bb);
|
||||||
fprintf (outfile, " ) ;; insn-chain\n");
|
fprintf (outfile, " ) ;; insn-chain\n");
|
||||||
|
|
||||||
/* The CFG. */
|
|
||||||
fprintf (outfile, " (cfg\n");
|
|
||||||
{
|
|
||||||
basic_block bb;
|
|
||||||
FOR_ALL_BB_FN (bb, fn)
|
|
||||||
{
|
|
||||||
fprintf (outfile, " (bb %i\n", bb->index);
|
|
||||||
edge e;
|
|
||||||
edge_iterator ei;
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
|
||||||
fprintf (outfile, " (edge %i %i (flags 0x%x))\n",
|
|
||||||
e->src->index, e->dest->index, e->flags);
|
|
||||||
fprintf (outfile, " ) ;; bb\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf (outfile, " ) ;; cfg\n");
|
|
||||||
|
|
||||||
/* Additional RTL state. */
|
/* Additional RTL state. */
|
||||||
fprintf (outfile, " (crtl\n");
|
fprintf (outfile, " (crtl\n");
|
||||||
fprintf (outfile, " (return_rtx \n");
|
fprintf (outfile, " (return_rtx \n");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue