From: Olivier Hainque Date: Tue, 13 Aug 2019 11:04:52 +0000 (+0000) Subject: Handle casesi dispatch tablejumps in create_trace_edges (as well) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3010ee5514a16902c1c31fd8afbbd0285d0134c0;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 75e5c2af689..aa036ca8c52 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2019-08-13 Olivier Hainque + + * 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 PR target/81800 diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 1f222aea5d1..39fc7aa36bf 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 d6aed358484..95ba0f71026 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -2445,6 +2445,13 @@ create_trace_edges (rtx_insn *insn) rtx_insn *lab = as_a (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)) { diff --git a/gcc/rtl.h b/gcc/rtl.h index 039ab05f951..bb67a133142 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -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 268a38799d6..3c5a64e0761 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 baf1b25cf44..a24386608a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-08-13 Olivier Hainque + + * gnat.dg/casesi.ad[bs], test_casesi.adb: New test. + 2019-08-13 Wilco Dijkstra PR target/81800 diff --git a/gcc/testsuite/gnat.dg/casesi.adb b/gcc/testsuite/gnat.dg/casesi.adb new file mode 100644 index 00000000000..388489873a4 --- /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 00000000000..665fa11486a --- /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 00000000000..a4318c9df06 --- /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; + +