Ignore:
Timestamp:
Nov 1, 2015, 4:48:03 PM (10 years ago)
Author:
[email protected]
Message:

Dominators should be factored out of the DFG
https://bugs.webkit.org/show_bug.cgi?id=150764

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Factored DFGDominators.h/DFGDominators.cpp into WTF. To do this, I made two changes to the
DFG:

1) DFG now has a CFG abstraction called DFG::CFG. The cool thing about this is that in the

future if we wanted to support inverted dominators, we could do it by just creating a
DFG::BackwardCFG.

2) Got rid of DFG::Analysis. From now on, an Analysis being invalidated is expressed by the

DFG::Graph having a null pointer for that analysis. When we "run" the analysis, we
just instantiate it. This makes it much more natural to integrate WTF::Dominators into
the DFG.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGAnalysis.h: Removed.
  • dfg/DFGCFG.h: Added.

(JSC::DFG::CFG::CFG):
(JSC::DFG::CFG::root):
(JSC::DFG::CFG::newMap<T>):
(JSC::DFG::CFG::successors):
(JSC::DFG::CFG::predecessors):
(JSC::DFG::CFG::index):
(JSC::DFG::CFG::node):
(JSC::DFG::CFG::numNodes):
(JSC::DFG::CFG::dump):

  • dfg/DFGCSEPhase.cpp:
  • dfg/DFGDisassembler.cpp:

(JSC::DFG::Disassembler::createDumpList):

  • dfg/DFGDominators.cpp: Removed.
  • dfg/DFGDominators.h:

(JSC::DFG::Dominators::Dominators):
(JSC::DFG::Dominators::strictlyDominates): Deleted.
(JSC::DFG::Dominators::dominates): Deleted.
(JSC::DFG::Dominators::immediateDominatorOf): Deleted.
(JSC::DFG::Dominators::forAllStrictDominatorsOf): Deleted.
(JSC::DFG::Dominators::forAllDominatorsOf): Deleted.
(JSC::DFG::Dominators::forAllBlocksStrictlyDominatedBy): Deleted.
(JSC::DFG::Dominators::forAllBlocksDominatedBy): Deleted.
(JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOf): Deleted.
(JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOf): Deleted.
(JSC::DFG::Dominators::forAllBlocksInPrunedIteratedDominanceFrontierOf): Deleted.
(JSC::DFG::Dominators::forAllBlocksInDominanceFrontierOfImpl): Deleted.
(JSC::DFG::Dominators::forAllBlocksInIteratedDominanceFrontierOfImpl): Deleted.
(JSC::DFG::Dominators::BlockData::BlockData): Deleted.

  • dfg/DFGEdgeDominates.h:

(JSC::DFG::EdgeDominates::operator()):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::Graph):
(JSC::DFG::Graph::dumpBlockHeader):
(JSC::DFG::Graph::invalidateCFG):
(JSC::DFG::Graph::substituteGetLocal):
(JSC::DFG::Graph::handleAssertionFailure):
(JSC::DFG::Graph::ensureDominators):
(JSC::DFG::Graph::ensurePrePostNumbering):
(JSC::DFG::Graph::ensureNaturalLoops):
(JSC::DFG::Graph::valueProfileFor):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::hasDebuggerEnabled):

  • dfg/DFGLICMPhase.cpp:

(JSC::DFG::LICMPhase::run):
(JSC::DFG::LICMPhase::attemptHoist):

  • dfg/DFGLoopPreHeaderCreationPhase.cpp:

(JSC::DFG::createPreHeader):
(JSC::DFG::LoopPreHeaderCreationPhase::run):

  • dfg/DFGNaturalLoops.cpp:

(JSC::DFG::NaturalLoop::dump):
(JSC::DFG::NaturalLoops::NaturalLoops):
(JSC::DFG::NaturalLoops::~NaturalLoops):
(JSC::DFG::NaturalLoops::loopsOf):
(JSC::DFG::NaturalLoops::computeDependencies): Deleted.
(JSC::DFG::NaturalLoops::compute): Deleted.

  • dfg/DFGNaturalLoops.h:

(JSC::DFG::NaturalLoops::numLoops):

  • dfg/DFGNode.h:

(JSC::DFG::Node::SuccessorsIterable::end):
(JSC::DFG::Node::SuccessorsIterable::size):
(JSC::DFG::Node::SuccessorsIterable::at):
(JSC::DFG::Node::SuccessorsIterable::operator[]):

  • dfg/DFGOSREntrypointCreationPhase.cpp:

