Minor cleanups to forward threader.

Every time we allocate a threading edge we push it onto the path in a
distinct step.  There's no need to do this in two steps, and avoiding
this, keeps us from exposing the internals of the registry.

I've also did some tiny cleanups in thread_across_edge, most importantly
removing the bitmap in favor of an auto_bitmap.

There are no functional changes.

gcc/ChangeLog:

	* tree-ssa-threadbackward.c
	(back_threader_registry::register_path): Use push_edge.
	* tree-ssa-threadedge.c
	(jump_threader::thread_around_empty_blocks): Same.
	(jump_threader::thread_through_normal_block): Same.
	(jump_threader::thread_across_edge): Same.  Also, use auto_bitmap.
	Tidy up code.
	* tree-ssa-threadupdate.c
	(jt_path_registry::allocate_thread_edge): Remove.
	(jt_path_registry::push_edge): New.
	(dump_jump_thread_path): Make static.
	* tree-ssa-threadupdate.h (allocate_thread_edge): Remove.
	(push_edge): New.
This commit is contained in:
Aldy Hernandez 2021-09-19 17:21:45 +02:00
parent 124c354ad7
commit 08900f2889
4 changed files with 30 additions and 63 deletions

View file

@ -902,15 +902,11 @@ back_threader_registry::register_path (const vec<basic_block> &m_path,
edge e = find_edge (bb1, bb2);
gcc_assert (e);
jump_thread_edge *x
= m_lowlevel_registry.allocate_thread_edge (e, EDGE_COPY_SRC_BLOCK);
jump_thread_path->safe_push (x);
m_lowlevel_registry.push_edge (jump_thread_path, e, EDGE_COPY_SRC_BLOCK);
}
jump_thread_edge *x
= m_lowlevel_registry.allocate_thread_edge (taken_edge,
EDGE_NO_COPY_SRC_BLOCK);
jump_thread_path->safe_push (x);
m_lowlevel_registry.push_edge (jump_thread_path,
taken_edge, EDGE_NO_COPY_SRC_BLOCK);
if (m_lowlevel_registry.register_jump_thread (jump_thread_path))
++m_threaded_paths;

View file

