diff options
author | Olivier Hainque <hainque@adacore.com> | 2019-08-13 11:04:52 +0000 |
---|---|---|
committer | Olivier Hainque <hainque@gcc.gnu.org> | 2019-08-13 11:04:52 +0000 |
commit | 3010ee5514a16902c1c31fd8afbbd0285d0134c0 (patch) | |
tree | a86ebb4ea1de27932e3f5b6d6b3446334d6e4f1e /gcc | |
parent | fb802d91461a2d65e9618abb6298c6ca7d39e7d7 (diff) | |
download | gcc-3010ee5514a16902c1c31fd8afbbd0285d0134c0.zip gcc-3010ee5514a16902c1c31fd8afbbd0285d0134c0.tar.gz gcc-3010ee5514a16902c1c31fd8afbbd0285d0134c0.tar.bz2 |
Handle casesi dispatch tablejumps in create_trace_edges (as well)
* rtlanal.c (tablejump_casesi_pattern): New function, to
determine if a tablejump insn is a casesi dispatcher. Extracted
from patch_jump_insn.
* rtl.h (tablejump_casesi_pattern): Declare.
* cfgrtl.c (patch_jump_insn): Use it.
* dwarf2cfi.c (create_trace_edges): Use it.
testsuite/
* gnat.dg/casesi.ad[bs], test_casesi.adb: New test.
From-SVN: r274377
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cfgrtl.c | 5 | ||||
-rw-r--r-- | gcc/dwarf2cfi.c | 7 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/casesi.adb | 28 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/casesi.ads | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/test_casesi.adb | 12 |
9 files changed, 83 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75e5c2a..aa036ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-08-13 Olivier Hainque <hainque@adacore.com> + + * rtlanal.c (tablejump_casesi_pattern): New function, to + determine if a tablejump insn is a casesi dispatcher. Extracted + from patch_jump_insn. + * rtl.h (tablejump_casesi_pattern): Declare. + * cfgrtl.c (patch_jump_insn): Use it. + * dwarf2cfi.c (create_trace_edges): Use it. + 2019-08-13 Wilco Dijkstra <wdijkstr@arm.com> PR target/81800 diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 1f222ae..39fc7aa 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1214,10 +1214,7 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb) } /* Handle casesi dispatch insns. */ - if ((tmp = single_set (insn)) != NULL - && SET_DEST (tmp) == pc_rtx - && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE - && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF + if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX && label_ref_label (XEXP (SET_SRC (tmp), 2)) == old_label) { XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode, diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index d6aed35..95ba0f7 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -2445,6 +2445,13 @@ create_trace_edges (rtx_insn *insn) rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0)); maybe_record_trace_start (lab, insn); } + + /* Handle casesi dispatch insns. */ + if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX) + { + rtx_insn * lab = label_ref_label (XEXP (SET_SRC (tmp), 2)); + maybe_record_trace_start (lab, insn); + } } else if (computed_jump_p (insn)) { @@ -2945,6 +2945,7 @@ extern rtvec shallow_copy_rtvec (rtvec); extern bool shared_const_p (const_rtx); extern rtx copy_rtx (rtx); extern enum rtx_code classify_insn (rtx); +extern rtx tablejump_casesi_pattern (const rtx_insn *insn); extern void dump_rtx_statistics (void); /* In emit-rtl.c */ diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 268a387..3c5a64e 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3272,6 +3272,23 @@ tablejump_p (const rtx_insn *insn, rtx_insn **labelp, return true; } +/* For INSN known to satisfy tablejump_p, determine if it actually is a + CASESI. Return the insn pattern if so, NULL_RTX otherwise. */ + +rtx +tablejump_casesi_pattern (const rtx_insn *insn) +{ + rtx tmp; + + if ((tmp = single_set (insn)) != NULL + && SET_DEST (tmp) == pc_rtx + && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE + && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF) + return tmp; + + return NULL_RTX; +} + /* A subroutine of computed_jump_p, return 1 if X contains a REG or MEM or constant that is not in the constant pool and not in the condition of an IF_THEN_ELSE. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index baf1b25..a243866 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-13 Olivier Hainque <hainque@adacore.com> + + * gnat.dg/casesi.ad[bs], test_casesi.adb: New test. + 2019-08-13 Wilco Dijkstra <wdijkstr@arm.com> PR target/81800 diff --git a/gcc/testsuite/gnat.dg/casesi.adb b/gcc/testsuite/gnat.dg/casesi.adb new file mode 100644 index 0000000..3884898 --- /dev/null +++ b/gcc/testsuite/gnat.dg/casesi.adb @@ -0,0 +1,28 @@ +with Ada.Assertions; +package body Casesi is + + function Process (X : Natural) return String is + begin + case X is + when 0 => raise Ada.Assertions.Assertion_Error; + when 1 => raise Ada.Assertions.Assertion_Error; + when 2 => return (1 .. 4 => 'T'); + when 3 => return (2 .. 8 => 'T'); + when 4 => return "hello"; + when others => return (1 .. 0 => <>); + end case; + end; + + procedure Try (X : Natural) is + begin + declare + Code : String := Process (X); + begin + if X < 2 then + raise Program_Error; + end if; + end; + exception + when Ada.Assertions.Assertion_Error => null; + end; +end; diff --git a/gcc/testsuite/gnat.dg/casesi.ads b/gcc/testsuite/gnat.dg/casesi.ads new file mode 100644 index 0000000..665fa11 --- /dev/null +++ b/gcc/testsuite/gnat.dg/casesi.ads @@ -0,0 +1,4 @@ + +package Casesi is + procedure Try (X : Natural); +end; diff --git a/gcc/testsuite/gnat.dg/test_casesi.adb b/gcc/testsuite/gnat.dg/test_casesi.adb new file mode 100644 index 0000000..a4318c9 --- /dev/null +++ b/gcc/testsuite/gnat.dg/test_casesi.adb @@ -0,0 +1,12 @@ +-- { dg-do run } +-- { dg-options "-O2" } + +with Casesi; +procedure Test_Casesi is +begin + Casesi.Try (1); + Casesi.Try (2); + Casesi.Try (3); +end; + + |