Handle casesi dispatch tablejumps in create_trace_edges (as well)
authorOlivier Hainque <hainque@adacore.com>
Tue, 13 Aug 2019 11:04:52 +0000 (11:04 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Tue, 13 Aug 2019 11:04:52 +0000 (11:04 +0000)
* 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

gcc/ChangeLog
gcc/cfgrtl.c
gcc/dwarf2cfi.c
gcc/rtl.h
gcc/rtlanal.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/casesi.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/casesi.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/test_casesi.adb [new file with mode: 0644]

index 75e5c2af689636102a010f03a2e80fc295191e35..aa036ca8c52f0c194c29976a206a63509fd6b4a6 100644 (file)
@@ -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
index 1f222aea5d153e1c9f0270f50326c68ee4386bfa..39fc7aa36bf4e2752f22fd5a527c6efd8e58cd7c 100644 (file)
@@ -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,
index d6aed358484594fd2f741d97e7c3447f9ee7655a..95ba0f71026408f74634f640de7dc17f15fee987 100644 (file)
@@ -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))
        {
index 039ab05f9510023ae27e4c7b2d0ae61abb9d25a7..bb67a133142edaf04b8326a0606be2bc59e2040f 100644 (file)
--- 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 */
index 268a38799d63c8c5a193b49d7fe7738e50894d41..3c5a64e076189ce4da6266a4201aaaaa6b8697ab 100644 (file)
@@ -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.  */
index baf1b25cf44abd0e121cc07483e8d434a7d75ebb..a24386608a44ed45be7abd39ee6c6d8553dae2ad 100644 (file)
@@ -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 (file)
index 0000000..3884898
--- /dev/null
@@ -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 (file)
index 0000000..665fa11
--- /dev/null
@@ -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 (file)
index 0000000..a4318c9
--- /dev/null
@@ -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;
+
+