Commit 5254eac4 by Jeff Law Committed by Jeff Law

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
parent 9adc2b3c
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> 2013-09-25 Yvan Roux <yvan.roux@linaro.org>
* lra.c (update_inc_notes): Remove all REG_DEAD and REG_UNUSED notes. * lra.c (update_inc_notes): Remove all REG_DEAD and REG_UNUSED notes.
......
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> 2013-09-25 Tobias Burnus <burnus@net-b.de>
PR fortran/58436 PR fortran/58436
......
...@@ -43,7 +43,6 @@ expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand) ...@@ -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. */ /* We should thread the jump, through an intermediate block. */
/* { dg-final { scan-tree-dump-times "Threaded" 1 "dom1"} } */ /* { 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" } } */ /* { dg-final { cleanup-tree-dump "dom1" } } */
...@@ -641,10 +641,6 @@ bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode, ...@@ -641,10 +641,6 @@ bool multiplier_allowed_in_address_p (HOST_WIDE_INT, enum machine_mode,
addr_space_t); addr_space_t);
bool may_be_nonaddressable_p (tree expr); 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 */ /* In gimplify.c */
tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree); tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
tree force_gimple_operand (tree, gimple_seq *, bool, tree); tree force_gimple_operand (tree, gimple_seq *, bool, tree);
......
...@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h" #include "domwalk.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-ssa-threadupdate.h"
#include "langhooks.h" #include "langhooks.h"
#include "params.h" #include "params.h"
......
...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h" #include "dumpfile.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-ssa-threadupdate.h"
#include "langhooks.h" #include "langhooks.h"
#include "params.h" #include "params.h"
...@@ -753,7 +754,7 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -753,7 +754,7 @@ thread_around_empty_blocks (edge taken_edge,
bool handle_dominating_asserts, bool handle_dominating_asserts,
tree (*simplify) (gimple, gimple), tree (*simplify) (gimple, gimple),
bitmap visited, bitmap visited,
vec<edge> *path) vec<jump_thread_edge *> *path)
{ {
basic_block bb = taken_edge->dest; basic_block bb = taken_edge->dest;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
...@@ -791,8 +792,10 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -791,8 +792,10 @@ thread_around_empty_blocks (edge taken_edge,
if ((taken_edge->flags & EDGE_DFS_BACK) == 0 if ((taken_edge->flags & EDGE_DFS_BACK) == 0
&& !bitmap_bit_p (visited, taken_edge->dest->index)) && !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); bitmap_set_bit (visited, taken_edge->dest->index);
path->safe_push (taken_edge);
return thread_around_empty_blocks (taken_edge, return thread_around_empty_blocks (taken_edge,
dummy_cond, dummy_cond,
handle_dominating_asserts, handle_dominating_asserts,
...@@ -828,7 +831,11 @@ thread_around_empty_blocks (edge taken_edge, ...@@ -828,7 +831,11 @@ thread_around_empty_blocks (edge taken_edge,
if (bitmap_bit_p (visited, taken_edge->dest->index)) if (bitmap_bit_p (visited, taken_edge->dest->index))
return false; return false;
bitmap_set_bit (visited, taken_edge->dest->index); 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, thread_around_empty_blocks (taken_edge,
dummy_cond, dummy_cond,
handle_dominating_asserts, handle_dominating_asserts,
...@@ -922,9 +929,13 @@ thread_across_edge (gimple dummy_cond, ...@@ -922,9 +929,13 @@ thread_across_edge (gimple dummy_cond,
if (dest == NULL || dest == e->dest) if (dest == NULL || dest == e->dest)
goto fail; goto fail;
vec<edge> path = vNULL; vec<jump_thread_edge *> path = vNULL;
path.safe_push (e); jump_thread_edge *x
path.safe_push (taken_edge); = 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 /* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or secondary effects of threading without having to re-run DOM or
...@@ -947,8 +958,11 @@ thread_across_edge (gimple dummy_cond, ...@@ -947,8 +958,11 @@ thread_across_edge (gimple dummy_cond,
} }
remove_temporary_equivalences (stack); remove_temporary_equivalences (stack);
propagate_threaded_block_debug_into (path.last ()->dest, e->dest); propagate_threaded_block_debug_into (path.last ()->e->dest,
register_jump_thread (path, false); e->dest);
register_jump_thread (path);
for (unsigned int i = 0; i < path.length (); i++)
delete path[i];
path.release (); path.release ();
return; return;
} }
...@@ -978,15 +992,18 @@ thread_across_edge (gimple dummy_cond, ...@@ -978,15 +992,18 @@ thread_across_edge (gimple dummy_cond,
bitmap_clear (visited); bitmap_clear (visited);
bitmap_set_bit (visited, taken_edge->dest->index); bitmap_set_bit (visited, taken_edge->dest->index);
bitmap_set_bit (visited, e->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 /* Record whether or not we were able to thread through a successor
of E->dest. */ of E->dest. */
path.safe_push (e); jump_thread_edge *x = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
path.safe_push (taken_edge); path.safe_push (x);
x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
path.safe_push (x);
found = false; found = false;
if ((e->flags & EDGE_DFS_BACK) == 0 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, found = thread_around_empty_blocks (taken_edge,
dummy_cond, dummy_cond,
handle_dominating_asserts, handle_dominating_asserts,
...@@ -998,11 +1015,13 @@ thread_across_edge (gimple dummy_cond, ...@@ -998,11 +1015,13 @@ thread_across_edge (gimple dummy_cond,
record the jump threading opportunity. */ record the jump threading opportunity. */
if (found) if (found)
{ {
propagate_threaded_block_debug_into (path.last ()->dest, propagate_threaded_block_debug_into (path.last ()->e->dest,
taken_edge->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(); path.release();
} }
BITMAP_FREE (visited); BITMAP_FREE (visited);
......
...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "basic-block.h" #include "basic-block.h"
#include "function.h" #include "function.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "tree-ssa-threadupdate.h"
#include "dumpfile.h" #include "dumpfile.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "hash-table.h" #include "hash-table.h"
...@@ -1380,6 +1381,39 @@ thread_through_all_blocks (bool may_peel_loop_headers) ...@@ -1380,6 +1381,39 @@ thread_through_all_blocks (bool may_peel_loop_headers)
return retval; 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 /* Register a jump threading opportunity. We queue up all the jump
threading opportunities discovered by a pass and update the CFG threading opportunities discovered by a pass and update the CFG
and SSA form all at once. and SSA form all at once.
...@@ -1389,43 +1423,47 @@ thread_through_all_blocks (bool may_peel_loop_headers) ...@@ -1389,43 +1423,47 @@ thread_through_all_blocks (bool may_peel_loop_headers)
after fixing the SSA graph. */ after fixing the SSA graph. */
void 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 /* First make sure there are no NULL outgoing edges on the jump threading
is temporary until we convert this file to use a path representation path. That can happen for jumping to a constant address. */
throughout. */ for (unsigned int i = 0; i < path.length (); i++)
edge e = path[0]; if (path[i]->e == NULL)
edge e2 = path[1]; {
edge e3; if (dump_file && (dump_flags & TDF_DETAILS))
{
if (!through_joiner) fprintf (dump_file,
e3 = NULL; "Found NULL edge in jump threading path. Cancelling jump thread:\n");
else dump_jump_thread_path (dump_file, path);
e3 = path.last (); }
return;
}
/* This can occur if we're jumping to a constant address or if (!threaded_edges.exists ())
or something similar. Just get out now. */ threaded_edges.create (15);
if (e2 == NULL)
return;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ dump_jump_thread_path (dump_file, path);
unsigned int i;
fprintf (dump_file, /* The first entry in the vector is always the start of the
" Registering jump thread %s:", jump threading path. */
through_joiner ? "(through joiner block)" : ""); threaded_edges.safe_push (path[0]->e);
for (i = 0; i < path.length (); i++) /* In our 3-edge representation, the joiner, if it exists is always the
fprintf (dump_file, " (%d, %d); ", 2nd edge and the final block on the path is the 3rd edge. If no
path[i]->src->index, path[i]->dest->index); jointer exists, then the final block on the path is the 2nd edge
fputc ('\n', dump_file); and the 3rd edge is NULL.
}
if (!threaded_edges.exists ())
threaded_edges.create (15);
threaded_edges.safe_push (e); With upcoming improvements, we're going to be holding onto the entire
threaded_edges.safe_push (e2); path, so we'll be able to clean this wart up shortly. */
threaded_edges.safe_push (e3); 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);
}
} }
/* 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
...@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h" #include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "tree-chrec.h" #include "tree-chrec.h"
#include "tree-ssa-threadupdate.h"
#include "gimple-fold.h" #include "gimple-fold.h"
#include "expr.h" #include "expr.h"
#include "optabs.h" #include "optabs.h"
......
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