Skip to content
  • Chandler Carruth's avatar
    Rewrite how machine block placement handles loop rotation. · ccc7e42b
    Chandler Carruth authored
    This is a complex change that resulted from a great deal of
    experimentation with several different benchmarks. The one which proved
    the most useful is included as a test case, but I don't know that it
    captures all of the relevant changes, as I didn't have specific
    regression tests for each, they were more the result of reasoning about
    what the old algorithm would possibly do wrong. I'm also failing at the
    moment to craft more targeted regression tests for these changes, if
    anyone has ideas, it would be welcome.
    
    The first big thing broken with the old algorithm is the idea that we
    can take a basic block which has a loop-exiting successor and a looping
    successor and use the looping successor as the layout top in order to
    get that particular block to be the bottom of the loop after layout.
    This happens to work in many cases, but not in all.
    
    The second big thing broken was that we didn't try to select the exit
    which fell into the nearest enclosing loop (to which we exit at all). As
    a consequence, even if the rotation worked perfectly, it would result in
    one of two bad layouts. Either the bottom of the loop would get
    fallthrough, skipping across a nearer enclosing loop and thereby making
    it discontiguous, or it would be forced to take an explicit jump over
    the nearest enclosing loop to earch its successor. The point of the
    rotation is to get fallthrough, so we need it to fallthrough to the
    nearest loop it can.
    
    The fix to the first issue is to actually layout the loop from the loop
    header, and then rotate the loop such that the correct exiting edge can
    be a fallthrough edge. This is actually much easier than I anticipated
    because we can handle all the hard parts of finding a viable rotation
    before we do the layout. We just store that, and then rotate after
    layout is finished. No inner loops get split across the post-rotation
    backedge because we check for them when selecting the rotation.
    
    That fix exposed a latent problem with our exitting block selection --
    we should allow the backedge to point into the middle of some inner-loop
    chain as there is no real penalty to it, the whole point is that it
    *won't* be a fallthrough edge. This may have blocked the rotation at all
    in some cases, I have no idea and no test case as I've never seen it in
    practice, it was just noticed by inspection.
    
    Finally, all of these fixes, and studying the loops they produce,
    highlighted another problem: in rotating loops like this, we sometimes
    fail to align the destination of these backwards jumping edges. Fix this
    by actually walking the backwards edges rather than relying on loopinfo.
    
    This fixes regressions on heapsort if block placement is enabled as well
    as lots of other cases where the previous logic would introduce an
    abundance of unnecessary branches into the execution.
    
    llvm-svn: 154783
    ccc7e42b
Loading