re PR tree-optimization/71550 (wrong code at -O3 on x86_64-linux-gnu)

PR tree-optimization/71550
	PR tree-optimization/71403
	* tree-ssa-threadbackward.c: Include tree-vectorizer.h
	(profitable_jump_thread_path): Also return boolean indicating if
	the realized path will create an irreducible loop.
	Remove loop depth tests from 71403.
	(fsm_find_control_statement_thread_paths): Remove loop depth tests
	from 71403.  If threading will create an irreducible loop, then
	throw away loop iteration and related information.

	PR tree-optimization/71550
	PR tree-optimization/71403
	* gcc.c-torture/execute/pr71550.c: New test.

From-SVN: r240727
This commit is contained in:
Jeff Law 2016-10-03 13:28:24 -06:00 committed by Jeff Law
parent 95ccd17c61
commit 0a4e5cf312
4 changed files with 64 additions and 18 deletions

View File

@ -1,3 +1,15 @@
2016-10-03 Jeff Law <law@redhat.com>
PR tree-optimization/71550
PR tree-optimization/71403
* tree-ssa-threadbackward.c: Include tree-vectorizer.h
(profitable_jump_thread_path): Also return boolean indicating if
the realized path will create an irreducible loop.
Remove loop depth tests from 71403.
(fsm_find_control_statement_thread_paths): Remove loop depth tests
from 71403. If threading will create an irreducible loop, then
throw away loop iteration and related information.
2016-10-03 Uros Bizjak <ubizjak@gmail.com> 2016-10-03 Uros Bizjak <ubizjak@gmail.com>
* configure.ac (strict_warn): Merge -Wmissing-format-attribute and * configure.ac (strict_warn): Merge -Wmissing-format-attribute and

View File

@ -1,3 +1,9 @@
2016-09-26 Jeff Law <law@redhat.com>
PR tree-optimization/71550
PR tree-optimization/71403
* gcc.c-torture/execute/pr71550.c: New test.
2016-10-03 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> 2016-10-03 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
* gcc.target/avr/torture/builtins-error.c: Add -ffat-lto-objects * gcc.target/avr/torture/builtins-error.c: Add -ffat-lto-objects

View File

@ -0,0 +1,26 @@
extern void exit (int);
int a = 3, b, c, f, g, h;
unsigned d;
char *e;
int
main ()
{
for (; a; a--)
{
int i;
if (h && i)
__builtin_printf ("%d%d", c, f);
i = 0;
for (; i < 2; i++)
if (g)
for (; d < 10; d++)
b = *e;
i = 0;
for (; i < 1; i++)
;
}
exit (0);
}

View File

