diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPhantomInsertionPhase.cpp')
| -rw-r--r-- | Source/JavaScriptCore/dfg/DFGPhantomInsertionPhase.cpp | 191 |
1 files changed, 0 insertions, 191 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPhantomInsertionPhase.cpp b/Source/JavaScriptCore/dfg/DFGPhantomInsertionPhase.cpp deleted file mode 100644 index 02b1958ce..000000000 --- a/Source/JavaScriptCore/dfg/DFGPhantomInsertionPhase.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2015 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DFGPhantomInsertionPhase.h" - -#if ENABLE(DFG_JIT) - -#include "BytecodeLivenessAnalysisInlines.h" -#include "DFGForAllKills.h" -#include "DFGGraph.h" -#include "DFGInsertionSet.h" -#include "DFGMayExit.h" -#include "DFGPhase.h" -#include "DFGPredictionPropagationPhase.h" -#include "DFGVariableAccessDataDump.h" -#include "JSCInlines.h" -#include "OperandsInlines.h" - -namespace JSC { namespace DFG { - -namespace { - -bool verbose = false; - -class PhantomInsertionPhase : public Phase { -public: - PhantomInsertionPhase(Graph& graph) - : Phase(graph, "phantom insertion") - , m_insertionSet(graph) - , m_values(OperandsLike, graph.block(0)->variablesAtHead) - { - } - - bool run() - { - // We assume that DCE has already run. If we run before DCE then we think that all - // SetLocals execute, which is inaccurate. That causes us to insert too few Phantoms. - DFG_ASSERT(m_graph, nullptr, m_graph.m_refCountState == ExactRefCount); - - if (verbose) { - dataLog("Graph before Phantom insertion:\n"); - m_graph.dump(); - } - - m_graph.clearEpochs(); - - for (BasicBlock* block : m_graph.blocksInNaturalOrder()) - handleBlock(block); - - if (verbose) { - dataLog("Graph after Phantom insertion:\n"); - m_graph.dump(); - } - - return true; - } - -private: - void handleBlock(BasicBlock* block) - { - // FIXME: For blocks that have low register pressure, it would make the most sense to - // simply insert Phantoms at the last point possible since that would obviate the need to - // query bytecode liveness: - // - // - If we MovHint @x into loc42 then put a Phantom on the last MovHinted value in loc42. - // - At the end of the block put Phantoms for each MovHinted value. - // - // This will definitely not work if there are any phantom allocations. For those blocks - // where this would be legal, it remains to be seen how profitable it would be even if there - // was high register pressure. After all, a Phantom would cause a spill but it wouldn't - // cause a fill. - // - // https://bugs.webkit.org/show_bug.cgi?id=144524 - - m_values.fill(nullptr); - - Epoch currentEpoch = Epoch::first(); - unsigned lastExitingIndex = 0; - for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) { - Node* node = block->at(nodeIndex); - if (verbose) - dataLog("Considering ", node, "\n"); - - switch (node->op()) { - case MovHint: - m_values.operand(node->unlinkedLocal()) = node->child1().node(); - break; - - case ZombieHint: - m_values.operand(node->unlinkedLocal()) = nullptr; - break; - - case SetLocal: - case GetLocal: - case SetArgument: - m_values.operand(node->local()) = nullptr; - break; - - default: - break; - } - - if (mayExit(m_graph, node) != DoesNotExit) { - currentEpoch.bump(); - lastExitingIndex = nodeIndex; - } - - m_graph.doToChildren( - node, - [&] (Edge edge) { - edge->setEpoch(currentEpoch); - }); - - node->setEpoch(currentEpoch); - - forAllKilledOperands( - m_graph, node, block->tryAt(nodeIndex + 1), - [&] (VirtualRegister reg) { - if (verbose) - dataLog(" Killed operand: ", reg, "\n"); - - Node* killedNode = m_values.operand(reg); - if (!killedNode) - return; - - // We only need to insert a Phantom if the node hasn't been used since the last - // exit, and was born before the last exit. - if (killedNode->epoch() == currentEpoch) - return; - - if (verbose) { - dataLog( - " Inserting Phantom on ", killedNode, " after ", - block->at(lastExitingIndex), "\n"); - } - - // We have exact ref counts, so creating a new use means that we have to - // increment the ref count. - killedNode->postfixRef(); - - Node* lastExitingNode = block->at(lastExitingIndex); - - m_insertionSet.insertNode( - lastExitingIndex + 1, SpecNone, Phantom, - lastExitingNode->origin.forInsertingAfter(m_graph, lastExitingNode), - killedNode->defaultEdge()); - }); - } - - m_insertionSet.execute(block); - } - - InsertionSet m_insertionSet; - Operands<Node*> m_values; -}; - -} // anonymous namespace - -bool performPhantomInsertion(Graph& graph) -{ - SamplingRegion samplingRegion("DFG Phantom Insertion Phase"); - return runPhase<PhantomInsertionPhase>(graph); -} - -} } // namespace JSC::DFG - -#endif // ENABLE(DFG_JIT) - |
