Bernd Schmidt wrote:

Thanks. Let me see if I understood the problem - please correct me if I describe anything incorrectly.

The previous cross jumping code didn't care about register liveness, since it just checked for identical instruction streams. The new, more clever code, requires that regsets are identical at the end of the blocks we're trying to match. In addition, cross-jumping can modify blocks, requiring us to update life information (by calling a global update_life_info in struct_equiv_init), which is the really expensive part that caused the slowdown (how often did we end up updating life info?).

The code has always required that the set of sucessor blocks is identical, which implies that the regsets of live registers at the end of the blocks must be identical too. The old code didn't require up-to-date liveness information. The new code does. As a sanity check, it verifies that the regsets are equal. Because the new code as of December actually updated life information incorrectly, the global updates that were done had also quite a lot of work to do (and didn't really do it right, because of the presence of fake edges).

The new patch prevents multiple updates by introducing STRUCT_EQUIV_SUSPEND_UPDATE. However, I don't see how this is safe given that cross jumping will modify basic blocks and change the set of registers live at their ends.

Is there a way to keep life info accurate when doing the cross jump (so we don't set any dirty flags)? Or, possibly, change the algorithm so that it visits blocks in a different order - dirtying more blocks before doing a global life update?

As far as I can tell, the global_live_{start,end} information is now kept up to date, although I have to admit that I don't really understand what was meant with the comment
 /* We may have some registers visible trought the block.  */
that is placed before setting the dirty flag on the block.
The REG_DEAD / REG_UNUSED notes may get out date, but AFAICS they are not needed inside the loop that does the cross-jumping, and there is a global update afterwards.


I'm not sure what the best way to keep the svn history sane is. When/if the patch is approved, should I first do an svn merge -r108792:108791, check that in, and then apply the patch with the actual new stuff?


Maybe

svn diff -r108792:108791 |patch -p0
patch <fixes.diff
svn commit

That is the easy way, but my concern was with keeping the information from svn annotate as sane as possible. Presumably a merge or svn copy could have preserved the old history from before the patch back-out, but since another patch to cfgcleanup has gone in in the meantime, an svn copy is no longer a realistic option.

Reply via email to