aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2013-09-25 21:28:03 -0600
committerJeff Law <law@gcc.gnu.org>2013-09-25 21:28:03 -0600
commit5254eac41daa5fc22a65bfa47d75fa0445dee4ee (patch)
tree51aec5a2d37e7596f984fc1365e772fdecb9e80b
parent9adc2b3c52c22752ffccfce101959f82e577e0f1 (diff)
downloadgcc-5254eac41daa5fc22a65bfa47d75fa0445dee4ee.zip
gcc-5254eac41daa5fc22a65bfa47d75fa0445dee4ee.tar.gz
gcc-5254eac41daa5fc22a65bfa47d75fa0445dee4ee.tar.bz2
tree-flow.h (thread_through_all_blocks): Prototype moved into tree-ssa-threadupdate.h.
* tree-flow.h (thread_through_all_blocks): Prototype moved into tree-ssa-threadupdate.h. (register_jump_thread): Similarly. * tree-ssa-threadupdate.h: New header file. * tree-ssa-dom.c: Include tree-ssa-threadupdate.h. * tree-vrp.c: Likewise. * tree-ssa-threadedge.c: Include tree-ssa-threadupdate.h. (thread_around_empty_blocks): Change type of path vector argument to an edge,type pair from just an edge. Initialize both elements when appending to a jump threading path. Tweak references to elements appropriately. (thread_across_edge): Similarly. Release memory for the elements as needed. * tree-ssa-threadupdate.c: Include tree-ssa-threadupdate.h. (dump_jump_thread_path): New function broken out from register_jump_thread. (register_jump_thread): Use dump_jump_thread_path. Change type of path vector entries. Search the path for NULL edges and dump the path if one is found. Tweak the conversion of path to 3-edge form to use the block copy type information embedded in the path. * gcc.dg/tree-ssa/ssa-dom-thread-3.c: Update expected output. From-SVN: r202933
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c3
-rw-r--r--gcc/tree-flow.h4
-rw-r--r--gcc/tree-ssa-dom.c1
-rw-r--r--gcc/tree-ssa-threadedge.c47
-rw-r--r--gcc/tree-ssa-threadupdate.c102
-rw-r--r--gcc/tree-ssa-threadupdate.h45
-rw-r--r--gcc/tree-vrp.c1
9 files changed, 178 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5adbaeb..8871aca6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2013-09-25 Jeff Law <law@redhat.com>
+
+ * tree-flow.h (thread_through_all_blocks): Prototype moved into
+ tree-ssa-threadupdate.h.
+ (register_jump_thread): Similarly.
+ * tree-ssa-threadupdate.h: New header file.
+ * tree-ssa-dom.c: Include tree-ssa-threadupdate.h.
+ * tree-vrp.c: Likewise.
+ * tree-ssa-threadedge.c: Include tree-ssa-threadupdate.h.
+ (thread_around_empty_blocks): Change type of path vector argument to
+ an edge,type pair from just an edge. Initialize both elements when
+ appending to a jump threading path. Tweak references to elements
+ appropriately.
+ (thread_across_edge): Similarly. Release memory for the elements
+ as needed.
+ * tree-ssa-threadupdate.c: Include tree-ssa-threadupdate.h.
+ (dump_jump_thread_path): New function broken out from
+ register_jump_thread.
+ (register_jump_thread): Use dump_jump_thread_path. Change type of
+ path vector entries. Search the path for NULL edges and dump
+ the path if one is found. Tweak the conversion of path to 3-edge
+ form to use the block copy type information embedded in the path.
+
2013-09-25 Yvan Roux <yvan.roux@linaro.org>
* lra.c (update_inc_notes): Remove all REG_DEAD and REG_UNUSED notes.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 634e747..a72615c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2013-09-25 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/ssa-dom-thread-3.c: Update expected output.
+
2013-09-25 Tobias Burnus <burnus@net-b.de>
PR fortran/58436
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
index d2a1fbb..222a97b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
@@ -43,7 +43,6 @@ expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand)
}
/* We should thread the jump, through an intermediate block. */
/* { dg-final { scan-tree-dump-times "Threaded" 1 "dom1"} } */
-/* { dg-final { scan-tree-dump-times "Registering jump thread .through joiner block.: \\(.*\\); \\(.*\\); \\(.*\\);" 1 "dom1"} } */
-
+/* { dg-final { scan-tree-dump-times "Registering jump thread: \\(.*\\) incoming edge; \\(.*\\) joiner; \\(.*\\) nocopy;" 1 "dom1"} } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 2f64abc..ee69179 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -641,10 +641,6 @@ bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode,
addr_space_t);
bool may_be_nonaddressable_p (tree expr);
-/* In tree-ssa-threadupdate.c. */
-extern bool thread_through_all_blocks (bool);
-extern void register_jump_thread (vec<edge>, bool);
-
/* In gimplify.c */
tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
tree force_gimple_operand (tree, gimple_seq *, bool, tree);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index f0cc0ee..81119c3 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
+#include "tree-ssa-threadupdate.h"
#include "langhooks.h"
#include "params.h"
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 2ca56342..467d982 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
+#include "tree-ssa-threadupdate.h"
#include "langhooks.h"
#include "params.h"
@@ -753,7 +754,7 @@ thread_around_empty_blocks (edge taken_edge,
bool handle_dominating_asserts,
tree (*simplify) (gimple, gimple),
bitmap visited,
- vec<edge> *path)
+ vec<jump_thread_edge *> *path)
{
basic_block bb = taken_edge->dest;
gimple_stmt_iterator gsi;
@@ -791,8 +792,10 @@ thread_around_empty_blocks (edge taken_edge,
if ((taken_edge->flags & EDGE_DFS_BACK) == 0
&& !bitmap_bit_p (visited, taken_edge->dest->index))
{
+ jump_thread_edge *x
+ = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
+ path->safe_push (x);
bitmap_set_bit (visited, taken_edge->dest->index);
- path->safe_push (taken_edge);
return thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
@@ -828,7 +831,11 @@ thread_around_empty_blocks (edge taken_edge,
if (bitmap_bit_p (visited, taken_edge->dest->index))
return false;
bitmap_set_bit (visited, taken_edge->dest->index);
- path->safe_push (taken_edge);
+
+ jump_thread_edge *x
+ = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
+ path->safe_push (x);
+
thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
@@ -922,9 +929,13 @@ thread_across_edge (gimple dummy_cond,
if (dest == NULL || dest == e->dest)
goto fail;
- vec<edge> path = vNULL;
- path.safe_push (e);
- path.safe_push (taken_edge);
+ vec<jump_thread_edge *> path = vNULL;
+ jump_thread_edge *x
+ = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
+ path.safe_push (x);
+
+ x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
+ path.safe_push (x);
/* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or
@@ -947,8 +958,11 @@ thread_across_edge (gimple dummy_cond,
}
remove_temporary_equivalences (stack);
- propagate_threaded_block_debug_into (path.last ()->dest, e->dest);
- register_jump_thread (path, false);
+ propagate_threaded_block_debug_into (path.last ()->e->dest,
+ e->dest);
+ register_jump_thread (path);
+ for (unsigned int i = 0; i < path.length (); i++)
+ delete path[i];
path.release ();
return;
}
@@ -978,15 +992,18 @@ thread_across_edge (gimple dummy_cond,
bitmap_clear (visited);
bitmap_set_bit (visited, taken_edge->dest->index);
bitmap_set_bit (visited, e->dest->index);
- vec<edge> path = vNULL;
+ vec<jump_thread_edge *> path = vNULL;
/* Record whether or not we were able to thread through a successor
of E->dest. */
- path.safe_push (e);
- path.safe_push (taken_edge);
+ jump_thread_edge *x = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
+ path.safe_push (x);
+
+ x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
+ path.safe_push (x);
found = false;
if ((e->flags & EDGE_DFS_BACK) == 0
- || ! cond_arg_set_in_bb (path.last (), e->dest))
+ || ! cond_arg_set_in_bb (path.last ()->e, e->dest))
found = thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
@@ -998,11 +1015,13 @@ thread_across_edge (gimple dummy_cond,
record the jump threading opportunity. */
if (found)
{
- propagate_threaded_block_debug_into (path.last ()->dest,
+ propagate_threaded_block_debug_into (path.last ()->e->dest,
taken_edge->dest);
- register_jump_thread (path, true);
+ register_jump_thread (path);
}
+ for (unsigned int i = 0; i < path.length (); i++)
+ delete path[i];
path.release();
}
BITMAP_FREE (visited);
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index fd5234c..75273ca 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h"
#include "function.h"
#include "tree-ssa.h"
+#include "tree-ssa-threadupdate.h"
#include "dumpfile.h"
#include "cfgloop.h"
#include "hash-table.h"
@@ -1380,6 +1381,39 @@ thread_through_all_blocks (bool may_peel_loop_headers)
return retval;
}
+/* Dump a jump threading path, including annotations about each
+ edge in the path. */
+
+static void
+dump_jump_thread_path (FILE *dump_file, vec<jump_thread_edge *> path)
+{
+ fprintf (dump_file,
+ " Registering jump thread: (%d, %d) incoming edge; ",
+ path[0]->e->src->index, path[0]->e->dest->index);
+
+ for (unsigned int i = 1; i < path.length (); i++)
+ {
+ /* We can get paths with a NULL edge when the final destination
+ of a jump thread turns out to be a constant address. We dump
+ those paths when debugging, so we have to be prepared for that
+ possibility here. */
+ if (path[i]->e == NULL)
+ continue;
+
+ if (path[i]->type == EDGE_COPY_SRC_JOINER_BLOCK)
+ fprintf (dump_file, " (%d, %d) joiner; ",
+ path[i]->e->src->index, path[i]->e->dest->index);
+ if (path[i]->type == EDGE_COPY_SRC_BLOCK)
+ fprintf (dump_file, " (%d, %d) normal;",
+ path[i]->e->src->index, path[i]->e->dest->index);
+ if (path[i]->type == EDGE_NO_COPY_SRC_BLOCK)
+ fprintf (dump_file, " (%d, %d) nocopy;",
+ path[i]->e->src->index, path[i]->e->dest->index);
+ }
+ fputc ('\n', dump_file);
+}
+
+
/* Register a jump threading opportunity. We queue up all the jump
threading opportunities discovered by a pass and update the CFG
and SSA form all at once.
@@ -1389,43 +1423,47 @@ thread_through_all_blocks (bool may_peel_loop_headers)
after fixing the SSA graph. */
void
-register_jump_thread (vec<edge> path, bool through_joiner)
+register_jump_thread (vec<jump_thread_edge *> path)
{
- /* Convert PATH into 3 edge representation we've been using. This
- is temporary until we convert this file to use a path representation
- throughout. */
- edge e = path[0];
- edge e2 = path[1];
- edge e3;
-
- if (!through_joiner)
- e3 = NULL;
- else
- e3 = path.last ();
+ /* First make sure there are no NULL outgoing edges on the jump threading
+ path. That can happen for jumping to a constant address. */
+ for (unsigned int i = 0; i < path.length (); i++)
+ if (path[i]->e == NULL)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file,
+ "Found NULL edge in jump threading path. Cancelling jump thread:\n");
+ dump_jump_thread_path (dump_file, path);
+ }
+ return;
+ }
- /* This can occur if we're jumping to a constant address or
- or something similar. Just get out now. */
- if (e2 == NULL)
- return;
+ if (!threaded_edges.exists ())
+ threaded_edges.create (15);
if (dump_file && (dump_flags & TDF_DETAILS))
- {
- unsigned int i;
+ dump_jump_thread_path (dump_file, path);
- fprintf (dump_file,
- " Registering jump thread %s:",
- through_joiner ? "(through joiner block)" : "");
+ /* The first entry in the vector is always the start of the
+ jump threading path. */
+ threaded_edges.safe_push (path[0]->e);
- for (i = 0; i < path.length (); i++)
- fprintf (dump_file, " (%d, %d); ",
- path[i]->src->index, path[i]->dest->index);
- fputc ('\n', dump_file);
- }
-
- if (!threaded_edges.exists ())
- threaded_edges.create (15);
+ /* In our 3-edge representation, the joiner, if it exists is always the
+ 2nd edge and the final block on the path is the 3rd edge. If no
+ jointer exists, then the final block on the path is the 2nd edge
+ and the 3rd edge is NULL.
- threaded_edges.safe_push (e);
- threaded_edges.safe_push (e2);
- threaded_edges.safe_push (e3);
+ With upcoming improvements, we're going to be holding onto the entire
+ path, so we'll be able to clean this wart up shortly. */
+ if (path[1]->type == EDGE_COPY_SRC_JOINER_BLOCK)
+ {
+ threaded_edges.safe_push (path[1]->e);
+ threaded_edges.safe_push (path.last ()->e);
+ }
+ else
+ {
+ threaded_edges.safe_push (path.last ()->e);
+ threaded_edges.safe_push (NULL);
+ }
}
diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h
new file mode 100644
index 0000000..723f5bb
--- /dev/null
+++ b/gcc/tree-ssa-threadupdate.h
@@ -0,0 +1,45 @@
+/* Communication between registering jump thread requests and
+ updating the SSA/CFG for jump threading.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef _TREE_SSA_THREADUPDATE_H
+#define _TREE_SSA_THREADUPDATE_H 1
+
+/* In tree-ssa-threadupdate.c. */
+extern bool thread_through_all_blocks (bool);
+enum jump_thread_edge_type
+{
+ EDGE_START_JUMP_THREAD,
+ EDGE_COPY_SRC_BLOCK,
+ EDGE_COPY_SRC_JOINER_BLOCK,
+ EDGE_NO_COPY_SRC_BLOCK
+};
+
+class jump_thread_edge
+{
+public:
+ jump_thread_edge (edge e, enum jump_thread_edge_type type)
+ : e (e), type (type) {}
+
+ edge e;
+ enum jump_thread_edge_type type;
+};
+
+extern void register_jump_thread (vec<class jump_thread_edge *>);
+#endif
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 0d50af7..1600724 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h"
#include "tree-chrec.h"
+#include "tree-ssa-threadupdate.h"
#include "gimple-fold.h"
#include "expr.h"
#include "optabs.h"