Commit 9ca951e8 authored by fpizlo@apple.com's avatar fpizlo@apple.com

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):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160295 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 929434af
2013-12-08 Filip Pizlo <fpizlo@apple.com>
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 <fpizlo@apple.com>
FTL should support UntypedUse versions of Compare nodes
......
......@@ -1440,7 +1440,8 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
m_state.setHaveStructures(true);
break;
}
case GetIndexedPropertyStorage: {
case GetIndexedPropertyStorage:
case ConstantStoragePointer: {
forNode(node).clear();
break;
}
......
......@@ -162,6 +162,21 @@ private:
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 @@ private:
setReplacement(weakConstantCSE(node));
break;
case ConstantStoragePointer:
if (cseMode == StoreElimination)
break;
setReplacement(constantStoragePointerCSE(node));
break;
case GetArrayLength:
if (cseMode == StoreElimination)
break;
......
......@@ -116,6 +116,7 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
case ExtractOSREntryLocal:
case Int52ToDouble:
case Int52ToValue:
case ConstantStoragePointer:
return;
case MovHintAndCheck:
......
......@@ -877,6 +877,10 @@ private:
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;
......
......@@ -290,6 +290,12 @@ void Graph::dump(PrintStream& out, const char* prefix, Node* node, DumpContext*
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);
......
......@@ -407,6 +407,13 @@ struct Node {
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 @@ struct Node {
{
return reinterpret_cast<JSArrayBufferView*>(m_opInfo);
}
bool hasStoragePointer()
{
return op() == ConstantStoragePointer;
}
void* storagePointer()
{
return reinterpret_cast<void*>(m_opInfo);
}
bool hasStructureTransitionData()
{
......
......@@ -171,6 +171,7 @@ namespace JSC { namespace DFG {
macro(Arrayify, NodeMustGenerate) \
macro(ArrayifyToStructure, NodeMustGenerate) \
macro(GetIndexedPropertyStorage, NodeResultStorage) \
macro(ConstantStoragePointer, NodeResultStorage) \
macro(TypedArrayWatchpoint, NodeMustGenerate) \
macro(GetByOffset, NodeResultJS) \
macro(PutByOffset, NodeMustGenerate) \
......
......@@ -578,6 +578,7 @@ private:
case NotifyWrite:
case FunctionReentryWatchpoint:
case TypedArrayWatchpoint:
case ConstantStoragePointer:
break;
// This gets ignored because it already has a prediction.
......
......@@ -245,6 +245,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
case NotifyWrite:
case FunctionReentryWatchpoint:
case TypedArrayWatchpoint:
case ConstantStoragePointer:
return true;
case GetByVal:
......
......@@ -4042,26 +4042,16 @@ void SpeculativeJIT::compileStringZeroLength(Node* node)
#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();
......
......@@ -2027,7 +2027,7 @@ public:
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);
......
......@@ -3946,6 +3946,11 @@ void SpeculativeJIT::compile(Node* node)
break;
}
case ConstantStoragePointer: {
compileConstantStoragePointer(node);
break;
}
case GetTypedArrayByteOffset: {
compileGetTypedArrayByteOffset(node);
break;
......
......@@ -4243,6 +4243,11 @@ void SpeculativeJIT::compile(Node* node)
break;
}
case ConstantStoragePointer: {
compileConstantStoragePointer(node);
break;
}
case GetTypedArrayByteOffset: {
compileGetTypedArrayByteOffset(node);
break;
......
......@@ -95,9 +95,22 @@ private:
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;
......@@ -105,12 +118,19 @@ private:
}
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;
......
......@@ -138,18 +138,6 @@ private:
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;
......
......@@ -343,6 +343,9 @@ private:
case GetButterfly:
compileGetButterfly();
break;
case ConstantStoragePointer:
compileConstantStoragePointer();
break;
case GetIndexedPropertyStorage:
compileGetIndexedPropertyStorage();
break;
......@@ -1397,6 +1400,11 @@ private:
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 @@ private:
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));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment