summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-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.cpp126
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