Ignore:
Timestamp:
Jul 24, 2013, 9:04:55 PM (12 years ago)
Author:
[email protected]
Message:

fourthTier: Add a phase to create loop pre-headers
https://bugs.webkit.org/show_bug.cgi?id=118778

Reviewed by Oliver Hunt.

Add a loop pre-header creation phase. Any loop that doesn't already have
just one predecessor that isn't part of the loop has a pre-header
prepended. All non-loop predecessors then jump to that pre-header.

Also fix a handful of bugs:

  • DFG::Analysis should set m_valid before running the analysis, since that makes it easier to use ASSERT(m_valid) in the analysis' methods, which may be called by the analysis before the analysis completes. NaturalLoops does this with loopsOf().
  • NaturalLoops::headerOf() was missing a check for innerMostLoopOf() returning 0, since that'll happen if the block isn't in any loop.
  • Change BlockInsertionSet to dethread the graph, since anyone using it will want to do so.
  • Change dethreading to ignore SSA form graphs.

This also adds NaturalLoops::belongsTo(), which I always used in the
pre-header creation phase. I didn't end up using it but I'll probably use
it in the near future.

(JSC::DFG::Analysis::computeIfNecessary):

  • dfg/DFGBlockInsertionSet.cpp:

(JSC::DFG::BlockInsertionSet::execute):

  • dfg/DFGCriticalEdgeBreakingPhase.cpp:

(JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dethread):

  • dfg/DFGLoopPreHeaderCreationPhase.cpp: Added.

(DFG):
(LoopPreHeaderCreationPhase):
(JSC::DFG::LoopPreHeaderCreationPhase::LoopPreHeaderCreationPhase):
(JSC::DFG::LoopPreHeaderCreationPhase::run):
(JSC::DFG::performLoopPreHeaderCreation):

  • dfg/DFGLoopPreHeaderCreationPhase.h: Added.

(DFG):

  • dfg/DFGNaturalLoops.h:

(NaturalLoop):
(JSC::DFG::NaturalLoops::headerOf):
(JSC::DFG::NaturalLoops::innerMostLoopOf):
(JSC::DFG::NaturalLoops::innerMostOuterLoop):
(JSC::DFG::NaturalLoops::belongsTo):
(NaturalLoops):

  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::compileInThreadImpl):

Conflicts:

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGNaturalLoops.h

    r153277 r153279  
    5959    BasicBlock* at(unsigned i) const { return m_body[i]; }
    6060    BasicBlock* operator[](unsigned i) const { return at(i); }
    61    
     61
     62    // This is the slower, but simpler, way of asking if a block belongs to
     63    // a natural loop. It's faster to call NaturalLoops::belongsTo(), which
     64    // tries to be O(loop depth) rather than O(loop size). Loop depth is
     65    // almost always smaller than loop size. A *lot* smaller.
    6266    bool contains(BasicBlock* block) const
    6367    {
     
    109113    const NaturalLoop* headerOf(BasicBlock* block) const
    110114    {
     115        ASSERT(isValid());
    111116        const NaturalLoop* loop = innerMostLoopOf(block);
     117        if (!loop)
     118            return 0;
    112119        if (loop->header() == block)
    113120            return loop;
     
    121128    const NaturalLoop* innerMostLoopOf(BasicBlock* block) const
    122129    {
     130        ASSERT(isValid());
    123131        unsigned index = block->innerMostLoopIndices[0];
    124132        if (index == UINT_MAX)
     
    129137    const NaturalLoop* innerMostOuterLoop(const NaturalLoop& loop) const
    130138    {
     139        ASSERT(isValid());
    131140        if (loop.m_outerLoopIndex == UINT_MAX)
    132141            return 0;
    133142        return &m_loops[loop.m_outerLoopIndex];
     143    }
     144   
     145    bool belongsTo(BasicBlock* block, const NaturalLoop& candidateLoop) const
     146    {
     147        ASSERT(isValid());
     148        // It's faster to do this test using the loop itself, if it's small.
     149        if (candidateLoop.size() < 4)
     150            return candidateLoop.contains(block);
     151       
     152        for (const NaturalLoop* loop = innerMostLoopOf(block); loop; loop = innerMostOuterLoop(*loop)) {
     153            if (loop == &candidateLoop)
     154                return true;
     155        }
     156        return false;
    134157    }
    135158   
Note: See TracChangeset for help on using the changeset viewer.