(JSC::DFG::OSREntrypointCreationPhase::run):

  • dfg/DFGObjectAllocationSinkingPhase.cpp:
  • dfg/DFGPlan.cpp:

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

  • dfg/DFGPrePostNumbering.cpp:

(JSC::DFG::PrePostNumbering::PrePostNumbering):
(JSC::DFG::PrePostNumbering::~PrePostNumbering):
(JSC::DFG::PrePostNumbering::compute): Deleted.

  • dfg/DFGPrePostNumbering.h:

(JSC::DFG::PrePostNumbering::preNumber):
(JSC::DFG::PrePostNumbering::postNumber):

  • dfg/DFGPutStackSinkingPhase.cpp:
  • dfg/DFGSSACalculator.cpp:

(JSC::DFG::SSACalculator::nonLocalReachingDef):
(JSC::DFG::SSACalculator::reachingDefAtTail):

  • dfg/DFGSSACalculator.h:

(JSC::DFG::SSACalculator::computePhis):

  • dfg/DFGSSAConversionPhase.cpp:

(JSC::DFG::SSAConversionPhase::run):

  • ftl/FTLLink.cpp:

(JSC::FTL::link):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::lower):
(JSC::FTL::DFG::LowerDFGToLLVM::safelyInvalidateAfterTermination):
(JSC::FTL::DFG::LowerDFGToLLVM::isValid):

Source/WTF:

This takes what used to be DFGDominators.h/DFGDominators.cpp and turns it into a generic
algorithm that can take any abstract graph. The idea is that you create Dominators<CFG> and
pass it a CFG object, which defines the types of graph nodes and methods for getting
successors, predecessors, etc. The DFG now defines a class called CFG, which is a wrapper for
DFG::Graph that conforms to the thing that wtf/Dominators.h expects.

When doing things to graphs, it's common to refer to the things in the graph as "nodes".
Because I intend to reuse the CFG abstraction with many graph algorithms, that abstraction uses
the term "node" to refer to a DFG basic block. But in Dominators, the method and variable names
still use "block". This is because although Dominators are applicable to any kind of directed
graph, it's super unlikely that we will ever use them for anything but compilers. Indeed, the
only reason why I'm factoring them out of the DFG is so that I can use them with B3 and Air.

This has the nice side effect that a user of WTF::Dominators<JSC::DFG::CFG> will see familiar
terminology like "blocksStrictlyDominatedBy(...)" instead of "nodesStrictlyDominatedBy(...)",
which would be super confusing.

Overall, wtf/Dominators.h is a combination of what used to be in DFGDominators.h,
DFGDominators.cpp, DFGNaiveDominators.h, and DFGNaiveDominators.cpp. I only changed code when I
had to in order to make it generic.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/CMakeLists.txt:
  • wtf/Dominators.h: Added.

