2011-09-22 Filip Pizlo <fpizlo@apple.com>
+ GetScopedVar should have value profiling
+ https://bugs.webkit.org/show_bug.cgi?id=68676
+
+ Reviewed by Oliver Hunt.
+
+ Added GetScopedVar value profiling and predictin propagation.
+ Added GetScopeChain to CSE.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::predict):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasPrediction):
+ * dfg/DFGPropagator.cpp:
+ (JSC::DFG::Propagator::propagateNodePredictions):
+ (JSC::DFG::Propagator::getScopeChainLoadElimination):
+ (JSC::DFG::Propagator::performNodeCSE):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_scoped_var):
+
+2011-09-22 Filip Pizlo <fpizlo@apple.com>
+
PPC build fix, part 3.
* runtime/Executable.cpp:
int slot = currentInstruction[2].u.operand;
int depth = currentInstruction[3].u.operand;
NodeIndex getScopeChain = addToGraph(GetScopeChain, OpInfo(depth));
- NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), getScopeChain);
+ NodeIndex getScopedVar = addToGraph(GetScopedVar, OpInfo(slot), OpInfo(PredictNone), getScopeChain);
set(dst, getScopedVar);
+ stronglyPredict(getScopedVar);
NEXT_OPCODE(op_get_scoped_var);
}
case op_put_scoped_var: {
changed |= mergeUse(node.child1(), PredictObjectUnknown | StrongPredictionTag);
changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
if (isStrongPrediction(node.getPrediction()))
- changed |= setPrediction(node.getPrediction());
+ changed |= mergePrediction(node.getPrediction());
break;
}
case GetByOffset: {
changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
if (isStrongPrediction(node.getPrediction()))
- changed |= setPrediction(node.getPrediction());
+ changed |= mergePrediction(node.getPrediction());
break;
}
changed |= mergeUse(m_graph.m_varArgChildren[node.firstChild()], PredictObjectUnknown | StrongPredictionTag);
changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
if (isStrongPrediction(node.getPrediction()))
- changed |= setPrediction(node.getPrediction());
+ changed |= mergePrediction(node.getPrediction());
break;
}
break;
}
+ case GetScopedVar: {
+ changed |= node.predict(m_uses[m_compileIndex] & ~PredictionTagMask, StrongPrediction);
+ PredictedType prediction = node.getPrediction();
+ if (isStrongPrediction(prediction))
+ changed |= mergePrediction(prediction);
+ break;
+ }
+
+ case GetScopeChain: {
+ changed |= setPrediction(makePrediction(PredictCellOther, StrongPrediction));
+ break;
+ }
+
case PutByVal:
case PutByValAlias:
case PutById:
break;
}
- case GetScopeChain:
case GetCallee: {
changed |= setPrediction(makePrediction(PredictObjectOther, StrongPrediction));
break;
case Resolve:
case ResolveBase:
case ResolveBaseStrictPut:
- case GetScopedVar:
break;
// This gets ignored because it doesn't do anything.
return NoNode;
}
+ NodeIndex getScopeChainLoadElimination(unsigned depth)
+ {
+ NodeIndex start = startIndexForChildren();
+ for (NodeIndex index = endIndexForPureCSE(); index-- > start;) {
+ Node& node = m_graph[index];
+ if (node.op == GetScopeChain
+ && node.scopeChainDepth() == depth)
+ return index;
+ }
+ return NoNode;
+ }
+
void performSubstitution(NodeIndex& child)
{
// Check if this operand is actually unused.
setReplacement(pureCSE(node));
break;
+ case GetScopeChain:
+ setReplacement(getScopeChainLoadElimination(node.scopeChainDepth()));
+ break;
+
// Handle nodes that are conditionally pure: these are pure, and can
// be CSE'd, so long as the prediction is the one we want.
case ValueAdd:
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT0);
loadPtr(Address(regT0, JSVariableObject::offsetOfRegisters()), regT0);
loadPtr(Address(regT0, currentInstruction[2].u.operand * sizeof(Register)), regT0);
+ emitValueProfilingSite(FirstProfilingSite);
emitPutVirtualRegister(currentInstruction[1].u.operand);
}