Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (160294 => 160295)
--- trunk/Source/_javascript_Core/ChangeLog 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-12-09 01:08:53 UTC (rev 160295)
@@ -1,5 +1,57 @@
2013-12-08 Filip Pizlo <[email protected]>
+ Add the notion of ConstantStoragePointer to DFG IR
+ https://bugs.webkit.org/show_bug.cgi?id=125395
+
+ Reviewed by Oliver Hunt.
+
+ This pushes more typed array folding into StrengthReductionPhase, and enables CSE on
+ storage pointers. Previously, you might have separate nodes for the same storage
+ pointer and this would cause some bad register pressure in the DFG. Note that this
+ was really a theoretical problem and not, to my knowledge a practical one - so this
+ patch is basically just a clean-up.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::constantStoragePointerCSE):
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGGraph.cpp:
+ (JSC::DFG::Graph::dump):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::convertToConstantStoragePointer):
+ (JSC::DFG::Node::hasStoragePointer):
+ (JSC::DFG::Node::storagePointer):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileConstantStoragePointer):
+ (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStrengthReductionPhase.cpp:
+ (JSC::DFG::StrengthReductionPhase::handleNode):
+ (JSC::DFG::StrengthReductionPhase::foldTypedArrayPropertyToConstant):
+ (JSC::DFG::StrengthReductionPhase::prepareToFoldTypedArray):
+ * dfg/DFGWatchpointCollectionPhase.cpp:
+ (JSC::DFG::WatchpointCollectionPhase::handle):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileNode):
+ (JSC::FTL::LowerDFGToLLVM::compileConstantStoragePointer):
+ (JSC::FTL::LowerDFGToLLVM::compileGetIndexedPropertyStorage):
+
+2013-12-08 Filip Pizlo <[email protected]>
+
FTL should support UntypedUse versions of Compare nodes
https://bugs.webkit.org/show_bug.cgi?id=125426
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -1440,7 +1440,8 @@
m_state.setHaveStructures(true);
break;
}
- case GetIndexedPropertyStorage: {
+ case GetIndexedPropertyStorage:
+ case ConstantStoragePointer: {
forNode(node).clear();
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -162,6 +162,21 @@
return 0;
}
+ Node* constantStoragePointerCSE(Node* node)
+ {
+ for (unsigned i = endIndexForPureCSE(); i--;) {
+ Node* otherNode = m_currentBlock->at(i);
+ if (otherNode->op() != ConstantStoragePointer)
+ continue;
+
+ if (otherNode->storagePointer() != node->storagePointer())
+ continue;
+
+ return otherNode;
+ }
+ return 0;
+ }
+
Node* getCalleeLoadElimination()
{
for (unsigned i = m_indexInBlock; i--;) {
@@ -1154,6 +1169,12 @@
setReplacement(weakConstantCSE(node));
break;
+ case ConstantStoragePointer:
+ if (cseMode == StoreElimination)
+ break;
+ setReplacement(constantStoragePointerCSE(node));
+ break;
+
case GetArrayLength:
if (cseMode == StoreElimination)
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -116,6 +116,7 @@
case ExtractOSREntryLocal:
case Int52ToDouble:
case Int52ToValue:
+ case ConstantStoragePointer:
return;
case MovHintAndCheck:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -877,6 +877,10 @@
case Int52ToValue:
case InvalidationPoint:
case CheckArray:
+ case ConstantStoragePointer:
+ // These are just nodes that we don't currently expect to see during fixup.
+ // If we ever wanted to insert them prior to fixup, then we just have to create
+ // fixup rules for them.
RELEASE_ASSERT_NOT_REACHED();
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -290,6 +290,12 @@
out.print(comma, "^", node->phi()->index());
if (node->hasExecutionCounter())
out.print(comma, RawPointer(node->executionCounter()));
+ if (node->hasVariableWatchpointSet())
+ out.print(comma, RawPointer(node->variableWatchpointSet()));
+ if (node->hasTypedArray())
+ out.print(comma, inContext(JSValue(node->typedArray()), context));
+ if (node->hasStoragePointer())
+ out.print(comma, RawPointer(node->storagePointer()));
if (op == JSConstant) {
out.print(comma, "$", node->constantNumber());
JSValue value = valueOfJSConstant(node);
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -407,6 +407,13 @@
children.reset();
}
+ void convertToConstantStoragePointer(void* pointer)
+ {
+ ASSERT(op() == GetIndexedPropertyStorage);
+ m_op = ConstantStoragePointer;
+ m_opInfo = bitwise_cast<uintptr_t>(pointer);
+ }
+
void convertToGetLocalUnlinked(VirtualRegister local)
{
m_op = GetLocalUnlinked;
@@ -982,6 +989,16 @@
{
return reinterpret_cast<JSArrayBufferView*>(m_opInfo);
}
+
+ bool hasStoragePointer()
+ {
+ return op() == ConstantStoragePointer;
+ }
+
+ void* storagePointer()
+ {
+ return reinterpret_cast<void*>(m_opInfo);
+ }
bool hasStructureTransitionData()
{
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -171,6 +171,7 @@
macro(Arrayify, NodeMustGenerate) \
macro(ArrayifyToStructure, NodeMustGenerate) \
macro(GetIndexedPropertyStorage, NodeResultStorage) \
+ macro(ConstantStoragePointer, NodeResultStorage) \
macro(TypedArrayWatchpoint, NodeMustGenerate) \
macro(GetByOffset, NodeResultJS) \
macro(PutByOffset, NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -578,6 +578,7 @@
case NotifyWrite:
case FunctionReentryWatchpoint:
case TypedArrayWatchpoint:
+ case ConstantStoragePointer:
break;
// This gets ignored because it already has a prediction.
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -245,6 +245,7 @@
case NotifyWrite:
case FunctionReentryWatchpoint:
case TypedArrayWatchpoint:
+ case ConstantStoragePointer:
return true;
case GetByVal:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -4042,26 +4042,16 @@
#endif
}
-bool SpeculativeJIT::compileConstantIndexedPropertyStorage(Node* node)
+void SpeculativeJIT::compileConstantStoragePointer(Node* node)
{
- JSArrayBufferView* view = m_jit.graph().tryGetFoldableViewForChild1(node);
- if (!view)
- return false;
- if (view->mode() == FastTypedArray)
- return false;
-
GPRTemporary storage(this);
GPRReg storageGPR = storage.gpr();
- m_jit.move(TrustedImmPtr(view->vector()), storageGPR);
+ m_jit.move(TrustedImmPtr(node->storagePointer()), storageGPR);
storageResult(storageGPR, node);
- return true;
}
void SpeculativeJIT::compileGetIndexedPropertyStorage(Node* node)
{
- if (compileConstantIndexedPropertyStorage(node))
- return;
-
SpeculateCellOperand base(this, node->child1());
GPRReg baseReg = base.gpr();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-12-09 01:08:53 UTC (rev 160295)
@@ -2027,7 +2027,7 @@
void compileArithIMul(Node*);
void compileArithDiv(Node*);
void compileArithMod(Node*);
- bool compileConstantIndexedPropertyStorage(Node*);
+ void compileConstantStoragePointer(Node*);
void compileGetIndexedPropertyStorage(Node*);
JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -3946,6 +3946,11 @@
break;
}
+ case ConstantStoragePointer: {
+ compileConstantStoragePointer(node);
+ break;
+ }
+
case GetTypedArrayByteOffset: {
compileGetTypedArrayByteOffset(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -4243,6 +4243,11 @@
break;
}
+ case ConstantStoragePointer: {
+ compileConstantStoragePointer(node);
+ break;
+ }
+
case GetTypedArrayByteOffset: {
compileGetTypedArrayByteOffset(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -95,9 +95,22 @@
foldTypedArrayPropertyToConstant(view, jsNumber(view->byteOffset()));
break;
- // FIXME: The constant-folding of GetIndexedPropertyStorage should be expressed
- // as an IR transformation in this phase.
- // https://bugs.webkit.org/show_bug.cgi?id=125395
+ case GetIndexedPropertyStorage:
+ if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
+ if (view->mode() != FastTypedArray) {
+ prepareToFoldTypedArray(view);
+ m_node->convertToConstantStoragePointer(view->vector());
+ m_changed = true;
+ break;
+ } else {
+ // FIXME: It would be awesome to be able to fold the property storage for
+ // these GC-allocated typed arrays. For now it doesn't matter because the
+ // most common use-cases for constant typed arrays involve large arrays with
+ // aliased buffer views.
+ // https://bugs.webkit.org/show_bug.cgi?id=125425
+ }
+ }
+ break;
default:
break;
@@ -106,11 +119,18 @@
void foldTypedArrayPropertyToConstant(JSArrayBufferView* view, JSValue constant)
{
+ prepareToFoldTypedArray(view);
+ m_graph.convertToConstant(m_node, constant);
+ m_changed = true;
+ }
+
+ void prepareToFoldTypedArray(JSArrayBufferView* view)
+ {
m_insertionSet.insertNode(
m_nodeIndex, SpecNone, TypedArrayWatchpoint, m_node->codeOrigin,
OpInfo(view));
- m_graph.convertToConstant(m_node, constant);
- m_changed = true;
+ m_insertionSet.insertNode(
+ m_nodeIndex, SpecNone, Phantom, m_node->codeOrigin, m_node->children);
}
InsertionSet m_insertionSet;
Modified: trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/dfg/DFGWatchpointCollectionPhase.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -138,18 +138,6 @@
addLazily(m_node->symbolTable()->m_functionEnteredOnce);
break;
- case GetIndexedPropertyStorage:
- if (JSArrayBufferView* view = m_graph.tryGetFoldableViewForChild1(m_node)) {
- // FIXME: It would be awesome to be able to fold the property storage for
- // these GC-allocated typed arrays. For now it doesn't matter because the
- // most common use-cases for constant typed arrays involve large arrays with
- // aliased buffer views.
- if (view->mode() == FastTypedArray)
- break;
- addLazily(view);
- }
- break;
-
case TypedArrayWatchpoint:
addLazily(m_node->typedArray());
break;
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (160294 => 160295)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-12-09 01:06:54 UTC (rev 160294)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-12-09 01:08:53 UTC (rev 160295)
@@ -343,6 +343,9 @@
case GetButterfly:
compileGetButterfly();
break;
+ case ConstantStoragePointer:
+ compileConstantStoragePointer();
+ break;
case GetIndexedPropertyStorage:
compileGetIndexedPropertyStorage();
break;
@@ -1397,6 +1400,11 @@
setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
}
+ void compileConstantStoragePointer()
+ {
+ setStorage(m_out.constIntPtr(m_node->storagePointer()));
+ }
+
void compileGetIndexedPropertyStorage()
{
LValue cell = lowCell(m_node->child1());
@@ -1423,13 +1431,6 @@
return;
}
- if (JSArrayBufferView* view = m_graph.tryGetFoldableView(m_node)) {
- if (view->mode() != FastTypedArray) {
- setStorage(m_out.constIntPtr(view->vector()));
- return;
- }
- }
-
setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
}