(WTF::Dominators::Dominators):
(WTF::Dominators::compute):
(WTF::Dominators::strictlyDominates):
(WTF::Dominators::dominates):
(WTF::Dominators::immediateDominatorOf):
(WTF::Dominators::forAllStrictDominatorsOf):
(WTF::Dominators::forAllDominatorsOf):
(WTF::Dominators::forAllBlocksStrictlyDominatedBy):
(WTF::Dominators::forAllBlocksDominatedBy):
(WTF::Dominators::strictDominatorsOf):
(WTF::Dominators::dominatorsOf):
(WTF::Dominators::blocksStrictlyDominatedBy):
(WTF::Dominators::blocksDominatedBy):
(WTF::Dominators::forAllBlocksInDominanceFrontierOf):
(WTF::Dominators::dominanceFrontierOf):
(WTF::Dominators::forAllBlocksInIteratedDominanceFrontierOf):
(WTF::Dominators::forAllBlocksInPrunedIteratedDominanceFrontierOf):
(WTF::Dominators::iteratedDominanceFrontierOf):
(WTF::Dominators::dump):
(WTF::Dominators::LengauerTarjan::LengauerTarjan):
(WTF::Dominators::LengauerTarjan::compute):
(WTF::Dominators::LengauerTarjan::immediateDominator):
(WTF::Dominators::LengauerTarjan::computeDepthFirstPreNumbering):
(WTF::Dominators::LengauerTarjan::computeSemiDominatorsAndImplicitImmediateDominators):
(WTF::Dominators::LengauerTarjan::computeExplicitImmediateDominators):
(WTF::Dominators::LengauerTarjan::link):
(WTF::Dominators::LengauerTarjan::eval):
(WTF::Dominators::LengauerTarjan::compress):
(WTF::Dominators::LengauerTarjan::BlockData::BlockData):
(WTF::Dominators::NaiveDominators::NaiveDominators):
(WTF::Dominators::NaiveDominators::dominates):
(WTF::Dominators::NaiveDominators::dump):
(WTF::Dominators::NaiveDominators::pruneDominators):
(WTF::Dominators::ValidationContext::ValidationContext):
(WTF::Dominators::ValidationContext::reportError):
(WTF::Dominators::ValidationContext::handleErrors):
(WTF::Dominators::naiveDominates):
(WTF::Dominators::forAllBlocksInDominanceFrontierOfImpl):
(WTF::Dominators::forAllBlocksInIteratedDominanceFrontierOfImpl):
(WTF::Dominators::BlockData::BlockData):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp

    r190896 r191870  
    3737#include "DFGGraph.h"
    3838#include "DFGInsertionSet.h"
     39#include "DFGNaturalLoops.h"
    3940#include "DFGPhase.h"
    4041#include "DFGSafeToExecute.h"
     
    7273        DFG_ASSERT(m_graph, nullptr, m_graph.m_form == SSA);
    7374       
    74         m_graph.m_dominators.computeIfNecessary(m_graph);
    75         m_graph.m_naturalLoops.computeIfNecessary(m_graph);
     75        m_graph.ensureDominators();
     76        m_graph.ensureNaturalLoops();
    7677
    7778        if (verbose) {
     
    8081        }
    8182       
    82         m_data.resize(m_graph.m_naturalLoops.numLoops());
     83        m_data.resize(m_graph.m_naturalLoops->numLoops());
    8384       
    8485        // Figure out the set of things each loop writes to, not including blocks that
     
    9596                continue;
    9697           
    97             const NaturalLoop* loop = m_graph.m_naturalLoops.innerMostLoopOf(block);
     98            const NaturalLoop* loop = m_graph.m_naturalLoops->innerMostLoopOf(block);
    9899            if (!loop)
    99100                continue;
     
    115116        // - Identify its pre-header.
    116117        // - Make sure its outer loops know what it clobbers.
    117         for (unsigned loopIndex = m_graph.m_naturalLoops.numLoops(); loopIndex--;) {
    118             const NaturalLoop& loop = m_graph.m_naturalLoops.loop(loopIndex);
     118        for (unsigned loopIndex = m_graph.m_naturalLoops->numLoops(); loopIndex--;) {
     119            const NaturalLoop& loop = m_graph.m_naturalLoops->loop(loopIndex);
    119120            LoopData& data = m_data[loop.index()];
    120121           
    121122            for (
    122                 const NaturalLoop* outerLoop = m_graph.m_naturalLoops.innerMostOuterLoop(loop);
     123                const NaturalLoop* outerLoop = m_graph.m_naturalLoops->innerMostOuterLoop(loop);
    123124                outerLoop;
    124                 outerLoop = m_graph.m_naturalLoops.innerMostOuterLoop(*outerLoop))
     125                outerLoop = m_graph.m_naturalLoops->innerMostOuterLoop(*outerLoop))
    125126                m_data[outerLoop->index()].writes.addAll(data.writes);
    126127           
     
    136137            for (unsigned i = header->predecessors.size(); i--;) {
    137138                BasicBlock* predecessor = header->predecessors[i];
    138                 if (m_graph.m_dominators.dominates(header, predecessor))
     139                if (m_graph.m_dominators->dominates(header, predecessor))
    139140                    continue;
    140141
     
    190191        bool changed = false;
    191192        for (BasicBlock* block : m_graph.blocksInPreOrder()) {
    192             const NaturalLoop* loop = m_graph.m_naturalLoops.innerMostLoopOf(block);
     193            const NaturalLoop* loop = m_graph.m_naturalLoops->innerMostLoopOf(block);
    193194            if (!loop)
    194195                continue;
     
    198199                const NaturalLoop* current = loop;
    199200                current;
    200                 current = m_graph.m_naturalLoops.innerMostOuterLoop(*current))
     201                current = m_graph.m_naturalLoops->innerMostOuterLoop(*current))
    201202                loopStack.append(current);
    202203           
     
    334335        for (unsigned bodyIndex = loop->size(); bodyIndex--;) {
    335336            BasicBlock* subBlock = loop->at(bodyIndex);
    336             const NaturalLoop* subLoop = m_graph.m_naturalLoops.headerOf(subBlock);
     337            const NaturalLoop* subLoop = m_graph.m_naturalLoops->headerOf(subBlock);
    337338            if (!subLoop)
    338339                continue;
Note: See TracChangeset for help on using the changeset viewer.