Commit 3010ee55 by Olivier Hainque Committed by Olivier Hainque

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
parent fb802d91
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> 2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
PR target/81800 PR target/81800
......
...@@ -1214,10 +1214,7 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb) ...@@ -1214,10 +1214,7 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb)
} }
/* Handle casesi dispatch insns. */ /* Handle casesi dispatch insns. */
if ((tmp = single_set (insn)) != NULL if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX
&& SET_DEST (tmp) == pc_rtx
&& GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
&& GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF
&& label_ref_label (XEXP (SET_SRC (tmp), 2)) == old_label) && label_ref_label (XEXP (SET_SRC (tmp), 2)) == old_label)
{ {
XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode, XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode,
......
...@@ -2445,6 +2445,13 @@ create_trace_edges (rtx_insn *insn) ...@@ -2445,6 +2445,13 @@ create_trace_edges (rtx_insn *insn)
rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0)); rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0));
maybe_record_trace_start (lab, insn); 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)) else if (computed_jump_p (insn))
{ {
......
...@@ -2945,6 +2945,7 @@ extern rtvec shallow_copy_rtvec (rtvec); ...@@ -2945,6 +2945,7 @@ extern rtvec shallow_copy_rtvec (rtvec);
extern bool shared_const_p (const_rtx); extern bool shared_const_p (const_rtx);
extern rtx copy_rtx (rtx); extern rtx copy_rtx (rtx);
extern enum rtx_code classify_insn (rtx); extern enum rtx_code classify_insn (rtx);
extern rtx tablejump_casesi_pattern (const rtx_insn *insn);
extern void dump_rtx_statistics (void); extern void dump_rtx_statistics (void);
/* In emit-rtl.c */ /* In emit-rtl.c */
......
...@@ -3272,6 +3272,23 @@ tablejump_p (const rtx_insn *insn, rtx_insn **labelp, ...@@ -3272,6 +3272,23 @@ tablejump_p (const rtx_insn *insn, rtx_insn **labelp,
return true; 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 /* 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 constant that is not in the constant pool and not in the condition
of an IF_THEN_ELSE. */ of an IF_THEN_ELSE. */
......
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> 2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
PR target/81800 PR target/81800
......
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;
package Casesi is
procedure Try (X : Natural);
end;
-- { dg-do run }
-- { dg-options "-O2" }
with Casesi;
procedure Test_Casesi is
begin
Casesi.Try (1);
Casesi.Try (2);
Casesi.Try (3);
end;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment