This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa]: Code movement is a pain in the ass.
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: gcc at gcc dot gnu dot org
- Cc: dnovillo at redhat dot com
- Date: Sun, 10 Aug 2003 01:42:20 -0400 (EDT)
- Subject: [tree-ssa]: Code movement is a pain in the ass.
Moving code around is a serious pain in the ass.
You can't simply bsi_remove a statement from one place, and bsi_insert it
somewhere else.
Why?
Because bsi_remove:
1. removes the annotations. This is secondary, we can just copy them
easily if they haven't changed.
2. Calls remove_stmt
remove_stmt:
1. Marks all the definitions invalid.
In other words, it goes through the def_ops, and sets SSA_NAME_DEF_STMT
of each thing to an empty statement. You don't notice this until dce
decides to remove your statement for no apparent reason. :)
2. Also resets the annotations.
Even cuter, the comment in remove_stmt suggests:
FIXME: We should probably traverse all the def-use edges originating at
this statement to update each use of the definitions made here, but
that is expensive and can easily be checked by every pass by
checking if SSA_NAME_DEF_STMT is a nop. */
Howzabout we don't?
Thus, to copy a statement from one place to another takes something like
this:
/* This is about to remove the annotations, so copy them.
It' also about to screw up our definitions. Fun, isn't it? */
oldann = stmt->common.ann;
bsi_remove (&bsi);
newbsi = bsi_last (loop->pre_header);
last = last_stmt (loop->pre_header);
stmt->common.ann = oldann;
if (is_ctrl_stmt (last) || is_ctrl_altering_stmt (last))
bsi_insert_before (&newbsi, stmt, BSI_SAME_STMT);
else
bsi_insert_after (&newbsi, stmt, BSI_SAME_STMT);
/* Fix the definitions, since bsi_remove erased them. */
defs = def_ops (stmt);
for (k = 0; defs && k < VARRAY_ACTIVE_SIZE (defs); k++)
{
tree *def_p = VARRAY_GENERIC_PTR (defs, k);
if (TREE_CODE (*def_p) == SSA_NAME)
SSA_NAME_DEF_STMT (*def_p) = stmt;
}
Anybody mind if i make bsi_remove take an argument to convince it i'm
only removing the statement temporarily (ie moving it), and then add
an argument to remove_stmt to tell it *not* to reset definitions and
annotations?
That way, i can just remove it from one place, and move it to another?