+2016-08-07 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-threadbackward.c: Include tree-inline.h
+ (profitable_jump_thread_path): Use estimate_num_insns to estimate
+ size of copied block; for cold paths reduce duplication.
+ (find_jump_threads_backwards): Remove redundant tests.
+ (pass_thread_jumps::gate): Enable for -Os.
+
2016-08-07 Jakub Jelinek <jakub@redhat.com>
PR c/72816
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats" } */
+/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */
/* { dg-final { scan-tree-dump "Jumps threaded: 16" "thread1" } } */
-/* { dg-final { scan-tree-dump "Jumps threaded: 11" "thread2" } } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 6" "thread2" } } */
/* { dg-final { scan-tree-dump "Jumps threaded: 3" "thread3" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "vrp2" } } */
#include "tree-pass.h"
#include "gimple-ssa.h"
#include "tree-phinodes.h"
+#include "tree-inline.h"
static int max_threaded_paths;
&& !(gimple_code (stmt) == GIMPLE_ASSIGN
&& gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
&& !is_gimple_debug (stmt))
- ++n_insns;
+ n_insns += estimate_num_insns (stmt, &eni_size_weights);
}
/* We do not look at the block with the threaded branch
threaded_through_latch = true;
}
+ gimple *stmt = get_gimple_control_stmt ((*path)[0]);
+ gcc_assert (stmt);
+
/* We are going to remove the control statement at the end of the
last block in the threading path. So don't count it against our
statement count. */
- n_insns--;
- gimple *stmt = get_gimple_control_stmt ((*path)[0]);
- gcc_assert (stmt);
+ n_insns-= estimate_num_insns (stmt, &eni_size_weights);
+
/* We have found a constant value for ARG. For GIMPLE_SWITCH
and GIMPLE_GOTO, we use it as-is. However, for a GIMPLE_COND
we need to substitute, fold and simplify so we can determine
return NULL;
}
- if (n_insns >= PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATH_INSNS))
+ if (optimize_edge_for_speed_p (taken_edge))
+ {
+ if (n_insns >= PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATH_INSNS))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "FSM jump-thread path not considered: "
+ "the number of instructions on the path "
+ "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
+ path->pop ();
+ return NULL;
+ }
+ }
+ else if (n_insns > 1)
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "FSM jump-thread path not considered: "
- "the number of instructions on the path "
- "exceeds PARAM_MAX_FSM_THREAD_PATH_INSNS.\n");
+ "duplication of %i insns is needed and optimizing for size.\n",
+ n_insns);
path->pop ();
return NULL;
}
void
find_jump_threads_backwards (basic_block bb)
{
- if (!flag_expensive_optimizations
- || optimize_function_for_size_p (cfun))
- return;
-
gimple *stmt = get_gimple_control_stmt (bb);
if (!stmt)
return;
bool
pass_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
{
- return (flag_expensive_optimizations
- && ! optimize_function_for_size_p (cfun));
+ return flag_expensive_optimizations;
}