@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-ssa.h" #include "gimple-ssa.h"
#include "tree-phinodes.h" #include "tree-phinodes.h"
#include "tree-inline.h" #include "tree-inline.h"
#include "tree-vectorizer.h"
static int max_threaded_paths; static int max_threaded_paths;
@ -110,7 +111,8 @@ fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
static edge static edge
profitable_jump_thread_path (vec<basic_block, va_gc> *&path, profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
basic_block bbi, tree name, tree arg, bool speed_p) basic_block bbi, tree name, tree arg, bool speed_p,
bool *creates_irreducible_loop)
{ {
/* Note BBI is not in the path yet, hence the +1 in the test below /* Note BBI is not in the path yet, hence the +1 in the test below
to make sure BBI is accounted for in the path length test. */ to make sure BBI is accounted for in the path length test. */
@ -296,12 +298,12 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
return NULL; return NULL;
} }
bool creates_irreducible_loop = false; *creates_irreducible_loop = false;
if (threaded_through_latch if (threaded_through_latch
&& loop == taken_edge->dest->loop_father && loop == taken_edge->dest->loop_father
&& (determine_bb_domination_status (loop, taken_edge->dest) && (determine_bb_domination_status (loop, taken_edge->dest)
== DOMST_NONDOMINATING)) == DOMST_NONDOMINATING))
creates_irreducible_loop = true; *creates_irreducible_loop = true;
if (path_crosses_loops) if (path_crosses_loops)
{ {
@ -343,7 +345,7 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
the path -- in that case there's little the traditional loop the path -- in that case there's little the traditional loop
optimizer would have done anyway, so an irreducible loop is not optimizer would have done anyway, so an irreducible loop is not
so bad. */ so bad. */
if (!threaded_multiway_branch && creates_irreducible_loop if (!threaded_multiway_branch && *creates_irreducible_loop
&& (n_insns * PARAM_VALUE (PARAM_FSM_SCALE_PATH_STMTS) && (n_insns * PARAM_VALUE (PARAM_FSM_SCALE_PATH_STMTS)
> path_length * PARAM_VALUE (PARAM_FSM_SCALE_PATH_BLOCKS))) > path_length * PARAM_VALUE (PARAM_FSM_SCALE_PATH_BLOCKS)))
@ -479,9 +481,6 @@ fsm_find_control_statement_thread_paths (tree name,
seen_loop_phi = true; seen_loop_phi = true;
} }
if (bb_loop_depth (last_bb_in_path) > bb_loop_depth (var_bb))
return;
/* Following the chain of SSA_NAME definitions, we jumped from a definition in /* Following the chain of SSA_NAME definitions, we jumped from a definition in
LAST_BB_IN_PATH to a definition in VAR_BB. When these basic blocks are LAST_BB_IN_PATH to a definition in VAR_BB. When these basic blocks are
different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB. */ different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB. */
@ -528,9 +527,7 @@ fsm_find_control_statement_thread_paths (tree name,
NEXT_PATH. Don't add them here to avoid pollution. */ NEXT_PATH. Don't add them here to avoid pollution. */
for (unsigned int i = 0; i < next_path->length () - 1; i++) for (unsigned int i = 0; i < next_path->length () - 1; i++)
{ {
if (visited_bbs->contains ((*next_path)[i]) if (visited_bbs->contains ((*next_path)[i]))
|| (bb_loop_depth (last_bb_in_path)
> bb_loop_depth ((*next_path)[i])))
{ {
vec_free (next_path); vec_free (next_path);
return; return;
@ -580,14 +577,16 @@ fsm_find_control_statement_thread_paths (tree name,
/* If this is a profitable jump thread path, then convert it /* If this is a profitable jump thread path, then convert it
into the canonical form and register it. */ into the canonical form and register it. */
bool irreducible = false;
edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg, edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg,
speed_p); speed_p, &irreducible);
if (taken_edge) if (taken_edge)
{ {
if (bb_loop_depth (taken_edge->src) convert_and_register_jump_thread_path (path, taken_edge);
>= bb_loop_depth (taken_edge->dest))
convert_and_register_jump_thread_path (path, taken_edge);
path->pop (); path->pop ();
if (irreducible)
vect_free_loop_info_assumptions ((*path)[0]->loop_father);
} }
} }
} }
@ -606,14 +605,17 @@ fsm_find_control_statement_thread_paths (tree name,
block at this point. So we can just pop it. */ block at this point. So we can just pop it. */
path->pop (); path->pop ();
bool irreducible = false;
edge taken_edge = profitable_jump_thread_path (path, var_bb, edge taken_edge = profitable_jump_thread_path (path, var_bb,
name, arg, speed_p); name, arg, speed_p,
&irreducible);
if (taken_edge) if (taken_edge)
{ {
if (bb_loop_depth (taken_edge->src) convert_and_register_jump_thread_path (path, taken_edge);
>= bb_loop_depth (taken_edge->dest))
convert_and_register_jump_thread_path (path, taken_edge);
path->pop (); path->pop ();
if (irreducible)
vect_free_loop_info_assumptions ((*path)[0]->loop_father);
} }
/* And put the current block back onto the path so that the /* And put the current block back onto the path so that the