Skip to content
  1. Jun 04, 2013
    • Shuxin Yang's avatar
      Fix a defect in code-layout pass, improving Benchmarks/Olden/em3d/em3d by about 30% · 8b8fd217
      Shuxin Yang authored
      (4.58s vs 3.2s on an oldish Mac Tower). 
      
        The corresponding src is excerpted bellow. The lopp accounts for about 90% of execution time.
        --------------------
          cat -n test-suite/MultiSource/Benchmarks/Olden/em3d/make_graph.c
           90 
           91         for (k=0; k<j; k++)
           92           if (other_node == cur_node->to_nodes[k]) break;
      
        The defective layout is sketched bellow, where the two branches need to swap.
        ------------------------------------------------------------------------
            L:
               ...
            if (cond) goto out-of-loop
            goto L
      
        While this code sequence is defective, I don't understand why it incurs 1/3 of 
      execution time. CPU-event-profiling indicates the poor laoyout dose not increase
      in br-misprediction; it dosen't increase stall cycle at all, and it dosen't 
      prevent the CPU detect the loop (i.e. Loop-Stream-Detector seems to be working fine
      as well)... 
      
         The root cause of the problem is that the layout pass calls AnalyzeBranch() 
      with basic-block which is not updated to reflect its current layout.
      
      rdar://13966341
      
      llvm-svn: 183174
      8b8fd217
  2. Apr 12, 2013
  3. Mar 29, 2013
  4. Jan 11, 2013
  5. Dec 30, 2012
  6. Dec 19, 2012
  7. Dec 03, 2012
    • Chandler Carruth's avatar
      Use the new script to sort the includes of every file under lib. · ed0881b2
      Chandler Carruth authored
      Sooooo many of these had incorrect or strange main module includes.
      I have manually inspected all of these, and fixed the main module
      include to be the nearest plausible thing I could find. If you own or
      care about any of these source files, I encourage you to take some time
      and check that these edits were sensible. I can't have broken anything
      (I strictly added headers, and reordered them, never removed), but they
      may not be the headers you'd really like to identify as containing the
      API being implemented.
      
      Many forward declarations and missing includes were added to a header
      files to allow them to parse cleanly when included first. The main
      module rule does in fact have its merits. =]
      
      llvm-svn: 169131
      ed0881b2
  8. Oct 09, 2012
  9. Sep 26, 2012
  10. Sep 14, 2012
  11. Aug 07, 2012
    • Chandler Carruth's avatar
      Add a much more conservative strategy for aligning branch targets. · 881d0a79
      Chandler Carruth authored
      Previously, MBP essentially aligned every branch target it could. This
      bloats code quite a bit, especially non-looping code which has no real
      reason to prefer aligned branch targets so heavily.
      
      As Andy said in review, it's still a bit odd to do this without a real
      cost model, but this at least has much more plausible heuristics.
      
      Fixes PR13265.
      
      llvm-svn: 161409
      881d0a79
  12. Jul 31, 2012
  13. Jun 26, 2012
  14. Jun 02, 2012
  15. Apr 16, 2012
    • Chandler Carruth's avatar
      Add a somewhat hacky heuristic to do something different from whole-loop · 8c0b41d6
      Chandler Carruth authored
      rotation. When there is a loop backedge which is an unconditional
      branch, we will end up with a branch somewhere no matter what. Try
      placing this backedge in a fallthrough position above the loop header as
      that will definitely remove at least one branch from the loop iteration,
      where whole loop rotation may not.
      
      I haven't seen any benchmarks where this is important but loop-blocks.ll
      tests for it, and so this will be covered when I flip the default.
      
      llvm-svn: 154812
      8c0b41d6
    • Chandler Carruth's avatar
      Tweak the loop rotation logic to check whether the loop is naturally · 8c74c7b1
      Chandler Carruth authored
      laid out in a form with a fallthrough into the header and a fallthrough
      out of the bottom. In that case, leave the loop alone because any
      rotation will introduce unnecessary branches. If either side looks like
      it will require an explicit branch, then the rotation won't add any, do
      it to ensure the branch occurs outside of the loop (if possible) and
      maximize the benefit of the fallthrough in the bottom.
      
      llvm-svn: 154806
      8c74c7b1
    • 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
  16. Apr 10, 2012
    • Chandler Carruth's avatar
      Make a somewhat subtle change in the logic of block placement. Sometimes · 68062617
      Chandler Carruth authored
      the loop header has a non-loop predecessor which has been pre-fused into
      its chain due to unanalyzable branches. In this case, rotating the
      header into the body of the loop in order to place a loop exit at the
      bottom of the loop is a Very Bad Idea as it makes the loop
      non-contiguous.
      
      I'm working on a good test case for this, but it's a bit annoynig to
      craft. I should get one shortly, but I'm submitting this now so I can
      begin the (lengthy) performance analysis process. An initial run of LNT
      looks really, really good, but there is too much noise there for me to
      trust it much.
      
      llvm-svn: 154395
      68062617
  17. Apr 08, 2012
    • Chandler Carruth's avatar
      Remove an over zealous assert. The assert was trying to catch places · bed1abf9
      Chandler Carruth authored
      where a chain outside of the loop block-set ended up in the worklist for
      scheduling as part of the contiguous loop. However, asserting the first
      block in the chain is in the loop-set isn't a valid check -- we may be
      forced to drag a chain into the worklist due to one block in the chain
      being part of the loop even though the first block is *not* in the loop.
      This occurs when we have been forced to form a chain early due to
      un-analyzable branches.
      
      No test case here as I have no idea how to even begin reducing one, and
      it will be hopelessly fragile. We have to somehow end up with a loop
      header of an inner loop which is a successor of a basic block with an
      unanalyzable pair of branch instructions. Ow. Self-host triggers it so
      it is unlikely it will regress.
      
      This at least gets block placement back to passing selfhost and the test
      suite. There are still a lot of slowdown that I don't like coming out of
      block placement, although there are now also a lot of speedups. =[ I'm
      seeing swings in both directions up to 10%. I'm going to try to find
      time to dig into this and see if we can turn this on for 3.1 as it does
      a really good job of cleaning up after some loops that degraded with the
      inliner changes.
      
      llvm-svn: 154287
      bed1abf9
    • Chandler Carruth's avatar
      Add a debug-only 'dump' method to the BlockChain structure to ease · 49158908
      Chandler Carruth authored
      debugging.
      
      llvm-svn: 154286
      49158908
  18. Feb 08, 2012
    • Andrew Trick's avatar
      Codegen pass definition cleanup. No functionality. · 1fa5bcbe
      Andrew Trick authored
      Moving toward a uniform style of pass definition to allow easier target configuration.
      Globally declare Pass ID.
      Globally declare pass initializer.
      Use INITIALIZE_PASS consistently.
      Add a call to the initializer from CodeGen.cpp.
      Remove redundant "createPass" functions and "getPassName" methods.
      
      While cleaning up declarations, cleaned up comments (sorry for large diff).
      
      llvm-svn: 150100
      1fa5bcbe
  19. Dec 22, 2011
  20. Dec 21, 2011
  21. Dec 07, 2011
  22. Nov 27, 2011
    • Chandler Carruth's avatar
      Prevent rotating the blocks of a loop (and thus getting a backedge to be · 4f567207
      Chandler Carruth authored
      fallthrough) in cases where we might fail to rotate an exit to an outer
      loop onto the end of the loop chain.
      
      Having *some* rotation, but not performing this rotation, is the primary
      fix of thep performance regression with -enable-block-placement for
      Olden/em3d (a whopping 30% regression). Still working on reducing the
      test case that actually exercises this and the new rotation strategy out
      of this code, but I want to check if this regresses other test cases
      first as that may indicate it isn't the correct fix.
      
      llvm-svn: 145195
      4f567207
    • Chandler Carruth's avatar
      Take two on rotating the block ordering of loops. My previous attempt · 03adbd46
      Chandler Carruth authored
      was centered around the premise of laying out a loop in a chain, and
      then rotating that chain. This is good for preserving contiguous layout,
      but bad for actually making sane rotations. In order to keep it safe,
      I had to essentially make it impossible to rotate deeply nested loops.
      The information needed to correctly reason about a deeply nested loop is
      actually available -- *before* we layout the loop. We know the inner
      loops are already fused into chains, etc. We lose information the moment
      we actually lay out the loop.
      
      The solution was the other alternative for this algorithm I discussed
      with Benjamin and some others: rather than rotating the loop
      after-the-fact, try to pick a profitable starting block for the loop's
      layout, and then use our existing layout logic. I was worried about the
      complexity of this "pick" step, but it turns out such complexity is
      needed to handle all the important cases I keep teasing out of benchmarks.
      
      This is, I'm afraid, a bit of a work-in-progress. It is still
      misbehaving on some likely important cases I'm investigating in Olden.
      It also isn't really tested. I'm going to try to craft some interesting
      nested-loop test cases, but it's likely to be extremely time consuming
      and I don't want to go there until I'm sure I'm testing the correct
      behavior. Sadly I can't come up with a way of getting simple, fine
      grained test cases for this logic. We need complex loop structures to
      even trigger much of it.
      
      llvm-svn: 145183
      03adbd46
    • Chandler Carruth's avatar
      Fix an impressive type-o / spell-o Duncan noticed. · 9e466841
      Chandler Carruth authored
      llvm-svn: 145181
      9e466841
    • Chandler Carruth's avatar
      Rework a bit of the implementation of loop block rotation to not rely so · a0545809
      Chandler Carruth authored
      heavily on AnalyzeBranch. That routine doesn't behave as we want given
      that rotation occurs mid-way through re-ordering the function. Instead
      merely check that there are not unanalyzable branching constructs
      present, and then reason about the CFG via successor lists. This
      actually simplifies my mental model for all of this as well.
      
      The concrete result is that we now will rotate more loop chains. I've
      added a test case from Olden highlighting the effect. There is still
      a bit more to do here though in order to regain all of the performance
      in Olden.
      
      llvm-svn: 145179
      a0545809
    • Chandler Carruth's avatar
      Introduce a loop block rotation optimization to the new block placement · 9ffb97e6
      Chandler Carruth authored
      pass. This is designed to achieve one of the important optimizations
      that the old code placement pass did, but more simply.
      
      This is a somewhat rough and *very* conservative version of the
      transform. We could get a lot fancier here if there are profitable cases
      to do so. In particular, this only looks for a single pattern, it
      insists that the loop backedge being rotated away is the last backedge
      in the chain, and it doesn't provide any means of doing better in-loop
      placement due to the rotation. However, it appears that it will handle
      the important loops I am finding in the LLVM test suite.
      
      llvm-svn: 145158
      9ffb97e6
  23. Nov 24, 2011
    • Chandler Carruth's avatar
      Fix a silly use-after-free issue. A much earlier version of this code · 7adee1a0
      Chandler Carruth authored
      need lots of fanciness around retaining a reference to a Chain's slot in
      the BlockToChain map, but that's all gone now. We can just go directly
      to allocating the new chain (which will update the mapping for us) and
      using it.
      
      Somewhat gross mechanically generated test case replicates the issue
      Duncan spotted when actually testing this out.
      
      llvm-svn: 145120
      7adee1a0
    • Chandler Carruth's avatar
      When adding blocks to the list of those which no longer have any CFG · d394bafd
      Chandler Carruth authored
      conflicts, we should only be adding the first block of the chain to the
      list, lest we try to merge into the middle of that chain. Most of the
      places we were doing this we already happened to be looking at the first
      block, but there is no reason to assume that, and in some cases it was
      clearly wrong.
      
      I've added a couple of tests here. One already worked, but I like having
      an explicit test for it. The other is reduced from a test case Duncan
      reduced for me and used to crash. Now it is handled correctly.
      
      llvm-svn: 145119
      d394bafd
  24. Nov 23, 2011
    • Chandler Carruth's avatar
      Relax an invariant that block placement was trying to assert a bit · 99fe42fb
      Chandler Carruth authored
      further. This invariant just wasn't going to work in the face of
      unanalyzable branches; we need to be resillient to the phenomenon of
      chains poking into a loop and poking out of a loop. In fact, we already
      were, we just needed to not assert on it.
      
      This was found during a bootstrap with block placement turned on.
      
      llvm-svn: 145100
      99fe42fb
    • Chandler Carruth's avatar
      Fix a crash in block placement due to an inner loop that happened to be · 4a87aa0c
      Chandler Carruth authored
      reversed in the function's original ordering, and we happened to
      encounter it while handling an outer unnatural CFG structure.
      
      Thanks to the test case reduced from GCC's source by Benjamin Kramer.
      This may also fix a crasher in gzip that Duncan reduced for me, but
      I haven't yet gotten to testing that one.
      
      llvm-svn: 145094
      4a87aa0c
  25. Nov 20, 2011
    • Chandler Carruth's avatar
      The logic for breaking the CFG in the presence of hot successors didn't · 18dfac38
      Chandler Carruth authored
      properly account for the *global* probability of the edge being taken.
      This manifested as a very large number of unconditional branches to
      blocks being merged against the CFG even though they weren't
      particularly hot within the CFG.
      
      The fix is to check whether the edge being merged is both locally hot
      relative to other successors for the source block, and globally hot
      compared to other (unmerged) predecessors of the destination block.
      
      This introduces a new crasher on GCC single-source, but it's currently
      behind a flag, and Ben has offered to work on the reduction. =]
      
      llvm-svn: 145010
      18dfac38
  26. Nov 19, 2011
    • Chandler Carruth's avatar
      Move the handling of unanalyzable branches out of the loop-driven chain · f3dc9eff
      Chandler Carruth authored
      formation phase and into the initial walk of the basic blocks. We
      essentially pre-merge all blocks where unanalyzable fallthrough exists,
      as we won't be able to update the terminators effectively after any
      reorderings. This is quite a bit more principled as there may be CFGs
      where the second half of the unanalyzable pair has some analyzable
      predecessor that gets placed first. Then it may get placed next,
      implicitly breaking the unanalyzable branch even though we never even
      looked at the part that isn't analyzable. I've included a test case that
      triggers this (thanks Benjamin yet again!), and I'm hoping to synthesize
      some more general ones as I dig into related issues.
      
      Also, to make this new scheme work we have to be able to handle branches
      into the middle of a chain, so add this check. We always fallback on the
      incoming ordering.
      
      Finally, this starts to really underscore a known limitation of the
      current implementation -- we don't consider broken predecessors when
      merging successors. This can caused major missed opportunities, and is
      something I'm planning on looking at next (modulo more bug reports).
      
      llvm-svn: 144994
      f3dc9eff
  27. Nov 15, 2011
    • Chandler Carruth's avatar
      Rather than trying to use the loop block sequence *or* the function · 9b548a7f
      Chandler Carruth authored
      block sequence when recovering from unanalyzable control flow
      constructs, *always* use the function sequence. I'm not sure why I ever
      went down the path of trying to use the loop sequence, it is
      fundamentally not the correct sequence to use. We're trying to preserve
      the incoming layout in the cases of unreasonable control flow, and that
      is only encoded at the function level. We already have a filter to
      select *exactly* the sub-set of blocks within the function that we're
      trying to form into a chain.
      
      The resulting code layout is also significantly better because of this.
      In several places we were ending up with completely unreasonable control
      flow constructs due to the ordering chosen by the loop structure for its
      internal storage. This change removes a completely wasteful vector of
      basic blocks, saving memory allocation in the common case even though it
      costs us CPU in the fairly rare case of unnatural loops. Finally, it
      fixes the latest crasher reduced out of GCC's single source. Thanks
      again to Benjamin Kramer for the reduction, my bugpoint skills failed at
      it.
      
      llvm-svn: 144627
      9b548a7f
  28. Nov 14, 2011
Loading