@ -898,10 +898,7 @@ jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path,
if (!bitmap_bit_p (visited, taken_edge->dest->index))
{
jump_thread_edge *x
= m_registry->allocate_thread_edge (taken_edge,
EDGE_NO_COPY_SRC_BLOCK);
path->safe_push (x);
m_registry->push_edge (path, taken_edge, EDGE_NO_COPY_SRC_BLOCK);
bitmap_set_bit (visited, taken_edge->dest->index);
return thread_around_empty_blocks (path, taken_edge, visited);
}
@ -942,10 +939,7 @@ jump_threader::thread_around_empty_blocks (vec<jump_thread_edge *> *path,
return false;
bitmap_set_bit (visited, taken_edge->dest->index);
jump_thread_edge *x
= m_registry->allocate_thread_edge (taken_edge,
EDGE_NO_COPY_SRC_BLOCK);
path->safe_push (x);
m_registry->push_edge (path, taken_edge, EDGE_NO_COPY_SRC_BLOCK);
thread_around_empty_blocks (path, taken_edge, visited);
return true;
@ -1051,16 +1045,9 @@ jump_threader::thread_through_normal_block (vec<jump_thread_edge *> *path,
/* Only push the EDGE_START_JUMP_THREAD marker if this is
first edge on the path. */
if (path->length () == 0)
{
jump_thread_edge *x
= m_registry->allocate_thread_edge (e, EDGE_START_JUMP_THREAD);
path->safe_push (x);
}
m_registry->push_edge (path, e, EDGE_START_JUMP_THREAD);
jump_thread_edge *x
= m_registry->allocate_thread_edge (taken_edge,
EDGE_COPY_SRC_BLOCK);
path->safe_push (x);
m_registry->push_edge (path, taken_edge, EDGE_COPY_SRC_BLOCK);
/* See if we can thread through DEST as well, this helps capture
secondary effects of threading without having to re-run DOM or
@ -1146,53 +1133,43 @@ edge_forwards_cmp_to_conditional_jump_through_empty_bb_p (edge e)
void
jump_threader::thread_across_edge (edge e)
{
bitmap visited = BITMAP_ALLOC (NULL);
auto_bitmap visited;
m_state->push (e);
stmt_count = 0;
vec<jump_thread_edge *> *path = m_registry->allocate_thread_path ();
bitmap_clear (visited);
bitmap_set_bit (visited, e->src->index);
bitmap_set_bit (visited, e->dest->index);
int threaded;
int threaded = 0;
if ((e->flags & EDGE_DFS_BACK) == 0)
threaded = thread_through_normal_block (path, e, visited);
else
threaded = 0;
if (threaded > 0)
{
propagate_threaded_block_debug_into (path->last ()->e->dest,
e->dest);
BITMAP_FREE (visited);
m_registry->register_jump_thread (path);
m_state->pop ();
return;
}
else
{
/* Negative and zero return values indicate no threading was possible,
thus there should be no edges on the thread path and no need to walk
through the vector entries. */
gcc_assert (path->length () == 0);
path->release ();
/* A negative status indicates the target block was deemed too big to
duplicate. Just quit now rather than trying to use the block as
a joiner in a jump threading path.
gcc_checking_assert (path->length () == 0);
path->release ();
if (threaded < 0)
{
/* The target block was deemed too big to duplicate. Just quit
now rather than trying to use the block as a joiner in a jump
threading path.
This prevents unnecessary code growth, but more importantly if we
do not look at all the statements in the block, then we may have
missed some invalidations if we had traversed a backedge! */
if (threaded < 0)
{
BITMAP_FREE (visited);
m_state->pop ();
return;
}
m_state->pop ();
return;
}
/* We were unable to determine what out edge from E->dest is taken. However,
@ -1217,7 +1194,6 @@ jump_threader::thread_across_edge (edge e)
if (taken_edge->flags & EDGE_COMPLEX)
{
m_state->pop ();
BITMAP_FREE (visited);
return;
}
@ -1235,17 +1211,11 @@ jump_threader::thread_across_edge (edge e)
bitmap_set_bit (visited, e->src->index);
bitmap_set_bit (visited, e->dest->index);
bitmap_set_bit (visited, taken_edge->dest->index);
vec<jump_thread_edge *> *path = m_registry->allocate_thread_path ();
m_registry->push_edge (path, e, EDGE_START_JUMP_THREAD);
m_registry->push_edge (path, taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
/* Record whether or not we were able to thread through a successor
of E->dest. */
jump_thread_edge *x
= m_registry->allocate_thread_edge (e, EDGE_START_JUMP_THREAD);
path->safe_push (x);
x = m_registry->allocate_thread_edge (taken_edge,
EDGE_COPY_SRC_JOINER_BLOCK);
path->safe_push (x);
found = thread_around_empty_blocks (path, taken_edge, visited);
if (!found)
@ -1267,7 +1237,6 @@ jump_threader::thread_across_edge (edge e)
m_state->pop ();
}
BITMAP_FREE (visited);
}
m_state->pop ();

View file

@ -196,10 +196,12 @@ back_jt_path_registry::back_jt_path_registry ()
{
}
jump_thread_edge *
jt_path_registry::allocate_thread_edge (edge e, jump_thread_edge_type t)
void
jt_path_registry::push_edge (vec<jump_thread_edge *> *path,
edge e, jump_thread_edge_type type)
{
return m_allocator.allocate_thread_edge (e, t);
jump_thread_edge *x = m_allocator.allocate_thread_edge (e, type);
path->safe_push (x);
}
vec<jump_thread_edge *> *
@ -211,9 +213,9 @@ jt_path_registry::allocate_thread_path ()
/* Dump a jump threading path, including annotations about each
edge in the path. */
void
static void
dump_jump_thread_path (FILE *dump_file,
const vec<jump_thread_edge *> path,
const vec<jump_thread_edge *> &path,
bool registering)
{
fprintf (dump_file,

View file

@ -66,7 +66,7 @@ public:
virtual ~jt_path_registry ();
bool register_jump_thread (vec<jump_thread_edge *> *);
bool thread_through_all_blocks (bool peel_loop_headers);
jump_thread_edge *allocate_thread_edge (edge e, jump_thread_edge_type t);
void push_edge (vec<jump_thread_edge *> *path, edge, jump_thread_edge_type);
vec<jump_thread_edge *> *allocate_thread_path ();
void debug ();
protected: