diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp | 126 |
1 files changed, 55 insertions, 71 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp index 5bdd9f746..5de36a0da 100644 --- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2015 Apple Inc. All rights reserved. + * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,7 +33,7 @@ #include "DFGInsertionSet.h" #include "DFGPhase.h" #include "DFGValidate.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { namespace DFG { @@ -46,9 +46,6 @@ public: bool run() { - // FIXME: We should make this work in SSA. https://bugs.webkit.org/show_bug.cgi?id=148260 - DFG_ASSERT(m_graph, nullptr, m_graph.m_form != SSA); - const bool extremeLogging = false; bool outerChanged = false; @@ -62,7 +59,7 @@ public: continue; ASSERT(block->isReachable); - switch (block->terminal()->op()) { + switch (block->last()->op()) { case Jump: { // Successor with one predecessor -> merge. if (block->successor(0)->predecessors.size() == 1) { @@ -82,8 +79,6 @@ public: // suboptimal, because if my successor has multiple predecessors then we'll // be keeping alive things on other predecessor edges unnecessarily. // What we really need is the notion of end-of-block ghosties! - // FIXME: Allow putting phantoms after terminals. - // https://bugs.webkit.org/show_bug.cgi?id=126778 break; } @@ -102,19 +97,17 @@ public: if (extremeLogging) m_graph.dump(); m_graph.dethread(); - - Node* terminal = block->terminal(); - ASSERT(terminal->isTerminal()); - NodeOrigin boundaryNodeOrigin = terminal->origin; - - jettisonBlock(block, jettisonedBlock, boundaryNodeOrigin); - - block->replaceTerminal( - m_graph, SpecNone, Jump, boundaryNodeOrigin, - OpInfo(targetBlock)); - - ASSERT(block->terminal()); + ASSERT(block->last()->isTerminal()); + CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin; + block->last()->convertToPhantom(); + ASSERT(block->last()->refCount() == 1); + + jettisonBlock(block, jettisonedBlock, boundaryCodeOrigin); + + block->appendNode( + m_graph, SpecNone, Jump, boundaryCodeOrigin, + OpInfo(targetBlock)); } innerChanged = outerChanged = true; break; @@ -134,47 +127,44 @@ public: } case Switch: { - SwitchData* data = block->terminal()->switchData(); + SwitchData* data = block->last()->switchData(); // Prune out cases that end up jumping to default. for (unsigned i = 0; i < data->cases.size(); ++i) { - if (data->cases[i].target.block == data->fallThrough.block) { - data->fallThrough.count += data->cases[i].target.count; - data->cases[i--] = data->cases.last(); - data->cases.removeLast(); - } + if (data->cases[i].target == data->fallThrough) + data->cases[i--] = data->cases.takeLast(); } // If there are no cases other than default then this turns // into a jump. if (data->cases.isEmpty()) { - convertToJump(block, data->fallThrough.block); + convertToJump(block, data->fallThrough); innerChanged = outerChanged = true; break; } // Switch on constant -> jettison all other targets and merge. - Node* terminal = block->terminal(); - if (terminal->child1()->hasConstant()) { - FrozenValue* value = terminal->child1()->constant(); + if (block->last()->child1()->hasConstant()) { + JSValue value = m_graph.valueOfJSConstant(block->last()->child1().node()); TriState found = FalseTriState; BasicBlock* targetBlock = 0; for (unsigned i = data->cases.size(); found == FalseTriState && i--;) { found = data->cases[i].value.strictEqual(value); if (found == TrueTriState) - targetBlock = data->cases[i].target.block; + targetBlock = data->cases[i].target; } if (found == MixedTriState) break; if (found == FalseTriState) - targetBlock = data->fallThrough.block; + targetBlock = data->fallThrough; ASSERT(targetBlock); Vector<BasicBlock*, 1> jettisonedBlocks; - for (BasicBlock* successor : terminal->successors()) { - if (successor != targetBlock) - jettisonedBlocks.append(successor); + for (unsigned i = block->numSuccessors(); i--;) { + BasicBlock* jettisonedBlock = block->successor(i); + if (jettisonedBlock != targetBlock) + jettisonedBlocks.append(jettisonedBlock); } if (targetBlock->predecessors.size() == 1) { @@ -188,13 +178,12 @@ public: m_graph.dump(); m_graph.dethread(); - NodeOrigin boundaryNodeOrigin = terminal->origin; - + CodeOrigin boundaryCodeOrigin = block->last()->codeOrigin; + block->last()->convertToPhantom(); for (unsigned i = jettisonedBlocks.size(); i--;) - jettisonBlock(block, jettisonedBlocks[i], boundaryNodeOrigin); - - block->replaceTerminal( - m_graph, SpecNone, Jump, boundaryNodeOrigin, OpInfo(targetBlock)); + jettisonBlock(block, jettisonedBlocks[i], boundaryCodeOrigin); + block->appendNode( + m_graph, SpecNone, Jump, boundaryCodeOrigin, OpInfo(targetBlock)); } innerChanged = outerChanged = true; break; @@ -244,7 +233,7 @@ public: } if (Options::validateGraphAtEachPhase()) - validate(); + validate(m_graph); } while (innerChanged); return outerChanged; @@ -259,40 +248,36 @@ private: m_graph.dethread(); mergeBlocks(block, targetBlock, noBlocks()); } else { - Node* branch = block->terminal(); + Node* branch = block->last(); + ASSERT(branch->isTerminal()); ASSERT(branch->op() == Branch || branch->op() == Switch); - - block->replaceTerminal( - m_graph, SpecNone, Jump, branch->origin, OpInfo(targetBlock)); + branch->convertToPhantom(); + ASSERT(branch->refCount() == 1); + + block->appendNode( + m_graph, SpecNone, Jump, branch->codeOrigin, + OpInfo(targetBlock)); } } - - void keepOperandAlive(BasicBlock* block, BasicBlock* jettisonedBlock, NodeOrigin nodeOrigin, VirtualRegister operand) + + void keepOperandAlive(BasicBlock* block, BasicBlock* jettisonedBlock, CodeOrigin codeOrigin, VirtualRegister operand) { Node* livenessNode = jettisonedBlock->variablesAtHead.operand(operand); if (!livenessNode) return; - NodeType nodeType; - if (livenessNode->flags() & NodeIsFlushed) - nodeType = Flush; - else { - // This seems like it shouldn't be necessary because we could just rematerialize - // PhantomLocals or something similar using bytecode liveness. However, in ThreadedCPS, it's - // worth the sanity to maintain this eagerly. See - // https://bugs.webkit.org/show_bug.cgi?id=144086 - nodeType = PhantomLocal; - } + if (livenessNode->variableAccessData()->isCaptured()) + return; block->appendNode( - m_graph, SpecNone, nodeType, nodeOrigin, + m_graph, SpecNone, PhantomLocal, codeOrigin, OpInfo(livenessNode->variableAccessData())); } - void jettisonBlock(BasicBlock* block, BasicBlock* jettisonedBlock, NodeOrigin boundaryNodeOrigin) + void jettisonBlock(BasicBlock* block, BasicBlock* jettisonedBlock, CodeOrigin boundaryCodeOrigin) { for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i) - keepOperandAlive(block, jettisonedBlock, boundaryNodeOrigin, virtualRegisterForArgument(i)); + keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, virtualRegisterForArgument(i)); for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i) - keepOperandAlive(block, jettisonedBlock, boundaryNodeOrigin, virtualRegisterForLocal(i)); + keepOperandAlive(block, jettisonedBlock, boundaryCodeOrigin, virtualRegisterForLocal(i)); fixJettisonedPredecessors(block, jettisonedBlock); } @@ -325,12 +310,11 @@ private: // kept alive. // Remove the terminal of firstBlock since we don't need it anymore. Well, we don't - // really remove it; we actually turn it into a check. - Node* terminal = firstBlock->terminal(); - ASSERT(terminal->isTerminal()); - NodeOrigin boundaryNodeOrigin = terminal->origin; - terminal->remove(); - ASSERT(terminal->refCount() == 1); + // really remove it; we actually turn it into a Phantom. + ASSERT(firstBlock->last()->isTerminal()); + CodeOrigin boundaryCodeOrigin = firstBlock->last()->codeOrigin; + firstBlock->last()->convertToPhantom(); + ASSERT(firstBlock->last()->refCount() == 1); for (unsigned i = jettisonedBlocks.size(); i--;) { BasicBlock* jettisonedBlock = jettisonedBlocks[i]; @@ -340,9 +324,9 @@ private: // different path than secondBlock. for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfArguments(); ++i) - keepOperandAlive(firstBlock, jettisonedBlock, boundaryNodeOrigin, virtualRegisterForArgument(i)); + keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, virtualRegisterForArgument(i)); for (size_t i = 0; i < jettisonedBlock->variablesAtHead.numberOfLocals(); ++i) - keepOperandAlive(firstBlock, jettisonedBlock, boundaryNodeOrigin, virtualRegisterForLocal(i)); + keepOperandAlive(firstBlock, jettisonedBlock, boundaryCodeOrigin, virtualRegisterForLocal(i)); } for (size_t i = 0; i < secondBlock->phis.size(); ++i) @@ -351,7 +335,7 @@ private: for (size_t i = 0; i < secondBlock->size(); ++i) firstBlock->append(secondBlock->at(i)); - ASSERT(firstBlock->terminal()->isTerminal()); + ASSERT(firstBlock->last()->isTerminal()); // Fix the predecessors of my new successors. This is tricky, since we are going to reset // all predecessors anyway due to reachability analysis. But we need to fix the |