This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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?



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]