12013-02-20 Filip Pizlo <fpizlo@apple.com>
2
3 DFG should not change its mind about what type speculations a node does, by encoding the checks in the NodeType, UseKind, and ArrayMode
4 https://bugs.webkit.org/show_bug.cgi?id=109371
5
6 Reviewed by NOBODY (OOPS!).
7
8 FixupPhase now locks in the speculations that each node will do. The DFG then
9 remembers those speculations, and doesn't change its mind about them even if the
10 graph is transformed - for example if a node's child is repointed to a different
11 node as part of CSE, CFG simplification, or folding. Each node ensures that it
12 executes the speculations promised by its edges. This is true even for Phantom
13 nodes.
14
15 This still leaves some craziness on the table for future work, like the
16 elimination of speculating SetLocal's due to CFG simplification
17 (webkit.org/b/109388) and elimination of nodes via DCE (webkit.org/b/109389).
18
19 In all, this allows for a huge simplification of the DFG. Instead of having to
20 execute the right speculation heuristic each time you want to decide what a node
21 does (for example Node::shouldSpeculateInteger(child1, child2) &&
22 node->canSpeculateInteger()), you just ask for the use kinds of its children
23 (typically node->binaryUseKind() == Int32Use). Because the use kinds are
24 discrete, you can often just switch over them. This makes many parts of the code
25 more clear than they were before.
26
27 Having UseKinds describe the speculations being performed also makes it far
28 easier to perform analyses that need to know what speculations are done. This is
29 so far only used to simplify large parts of the CFA.
30
31 To have a larger vocabulary of UseKinds, this also changes the node allocator to
32 be able to round up Node sizes to the nearest multiple of 16.
33
34 This appears to be neutral on benchmarks, except for some goofy speed-ups, like
35 8% on Octane/box2d.
36
37 * CMakeLists.txt:
38 * GNUmakefile.list.am:
39 * JavaScriptCore.xcodeproj/project.pbxproj:
40 * Target.pri:
41 * dfg/DFGAbstractState.cpp:
42 (JSC::DFG::AbstractState::startExecuting):
43 (DFG):
44 (JSC::DFG::AbstractState::executeEdges):
45 (JSC::DFG::AbstractState::verifyEdge):
46 (JSC::DFG::AbstractState::verifyEdges):
47 (JSC::DFG::AbstractState::executeEffects):
48 (JSC::DFG::AbstractState::execute):
49 * dfg/DFGAbstractState.h:
50 (AbstractState):
51 (JSC::DFG::AbstractState::filterEdgeByUse):
52 (JSC::DFG::AbstractState::filterByType):
53 * dfg/DFGAbstractValue.h:
54 (JSC::DFG::AbstractValue::filter):
55 * dfg/DFGAdjacencyList.h:
56 (JSC::DFG::AdjacencyList::AdjacencyList):
57 (JSC::DFG::AdjacencyList::child):
58 (JSC::DFG::AdjacencyList::setChild):
59 (JSC::DFG::AdjacencyList::reset):
60 (JSC::DFG::AdjacencyList::firstChild):
61 (JSC::DFG::AdjacencyList::setFirstChild):
62 (JSC::DFG::AdjacencyList::numChildren):
63 (JSC::DFG::AdjacencyList::setNumChildren):
64 (AdjacencyList):
65 * dfg/DFGAllocator.h:
66 (DFG):
67 (Allocator):
68 (JSC::DFG::Allocator::cellSize):
69 (JSC::DFG::Allocator::Region::headerSize):
70 (JSC::DFG::Allocator::Region::numberOfThingsPerRegion):
71 (JSC::DFG::Allocator::Region::payloadSize):
72 (JSC::DFG::Allocator::Region::payloadBegin):
73 (JSC::DFG::Allocator::Region::payloadEnd):
74 (JSC::DFG::Allocator::Region::isInThisRegion):
75 (JSC::DFG::::Allocator):
76 (JSC::DFG::::~Allocator):
77 (JSC::DFG::::allocate):
78 (JSC::DFG::::free):
79 (JSC::DFG::::freeAll):
80 (JSC::DFG::::reset):
81 (JSC::DFG::::indexOf):
82 (JSC::DFG::::allocatorOf):
83 (JSC::DFG::::bumpAllocate):
84 (JSC::DFG::::freeListAllocate):
85 (JSC::DFG::::allocateSlow):
86 (JSC::DFG::::freeRegionsStartingAt):
87 (JSC::DFG::::startBumpingIn):
88 * dfg/DFGByteCodeParser.cpp:
89 (JSC::DFG::ByteCodeParser::addToGraph):
90 (JSC::DFG::ByteCodeParser::handleMinMax):
91 * dfg/DFGCSEPhase.cpp:
92 (JSC::DFG::CSEPhase::setLocalStoreElimination):
93 (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
94 (JSC::DFG::CSEPhase::setReplacement):
95 (JSC::DFG::CSEPhase::performNodeCSE):
96 * dfg/DFGCommon.h:
97 (DFG):
98 * dfg/DFGConstantFoldingPhase.cpp:
99 (JSC::DFG::ConstantFoldingPhase::foldConstants):
100 (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
101 * dfg/DFGDriver.cpp:
102 (JSC::DFG::compile):
103 * dfg/DFGEdge.cpp:
104 (JSC::DFG::Edge::dump):
105 * dfg/DFGEdge.h:
106 (JSC::DFG::Edge::useKindUnchecked):
107 (JSC::DFG::Edge::useKind):
108 (JSC::DFG::Edge::shift):
109 * dfg/DFGFixupPhase.cpp:
110 (JSC::DFG::FixupPhase::run):
111 (JSC::DFG::FixupPhase::fixupNode):
112 (JSC::DFG::FixupPhase::checkArray):
113 (JSC::DFG::FixupPhase::blessArrayOperation):
114 (JSC::DFG::FixupPhase::fixIntEdge):
115 (JSC::DFG::FixupPhase::fixDoubleEdge):
116 (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
117 (FixupPhase):
118 (JSC::DFG::FixupPhase::truncateConstantToInt32):
119 (JSC::DFG::FixupPhase::truncateConstantsIfNecessary):
120 (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
121 * dfg/DFGGraph.cpp:
122 (DFG):
123 (JSC::DFG::Graph::refChildren):
124 (JSC::DFG::Graph::derefChildren):
125 * dfg/DFGGraph.h:
126 (JSC::DFG::Graph::ref):
127 (JSC::DFG::Graph::deref):
128 (JSC::DFG::Graph::performSubstitution):
129 (JSC::DFG::Graph::isPredictedNumerical):
130 (JSC::DFG::Graph::addImmediateShouldSpeculateInteger):
131 (DFG):
132 * dfg/DFGNode.h:
133 (JSC::DFG::Node::Node):
134 (JSC::DFG::Node::convertToGetByOffset):
135 (JSC::DFG::Node::convertToPutByOffset):
136 (JSC::DFG::Node::willHaveCodeGenOrOSR):
137 (JSC::DFG::Node::child1):
138 (JSC::DFG::Node::child2):
139 (JSC::DFG::Node::child3):
140 (JSC::DFG::Node::binaryUseKind):
141 (Node):
142 (JSC::DFG::Node::isBinaryUseKind):
143 * dfg/DFGNodeAllocator.h:
144 (DFG):
145 * dfg/DFGNodeFlags.cpp:
146 (JSC::DFG::nodeFlagsAsString):
147 * dfg/DFGNodeType.h:
148 (DFG):
149 * dfg/DFGPredictionPropagationPhase.cpp:
150 (JSC::DFG::PredictionPropagationPhase::propagate):
151 * dfg/DFGSpeculativeJIT.cpp:
152 (JSC::DFG::SpeculativeJIT::speculationCheck):
153 (DFG):
154 (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
155 (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck):
156 (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
157 (JSC::DFG::SpeculativeJIT::typeCheck):
158 (JSC::DFG::SpeculativeJIT::forwardTypeCheck):
159 (JSC::DFG::SpeculativeJIT::fillStorage):
160 (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
161 (JSC::DFG::SpeculativeJIT::compile):
162 (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
163 (JSC::DFG::SpeculativeJIT::compileValueToInt32):
164 (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
165 (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
166 (JSC::DFG::SpeculativeJIT::compileInstanceOf):
167 (JSC::DFG::SpeculativeJIT::compileAdd):
168 (JSC::DFG::SpeculativeJIT::compileArithSub):
169 (JSC::DFG::SpeculativeJIT::compileArithNegate):
170 (JSC::DFG::SpeculativeJIT::compileArithMul):
171 (JSC::DFG::SpeculativeJIT::compileArithMod):
172 (JSC::DFG::SpeculativeJIT::compare):
173 (JSC::DFG::SpeculativeJIT::compileStrictEq):
174 (JSC::DFG::SpeculativeJIT::speculateInt32):
175 (JSC::DFG::SpeculativeJIT::speculateNumber):
176 (JSC::DFG::SpeculativeJIT::speculateRealNumber):
177 (JSC::DFG::SpeculativeJIT::speculateBoolean):
178 (JSC::DFG::SpeculativeJIT::speculateCell):
179 (JSC::DFG::SpeculativeJIT::speculateObject):
180 (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
181 (JSC::DFG::SpeculativeJIT::speculateString):
182 (JSC::DFG::SpeculativeJIT::speculateNotCell):
183 (JSC::DFG::SpeculativeJIT::speculateOther):
184 (JSC::DFG::SpeculativeJIT::speculate):
185 * dfg/DFGSpeculativeJIT.h:
186 (SpeculativeJIT):
187 (JSC::DFG::SpeculativeJIT::valueOfNumberConstant):
188 (JSC::DFG::SpeculativeJIT::needsTypeCheck):
189 (JSC::DFG::IntegerOperand::IntegerOperand):
190 (JSC::DFG::IntegerOperand::edge):
191 (IntegerOperand):
192 (JSC::DFG::IntegerOperand::node):
193 (JSC::DFG::IntegerOperand::gpr):
194 (JSC::DFG::IntegerOperand::use):
195 (JSC::DFG::JSValueOperand::JSValueOperand):
196 (JSValueOperand):
197 (JSC::DFG::JSValueOperand::edge):
198 (JSC::DFG::JSValueOperand::node):
199 (JSC::DFG::JSValueOperand::gpr):
200 (JSC::DFG::JSValueOperand::fill):
201 (JSC::DFG::JSValueOperand::use):
202 (JSC::DFG::StorageOperand::StorageOperand):
203 (JSC::DFG::StorageOperand::edge):
204 (StorageOperand):
205 (JSC::DFG::StorageOperand::node):
206 (JSC::DFG::StorageOperand::gpr):
207 (JSC::DFG::StorageOperand::use):
208 (JSC::DFG::SpeculateIntegerOperand::SpeculateIntegerOperand):
209 (SpeculateIntegerOperand):
210 (JSC::DFG::SpeculateIntegerOperand::edge):
211 (JSC::DFG::SpeculateIntegerOperand::node):
212 (JSC::DFG::SpeculateIntegerOperand::gpr):
213 (JSC::DFG::SpeculateIntegerOperand::use):
214 (JSC::DFG::SpeculateStrictInt32Operand::SpeculateStrictInt32Operand):
215 (SpeculateStrictInt32Operand):
216 (JSC::DFG::SpeculateStrictInt32Operand::edge):
217 (JSC::DFG::SpeculateStrictInt32Operand::node):
218 (JSC::DFG::SpeculateStrictInt32Operand::gpr):
219 (JSC::DFG::SpeculateStrictInt32Operand::use):
220 (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):
221 (SpeculateDoubleOperand):
222 (JSC::DFG::SpeculateDoubleOperand::edge):
223 (JSC::DFG::SpeculateDoubleOperand::node):
224 (JSC::DFG::SpeculateDoubleOperand::fpr):
225 (JSC::DFG::SpeculateDoubleOperand::use):
226 (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
227 (SpeculateCellOperand):
228 (JSC::DFG::SpeculateCellOperand::edge):
229 (JSC::DFG::SpeculateCellOperand::node):
230 (JSC::DFG::SpeculateCellOperand::gpr):
231 (JSC::DFG::SpeculateCellOperand::use):
232 (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
233 (JSC::DFG::SpeculateBooleanOperand::edge):
234 (SpeculateBooleanOperand):
235 (JSC::DFG::SpeculateBooleanOperand::node):
236 (JSC::DFG::SpeculateBooleanOperand::gpr):
237 (JSC::DFG::SpeculateBooleanOperand::use):
238 (DFG):
239 * dfg/DFGSpeculativeJIT32_64.cpp:
240 (JSC::DFG::SpeculativeJIT::fillInteger):
241 (JSC::DFG::SpeculativeJIT::fillJSValue):
242 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
243 (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
244 (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
245 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
246 (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
247 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
248 (JSC::DFG::SpeculativeJIT::compileObjectEquality):
249 (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
250 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
251 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
252 (JSC::DFG::SpeculativeJIT::compileLogicalNot):
253 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
254 (JSC::DFG::SpeculativeJIT::emitBranch):
255 (JSC::DFG::SpeculativeJIT::compile):
256 * dfg/DFGSpeculativeJIT64.cpp:
257 (JSC::DFG::SpeculativeJIT::fillInteger):
258 (JSC::DFG::SpeculativeJIT::fillJSValue):
259 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
260 (JSC::DFG::SpeculativeJIT::fillSpeculateInt):
261 (JSC::DFG::SpeculativeJIT::fillSpeculateIntStrict):
262 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
263 (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
264 (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
265 (JSC::DFG::SpeculativeJIT::compileObjectEquality):
266 (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
267 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
268 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
269 (JSC::DFG::SpeculativeJIT::compileLogicalNot):
270 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
271 (JSC::DFG::SpeculativeJIT::emitBranch):
272 (JSC::DFG::SpeculativeJIT::compile):
273 * dfg/DFGStructureCheckHoistingPhase.cpp:
274 (JSC::DFG::StructureCheckHoistingPhase::run):
275 * dfg/DFGUseKind.cpp: Added.
276 (WTF):
277 (WTF::printInternal):
278 * dfg/DFGUseKind.h: Added.
279 (DFG):
280 (JSC::DFG::typeFilterFor):
281 (JSC::DFG::isNumerical):
282 (WTF):
283 * dfg/DFGValidate.cpp:
284 (JSC::DFG::Validate::reportValidationContext):
285