aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/passes.def1
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/g++.dg/predict-loop-exit-1.C2
-rw-r--r--gcc/testsuite/g++.dg/predict-loop-exit-2.C2
-rw-r--r--gcc/testsuite/g++.dg/predict-loop-exit-3.C2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr68198.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp01.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp56.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp92.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-15.c10
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-ssa-threadbackward.c100
16 files changed, 128 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b8a9dab..8eecbfe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-09-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * passes.def (pass_early_thread_jumps): Schedule after forwprop.
+ * tree-pass.h (make_pass_early_thread_jumps): Declare.
+ * tree-ssa-threadbackward.c (fsm_find_thread_path,
+ fsm_find_thread_path, profitable_jump_thread_path,
+ fsm_find_control_statement_thread_paths,
+ find_jump_threads_backwards): Add speed_p parameter.
+ (pass_data_early_thread_jumps): New pass.
+ (make_pass_early_thread_jumps): New function.
+
2016-09-17 Andreas Schwab <schwab@suse.de>
* config/ia64/ia64.h (ASM_OUTPUT_DWARF_OFFSET): Add cast.
diff --git a/gcc/passes.def b/gcc/passes.def
index 533157d..e98a719 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
/* After CCP we rewrite no longer addressed locals into SSA
form if possible. */
NEXT_PASS (pass_forwprop);
+ NEXT_PASS (pass_early_thread_jumps);
NEXT_PASS (pass_sra_early);
/* pass_build_ealias is a dummy pass that ensures that we
execute TODO_rebuild_alias at this point. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5793f83..956977c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,17 @@
+2016-09-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/predict-loop-exit-1.C: Disable early jump threading.
+ * g++.dg/predict-loop-exit-2.C: Disable early jump threading.
+ * g++.dg/predict-loop-exit-3.C: Disable early jump threading.
+ * gcc.dg/tree-ssa/pr69196-1.c: Disable early jump threading.
+ * gcc.dg/tree-ssa/vrp01.c: Disable early jump threading.
+ * gcc.dg/tree-ssa/ssa-dom-thread-2b.c: Disable early jump threading.
+ * gcc.dg/tree-ssa/pr68198.c: Scan ethread dump.
+ * gcc.dg/tree-ssa/ssa-thread-13.c: Scan ethread dump.
+ * gcc.dg/tree-ssa/vrp56.c: Scan ethread dump.
+ * gcc.dg/tree-ssa/vrp92.c: Scan ethread dump.
+ * gcc.dg/uninit-15.c: Swap xfailed and non-xfailed alternative.
+
2016-09-18 Kirill Yukhin <kirill.yukhin@gmaile.com>
* gcc.target/i386/pr68633.c: Fix expected result.
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-1.C b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
index 88262eb..47bdf51 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-1.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-1.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate -fdisable-tree-ethread" } */
int g;
int foo();
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-2.C b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
index 15e9866..15b63ee 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-2.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate -fdisable-tree-ethread" } */
int g;
int foo();
diff --git a/gcc/testsuite/g++.dg/predict-loop-exit-3.C b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
index 61af84b..8d41742 100644
--- a/gcc/testsuite/g++.dg/predict-loop-exit-3.C
+++ b/gcc/testsuite/g++.dg/predict-loop-exit-3.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate -fdisable-tree-ethread" } */
int g;
int foo();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
index d678dc8..79e65aa 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68198.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-details" } */
+/* { dg-options "-O2 -fdump-tree-thread1-details -fdisable-tree-ethread" } */
extern void abort (void);
@@ -40,4 +40,4 @@ c_finish_omp_clauses (tree clauses)
/* There are 3 FSM jump threading opportunities, two of which will
get filtered out. */
/* { dg-final { scan-tree-dump-times "Registering FSM" 1 "thread1"} } */
-/* { dg-final { scan-tree-dump-times "FSM Thread through multiway branch without threading a multiway branch" 2 "thread1"} } */
+/* { dg-final { scan-tree-dump-times "FSM Thread through multiway branch without threading a multiway branch" 2 "ethread"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c
index 5842e28..5f92447 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target sparc*-*-* x86_64-*-* } } */
-/* { dg-options "-O2 -fdump-tree-thread1-details" } */
+/* { dg-options "-O2 -fdump-tree-thread1-details -fdisable-tree-ethread" } */
/* { dg-final { scan-tree-dump "FSM did not thread around loop and would copy too many statements" "thread1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c
index eb66136..e1c33e8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-2b.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-dom2-stats" } */
+/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-dom2-stats -fdisable-tree-ethread" } */
void foo();
void bla();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c
index f5f338b..061f223 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-13.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-details" } */
-/* { dg-final { scan-tree-dump "FSM" "thread1" } } */
+/* { dg-options "-O2 -fdump-tree-ethread-details" } */
+/* { dg-final { scan-tree-dump "FSM" "ethread" } } */
typedef struct rtx_def *rtx;
typedef const struct rtx_def *const_rtx;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp01.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp01.c
index c6d10c2..f25f276 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp01.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp01.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fdump-tree-vrp1 -fdisable-tree-ethread" } */
int
foo (int *p, int i)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp56.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp56.c
index 3a64b01..c2870c4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp56.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp56.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread1-stats" } */
+/* { dg-options "-O2 -fdump-tree-ethread-stats" } */
typedef struct basic_block_def *basic_block;
struct basic_block_def;
struct edge_def;
@@ -38,5 +38,5 @@ cleanup_empty_eh (basic_block bb)
foo ();
}
}
-/* { dg-final { scan-tree-dump "Jumps threaded: 1" "thread1"} } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 1" "ethread"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
index b096e9b..5d53750 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp92.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details -fdisable-tree-ethread" } */
void bar (void);
int foo (int i, int j)
diff --git a/gcc/testsuite/gcc.dg/uninit-15.c b/gcc/testsuite/gcc.dg/uninit-15.c
index 20bea95..6154f4b 100644
--- a/gcc/testsuite/gcc.dg/uninit-15.c
+++ b/gcc/testsuite/gcc.dg/uninit-15.c
@@ -1,16 +1,16 @@
/* PR tree-optimization/17506
We issue an uninitialized variable warning at a wrong location at
line 11, which is very confusing. Make sure we print out a note to
- make it less confusing. (xfailed alternative)
+ make it less confusing. (not xfailed alternative)
But it is of course ok if we warn in bar about uninitialized use
- of j. (not xfailed alternative) */
+ of j. (xfailed alternative) */
/* { dg-do compile } */
/* { dg-options "-O1 -Wuninitialized" } */
inline int
foo (int i)
{
- if (i) /* { dg-warning "used uninitialized in this function" "" { xfail *-*-* } } */
+ if (i) /* { dg-warning "used uninitialized in this function" } */
return 1;
return 0;
}
@@ -20,7 +20,7 @@ void baz (void);
void
bar (void)
{
- int j; /* { dg-message "note: 'j' was declared here" "" { xfail *-*-* } } */
- for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" } */
+ int j; /* { dg-message "note: 'j' was declared here" } */
+ for (; foo (j); ++j) /* { dg-warning "'j' is used uninitialized" "" { xfail *-*-* } } */
baz ();
}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index c0059de..cc87b18 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -399,6 +399,7 @@ extern gimple_opt_pass *make_pass_cd_dce (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_call_cdce (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_merge_phi (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_thread_jumps (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_early_thread_jumps (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_split_crit_edges (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_laddress (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_pre (gcc::context *ctxt);
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index 506078f..6b522ad 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -61,12 +61,14 @@ get_gimple_control_stmt (basic_block bb)
/* Return true if the CFG contains at least one path from START_BB to END_BB.
When a path is found, record in PATH the blocks from END_BB to START_BB.
VISITED_BBS is used to make sure we don't fall into an infinite loop. Bound
- the recursion to basic blocks belonging to LOOP. */
+ the recursion to basic blocks belonging to LOOP.
+ SPEED_P indicate that we could increase code size to improve the code path */
static bool
fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
vec<basic_block, va_gc> *&path,
- hash_set<basic_block> *visited_bbs, loop_p loop)
+ hash_set<basic_block> *visited_bbs, loop_p loop,
+ bool speed_p)
{
if (loop != start_bb->loop_father)
return false;
@@ -82,7 +84,8 @@ fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
edge e;
edge_iterator ei;
FOR_EACH_EDGE (e, ei, start_bb->succs)
- if (fsm_find_thread_path (e->dest, end_bb, path, visited_bbs, loop))
+ if (fsm_find_thread_path (e->dest, end_bb, path, visited_bbs, loop,
+ speed_p))
{
vec_safe_push (path, start_bb);
return true;
@@ -101,11 +104,13 @@ fsm_find_thread_path (basic_block start_bb, basic_block end_bb,
value on PATH. ARG is the value of that SSA_NAME.
BBI will be appended to PATH when we have a profitable jump threading
- path. Callers are responsible for removing BBI from PATH in that case. */
+ path. Callers are responsible for removing BBI from PATH in that case.
+
+ SPEED_P indicate that we could increase code size to improve the code path */
static edge
profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
- basic_block bbi, tree name, tree arg)
+ basic_block bbi, tree name, tree arg, bool speed_p)
{
/* 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. */
@@ -307,7 +312,7 @@ profitable_jump_thread_path (vec<basic_block, va_gc> *&path,
return NULL;
}
- if (optimize_edge_for_speed_p (taken_edge))
+ if (speed_p && optimize_edge_for_speed_p (taken_edge))
{
if (n_insns >= PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATH_INSNS))
{
@@ -422,13 +427,15 @@ convert_and_register_jump_thread_path (vec<basic_block, va_gc> *path,
/* We trace the value of the SSA_NAME NAME back through any phi nodes looking
for places where it gets a constant value and save the path. Stop after
- having recorded MAX_PATHS jump threading paths. */
+ having recorded MAX_PATHS jump threading paths.
+
+ SPEED_P indicate that we could increase code size to improve the code path */
static void
fsm_find_control_statement_thread_paths (tree name,
hash_set<basic_block> *visited_bbs,
vec<basic_block, va_gc> *&path,
- bool seen_loop_phi)
+ bool seen_loop_phi, bool speed_p)
{
/* If NAME appears in an abnormal PHI, then don't try to trace its
value back through PHI nodes. */
@@ -496,7 +503,7 @@ fsm_find_control_statement_thread_paths (tree name,
hash_set<basic_block> *visited_bbs = new hash_set<basic_block>;
if (fsm_find_thread_path (var_bb, e->src, next_path, visited_bbs,
- e->src->loop_father))
+ e->src->loop_father, speed_p))
++e_count;
delete visited_bbs;
@@ -562,7 +569,7 @@ fsm_find_control_statement_thread_paths (tree name,
/* Recursively follow SSA_NAMEs looking for a constant
definition. */
fsm_find_control_statement_thread_paths (arg, visited_bbs, path,
- seen_loop_phi);
+ seen_loop_phi, speed_p);
path->pop ();
continue;
@@ -573,7 +580,8 @@ fsm_find_control_statement_thread_paths (tree name,
/* If this is a profitable jump thread path, then convert it
into the canonical form and register it. */
- edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg);
+ edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg,
+ speed_p);
if (taken_edge)
{
if (bb_loop_depth (taken_edge->src)
@@ -589,7 +597,7 @@ fsm_find_control_statement_thread_paths (tree name,
if (TREE_CODE (arg) == SSA_NAME)
fsm_find_control_statement_thread_paths (arg, visited_bbs,
- path, seen_loop_phi);
+ path, seen_loop_phi, speed_p);
else
{
@@ -599,7 +607,7 @@ fsm_find_control_statement_thread_paths (tree name,
path->pop ();
edge taken_edge = profitable_jump_thread_path (path, var_bb,
- name, arg);
+ name, arg, speed_p);
if (taken_edge)
{
if (bb_loop_depth (taken_edge->src)
@@ -623,10 +631,11 @@ fsm_find_control_statement_thread_paths (tree name,
is a constant. Record such paths for jump threading.
It is assumed that BB ends with a control statement and that by
- finding a path where NAME is a constant, we can thread the path. */
+ finding a path where NAME is a constant, we can thread the path.
+ SPEED_P indicate that we could increase code size to improve the code path */
void
-find_jump_threads_backwards (basic_block bb)
+find_jump_threads_backwards (basic_block bb, bool speed_p)
{
gimple *stmt = get_gimple_control_stmt (bb);
if (!stmt)
@@ -656,7 +665,8 @@ find_jump_threads_backwards (basic_block bb)
hash_set<basic_block> *visited_bbs = new hash_set<basic_block>;
max_threaded_paths = PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATHS);
- fsm_find_control_statement_thread_paths (name, visited_bbs, bb_path, false);
+ fsm_find_control_statement_thread_paths (name, visited_bbs, bb_path, false,
+ speed_p);
delete visited_bbs;
vec_free (bb_path);
@@ -706,7 +716,7 @@ pass_thread_jumps::execute (function *fun)
FOR_EACH_BB_FN (bb, fun)
{
if (EDGE_COUNT (bb->succs) > 1)
- find_jump_threads_backwards (bb);
+ find_jump_threads_backwards (bb, true);
}
bool changed = thread_through_all_blocks (true);
@@ -721,3 +731,59 @@ make_pass_thread_jumps (gcc::context *ctxt)
{
return new pass_thread_jumps (ctxt);
}
+
+namespace {
+
+const pass_data pass_data_early_thread_jumps =
+{
+ GIMPLE_PASS,
+ "ethread",
+ OPTGROUP_NONE,
+ TV_TREE_SSA_THREAD_JUMPS,
+ ( PROP_cfg | PROP_ssa ),
+ 0,
+ 0,
+ 0,
+ ( TODO_cleanup_cfg | TODO_update_ssa ),
+};
+
+class pass_early_thread_jumps : public gimple_opt_pass
+{
+public:
+ pass_early_thread_jumps (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_early_thread_jumps, ctxt)
+ {}
+
+ opt_pass * clone (void) { return new pass_early_thread_jumps (m_ctxt); }
+ virtual bool gate (function *);
+ virtual unsigned int execute (function *);
+};
+
+bool
+pass_early_thread_jumps::gate (function *fun ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+
+unsigned int
+pass_early_thread_jumps::execute (function *fun)
+{
+ /* Try to thread each block with more than one successor. */
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, fun)
+ {
+ if (EDGE_COUNT (bb->succs) > 1)
+ find_jump_threads_backwards (bb, false);
+ }
+ thread_through_all_blocks (true);
+ return 0;
+}
+
+}
+
+gimple_opt_pass *
+make_pass_early_thread_jumps (gcc::context *ctxt)
+{
+ return new pass_early_thread_jumps (ctxt);
+}