Commit 0dfa7ba1 by Eric Botcazou Committed by Eric Botcazou

stmt.c (expand_case): Try to narrow the index type if it's larger than a word.

	* stmt.c (expand_case): Try to narrow the index type if it's larger
	than a word.  Tidy up.

From-SVN: r273805
parent 5ab2422a
2019-07-25 Eric Botcazou <ebotcazou@adacore.com> 2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
* stmt.c (expand_case): Try to narrow the index type if it's larger
than a word. Tidy up.
2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
* cif-code.def (NEVER_CALL): New code. * cif-code.def (NEVER_CALL): New code.
* ipa-inline.c (want_inline_small_function_p): Fix formatting issues. * ipa-inline.c (want_inline_small_function_p): Fix formatting issues.
Set the failure to CIF_NEVER_CALL if the IPA count is zero. Set the failure to CIF_NEVER_CALL if the IPA count is zero.
......
...@@ -885,6 +885,7 @@ expand_case (gswitch *stmt) ...@@ -885,6 +885,7 @@ expand_case (gswitch *stmt)
tree index_type = TREE_TYPE (index_expr); tree index_type = TREE_TYPE (index_expr);
tree elt; tree elt;
basic_block bb = gimple_bb (stmt); basic_block bb = gimple_bb (stmt);
gimple *def_stmt;
auto_vec<simple_case_node> case_list; auto_vec<simple_case_node> case_list;
...@@ -918,6 +919,31 @@ expand_case (gswitch *stmt) ...@@ -918,6 +919,31 @@ expand_case (gswitch *stmt)
else else
maxval = fold_convert (index_type, CASE_LOW (elt)); maxval = fold_convert (index_type, CASE_LOW (elt));
/* Try to narrow the index type if it's larger than a word.
That is mainly for -O0 where an equivalent optimization
done by forward propagation is not run and is aimed at
avoiding a call to a comparison routine of libgcc. */
if (TYPE_PRECISION (index_type) > BITS_PER_WORD
&& TREE_CODE (index_expr) == SSA_NAME
&& (def_stmt = SSA_NAME_DEF_STMT (index_expr))
&& is_gimple_assign (def_stmt)
&& gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
{
tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
tree inner_index_type = TREE_TYPE (inner_index_expr);
if (INTEGRAL_TYPE_P (inner_index_type)
&& TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
&& int_fits_type_p (minval, inner_index_type)
&& int_fits_type_p (maxval, inner_index_type))
{
index_expr = inner_index_expr;
index_type = inner_index_type;
minval = fold_convert (index_type, minval);
maxval = fold_convert (index_type, maxval);
}
}
/* Compute span of values. */ /* Compute span of values. */
range = fold_build2 (MINUS_EXPR, index_type, maxval, minval); range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
...@@ -969,27 +995,22 @@ expand_case (gswitch *stmt) ...@@ -969,27 +995,22 @@ expand_case (gswitch *stmt)
rtx_insn *before_case = get_last_insn (); rtx_insn *before_case = get_last_insn ();
/* Decide how to expand this switch. /* If the default case is unreachable, then set default_label to NULL
The two options at this point are a dispatch table (casesi or so that we omit the range check when generating the dispatch table.
tablejump) or a decision tree. */ We also remove the edge to the unreachable default case. The block
itself will be automatically removed later. */
if (EDGE_COUNT (default_edge->dest->succs) == 0
&& gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
{ {
/* If the default case is unreachable, then set default_label to NULL default_label = NULL;
so that we omit the range check when generating the dispatch table. remove_edge (default_edge);
We also remove the edge to the unreachable default case. The block default_edge = NULL;
itself will be automatically removed later. */
if (EDGE_COUNT (default_edge->dest->succs) == 0
&& gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
{
default_label = NULL;
remove_edge (default_edge);
default_edge = NULL;
}
emit_case_dispatch_table (index_expr, index_type,
case_list, default_label, default_edge,
minval, maxval, range, bb);
} }
emit_case_dispatch_table (index_expr, index_type,
case_list, default_label, default_edge,
minval, maxval, range, bb);
reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case); reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
free_temp_slots (); free_temp_slots ();
......
2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/case_optimization3.ad[sb]: New test.
2019-07-25 Martin Liska <mliska@suse.cz 2019-07-25 Martin Liska <mliska@suse.cz
Dominik Infuhr <dominik.infuehr@theobroma-systems.com> Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
......
-- { dg-do compile }
package body Case_Optimization3 is
procedure Proc (Val : T_RANGE) is
begin
case Val is
when 0 =>
raise Program_Error;
when 1 =>
null;
when 2 =>
null;
when 3 =>
null;
when 4 =>
null;
when others =>
null;
end case;
end;
end Case_Optimization3;
-- { dg-final { scan-assembler-not "__ucmpdi2" } }
package Case_Optimization3 is
type T_UINT32 is range 0 .. (2 ** 32) - 1;
for T_UINT32'Size use 32;
subtype T_RANGE is T_UINT32 range 0 .. 7;
procedure Proc (Val : T_RANGE);
end Case_Optimization3;
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