This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 8b/9] Add target-independent selftests of RTL function reader
- From: David Malcolm <dmalcolm at redhat dot com>
- To: Bernd Schmidt <bschmidt at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Thu, 1 Dec 2016 21:00:10 -0500
- Subject: [PATCH 8b/9] Add target-independent selftests of RTL function reader
- Authentication-results: sourceware.org; auth=none
- References: <1480628601.24224.64.camel@redhat.com> <1480644013-3660-1-git-send-email-dmalcolm@redhat.com>
gcc/ChangeLog:
* function-tests.c (selftest::verify_three_block_rtl_cfg): Remove
"static".
* read-rtl-function.c (selftest::assert_edge_at): New function.
(ASSERT_EDGE): New macro.
(selftest::test_loading_dump_fragment_1): New function.
(selftest::test_loading_dump_fragment_2): New function.
(selftest::test_loading_labels): New function.
(selftest::test_loading_insn_with_mode): New function.
(selftest::test_loading_jump_to_label_ref): New function.
(selftest::test_loading_jump_to_return): New function.
(selftest::test_loading_jump_to_simple_return): New function.
(selftest::test_loading_note_insn_basic_block): New function.
(selftest::test_loading_note_insn_deleted): New function.
(selftest::test_loading_const_int): New function.
(selftest::test_loading_symbol_ref): New function.
(selftest::test_loading_cfg): New function.
(selftest::test_loading_bb_index): New function.
(selftest::read_rtl_function_c_tests): Call the new functions.
* selftest-rtl.h (selftest::verify_three_block_rtl_cfg): New decl.
gcc/testsuite/ChangeLog:
* selftests/asr_div1.rtl: New file.
* selftests/bb-index.rtl: New file.
* selftests/cfg-test.rtl: New file.
* selftests/const-int.rtl: New file.
* selftests/example-labels.rtl: New file.
* selftests/insn-with-mode.rtl: New file.
* selftests/jump-to-label-ref.rtl: New file.
* selftests/jump-to-return.rtl: New file.
* selftests/jump-to-simple-return.rtl: New file.
* selftests/note-insn-deleted.rtl: New file.
* selftests/note_insn_basic_block.rtl: New file.
* selftests/simple-cse.rtl: New file.
* selftests/symbol-ref.rtl: New file.
---
gcc/function-tests.c | 2 +-
gcc/read-rtl-function.c | 434 ++++++++++++++++++++++
gcc/selftest-rtl.h | 2 +
gcc/testsuite/selftests/asr_div1.rtl | 24 ++
gcc/testsuite/selftests/bb-index.rtl | 8 +
gcc/testsuite/selftests/cfg-test.rtl | 37 ++
gcc/testsuite/selftests/const-int.rtl | 20 +
gcc/testsuite/selftests/example-labels.rtl | 8 +
gcc/testsuite/selftests/insn-with-mode.rtl | 7 +
gcc/testsuite/selftests/jump-to-label-ref.rtl | 17 +
gcc/testsuite/selftests/jump-to-return.rtl | 11 +
gcc/testsuite/selftests/jump-to-simple-return.rtl | 11 +
gcc/testsuite/selftests/note-insn-deleted.rtl | 5 +
gcc/testsuite/selftests/note_insn_basic_block.rtl | 9 +
gcc/testsuite/selftests/simple-cse.rtl | 16 +
gcc/testsuite/selftests/symbol-ref.rtl | 13 +
16 files changed, 623 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/selftests/asr_div1.rtl
create mode 100644 gcc/testsuite/selftests/bb-index.rtl
create mode 100644 gcc/testsuite/selftests/cfg-test.rtl
create mode 100644 gcc/testsuite/selftests/const-int.rtl
create mode 100644 gcc/testsuite/selftests/example-labels.rtl
create mode 100644 gcc/testsuite/selftests/insn-with-mode.rtl
create mode 100644 gcc/testsuite/selftests/jump-to-label-ref.rtl
create mode 100644 gcc/testsuite/selftests/jump-to-return.rtl
create mode 100644 gcc/testsuite/selftests/jump-to-simple-return.rtl
create mode 100644 gcc/testsuite/selftests/note-insn-deleted.rtl
create mode 100644 gcc/testsuite/selftests/note_insn_basic_block.rtl
create mode 100644 gcc/testsuite/selftests/simple-cse.rtl
create mode 100644 gcc/testsuite/selftests/symbol-ref.rtl
diff --git a/gcc/function-tests.c b/gcc/function-tests.c
index b0c44cf..90fec6d 100644
--- a/gcc/function-tests.c
+++ b/gcc/function-tests.c
@@ -421,7 +421,7 @@ verify_three_block_gimple_cfg (function *fun)
/* As above, but additionally verify the RTL insns are sane. */
-static void
+void
verify_three_block_rtl_cfg (function *fun)
{
verify_three_block_cfg (fun);
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index cef834e..07c0e7a 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -1643,6 +1643,427 @@ test_parsing_regnos ()
ASSERT_EQ (LAST_VIRTUAL_REGISTER + 2, lookup_reg_by_dump_name ("%1"));
}
+/* Verify that edge E is as expected, with the src and dest basic blocks
+ having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
+ the edge having flags equal to EXPECTED_FLAGS.
+ Use LOC as the effective location when reporting failures. */
+
+static void
+assert_edge_at (const location &loc, edge e, int expected_src_idx,
+ int expected_dest_idx, int expected_flags)
+{
+ ASSERT_EQ_AT (loc, expected_src_idx, e->src->index);
+ ASSERT_EQ_AT (loc, expected_dest_idx, e->dest->index);
+ ASSERT_EQ_AT (loc, expected_flags, e->flags);
+}
+
+/* Verify that edge EDGE is as expected, with the src and dest basic blocks
+ having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
+ the edge having flags equal to EXPECTED_FLAGS. */
+
+#define ASSERT_EDGE(EDGE, EXPECTED_SRC_IDX, EXPECTED_DEST_IDX, \
+ EXPECTED_FLAGS) \
+ assert_edge_at (SELFTEST_LOCATION, EDGE, EXPECTED_SRC_IDX, \
+ EXPECTED_DEST_IDX, EXPECTED_FLAGS)
+
+/* Verify that we can load RTL dumps. */
+
+static void
+test_loading_dump_fragment_1 ()
+{
+ // TODO: filter on target?
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("asr_div1.rtl"));
+
+ /* Verify that the insns were loaded correctly. */
+ rtx_insn *insn_1 = get_insns ();
+ ASSERT_TRUE (insn_1);
+ ASSERT_EQ (1, INSN_UID (insn_1));
+ ASSERT_EQ (INSN, GET_CODE (insn_1));
+ ASSERT_EQ (SET, GET_CODE (PATTERN (insn_1)));
+ ASSERT_EQ (NULL, PREV_INSN (insn_1));
+
+ rtx_insn *insn_2 = NEXT_INSN (insn_1);
+ ASSERT_TRUE (insn_2);
+ ASSERT_EQ (2, INSN_UID (insn_2));
+ ASSERT_EQ (INSN, GET_CODE (insn_2));
+ ASSERT_EQ (insn_1, PREV_INSN (insn_2));
+ ASSERT_EQ (NULL, NEXT_INSN (insn_2));
+
+ /* Verify that registers were loaded correctly. */
+ rtx insn_1_dest = SET_DEST (PATTERN (insn_1));
+ ASSERT_EQ (REG, GET_CODE (insn_1_dest));
+ ASSERT_EQ ((LAST_VIRTUAL_REGISTER + 1) + 2, REGNO (insn_1_dest));
+ rtx insn_1_src = SET_SRC (PATTERN (insn_1));
+ ASSERT_EQ (LSHIFTRT, GET_CODE (insn_1_src));
+ rtx reg = XEXP (insn_1_src, 0);
+ ASSERT_EQ (REG, GET_CODE (reg));
+ ASSERT_EQ (LAST_VIRTUAL_REGISTER + 1, REGNO (reg));
+
+ /* Verify that get_insn_by_uid works. */
+ ASSERT_EQ (insn_1, get_insn_by_uid (1));
+ ASSERT_EQ (insn_2, get_insn_by_uid (2));
+
+ /* Verify that basic blocks were created. */
+ ASSERT_EQ (2, BLOCK_FOR_INSN (insn_1)->index);
+ ASSERT_EQ (2, BLOCK_FOR_INSN (insn_2)->index);
+
+ /* Verify that the CFG was recreated. */
+ ASSERT_TRUE (cfun);
+ verify_three_block_rtl_cfg (cfun);
+ basic_block bb2 = BASIC_BLOCK_FOR_FN (cfun, 2);
+ ASSERT_TRUE (bb2 != NULL);
+ ASSERT_EQ (BB_RTL, bb2->flags & BB_RTL);
+ ASSERT_EQ (2, bb2->index);
+ ASSERT_EQ (insn_1, BB_HEAD (bb2));
+ ASSERT_EQ (insn_2, BB_END (bb2));
+}
+
+/* Verify loading another RTL dump. */
+
+static void
+test_loading_dump_fragment_2 ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("simple-cse.rtl"));
+
+ rtx_insn *insn_1 = get_insn_by_uid (1);
+ rtx_insn *insn_2 = get_insn_by_uid (2);
+ rtx_insn *insn_3 = get_insn_by_uid (3);
+
+ rtx set1 = single_set (insn_1);
+ ASSERT_NE (NULL, set1);
+ rtx set2 = single_set (insn_2);
+ ASSERT_NE (NULL, set2);
+ rtx set3 = single_set (insn_3);
+ ASSERT_NE (NULL, set3);
+
+ rtx src1 = SET_SRC (set1);
+ ASSERT_EQ (PLUS, GET_CODE (src1));
+
+ rtx src2 = SET_SRC (set2);
+ ASSERT_EQ (PLUS, GET_CODE (src2));
+
+ /* Both src1 and src2 refer to "(reg:SI %0)".
+ Verify that we have pointer equality. */
+ rtx lhs1 = XEXP (src1, 0);
+ rtx lhs2 = XEXP (src2, 0);
+ ASSERT_EQ (lhs1, lhs2);
+
+ /* Verify that the CFG was recreated. */
+ ASSERT_TRUE (cfun);
+ verify_three_block_rtl_cfg (cfun);
+}
+
+/* Verify that CODE_LABEL insns are loaded correctly. */
+
+static void
+test_loading_labels ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("example-labels.rtl"));
+
+ rtx_insn *insn_100 = get_insn_by_uid (100);
+ ASSERT_EQ (CODE_LABEL, GET_CODE (insn_100));
+ ASSERT_EQ (100, INSN_UID (insn_100));
+ ASSERT_EQ (NULL, LABEL_NAME (insn_100));
+ ASSERT_EQ (0, LABEL_NUSES (insn_100));
+ ASSERT_EQ (30, CODE_LABEL_NUMBER (insn_100));
+
+ rtx_insn *insn_200 = get_insn_by_uid (200);
+ ASSERT_EQ (CODE_LABEL, GET_CODE (insn_200));
+ ASSERT_EQ (200, INSN_UID (insn_200));
+ ASSERT_STREQ ("some_label_name", LABEL_NAME (insn_200));
+ ASSERT_EQ (0, LABEL_NUSES (insn_200));
+ ASSERT_EQ (40, CODE_LABEL_NUMBER (insn_200));
+
+ /* Ensure that the presence of CODE_LABEL_NUMBER == 40
+ means that the next label num to be handed out will be 41. */
+ ASSERT_EQ (41, max_label_num ());
+
+ /* Ensure that label names read from a dump are GC-managed
+ and are found through the insn. */
+ forcibly_ggc_collect ();
+ ASSERT_TRUE (ggc_marked_p (insn_200));
+ ASSERT_TRUE (ggc_marked_p (LABEL_NAME (insn_200)));
+}
+
+/* Verify that the loader copes with an insn with a mode. */
+
+static void
+test_loading_insn_with_mode ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("insn-with-mode.rtl"));
+ rtx_insn *insn = get_insns ();
+ ASSERT_EQ (INSN, GET_CODE (insn));
+
+ /* Verify that the "TI" mode was set from "insn:TI". */
+ ASSERT_EQ (TImode, GET_MODE (insn));
+}
+
+/* Verify that the loader copes with a jump_insn to a label_ref. */
+
+static void
+test_loading_jump_to_label_ref ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-label-ref.rtl"));
+
+ rtx_insn *jump_insn = get_insn_by_uid (1);
+ ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
+
+ rtx_insn *barrier = get_insn_by_uid (2);
+ ASSERT_EQ (BARRIER, GET_CODE (barrier));
+
+ rtx_insn *code_label = get_insn_by_uid (100);
+ ASSERT_EQ (CODE_LABEL, GET_CODE (code_label));
+
+ /* Verify the jump_insn. */
+ ASSERT_EQ (4, BLOCK_FOR_INSN (jump_insn)->index);
+ ASSERT_EQ (SET, GET_CODE (PATTERN (jump_insn)));
+ /* Ensure that the "(pc)" is using the global singleton. */
+ ASSERT_EQ (pc_rtx, SET_DEST (PATTERN (jump_insn)));
+ // FIXME: ^^^ use ASSERT_RTX_PTR_EQ here ^^^
+ rtx label_ref = SET_SRC (PATTERN (jump_insn));
+ ASSERT_EQ (LABEL_REF, GET_CODE (label_ref));
+ ASSERT_EQ (code_label, label_ref_label (label_ref));
+ ASSERT_EQ (code_label, JUMP_LABEL (jump_insn));
+
+ /* Verify the code_label. */
+ ASSERT_EQ (5, BLOCK_FOR_INSN (code_label)->index);
+ ASSERT_EQ (NULL, LABEL_NAME (code_label));
+ ASSERT_EQ (1, LABEL_NUSES (code_label));
+
+ /* Verify the generated CFG. */
+
+ /* Locate blocks. */
+ basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+ ASSERT_TRUE (entry != NULL);
+ ASSERT_EQ (ENTRY_BLOCK, entry->index);
+
+ basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
+ ASSERT_TRUE (exit != NULL);
+ ASSERT_EQ (EXIT_BLOCK, exit->index);
+
+ basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
+ basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];
+ ASSERT_EQ (4, bb4->index);
+ ASSERT_EQ (5, bb5->index);
+
+ /* Entry block. */
+ ASSERT_EQ (NULL, entry->preds);
+ ASSERT_EQ (1, entry->succs->length ());
+ ASSERT_EDGE ((*entry->succs)[0], 0, 4, EDGE_FALLTHRU);
+
+ /* bb4. */
+ ASSERT_EQ (1, bb4->preds->length ());
+ ASSERT_EDGE ((*bb4->preds)[0], 0, 4, EDGE_FALLTHRU);
+ ASSERT_EQ (1, bb4->succs->length ());
+ ASSERT_EDGE ((*bb4->succs)[0], 4, 5, 0x0);
+
+ /* bb5. */
+ ASSERT_EQ (1, bb5->preds->length ());
+ ASSERT_EDGE ((*bb5->preds)[0], 4, 5, 0x0);
+ ASSERT_EQ (1, bb5->succs->length ());
+ ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);
+
+ /* Exit block. */
+ ASSERT_EQ (1, exit->preds->length ());
+ ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
+ ASSERT_EQ (NULL, exit->succs);
+}
+
+/* Verify that the loader copes with a jump_insn to a label_ref
+ marked "return". */
+
+static void
+test_loading_jump_to_return ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-return.rtl"));
+
+ rtx_insn *jump_insn = get_insn_by_uid (1);
+ ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
+ ASSERT_EQ (ret_rtx, JUMP_LABEL (jump_insn));
+ // FIXME: ^^^ use ASSERT_RTX_PTR_EQ here ^^^
+}
+
+/* Verify that the loader copes with a jump_insn to a label_ref
+ marked "simple_return". */
+
+static void
+test_loading_jump_to_simple_return ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION,
+ locate_file ("jump-to-simple-return.rtl"));
+
+ rtx_insn *jump_insn = get_insn_by_uid (1);
+ ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
+ ASSERT_EQ (simple_return_rtx, JUMP_LABEL (jump_insn));
+ // FIXME: ^^^ use ASSERT_RTX_PTR_EQ here ^^^
+}
+
+/* Verify that the loader copes with a NOTE_INSN_BASIC_BLOCK. */
+
+static void
+test_loading_note_insn_basic_block ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION,
+ locate_file ("note_insn_basic_block.rtl"));
+
+ rtx_insn *note = get_insn_by_uid (1);
+ ASSERT_EQ (NOTE, GET_CODE (note));
+ ASSERT_EQ (2, BLOCK_FOR_INSN (note)->index);
+
+ ASSERT_EQ (NOTE_INSN_BASIC_BLOCK, NOTE_KIND (note));
+ ASSERT_EQ (2, NOTE_BASIC_BLOCK (note)->index);
+ ASSERT_EQ (BASIC_BLOCK_FOR_FN (cfun, 2), NOTE_BASIC_BLOCK (note));
+}
+
+/* Verify that the loader copes with a NOTE_INSN_DELETED. */
+
+static void
+test_loading_note_insn_deleted ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("note-insn-deleted.rtl"));
+
+ rtx_insn *note = get_insn_by_uid (1);
+ ASSERT_EQ (NOTE, GET_CODE (note));
+ ASSERT_EQ (NOTE_INSN_DELETED, NOTE_KIND (note));
+}
+
+/* Verify that the const_int values are consolidated, since
+ pointer equality corresponds to value equality.
+ TODO: do this for all in CASE_CONST_UNIQUE. */
+
+static void
+test_loading_const_int ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("const-int.rtl"));
+
+ /* Verify that const_int values below MAX_SAVED_CONST_INT use
+ the global values. */
+ ASSERT_EQ (const0_rtx, SET_SRC (PATTERN (get_insn_by_uid (1))));
+ ASSERT_EQ (const1_rtx, SET_SRC (PATTERN (get_insn_by_uid (2))));
+ ASSERT_EQ (constm1_rtx, SET_SRC (PATTERN (get_insn_by_uid (3))));
+
+ /* Verify that other const_int values are consolidated. */
+ rtx int256 = gen_rtx_CONST_INT (SImode, 256);
+ ASSERT_EQ (int256, SET_SRC (PATTERN (get_insn_by_uid (4))));
+}
+
+/* Verify that the loader copes with a SYMBOL_REF. */
+
+static void
+test_loading_symbol_ref ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("symbol-ref.rtl"));
+
+ rtx_insn *insn = get_insns ();
+
+ rtx high = SET_SRC (PATTERN (insn));
+ ASSERT_EQ (HIGH, GET_CODE (high));
+
+ rtx symbol_ref = XEXP (high, 0);
+ ASSERT_EQ (SYMBOL_REF, GET_CODE (symbol_ref));
+
+ /* Verify that "[flags 0xc0]" was parsed. */
+ ASSERT_EQ (0xc0, SYMBOL_REF_FLAGS (symbol_ref));
+ /* TODO: we don't yet load SYMBOL_REF_DECL. */
+}
+
+/* Verify that the loader can rebuild a CFG. */
+
+static void
+test_loading_cfg ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("cfg-test.rtl"));
+
+ ASSERT_STREQ ("cfg_test", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
+
+ ASSERT_TRUE (cfun);
+
+ ASSERT_TRUE (cfun->cfg != NULL);
+ ASSERT_EQ (6, n_basic_blocks_for_fn (cfun));
+ ASSERT_EQ (6, n_edges_for_fn (cfun));
+
+ /* The "fake" basic blocks. */
+ basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+ ASSERT_TRUE (entry != NULL);
+ ASSERT_EQ (ENTRY_BLOCK, entry->index);
+
+ basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
+ ASSERT_TRUE (exit != NULL);
+ ASSERT_EQ (EXIT_BLOCK, exit->index);
+
+ /* The "real" basic blocks. */
+ basic_block bb2 = (*cfun->cfg->x_basic_block_info)[2];
+ basic_block bb3 = (*cfun->cfg->x_basic_block_info)[3];
+ basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
+ basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];
+
+ ASSERT_EQ (2, bb2->index);
+ ASSERT_EQ (3, bb3->index);
+ ASSERT_EQ (4, bb4->index);
+ ASSERT_EQ (5, bb5->index);
+
+ /* Verify connectivity. */
+
+ /* Entry block. */
+ ASSERT_EQ (NULL, entry->preds);
+ ASSERT_EQ (1, entry->succs->length ());
+ ASSERT_EDGE ((*entry->succs)[0], 0, 2, EDGE_FALLTHRU);
+
+ /* bb2. */
+ ASSERT_EQ (1, bb2->preds->length ());
+ ASSERT_EDGE ((*bb2->preds)[0], 0, 2, EDGE_FALLTHRU);
+ ASSERT_EQ (2, bb2->succs->length ());
+ ASSERT_EDGE ((*bb2->succs)[0], 2, 3, EDGE_TRUE_VALUE);
+ ASSERT_EDGE ((*bb2->succs)[1], 2, 4, EDGE_FALSE_VALUE);
+
+ /* bb3. */
+ ASSERT_EQ (1, bb3->preds->length ());
+ ASSERT_EDGE ((*bb3->preds)[0], 2, 3, EDGE_TRUE_VALUE);
+ ASSERT_EQ (1, bb3->succs->length ());
+ ASSERT_EDGE ((*bb3->succs)[0], 3, 5, EDGE_FALLTHRU);
+
+ /* bb4. */
+ ASSERT_EQ (1, bb4->preds->length ());
+ ASSERT_EDGE ((*bb4->preds)[0], 2, 4, EDGE_FALSE_VALUE);
+ ASSERT_EQ (1, bb4->succs->length ());
+ ASSERT_EDGE ((*bb4->succs)[0], 4, 5, EDGE_FALLTHRU);
+
+ /* bb5. */
+ ASSERT_EQ (2, bb5->preds->length ());
+ ASSERT_EDGE ((*bb5->preds)[0], 3, 5, EDGE_FALLTHRU);
+ ASSERT_EDGE ((*bb5->preds)[1], 4, 5, EDGE_FALLTHRU);
+ ASSERT_EQ (1, bb5->succs->length ());
+ ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);
+
+ /* Exit block. */
+ ASSERT_EQ (1, exit->preds->length ());
+ ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
+ ASSERT_EQ (NULL, exit->succs);
+}
+
+/* Verify that the loader copes with sparse block indices.
+ This testcase loads a file with a "(block 42)". */
+
+static void
+test_loading_bb_index ()
+{
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("bb-index.rtl"));
+
+ ASSERT_STREQ ("test_bb_index", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
+
+ ASSERT_TRUE (cfun);
+
+ ASSERT_TRUE (cfun->cfg != NULL);
+ ASSERT_EQ (3, n_basic_blocks_for_fn (cfun));
+ ASSERT_EQ (43, basic_block_info_for_fn (cfun)->length ());
+ ASSERT_EQ (2, n_edges_for_fn (cfun));
+
+ ASSERT_EQ (NULL, (*cfun->cfg->x_basic_block_info)[41]);
+ basic_block bb42 = (*cfun->cfg->x_basic_block_info)[42];
+ ASSERT_NE (NULL, bb42);
+ ASSERT_EQ (42, bb42->index);
+}
+
/* Run all of the selftests within this file. */
void
@@ -1650,6 +2071,19 @@ read_rtl_function_c_tests ()
{
test_edge_flags ();
test_parsing_regnos ();
+ test_loading_dump_fragment_1 ();
+ test_loading_dump_fragment_2 ();
+ test_loading_labels ();
+ test_loading_insn_with_mode ();
+ test_loading_jump_to_label_ref ();
+ test_loading_jump_to_return ();
+ test_loading_jump_to_simple_return ();
+ test_loading_note_insn_basic_block ();
+ test_loading_note_insn_deleted ();
+ test_loading_const_int ();
+ test_loading_symbol_ref ();
+ test_loading_cfg ();
+ test_loading_bb_index ();
}
} // namespace selftest
diff --git a/gcc/selftest-rtl.h b/gcc/selftest-rtl.h
index accb486..35d6437 100644
--- a/gcc/selftest-rtl.h
+++ b/gcc/selftest-rtl.h
@@ -64,6 +64,8 @@ class rtl_dump_test
extern rtx_insn *get_insn_by_uid (int uid);
+extern void verify_three_block_rtl_cfg (function *fun);
+
} /* end of namespace selftest. */
#endif /* #if CHECKING_P */
diff --git a/gcc/testsuite/selftests/asr_div1.rtl b/gcc/testsuite/selftests/asr_div1.rtl
new file mode 100644
index 0000000..1507893
--- /dev/null
+++ b/gcc/testsuite/selftests/asr_div1.rtl
@@ -0,0 +1,24 @@
+;; Taken from
+;; gcc/testsuite/gcc.dg/asr_div1.c -O2 -fdump-rtl-all -mtune=cortex-a53
+;; for aarch64, hand editing to the new format.
+
+(function "f1"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cinsn 1 (set (reg:DI %2)
+ (lshiftrt:DI (reg:DI %0)
+ (const_int 32)))
+ "../../src/gcc/testsuite/gcc.dg/asr_div1.c":14
+ (expr_list:REG_DEAD (reg:DI %0)
+ (nil)))
+ (cinsn 2 (set (reg:SI %1)
+ (ashiftrt:SI (subreg:SI (reg:DI %2) 0)
+ (const_int 3)))
+ "../../src/gcc/testsuite/gcc.dg/asr_div1.c":14
+ (expr_list:REG_DEAD (reg:DI %2)
+ (nil)))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/bb-index.rtl b/gcc/testsuite/selftests/bb-index.rtl
new file mode 100644
index 0000000..7c66f22
--- /dev/null
+++ b/gcc/testsuite/selftests/bb-index.rtl
@@ -0,0 +1,8 @@
+(function "test_bb_index"
+ (insn-chain
+ (block 42
+ (edge-from entry (flags "FALLTHRU"))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 42
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/cfg-test.rtl b/gcc/testsuite/selftests/cfg-test.rtl
new file mode 100644
index 0000000..08a0e22
--- /dev/null
+++ b/gcc/testsuite/selftests/cfg-test.rtl
@@ -0,0 +1,37 @@
+/* Example of a loading a CFG like this:
+ 0 (entry)
+ |
+ 2
+ / \
+ 3 4
+ \ /
+ 5
+ |
+ 1 (exit). */
+
+(function "cfg_test"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (edge-to 3 (flags "TRUE_VALUE"))
+ (edge-to 4 (flags "FALSE_VALUE"))
+ ) ;; block 2
+ (block 3
+ (edge-from 2 (flags "TRUE_VALUE"))
+ (cnote 2 [bb 3] NOTE_INSN_BASIC_BLOCK)
+ (edge-to 5 (flags "FALLTHRU"))
+ ) ;; block 3
+ (block 4
+ (edge-from 2 (flags "FALSE_VALUE"))
+ (cnote 3 [bb 4] NOTE_INSN_BASIC_BLOCK)
+ (edge-to 5 (flags "FALLTHRU"))
+ ) ;; block 4
+ (block 5
+ (edge-from 3 (flags "FALLTHRU"))
+ (edge-from 4 (flags "FALLTHRU"))
+ (cnote 4 [bb 5] NOTE_INSN_BASIC_BLOCK)
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 5
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/const-int.rtl b/gcc/testsuite/selftests/const-int.rtl
new file mode 100644
index 0000000..e50dd88
--- /dev/null
+++ b/gcc/testsuite/selftests/const-int.rtl
@@ -0,0 +1,20 @@
+(function "const_int_examples"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cinsn 1
+ (set (reg:SI %0) (const_int 0))
+ "test.c":2 (nil))
+ (cinsn 2
+ (set (reg:SI %1) (const_int 1))
+ "test.c":2 (nil))
+ (cinsn 3
+ (set (reg:SI %2) (const_int -1))
+ "test.c":2 (nil))
+ (cinsn 4
+ (set (reg:SI %3) (const_int 256))
+ "test.c":2 (nil))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/example-labels.rtl b/gcc/testsuite/selftests/example-labels.rtl
new file mode 100644
index 0000000..ec33bfd
--- /dev/null
+++ b/gcc/testsuite/selftests/example-labels.rtl
@@ -0,0 +1,8 @@
+(function "example_labels"
+ (insn-chain
+ (block 6
+ (clabel 100 30 (nil))
+ (clabel 200 40 ("some_label_name"))
+ ) ;; block 6
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/insn-with-mode.rtl b/gcc/testsuite/selftests/insn-with-mode.rtl
new file mode 100644
index 0000000..8c4609b
--- /dev/null
+++ b/gcc/testsuite/selftests/insn-with-mode.rtl
@@ -0,0 +1,7 @@
+(function "insn_with_mode"
+ (insn-chain
+ (block 2
+ (insn:TI 1 (set (reg:SI %0) (reg:SI %1)) (nil))
+ ) ;; block
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/jump-to-label-ref.rtl b/gcc/testsuite/selftests/jump-to-label-ref.rtl
new file mode 100644
index 0000000..29184bf
--- /dev/null
+++ b/gcc/testsuite/selftests/jump-to-label-ref.rtl
@@ -0,0 +1,17 @@
+(function "jump_to_label_ref"
+ (insn-chain
+ (block 4
+ (edge-from entry (flags "FALLTHRU"))
+ (cjump_insn 1 (set (pc) (label_ref 100))
+ "../../src/gcc/testsuite/rtl.dg/test.c":4)
+ (edge-to 5)
+ ) ;; block 4
+ (cbarrier 2)
+ (block 5
+ (edge-from 4)
+ (clabel 100 2 (nil) [1 uses])
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 5
+ ) ;; insn-chain
+) ;; function
+
diff --git a/gcc/testsuite/selftests/jump-to-return.rtl b/gcc/testsuite/selftests/jump-to-return.rtl
new file mode 100644
index 0000000..9da89ef
--- /dev/null
+++ b/gcc/testsuite/selftests/jump-to-return.rtl
@@ -0,0 +1,11 @@
+(function "jump_to_return"
+ (insn-chain
+ (block 4
+ (edge-from entry (flags "FALLTHRU"))
+ (cjump_insn 1 (return)
+ "../../src/gcc/testsuite/rtl.dg/test.c":4
+ (nil))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 4
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/jump-to-simple-return.rtl b/gcc/testsuite/selftests/jump-to-simple-return.rtl
new file mode 100644
index 0000000..5a9c1d5
--- /dev/null
+++ b/gcc/testsuite/selftests/jump-to-simple-return.rtl
@@ -0,0 +1,11 @@
+(function "jump_to_simple_return"
+ (insn-chain
+ (block 4
+ (edge-from entry (flags "FALLTHRU"))
+ (cjump_insn 1 (simple_return)
+ "../../src/gcc/testsuite/rtl.dg/test.c":4
+ (nil))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 4
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/note-insn-deleted.rtl b/gcc/testsuite/selftests/note-insn-deleted.rtl
new file mode 100644
index 0000000..a388acd
--- /dev/null
+++ b/gcc/testsuite/selftests/note-insn-deleted.rtl
@@ -0,0 +1,5 @@
+(function "example_note"
+ (insn-chain
+ (cnote 1 NOTE_INSN_DELETED)
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/note_insn_basic_block.rtl b/gcc/testsuite/selftests/note_insn_basic_block.rtl
new file mode 100644
index 0000000..e792d98
--- /dev/null
+++ b/gcc/testsuite/selftests/note_insn_basic_block.rtl
@@ -0,0 +1,9 @@
+(function "example_of_note"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cnote 1 [bb 2] NOTE_INSN_BASIC_BLOCK)
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/simple-cse.rtl b/gcc/testsuite/selftests/simple-cse.rtl
new file mode 100644
index 0000000..5fe745d
--- /dev/null
+++ b/gcc/testsuite/selftests/simple-cse.rtl
@@ -0,0 +1,16 @@
+(function "test"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cinsn 1 (set (reg:SI %1)
+ (plus:SI (reg:SI %0)
+ (const_int 1))) (nil))
+ (cinsn 2 (set (reg:SI %2)
+ (plus:SI (reg:SI %0)
+ (const_int 1))) (nil))
+ (cinsn 3 (set (mem:SI (reg:SI %3) [1 i+0 S4 A32])
+ (mult:SI (reg:SI %1) (reg:SI %2))) (nil))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
diff --git a/gcc/testsuite/selftests/symbol-ref.rtl b/gcc/testsuite/selftests/symbol-ref.rtl
new file mode 100644
index 0000000..8339eca
--- /dev/null
+++ b/gcc/testsuite/selftests/symbol-ref.rtl
@@ -0,0 +1,13 @@
+(function "example_of_symbol_ref"
+ (insn-chain
+ (block 2
+ (edge-from entry (flags "FALLTHRU"))
+ (cinsn 1
+ (set (reg:SI %0)
+ (high:SI (symbol_ref:SI ("isl_obj_map_vtable") [flags 0xc0] <var_decl 0x7fa0363ea240 isl_obj_map_vtable>)))
+ "y.c":12702
+ (nil))
+ (edge-to exit (flags "FALLTHRU"))
+ ) ;; block 2
+ ) ;; insn-chain
+) ;; function
--
1.8.5.3