Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/verifier.h"
6 :
7 : #include <algorithm>
8 : #include <deque>
9 : #include <queue>
10 : #include <sstream>
11 : #include <string>
12 :
13 : #include "src/bit-vector.h"
14 : #include "src/compiler/all-nodes.h"
15 : #include "src/compiler/common-operator.h"
16 : #include "src/compiler/graph.h"
17 : #include "src/compiler/js-operator.h"
18 : #include "src/compiler/node-properties.h"
19 : #include "src/compiler/node.h"
20 : #include "src/compiler/opcodes.h"
21 : #include "src/compiler/operator-properties.h"
22 : #include "src/compiler/operator.h"
23 : #include "src/compiler/schedule.h"
24 : #include "src/compiler/simplified-operator.h"
25 : #include "src/compiler/type-cache.h"
26 : #include "src/ostreams.h"
27 :
28 : namespace v8 {
29 : namespace internal {
30 : namespace compiler {
31 :
32 :
33 : class Verifier::Visitor {
34 : public:
35 : Visitor(Zone* z, Typing typed, CheckInputs check_inputs, CodeType code_type)
36 : : zone(z),
37 : typing(typed),
38 : check_inputs(check_inputs),
39 67187 : code_type(code_type) {}
40 :
41 : void Check(Node* node, const AllNodes& all);
42 :
43 : Zone* zone;
44 : Typing typing;
45 : CheckInputs check_inputs;
46 : CodeType code_type;
47 :
48 : private:
49 10071819 : void CheckNotTyped(Node* node) {
50 10071819 : if (NodeProperties::IsTyped(node)) {
51 0 : std::ostringstream str;
52 0 : str << "TypeError: node #" << node->id() << ":" << *node->op()
53 0 : << " should never have a type";
54 0 : FATAL("%s", str.str().c_str());
55 : }
56 10071819 : }
57 1353734 : void CheckTypeIs(Node* node, Type type) {
58 1356638 : if (typing == TYPED && !NodeProperties::GetType(node).Is(type)) {
59 0 : std::ostringstream str;
60 0 : str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
61 0 : << NodeProperties::GetType(node) << " is not " << type;
62 0 : FATAL("%s", str.str().c_str());
63 : }
64 1353734 : }
65 77 : void CheckTypeMaybe(Node* node, Type type) {
66 77 : if (typing == TYPED && !NodeProperties::GetType(node).Maybe(type)) {
67 0 : std::ostringstream str;
68 0 : str << "TypeError: node #" << node->id() << ":" << *node->op() << " type "
69 0 : << NodeProperties::GetType(node) << " must intersect " << type;
70 0 : FATAL("%s", str.str().c_str());
71 : }
72 77 : }
73 1328110 : void CheckValueInputIs(Node* node, int i, Type type) {
74 1328110 : Node* input = NodeProperties::GetValueInput(node, i);
75 1329402 : if (typing == TYPED && !NodeProperties::GetType(input).Is(type)) {
76 0 : std::ostringstream str;
77 0 : str << "TypeError: node #" << node->id() << ":" << *node->op()
78 0 : << "(input @" << i << " = " << input->opcode() << ":"
79 0 : << input->op()->mnemonic() << ") type "
80 0 : << NodeProperties::GetType(input) << " is not " << type;
81 0 : FATAL("%s", str.str().c_str());
82 : }
83 1328110 : }
84 35700781 : void CheckOutput(Node* node, Node* use, int count, const char* kind) {
85 35700781 : if (count <= 0) {
86 0 : std::ostringstream str;
87 0 : str << "GraphError: node #" << node->id() << ":" << *node->op()
88 0 : << " does not produce " << kind << " output used by node #"
89 0 : << use->id() << ":" << *use->op();
90 0 : FATAL("%s", str.str().c_str());
91 : }
92 35700781 : }
93 : };
94 :
95 121393840 : void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
96 20490280 : int value_count = node->op()->ValueInputCount();
97 : int context_count = OperatorProperties::GetContextInputCount(node->op());
98 : int frame_state_count =
99 : OperatorProperties::GetFrameStateInputCount(node->op());
100 20490280 : int effect_count = node->op()->EffectInputCount();
101 20490280 : int control_count = node->op()->ControlInputCount();
102 :
103 : // Verify number of inputs matches up.
104 20490280 : int input_count = value_count + context_count + frame_state_count;
105 20490280 : if (check_inputs == kAll) {
106 20490280 : input_count += effect_count + control_count;
107 : }
108 20490280 : CHECK_EQ(input_count, node->InputCount());
109 :
110 : // If this node has any effect outputs, make sure that it is
111 : // consumed as an effect input somewhere else.
112 : // TODO(mvstanton): support this kind of verification for WASM
113 : // compiles, too.
114 40980560 : if (code_type != kWasm && node->op()->EffectOutputCount() > 0) {
115 : int effect_edges = 0;
116 28510994 : for (Edge edge : node->use_edges()) {
117 10213653 : if (all.IsLive(edge.from()) && NodeProperties::IsEffectEdge(edge)) {
118 : effect_edges++;
119 : }
120 : }
121 : DCHECK_GT(effect_edges, 0);
122 : }
123 :
124 : // Verify that frame state has been inserted for the nodes that need it.
125 8647 : for (int i = 0; i < frame_state_count; i++) {
126 8647 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
127 13074 : CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
128 : // kFrameState uses Start as a sentinel.
129 : (node->opcode() == IrOpcode::kFrameState &&
130 : frame_state->opcode() == IrOpcode::kStart));
131 : }
132 :
133 : // Verify all value inputs actually produce a value.
134 18927658 : for (int i = 0; i < value_count; ++i) {
135 37624364 : Node* value = NodeProperties::GetValueInput(node, i);
136 37855316 : CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
137 : // Verify that only parameters and projections can have input nodes with
138 : // multiple outputs.
139 56321070 : CHECK(node->opcode() == IrOpcode::kParameter ||
140 : node->opcode() == IrOpcode::kProjection ||
141 : value->op()->ValueOutputCount() <= 1);
142 : }
143 :
144 : // Verify all context inputs are value nodes.
145 2271 : for (int i = 0; i < context_count; ++i) {
146 2271 : Node* context = NodeProperties::GetContextInput(node);
147 4542 : CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
148 : }
149 :
150 20490280 : if (check_inputs == kAll) {
151 : // Verify all effect inputs actually have an effect.
152 5471939 : for (int i = 0; i < effect_count; ++i) {
153 5471939 : Node* effect = NodeProperties::GetEffectInput(node);
154 10943878 : CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
155 : }
156 :
157 : // Verify all control inputs are control nodes.
158 11298913 : for (int i = 0; i < control_count; ++i) {
159 11298913 : Node* control = NodeProperties::GetControlInput(node, i);
160 : CheckOutput(control, node, control->op()->ControlOutputCount(),
161 22597826 : "control");
162 : }
163 :
164 : // Verify that nodes that can throw either have both IfSuccess/IfException
165 : // projections as the only control uses or no projections at all.
166 20490280 : if (!node->op()->HasProperty(Operator::kNoThrow)) {
167 0 : Node* discovered_if_exception = nullptr;
168 0 : Node* discovered_if_success = nullptr;
169 : int total_number_of_control_uses = 0;
170 2596856 : for (Edge edge : node->use_edges()) {
171 1024355 : if (!NodeProperties::IsControlEdge(edge)) {
172 : continue;
173 : }
174 435148 : total_number_of_control_uses++;
175 435148 : Node* control_use = edge.from();
176 435148 : if (control_use->opcode() == IrOpcode::kIfSuccess) {
177 12379 : CHECK_NULL(discovered_if_success); // Only one allowed.
178 : discovered_if_success = control_use;
179 : }
180 435148 : if (control_use->opcode() == IrOpcode::kIfException) {
181 12379 : CHECK_NULL(discovered_if_exception); // Only one allowed.
182 : discovered_if_exception = control_use;
183 : }
184 : }
185 274073 : if (discovered_if_success && !discovered_if_exception) {
186 0 : FATAL(
187 : "#%d:%s should be followed by IfSuccess/IfException, but is "
188 : "only followed by single #%d:%s",
189 : node->id(), node->op()->mnemonic(), discovered_if_success->id(),
190 0 : discovered_if_success->op()->mnemonic());
191 : }
192 274073 : if (discovered_if_exception && !discovered_if_success) {
193 0 : FATAL(
194 : "#%d:%s should be followed by IfSuccess/IfException, but is "
195 : "only followed by single #%d:%s",
196 : node->id(), node->op()->mnemonic(), discovered_if_exception->id(),
197 0 : discovered_if_exception->op()->mnemonic());
198 : }
199 274073 : if (discovered_if_success || discovered_if_exception) {
200 12379 : CHECK_EQ(2, total_number_of_control_uses);
201 : }
202 : }
203 : }
204 :
205 20490280 : switch (node->opcode()) {
206 : case IrOpcode::kStart:
207 : // Start has no inputs.
208 67187 : CHECK_EQ(0, input_count);
209 : // Type is a tuple.
210 : // TODO(rossberg): Multiple outputs are currently typed as Internal.
211 67187 : CheckTypeIs(node, Type::Internal());
212 67187 : break;
213 : case IrOpcode::kEnd:
214 : // End has no outputs.
215 67187 : CHECK_EQ(0, node->op()->ValueOutputCount());
216 67187 : CHECK_EQ(0, node->op()->EffectOutputCount());
217 67187 : CHECK_EQ(0, node->op()->ControlOutputCount());
218 : // All inputs are graph terminators.
219 807990 : for (const Node* input : node->inputs()) {
220 336808 : CHECK(IrOpcode::IsGraphTerminator(input->opcode()));
221 : }
222 : // Type is empty.
223 67187 : CheckNotTyped(node);
224 67187 : break;
225 : case IrOpcode::kDead:
226 : // Dead is never connected to the graph.
227 0 : UNREACHABLE();
228 : case IrOpcode::kDeadValue:
229 0 : CheckValueInputIs(node, 0, Type::None());
230 0 : CheckTypeIs(node, Type::None());
231 0 : break;
232 : case IrOpcode::kUnreachable:
233 0 : CheckTypeIs(node, Type::None());
234 0 : for (Edge edge : node->use_edges()) {
235 0 : Node* use = edge.from();
236 0 : if (NodeProperties::IsValueEdge(edge) && all.IsLive(use)) {
237 : // {Unreachable} nodes can only be used by {DeadValue}, because they
238 : // don't actually produce a value.
239 0 : CHECK_EQ(IrOpcode::kDeadValue, use->opcode());
240 : }
241 : }
242 0 : break;
243 : case IrOpcode::kBranch: {
244 : // Branch uses are IfTrue and IfFalse.
245 : int count_true = 0, count_false = 0;
246 10605600 : for (const Node* use : node->uses()) {
247 5302800 : CHECK(all.IsLive(use) && (use->opcode() == IrOpcode::kIfTrue ||
248 : use->opcode() == IrOpcode::kIfFalse));
249 2651400 : if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
250 2651400 : if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
251 : }
252 1325700 : CHECK_EQ(1, count_true);
253 1325700 : CHECK_EQ(1, count_false);
254 : // The condition must be a Boolean.
255 1325700 : CheckValueInputIs(node, 0, Type::Boolean());
256 : // Type is empty.
257 1325700 : CheckNotTyped(node);
258 1325700 : break;
259 : }
260 : case IrOpcode::kIfTrue:
261 : case IrOpcode::kIfFalse: {
262 2651400 : Node* control = NodeProperties::GetControlInput(node, 0);
263 2651400 : CHECK_EQ(IrOpcode::kBranch, control->opcode());
264 : // Type is empty.
265 2651400 : CheckNotTyped(node);
266 2651400 : break;
267 : }
268 : case IrOpcode::kIfSuccess: {
269 : // IfSuccess and IfException continuation only on throwing nodes.
270 12379 : Node* input = NodeProperties::GetControlInput(node, 0);
271 12379 : CHECK(!input->op()->HasProperty(Operator::kNoThrow));
272 : // Type is empty.
273 12379 : CheckNotTyped(node);
274 12379 : break;
275 : }
276 : case IrOpcode::kIfException: {
277 : // IfSuccess and IfException continuation only on throwing nodes.
278 12379 : Node* input = NodeProperties::GetControlInput(node, 0);
279 12379 : CHECK(!input->op()->HasProperty(Operator::kNoThrow));
280 : // Type can be anything.
281 12379 : CheckTypeIs(node, Type::Any());
282 12379 : break;
283 : }
284 : case IrOpcode::kSwitch: {
285 : // Switch uses are Case and Default.
286 : int count_case = 0, count_default = 0;
287 1065228 : for (const Node* use : node->uses()) {
288 90543 : CHECK(all.IsLive(use));
289 90543 : switch (use->opcode()) {
290 : case IrOpcode::kIfValue: {
291 2995889 : for (const Node* user : node->uses()) {
292 1970389 : if (user != use && user->opcode() == IrOpcode::kIfValue) {
293 1728556 : CHECK_NE(IfValueParametersOf(use->op()).value(),
294 : IfValueParametersOf(user->op()).value());
295 : }
296 : }
297 80611 : ++count_case;
298 80611 : break;
299 : }
300 : case IrOpcode::kIfDefault: {
301 9932 : ++count_default;
302 9932 : break;
303 : }
304 : default: {
305 0 : FATAL("Switch #%d illegally used by #%d:%s", node->id(), use->id(),
306 0 : use->op()->mnemonic());
307 : break;
308 : }
309 : }
310 : }
311 9932 : CHECK_EQ(1, count_default);
312 29796 : CHECK_EQ(node->op()->ControlOutputCount(), count_case + count_default);
313 : // Type is empty.
314 9932 : CheckNotTyped(node);
315 9932 : break;
316 : }
317 : case IrOpcode::kIfValue:
318 : case IrOpcode::kIfDefault:
319 181086 : CHECK_EQ(IrOpcode::kSwitch,
320 : NodeProperties::GetControlInput(node)->opcode());
321 : // Type is empty.
322 90543 : CheckNotTyped(node);
323 90543 : break;
324 : case IrOpcode::kLoop: {
325 97497 : CHECK_EQ(control_count, input_count);
326 : // Type is empty.
327 97497 : CheckNotTyped(node);
328 : // All loops need to be connected to a {Terminate} node to ensure they
329 : // stay connected to the graph end.
330 : bool has_terminate = false;
331 997369 : for (const Node* use : node->uses()) {
332 899872 : if (all.IsLive(use) && use->opcode() == IrOpcode::kTerminate) {
333 : has_terminate = true;
334 : break;
335 : }
336 : }
337 97497 : CHECK(has_terminate);
338 : break;
339 : }
340 : case IrOpcode::kMerge:
341 623946 : CHECK_EQ(control_count, input_count);
342 : // Type is empty.
343 623946 : CheckNotTyped(node);
344 623946 : break;
345 : case IrOpcode::kDeoptimizeIf:
346 : case IrOpcode::kDeoptimizeUnless:
347 : // Type is empty.
348 252 : CheckNotTyped(node);
349 252 : break;
350 : case IrOpcode::kTrapIf:
351 : case IrOpcode::kTrapUnless:
352 : // Type is empty.
353 0 : CheckNotTyped(node);
354 0 : break;
355 : case IrOpcode::kDeoptimize:
356 : case IrOpcode::kReturn:
357 : case IrOpcode::kThrow:
358 : // Deoptimize, Return and Throw uses are End.
359 705956 : for (const Node* use : node->uses()) {
360 176489 : if (all.IsLive(use)) {
361 176489 : CHECK_EQ(IrOpcode::kEnd, use->opcode());
362 : }
363 : }
364 : // Type is empty.
365 176489 : CheckNotTyped(node);
366 176489 : break;
367 : case IrOpcode::kTerminate:
368 : // Terminates take one loop and effect.
369 97497 : CHECK_EQ(1, control_count);
370 97497 : CHECK_EQ(1, effect_count);
371 97497 : CHECK_EQ(2, input_count);
372 194994 : CHECK_EQ(IrOpcode::kLoop,
373 : NodeProperties::GetControlInput(node)->opcode());
374 : // Terminate uses are End.
375 389988 : for (const Node* use : node->uses()) {
376 97497 : if (all.IsLive(use)) {
377 97497 : CHECK_EQ(IrOpcode::kEnd, use->opcode());
378 : }
379 : }
380 : // Type is empty.
381 97497 : CheckNotTyped(node);
382 97497 : break;
383 : case IrOpcode::kOsrNormalEntry:
384 : case IrOpcode::kOsrLoopEntry:
385 : // Osr entries take one control and effect.
386 0 : CHECK_EQ(1, control_count);
387 0 : CHECK_EQ(1, effect_count);
388 0 : CHECK_EQ(2, input_count);
389 : // Type is empty.
390 0 : CheckNotTyped(node);
391 0 : break;
392 :
393 : // Common operators
394 : // ----------------
395 : case IrOpcode::kParameter: {
396 : // Parameters have the start node as inputs.
397 211780 : CHECK_EQ(1, input_count);
398 : // Parameter has an input that produces enough values.
399 211780 : int const index = ParameterIndexOf(node->op());
400 211780 : Node* const start = NodeProperties::GetValueInput(node, 0);
401 211780 : CHECK_EQ(IrOpcode::kStart, start->opcode());
402 : // Currently, parameter indices start at -1 instead of 0.
403 211780 : CHECK_LE(-1, index);
404 423560 : CHECK_LT(index + 1, start->op()->ValueOutputCount());
405 : // Type can be anything.
406 211780 : CheckTypeIs(node, Type::Any());
407 211780 : break;
408 : }
409 : case IrOpcode::kInt32Constant: // TODO(turbofan): rename Word32Constant?
410 : case IrOpcode::kInt64Constant: // TODO(turbofan): rename Word64Constant?
411 : case IrOpcode::kFloat32Constant:
412 : case IrOpcode::kFloat64Constant:
413 : case IrOpcode::kRelocatableInt32Constant:
414 : case IrOpcode::kRelocatableInt64Constant:
415 : // Constants have no inputs.
416 4844907 : CHECK_EQ(0, input_count);
417 : // Type is empty.
418 4844907 : CheckNotTyped(node);
419 4844907 : break;
420 : case IrOpcode::kNumberConstant:
421 : // Constants have no inputs.
422 1226 : CHECK_EQ(0, input_count);
423 : // Type is a number.
424 1226 : CheckTypeIs(node, Type::Number());
425 1226 : break;
426 : case IrOpcode::kHeapConstant:
427 : // Constants have no inputs.
428 774336 : CHECK_EQ(0, input_count);
429 : // Type is anything.
430 774336 : CheckTypeIs(node, Type::Any());
431 774336 : break;
432 : case IrOpcode::kExternalConstant:
433 : case IrOpcode::kPointerConstant:
434 : // Constants have no inputs.
435 265013 : CHECK_EQ(0, input_count);
436 : // Type is an external pointer.
437 265013 : CheckTypeIs(node, Type::ExternalPointer());
438 265013 : break;
439 : case IrOpcode::kOsrValue:
440 : // OSR values have a value and a control input.
441 0 : CHECK_EQ(1, control_count);
442 0 : CHECK_EQ(1, input_count);
443 : // Type is merged from other values in the graph and could be any.
444 0 : CheckTypeIs(node, Type::Any());
445 0 : break;
446 : case IrOpcode::kProjection: {
447 : // Projection has an input that produces enough values.
448 19172 : int index = static_cast<int>(ProjectionIndexOf(node->op()));
449 19172 : Node* input = NodeProperties::GetValueInput(node, 0);
450 38344 : CHECK_GT(input->op()->ValueOutputCount(), index);
451 : // Type can be anything.
452 : // TODO(rossberg): Introduce tuple types for this.
453 : // TODO(titzer): Convince rossberg not to.
454 19172 : CheckTypeIs(node, Type::Any());
455 19172 : break;
456 : }
457 : case IrOpcode::kSelect: {
458 98 : CHECK_EQ(0, effect_count);
459 98 : CHECK_EQ(0, control_count);
460 98 : CHECK_EQ(3, value_count);
461 : // The condition must be a Boolean.
462 98 : CheckValueInputIs(node, 0, Type::Boolean());
463 : // Type can be anything.
464 98 : CheckTypeIs(node, Type::Any());
465 98 : break;
466 : }
467 : case IrOpcode::kPhi: {
468 : // Phi input count matches parent control node.
469 564568 : CHECK_EQ(0, effect_count);
470 564568 : CHECK_EQ(1, control_count);
471 564568 : Node* control = NodeProperties::GetControlInput(node, 0);
472 1129136 : CHECK_EQ(value_count, control->op()->ControlInputCount());
473 564568 : CHECK_EQ(input_count, 1 + value_count);
474 : // Type must be subsumed by all input types.
475 : // TODO(rossberg): for now at least, narrowing does not really hold.
476 : /*
477 : for (int i = 0; i < value_count; ++i) {
478 : CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
479 : }
480 : */
481 : break;
482 : }
483 : case IrOpcode::kInductionVariablePhi: {
484 : // This is only a temporary node for the typer.
485 0 : UNREACHABLE();
486 : break;
487 : }
488 : case IrOpcode::kEffectPhi: {
489 : // EffectPhi input count matches parent control node.
490 655078 : CHECK_EQ(0, value_count);
491 655078 : CHECK_EQ(1, control_count);
492 655078 : Node* control = NodeProperties::GetControlInput(node, 0);
493 1310156 : CHECK_EQ(effect_count, control->op()->ControlInputCount());
494 655078 : CHECK_EQ(input_count, 1 + effect_count);
495 : // If the control input is a Merge, then make sure that at least one
496 : // of it's usages is non-phi.
497 655078 : if (control->opcode() == IrOpcode::kMerge) {
498 : bool non_phi_use_found = false;
499 5655962 : for (Node* use : control->uses()) {
500 4540800 : if (all.IsLive(use) && use->opcode() != IrOpcode::kEffectPhi &&
501 : use->opcode() != IrOpcode::kPhi) {
502 : non_phi_use_found = true;
503 : }
504 : }
505 557581 : CHECK(non_phi_use_found);
506 : }
507 : break;
508 : }
509 : case IrOpcode::kLoopExit: {
510 0 : CHECK_EQ(2, control_count);
511 0 : Node* loop = NodeProperties::GetControlInput(node, 1);
512 0 : CHECK_EQ(IrOpcode::kLoop, loop->opcode());
513 : break;
514 : }
515 : case IrOpcode::kLoopExitValue: {
516 0 : CHECK_EQ(1, control_count);
517 0 : Node* loop_exit = NodeProperties::GetControlInput(node, 0);
518 0 : CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
519 : break;
520 : }
521 : case IrOpcode::kLoopExitEffect: {
522 0 : CHECK_EQ(1, control_count);
523 0 : Node* loop_exit = NodeProperties::GetControlInput(node, 0);
524 0 : CHECK_EQ(IrOpcode::kLoopExit, loop_exit->opcode());
525 : break;
526 : }
527 : case IrOpcode::kCheckpoint:
528 : // Type is empty.
529 1843 : CheckNotTyped(node);
530 1843 : break;
531 : case IrOpcode::kBeginRegion:
532 : // TODO(rossberg): what are the constraints on these?
533 : break;
534 : case IrOpcode::kFinishRegion: {
535 : // TODO(rossberg): what are the constraints on these?
536 : // Type must be subsumed by input type.
537 433 : if (typing == TYPED) {
538 188 : Node* val = NodeProperties::GetValueInput(node, 0);
539 376 : CHECK(NodeProperties::GetType(val).Is(NodeProperties::GetType(node)));
540 : }
541 : break;
542 : }
543 : case IrOpcode::kFrameState: {
544 : // TODO(jarin): what are the constraints on these?
545 5232 : CHECK_EQ(5, value_count);
546 5232 : CHECK_EQ(0, control_count);
547 5232 : CHECK_EQ(0, effect_count);
548 5232 : CHECK_EQ(6, input_count);
549 : // Check that the parameters and registers are kStateValues or
550 : // kTypedStateValues.
551 10464 : for (int i = 0; i < 2; ++i) {
552 25536 : CHECK(NodeProperties::GetValueInput(node, i)->opcode() ==
553 : IrOpcode::kStateValues ||
554 : NodeProperties::GetValueInput(node, i)->opcode() ==
555 : IrOpcode::kTypedStateValues);
556 : }
557 : // The accumulator (InputAt(2)) cannot be kStateValues, but it can be
558 : // kTypedStateValues (to signal the type). Once AST graph builder
559 : // is removed, we should check this here. Until then, AST graph
560 : // builder can generate expression stack as InputAt(2), which can
561 : // still be kStateValues.
562 : break;
563 : }
564 : case IrOpcode::kObjectId:
565 0 : CheckTypeIs(node, Type::Object());
566 0 : break;
567 : case IrOpcode::kStateValues:
568 : case IrOpcode::kTypedStateValues:
569 : case IrOpcode::kArgumentsElementsState:
570 : case IrOpcode::kArgumentsLengthState:
571 : case IrOpcode::kObjectState:
572 : case IrOpcode::kTypedObjectState:
573 : // TODO(jarin): what are the constraints on these?
574 : break;
575 : case IrOpcode::kCall:
576 : case IrOpcode::kCallWithCallerSavedRegisters:
577 : // TODO(rossberg): what are the constraints on these?
578 : break;
579 : case IrOpcode::kTailCall:
580 : // TODO(bmeurer): what are the constraints on these?
581 : break;
582 :
583 : // JavaScript operators
584 : // --------------------
585 : case IrOpcode::kJSEqual:
586 : case IrOpcode::kJSStrictEqual:
587 : case IrOpcode::kJSLessThan:
588 : case IrOpcode::kJSGreaterThan:
589 : case IrOpcode::kJSLessThanOrEqual:
590 : case IrOpcode::kJSGreaterThanOrEqual:
591 : // Type is Boolean.
592 37 : CheckTypeIs(node, Type::Boolean());
593 37 : break;
594 :
595 : case IrOpcode::kJSAdd:
596 0 : CheckTypeIs(node, Type::NumericOrString());
597 0 : break;
598 : case IrOpcode::kJSBitwiseOr:
599 : case IrOpcode::kJSBitwiseXor:
600 : case IrOpcode::kJSBitwiseAnd:
601 : case IrOpcode::kJSShiftLeft:
602 : case IrOpcode::kJSShiftRight:
603 : case IrOpcode::kJSShiftRightLogical:
604 : case IrOpcode::kJSSubtract:
605 : case IrOpcode::kJSMultiply:
606 : case IrOpcode::kJSDivide:
607 : case IrOpcode::kJSModulus:
608 : case IrOpcode::kJSExponentiate:
609 : case IrOpcode::kJSBitwiseNot:
610 : case IrOpcode::kJSDecrement:
611 : case IrOpcode::kJSIncrement:
612 : case IrOpcode::kJSNegate:
613 0 : CheckTypeIs(node, Type::Numeric());
614 0 : break;
615 :
616 : case IrOpcode::kToBoolean:
617 : // Type is Boolean.
618 0 : CheckTypeIs(node, Type::Boolean());
619 0 : break;
620 : case IrOpcode::kJSToLength:
621 0 : CheckTypeIs(node, Type::Range(0, kMaxSafeInteger, zone));
622 0 : break;
623 : case IrOpcode::kJSToName:
624 : // Type is Name.
625 0 : CheckTypeIs(node, Type::Name());
626 0 : break;
627 : case IrOpcode::kJSToNumber:
628 : case IrOpcode::kJSToNumberConvertBigInt:
629 : // Type is Number.
630 0 : CheckTypeIs(node, Type::Number());
631 0 : break;
632 : case IrOpcode::kJSToNumeric:
633 : // Type is Numeric.
634 0 : CheckTypeIs(node, Type::Numeric());
635 0 : break;
636 : case IrOpcode::kJSToString:
637 : // Type is String.
638 0 : CheckTypeIs(node, Type::String());
639 0 : break;
640 : case IrOpcode::kJSToObject:
641 : // Type is Receiver.
642 0 : CheckTypeIs(node, Type::Receiver());
643 0 : break;
644 : case IrOpcode::kJSParseInt:
645 0 : CheckValueInputIs(node, 0, Type::Any());
646 0 : CheckValueInputIs(node, 1, Type::Any());
647 0 : CheckTypeIs(node, Type::Number());
648 0 : break;
649 : case IrOpcode::kJSRegExpTest:
650 0 : CheckValueInputIs(node, 0, Type::Any());
651 0 : CheckValueInputIs(node, 1, Type::String());
652 0 : CheckTypeIs(node, Type::Boolean());
653 0 : break;
654 : case IrOpcode::kJSCreate:
655 : // Type is Object.
656 0 : CheckTypeIs(node, Type::Object());
657 0 : break;
658 : case IrOpcode::kJSCreateArguments:
659 : // Type is Array \/ OtherObject.
660 29 : CheckTypeIs(node, Type::ArrayOrOtherObject());
661 29 : break;
662 : case IrOpcode::kJSCreateArray:
663 : // Type is Array.
664 0 : CheckTypeIs(node, Type::Array());
665 0 : break;
666 : case IrOpcode::kJSCreateArrayIterator:
667 : // Type is OtherObject.
668 0 : CheckTypeIs(node, Type::OtherObject());
669 0 : break;
670 : case IrOpcode::kJSCreateAsyncFunctionObject:
671 : // Type is OtherObject.
672 0 : CheckTypeIs(node, Type::OtherObject());
673 0 : break;
674 : case IrOpcode::kJSCreateCollectionIterator:
675 : // Type is OtherObject.
676 0 : CheckTypeIs(node, Type::OtherObject());
677 0 : break;
678 : case IrOpcode::kJSCreateBoundFunction:
679 : // Type is BoundFunction.
680 0 : CheckTypeIs(node, Type::BoundFunction());
681 0 : break;
682 : case IrOpcode::kJSCreateClosure:
683 : // Type is Function.
684 489 : CheckTypeIs(node, Type::Function());
685 489 : break;
686 : case IrOpcode::kJSCreateIterResultObject:
687 : // Type is OtherObject.
688 0 : CheckTypeIs(node, Type::OtherObject());
689 0 : break;
690 : case IrOpcode::kJSCreateStringIterator:
691 : // Type is OtherObject.
692 0 : CheckTypeIs(node, Type::OtherObject());
693 0 : break;
694 : case IrOpcode::kJSCreateKeyValueArray:
695 : // Type is OtherObject.
696 0 : CheckTypeIs(node, Type::OtherObject());
697 0 : break;
698 : case IrOpcode::kJSCreateObject:
699 : // Type is Object.
700 0 : CheckTypeIs(node, Type::OtherObject());
701 0 : break;
702 : case IrOpcode::kJSCreatePromise:
703 : // Type is OtherObject.
704 0 : CheckTypeIs(node, Type::OtherObject());
705 0 : break;
706 : case IrOpcode::kJSCreateTypedArray:
707 : // Type is OtherObject.
708 0 : CheckTypeIs(node, Type::OtherObject());
709 0 : break;
710 : case IrOpcode::kJSCreateLiteralArray:
711 : // Type is Array.
712 0 : CheckTypeIs(node, Type::Array());
713 0 : break;
714 : case IrOpcode::kJSCreateEmptyLiteralArray:
715 : // Type is Array.
716 0 : CheckTypeIs(node, Type::Array());
717 0 : break;
718 : case IrOpcode::kJSCreateArrayFromIterable:
719 : // Type is Array.
720 0 : CheckTypeIs(node, Type::Array());
721 0 : break;
722 : case IrOpcode::kJSCreateLiteralObject:
723 : case IrOpcode::kJSCreateEmptyLiteralObject:
724 : case IrOpcode::kJSCloneObject:
725 : case IrOpcode::kJSCreateLiteralRegExp:
726 : // Type is OtherObject.
727 0 : CheckTypeIs(node, Type::OtherObject());
728 0 : break;
729 : case IrOpcode::kJSLoadProperty:
730 : // Type can be anything.
731 9 : CheckTypeIs(node, Type::Any());
732 18 : CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
733 : break;
734 : case IrOpcode::kJSLoadNamed:
735 : // Type can be anything.
736 239 : CheckTypeIs(node, Type::Any());
737 239 : break;
738 : case IrOpcode::kJSLoadGlobal:
739 : // Type can be anything.
740 92 : CheckTypeIs(node, Type::Any());
741 184 : CHECK(LoadGlobalParametersOf(node->op()).feedback().IsValid());
742 : break;
743 : case IrOpcode::kJSStoreProperty:
744 : // Type is empty.
745 16 : CheckNotTyped(node);
746 32 : CHECK(PropertyAccessOf(node->op()).feedback().IsValid());
747 : break;
748 : case IrOpcode::kJSStoreNamed:
749 : // Type is empty.
750 106 : CheckNotTyped(node);
751 106 : break;
752 : case IrOpcode::kJSStoreGlobal:
753 : // Type is empty.
754 306 : CheckNotTyped(node);
755 612 : CHECK(StoreGlobalParametersOf(node->op()).feedback().IsValid());
756 : break;
757 : case IrOpcode::kJSStoreNamedOwn:
758 : // Type is empty.
759 0 : CheckNotTyped(node);
760 0 : CHECK(StoreNamedOwnParametersOf(node->op()).feedback().IsValid());
761 : break;
762 : case IrOpcode::kJSStoreDataPropertyInLiteral:
763 : case IrOpcode::kJSStoreInArrayLiteral:
764 : // Type is empty.
765 0 : CheckNotTyped(node);
766 0 : CHECK(FeedbackParameterOf(node->op()).feedback().IsValid());
767 : break;
768 : case IrOpcode::kJSDeleteProperty:
769 : case IrOpcode::kJSHasProperty:
770 : case IrOpcode::kJSHasInPrototypeChain:
771 : case IrOpcode::kJSInstanceOf:
772 : case IrOpcode::kJSOrdinaryHasInstance:
773 : // Type is Boolean.
774 30 : CheckTypeIs(node, Type::Boolean());
775 30 : break;
776 : case IrOpcode::kTypeOf:
777 : // Type is InternalizedString.
778 0 : CheckTypeIs(node, Type::InternalizedString());
779 0 : break;
780 : case IrOpcode::kJSGetSuperConstructor:
781 : // We don't check the input for Type::Function because
782 : // this_function can be context-allocated.
783 : // Any -> Callable.
784 57 : CheckValueInputIs(node, 0, Type::Any());
785 57 : CheckTypeIs(node, Type::Callable());
786 57 : break;
787 :
788 : case IrOpcode::kJSLoadContext:
789 : // Type can be anything.
790 0 : CheckTypeIs(node, Type::Any());
791 0 : break;
792 : case IrOpcode::kJSStoreContext:
793 : // Type is empty.
794 88 : CheckNotTyped(node);
795 88 : break;
796 : case IrOpcode::kJSCreateFunctionContext:
797 : case IrOpcode::kJSCreateCatchContext:
798 : case IrOpcode::kJSCreateWithContext:
799 : case IrOpcode::kJSCreateBlockContext: {
800 : // Type is Context, and operand is Internal.
801 77 : Node* context = NodeProperties::GetContextInput(node);
802 : // TODO(bmeurer): This should say CheckTypeIs, but we don't have type
803 : // OtherInternal on certain contexts, i.e. those from OsrValue inputs.
804 77 : CheckTypeMaybe(context, Type::OtherInternal());
805 77 : CheckTypeIs(node, Type::OtherInternal());
806 77 : break;
807 : }
808 :
809 : case IrOpcode::kJSConstructForwardVarargs:
810 : case IrOpcode::kJSConstruct:
811 : case IrOpcode::kJSConstructWithArrayLike:
812 : case IrOpcode::kJSConstructWithSpread:
813 : // Type is Receiver.
814 88 : CheckTypeIs(node, Type::Receiver());
815 88 : break;
816 : case IrOpcode::kJSCallForwardVarargs:
817 : case IrOpcode::kJSCall:
818 : case IrOpcode::kJSCallWithArrayLike:
819 : case IrOpcode::kJSCallWithSpread:
820 : case IrOpcode::kJSCallRuntime:
821 : // Type can be anything.
822 456 : CheckTypeIs(node, Type::Any());
823 456 : break;
824 :
825 : case IrOpcode::kJSForInEnumerate:
826 : // Any -> OtherInternal.
827 0 : CheckValueInputIs(node, 0, Type::Any());
828 0 : CheckTypeIs(node, Type::OtherInternal());
829 0 : break;
830 : case IrOpcode::kJSForInPrepare:
831 : // TODO(bmeurer): What are the constraints on thse?
832 0 : CheckTypeIs(node, Type::Any());
833 0 : break;
834 : case IrOpcode::kJSForInNext:
835 0 : CheckTypeIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
836 0 : break;
837 :
838 : case IrOpcode::kJSLoadMessage:
839 : case IrOpcode::kJSStoreMessage:
840 : break;
841 :
842 : case IrOpcode::kJSLoadModule:
843 0 : CheckTypeIs(node, Type::Any());
844 0 : break;
845 : case IrOpcode::kJSStoreModule:
846 0 : CheckNotTyped(node);
847 0 : break;
848 :
849 : case IrOpcode::kJSGeneratorStore:
850 0 : CheckNotTyped(node);
851 0 : break;
852 :
853 : case IrOpcode::kJSCreateGeneratorObject:
854 0 : CheckTypeIs(node, Type::OtherObject());
855 0 : break;
856 :
857 : case IrOpcode::kJSGeneratorRestoreContinuation:
858 0 : CheckTypeIs(node, Type::SignedSmall());
859 0 : break;
860 :
861 : case IrOpcode::kJSGeneratorRestoreContext:
862 0 : CheckTypeIs(node, Type::Any());
863 0 : break;
864 :
865 : case IrOpcode::kJSGeneratorRestoreRegister:
866 0 : CheckTypeIs(node, Type::Any());
867 0 : break;
868 :
869 : case IrOpcode::kJSGeneratorRestoreInputOrDebugPos:
870 0 : CheckTypeIs(node, Type::Any());
871 0 : break;
872 :
873 : case IrOpcode::kJSStackCheck:
874 : case IrOpcode::kJSDebugger:
875 : // Type is empty.
876 144 : CheckNotTyped(node);
877 144 : break;
878 :
879 : case IrOpcode::kJSAsyncFunctionEnter:
880 0 : CheckValueInputIs(node, 0, Type::Any());
881 0 : CheckValueInputIs(node, 1, Type::Any());
882 0 : CheckTypeIs(node, Type::OtherObject());
883 0 : break;
884 : case IrOpcode::kJSAsyncFunctionReject:
885 0 : CheckValueInputIs(node, 0, Type::Any());
886 0 : CheckValueInputIs(node, 1, Type::Any());
887 0 : CheckValueInputIs(node, 2, Type::Boolean());
888 0 : CheckTypeIs(node, Type::OtherObject());
889 0 : break;
890 : case IrOpcode::kJSAsyncFunctionResolve:
891 0 : CheckValueInputIs(node, 0, Type::Any());
892 0 : CheckValueInputIs(node, 1, Type::Any());
893 0 : CheckValueInputIs(node, 2, Type::Boolean());
894 0 : CheckTypeIs(node, Type::OtherObject());
895 0 : break;
896 : case IrOpcode::kJSFulfillPromise:
897 0 : CheckValueInputIs(node, 0, Type::Any());
898 0 : CheckValueInputIs(node, 1, Type::Any());
899 0 : CheckTypeIs(node, Type::Undefined());
900 0 : break;
901 : case IrOpcode::kJSPerformPromiseThen:
902 0 : CheckValueInputIs(node, 0, Type::Any());
903 0 : CheckValueInputIs(node, 1, Type::Any());
904 0 : CheckValueInputIs(node, 2, Type::Any());
905 0 : CheckValueInputIs(node, 3, Type::Any());
906 0 : CheckTypeIs(node, Type::Receiver());
907 0 : break;
908 : case IrOpcode::kJSPromiseResolve:
909 0 : CheckValueInputIs(node, 0, Type::Any());
910 0 : CheckValueInputIs(node, 1, Type::Any());
911 0 : CheckTypeIs(node, Type::Receiver());
912 0 : break;
913 : case IrOpcode::kJSRejectPromise:
914 0 : CheckValueInputIs(node, 0, Type::Any());
915 0 : CheckValueInputIs(node, 1, Type::Any());
916 0 : CheckValueInputIs(node, 2, Type::Any());
917 0 : CheckTypeIs(node, Type::Undefined());
918 0 : break;
919 : case IrOpcode::kJSResolvePromise:
920 0 : CheckValueInputIs(node, 0, Type::Any());
921 0 : CheckValueInputIs(node, 1, Type::Any());
922 0 : CheckTypeIs(node, Type::Undefined());
923 0 : break;
924 : case IrOpcode::kJSObjectIsArray:
925 0 : CheckValueInputIs(node, 0, Type::Any());
926 0 : CheckTypeIs(node, Type::Boolean());
927 0 : break;
928 :
929 : case IrOpcode::kComment:
930 : case IrOpcode::kDebugAbort:
931 : case IrOpcode::kDebugBreak:
932 : case IrOpcode::kRetain:
933 : case IrOpcode::kUnsafePointerAdd:
934 : case IrOpcode::kRuntimeAbort:
935 67199 : CheckNotTyped(node);
936 67199 : break;
937 :
938 : // Simplified operators
939 : // -------------------------------
940 : case IrOpcode::kBooleanNot:
941 : // Boolean -> Boolean
942 0 : CheckValueInputIs(node, 0, Type::Boolean());
943 0 : CheckTypeIs(node, Type::Boolean());
944 0 : break;
945 : case IrOpcode::kNumberEqual:
946 : // (Number, Number) -> Boolean
947 28 : CheckValueInputIs(node, 0, Type::Number());
948 28 : CheckValueInputIs(node, 1, Type::Number());
949 28 : CheckTypeIs(node, Type::Boolean());
950 28 : break;
951 : case IrOpcode::kNumberLessThan:
952 : case IrOpcode::kNumberLessThanOrEqual:
953 : // (Number, Number) -> Boolean
954 105 : CheckValueInputIs(node, 0, Type::Number());
955 105 : CheckValueInputIs(node, 1, Type::Number());
956 105 : CheckTypeIs(node, Type::Boolean());
957 105 : break;
958 : case IrOpcode::kSpeculativeSafeIntegerAdd:
959 : case IrOpcode::kSpeculativeSafeIntegerSubtract:
960 : case IrOpcode::kSpeculativeNumberAdd:
961 : case IrOpcode::kSpeculativeNumberSubtract:
962 : case IrOpcode::kSpeculativeNumberMultiply:
963 : case IrOpcode::kSpeculativeNumberDivide:
964 : case IrOpcode::kSpeculativeNumberModulus:
965 0 : CheckTypeIs(node, Type::Number());
966 0 : break;
967 : case IrOpcode::kSpeculativeNumberEqual:
968 : case IrOpcode::kSpeculativeNumberLessThan:
969 : case IrOpcode::kSpeculativeNumberLessThanOrEqual:
970 0 : CheckTypeIs(node, Type::Boolean());
971 0 : break;
972 : case IrOpcode::kNumberAdd:
973 : case IrOpcode::kNumberSubtract:
974 : case IrOpcode::kNumberMultiply:
975 : case IrOpcode::kNumberDivide:
976 : // (Number, Number) -> Number
977 70 : CheckValueInputIs(node, 0, Type::Number());
978 70 : CheckValueInputIs(node, 1, Type::Number());
979 70 : CheckTypeIs(node, Type::Number());
980 70 : break;
981 : case IrOpcode::kNumberModulus:
982 : // (Number, Number) -> Number
983 0 : CheckValueInputIs(node, 0, Type::Number());
984 0 : CheckValueInputIs(node, 1, Type::Number());
985 0 : CheckTypeIs(node, Type::Number());
986 0 : break;
987 : case IrOpcode::kNumberBitwiseOr:
988 : case IrOpcode::kNumberBitwiseXor:
989 : case IrOpcode::kNumberBitwiseAnd:
990 : // (Signed32, Signed32) -> Signed32
991 49 : CheckValueInputIs(node, 0, Type::Signed32());
992 49 : CheckValueInputIs(node, 1, Type::Signed32());
993 49 : CheckTypeIs(node, Type::Signed32());
994 49 : break;
995 : case IrOpcode::kSpeculativeNumberBitwiseOr:
996 : case IrOpcode::kSpeculativeNumberBitwiseXor:
997 : case IrOpcode::kSpeculativeNumberBitwiseAnd:
998 0 : CheckTypeIs(node, Type::Signed32());
999 0 : break;
1000 : case IrOpcode::kNumberShiftLeft:
1001 : case IrOpcode::kNumberShiftRight:
1002 : // (Signed32, Unsigned32) -> Signed32
1003 49 : CheckValueInputIs(node, 0, Type::Signed32());
1004 49 : CheckValueInputIs(node, 1, Type::Unsigned32());
1005 49 : CheckTypeIs(node, Type::Signed32());
1006 49 : break;
1007 : case IrOpcode::kSpeculativeNumberShiftLeft:
1008 : case IrOpcode::kSpeculativeNumberShiftRight:
1009 0 : CheckTypeIs(node, Type::Signed32());
1010 0 : break;
1011 : case IrOpcode::kNumberShiftRightLogical:
1012 : // (Unsigned32, Unsigned32) -> Unsigned32
1013 0 : CheckValueInputIs(node, 0, Type::Unsigned32());
1014 0 : CheckValueInputIs(node, 1, Type::Unsigned32());
1015 0 : CheckTypeIs(node, Type::Unsigned32());
1016 0 : break;
1017 : case IrOpcode::kSpeculativeNumberShiftRightLogical:
1018 0 : CheckTypeIs(node, Type::Unsigned32());
1019 0 : break;
1020 : case IrOpcode::kNumberImul:
1021 : // (Unsigned32, Unsigned32) -> Signed32
1022 0 : CheckValueInputIs(node, 0, Type::Unsigned32());
1023 0 : CheckValueInputIs(node, 1, Type::Unsigned32());
1024 0 : CheckTypeIs(node, Type::Signed32());
1025 0 : break;
1026 : case IrOpcode::kNumberClz32:
1027 : // Unsigned32 -> Unsigned32
1028 0 : CheckValueInputIs(node, 0, Type::Unsigned32());
1029 0 : CheckTypeIs(node, Type::Unsigned32());
1030 0 : break;
1031 : case IrOpcode::kNumberAtan2:
1032 : case IrOpcode::kNumberMax:
1033 : case IrOpcode::kNumberMin:
1034 : case IrOpcode::kNumberPow:
1035 : // (Number, Number) -> Number
1036 0 : CheckValueInputIs(node, 0, Type::Number());
1037 0 : CheckValueInputIs(node, 1, Type::Number());
1038 0 : CheckTypeIs(node, Type::Number());
1039 0 : break;
1040 : case IrOpcode::kNumberAbs:
1041 : case IrOpcode::kNumberCeil:
1042 : case IrOpcode::kNumberFloor:
1043 : case IrOpcode::kNumberFround:
1044 : case IrOpcode::kNumberAcos:
1045 : case IrOpcode::kNumberAcosh:
1046 : case IrOpcode::kNumberAsin:
1047 : case IrOpcode::kNumberAsinh:
1048 : case IrOpcode::kNumberAtan:
1049 : case IrOpcode::kNumberAtanh:
1050 : case IrOpcode::kNumberCos:
1051 : case IrOpcode::kNumberCosh:
1052 : case IrOpcode::kNumberExp:
1053 : case IrOpcode::kNumberExpm1:
1054 : case IrOpcode::kNumberLog:
1055 : case IrOpcode::kNumberLog1p:
1056 : case IrOpcode::kNumberLog2:
1057 : case IrOpcode::kNumberLog10:
1058 : case IrOpcode::kNumberCbrt:
1059 : case IrOpcode::kNumberRound:
1060 : case IrOpcode::kNumberSign:
1061 : case IrOpcode::kNumberSin:
1062 : case IrOpcode::kNumberSinh:
1063 : case IrOpcode::kNumberSqrt:
1064 : case IrOpcode::kNumberTan:
1065 : case IrOpcode::kNumberTanh:
1066 : case IrOpcode::kNumberTrunc:
1067 : // Number -> Number
1068 0 : CheckValueInputIs(node, 0, Type::Number());
1069 0 : CheckTypeIs(node, Type::Number());
1070 0 : break;
1071 : case IrOpcode::kNumberToBoolean:
1072 : // Number -> Boolean
1073 0 : CheckValueInputIs(node, 0, Type::Number());
1074 0 : CheckTypeIs(node, Type::Boolean());
1075 0 : break;
1076 : case IrOpcode::kNumberToInt32:
1077 : // Number -> Signed32
1078 0 : CheckValueInputIs(node, 0, Type::Number());
1079 0 : CheckTypeIs(node, Type::Signed32());
1080 0 : break;
1081 : case IrOpcode::kNumberToString:
1082 : // Number -> String
1083 0 : CheckValueInputIs(node, 0, Type::Number());
1084 0 : CheckTypeIs(node, Type::String());
1085 0 : break;
1086 : case IrOpcode::kNumberToUint32:
1087 : case IrOpcode::kNumberToUint8Clamped:
1088 : // Number -> Unsigned32
1089 0 : CheckValueInputIs(node, 0, Type::Number());
1090 0 : CheckTypeIs(node, Type::Unsigned32());
1091 0 : break;
1092 : case IrOpcode::kSpeculativeToNumber:
1093 : // Any -> Number
1094 0 : CheckValueInputIs(node, 0, Type::Any());
1095 0 : CheckTypeIs(node, Type::Number());
1096 0 : break;
1097 : case IrOpcode::kPlainPrimitiveToNumber:
1098 : // PlainPrimitive -> Number
1099 0 : CheckValueInputIs(node, 0, Type::PlainPrimitive());
1100 0 : CheckTypeIs(node, Type::Number());
1101 0 : break;
1102 : case IrOpcode::kPlainPrimitiveToWord32:
1103 : // PlainPrimitive -> Integral32
1104 0 : CheckValueInputIs(node, 0, Type::PlainPrimitive());
1105 0 : CheckTypeIs(node, Type::Integral32());
1106 0 : break;
1107 : case IrOpcode::kPlainPrimitiveToFloat64:
1108 : // PlainPrimitive -> Number
1109 0 : CheckValueInputIs(node, 0, Type::PlainPrimitive());
1110 0 : CheckTypeIs(node, Type::Number());
1111 0 : break;
1112 : case IrOpcode::kStringConcat:
1113 0 : CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1114 0 : CheckValueInputIs(node, 1, Type::String());
1115 0 : CheckValueInputIs(node, 2, Type::String());
1116 0 : CheckTypeIs(node, Type::String());
1117 0 : break;
1118 : case IrOpcode::kStringEqual:
1119 : case IrOpcode::kStringLessThan:
1120 : case IrOpcode::kStringLessThanOrEqual:
1121 : // (String, String) -> Boolean
1122 0 : CheckValueInputIs(node, 0, Type::String());
1123 0 : CheckValueInputIs(node, 1, Type::String());
1124 0 : CheckTypeIs(node, Type::Boolean());
1125 0 : break;
1126 : case IrOpcode::kStringToNumber:
1127 : // String -> Number
1128 0 : CheckValueInputIs(node, 0, Type::String());
1129 0 : CheckTypeIs(node, Type::Number());
1130 0 : break;
1131 : case IrOpcode::kStringCharCodeAt:
1132 : // (String, Unsigned32) -> UnsignedSmall
1133 0 : CheckValueInputIs(node, 0, Type::String());
1134 0 : CheckValueInputIs(node, 1, Type::Unsigned32());
1135 0 : CheckTypeIs(node, Type::UnsignedSmall());
1136 0 : break;
1137 : case IrOpcode::kStringCodePointAt:
1138 : // (String, Unsigned32) -> UnsignedSmall
1139 0 : CheckValueInputIs(node, 0, Type::String());
1140 0 : CheckValueInputIs(node, 1, Type::Unsigned32());
1141 0 : CheckTypeIs(node, Type::UnsignedSmall());
1142 0 : break;
1143 : case IrOpcode::kStringFromSingleCharCode:
1144 : // Number -> String
1145 0 : CheckValueInputIs(node, 0, Type::Number());
1146 0 : CheckTypeIs(node, Type::String());
1147 0 : break;
1148 : case IrOpcode::kStringFromSingleCodePoint:
1149 : // (Unsigned32) -> String
1150 0 : CheckValueInputIs(node, 0, Type::Number());
1151 0 : CheckTypeIs(node, Type::String());
1152 0 : break;
1153 : case IrOpcode::kStringIndexOf:
1154 : // (String, String, SignedSmall) -> SignedSmall
1155 0 : CheckValueInputIs(node, 0, Type::String());
1156 0 : CheckValueInputIs(node, 1, Type::String());
1157 0 : CheckValueInputIs(node, 2, Type::SignedSmall());
1158 0 : CheckTypeIs(node, Type::SignedSmall());
1159 0 : break;
1160 : case IrOpcode::kStringLength:
1161 0 : CheckValueInputIs(node, 0, Type::String());
1162 0 : CheckTypeIs(node, TypeCache::Get()->kStringLengthType);
1163 0 : break;
1164 : case IrOpcode::kStringToLowerCaseIntl:
1165 : case IrOpcode::kStringToUpperCaseIntl:
1166 0 : CheckValueInputIs(node, 0, Type::String());
1167 0 : CheckTypeIs(node, Type::String());
1168 0 : break;
1169 : case IrOpcode::kStringSubstring:
1170 0 : CheckValueInputIs(node, 0, Type::String());
1171 0 : CheckValueInputIs(node, 1, Type::SignedSmall());
1172 0 : CheckValueInputIs(node, 2, Type::SignedSmall());
1173 0 : CheckTypeIs(node, Type::String());
1174 0 : break;
1175 : case IrOpcode::kReferenceEqual:
1176 : // (Unique, Any) -> Boolean and
1177 : // (Any, Unique) -> Boolean
1178 105 : CheckTypeIs(node, Type::Boolean());
1179 105 : break;
1180 : case IrOpcode::kSameValue:
1181 : // (Any, Any) -> Boolean
1182 0 : CheckValueInputIs(node, 0, Type::Any());
1183 0 : CheckValueInputIs(node, 1, Type::Any());
1184 0 : CheckTypeIs(node, Type::Boolean());
1185 0 : break;
1186 :
1187 : case IrOpcode::kObjectIsArrayBufferView:
1188 : case IrOpcode::kObjectIsBigInt:
1189 : case IrOpcode::kObjectIsCallable:
1190 : case IrOpcode::kObjectIsConstructor:
1191 : case IrOpcode::kObjectIsDetectableCallable:
1192 : case IrOpcode::kObjectIsMinusZero:
1193 : case IrOpcode::kObjectIsNaN:
1194 : case IrOpcode::kObjectIsNonCallable:
1195 : case IrOpcode::kObjectIsNumber:
1196 : case IrOpcode::kObjectIsReceiver:
1197 : case IrOpcode::kObjectIsSmi:
1198 : case IrOpcode::kObjectIsString:
1199 : case IrOpcode::kObjectIsSymbol:
1200 : case IrOpcode::kObjectIsUndetectable:
1201 161 : CheckValueInputIs(node, 0, Type::Any());
1202 161 : CheckTypeIs(node, Type::Boolean());
1203 161 : break;
1204 : case IrOpcode::kNumberIsFloat64Hole:
1205 0 : CheckValueInputIs(node, 0, Type::NumberOrHole());
1206 0 : CheckTypeIs(node, Type::Boolean());
1207 0 : break;
1208 : case IrOpcode::kNumberIsFinite:
1209 0 : CheckValueInputIs(node, 0, Type::Number());
1210 0 : CheckTypeIs(node, Type::Boolean());
1211 0 : break;
1212 : case IrOpcode::kNumberIsMinusZero:
1213 : case IrOpcode::kNumberIsNaN:
1214 0 : CheckValueInputIs(node, 0, Type::Number());
1215 0 : CheckTypeIs(node, Type::Boolean());
1216 0 : break;
1217 : case IrOpcode::kObjectIsFiniteNumber:
1218 0 : CheckValueInputIs(node, 0, Type::Any());
1219 0 : CheckTypeIs(node, Type::Boolean());
1220 0 : break;
1221 : case IrOpcode::kNumberIsInteger:
1222 0 : CheckValueInputIs(node, 0, Type::Number());
1223 0 : CheckTypeIs(node, Type::Boolean());
1224 0 : break;
1225 : case IrOpcode::kObjectIsSafeInteger:
1226 0 : CheckValueInputIs(node, 0, Type::Any());
1227 0 : CheckTypeIs(node, Type::Boolean());
1228 0 : break;
1229 : case IrOpcode::kNumberIsSafeInteger:
1230 0 : CheckValueInputIs(node, 0, Type::Number());
1231 0 : CheckTypeIs(node, Type::Boolean());
1232 0 : break;
1233 : case IrOpcode::kObjectIsInteger:
1234 0 : CheckValueInputIs(node, 0, Type::Any());
1235 0 : CheckTypeIs(node, Type::Boolean());
1236 0 : break;
1237 : case IrOpcode::kFindOrderedHashMapEntry:
1238 0 : CheckValueInputIs(node, 0, Type::Any());
1239 0 : CheckTypeIs(node, Type::SignedSmall());
1240 0 : break;
1241 : case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
1242 0 : CheckValueInputIs(node, 0, Type::Any());
1243 0 : CheckValueInputIs(node, 1, Type::Signed32());
1244 0 : CheckTypeIs(node, Type::SignedSmall());
1245 0 : break;
1246 : case IrOpcode::kArgumentsLength:
1247 10 : CheckValueInputIs(node, 0, Type::ExternalPointer());
1248 10 : CheckTypeIs(node, TypeCache::Get()->kArgumentsLengthType);
1249 10 : break;
1250 : case IrOpcode::kArgumentsFrame:
1251 10 : CheckTypeIs(node, Type::ExternalPointer());
1252 10 : break;
1253 : case IrOpcode::kNewDoubleElements:
1254 : case IrOpcode::kNewSmiOrObjectElements:
1255 : CheckValueInputIs(node, 0,
1256 0 : Type::Range(0.0, FixedArray::kMaxLength, zone));
1257 0 : CheckTypeIs(node, Type::OtherInternal());
1258 0 : break;
1259 : case IrOpcode::kNewArgumentsElements:
1260 10 : CheckValueInputIs(node, 0, Type::ExternalPointer());
1261 : CheckValueInputIs(node, 1,
1262 10 : Type::Range(0.0, FixedArray::kMaxLength, zone));
1263 10 : CheckTypeIs(node, Type::OtherInternal());
1264 10 : break;
1265 : case IrOpcode::kNewConsString:
1266 0 : CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1267 0 : CheckValueInputIs(node, 1, Type::String());
1268 0 : CheckValueInputIs(node, 2, Type::String());
1269 0 : CheckTypeIs(node, Type::String());
1270 0 : break;
1271 : case IrOpcode::kDelayedStringConstant:
1272 0 : CheckTypeIs(node, Type::String());
1273 0 : break;
1274 : case IrOpcode::kAllocate:
1275 363 : CheckValueInputIs(node, 0, Type::PlainNumber());
1276 363 : break;
1277 : case IrOpcode::kAllocateRaw:
1278 : // CheckValueInputIs(node, 0, Type::PlainNumber());
1279 : break;
1280 : case IrOpcode::kEnsureWritableFastElements:
1281 0 : CheckValueInputIs(node, 0, Type::Any());
1282 0 : CheckValueInputIs(node, 1, Type::Internal());
1283 0 : CheckTypeIs(node, Type::Internal());
1284 0 : break;
1285 : case IrOpcode::kMaybeGrowFastElements:
1286 70 : CheckValueInputIs(node, 0, Type::Any());
1287 70 : CheckValueInputIs(node, 1, Type::Internal());
1288 70 : CheckValueInputIs(node, 2, Type::Unsigned31());
1289 70 : CheckValueInputIs(node, 3, Type::Unsigned31());
1290 70 : CheckTypeIs(node, Type::Internal());
1291 70 : break;
1292 : case IrOpcode::kTransitionElementsKind:
1293 70 : CheckValueInputIs(node, 0, Type::Any());
1294 70 : CheckNotTyped(node);
1295 70 : break;
1296 :
1297 : case IrOpcode::kChangeTaggedSignedToInt32: {
1298 : // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1299 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1300 : // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1301 : // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1302 : // CheckValueInputIs(node, 0, from));
1303 : // CheckTypeIs(node, to));
1304 : break;
1305 : }
1306 : case IrOpcode::kChangeTaggedSignedToInt64:
1307 : break;
1308 : case IrOpcode::kChangeTaggedToInt32: {
1309 : // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1310 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1311 : // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1312 : // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1313 : // CheckValueInputIs(node, 0, from));
1314 : // CheckTypeIs(node, to));
1315 : break;
1316 : }
1317 : case IrOpcode::kChangeTaggedToInt64:
1318 : break;
1319 : case IrOpcode::kChangeTaggedToUint32: {
1320 : // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
1321 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1322 : // Type from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1323 : // Type to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
1324 : // CheckValueInputIs(node, 0, from));
1325 : // CheckTypeIs(node, to));
1326 : break;
1327 : }
1328 : case IrOpcode::kChangeTaggedToFloat64: {
1329 : // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1330 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1331 : // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1332 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1333 : // CheckValueInputIs(node, 0, from));
1334 : // CheckTypeIs(node, to));
1335 : break;
1336 : }
1337 : case IrOpcode::kChangeTaggedToTaggedSigned:
1338 : break;
1339 : case IrOpcode::kTruncateTaggedToFloat64: {
1340 : // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1341 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1342 : // Type from = Type::Intersect(Type::NumberOrUndefined(),
1343 : // Type::Tagged());
1344 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1345 : // CheckValueInputIs(node, 0, from));
1346 : // CheckTypeIs(node, to));
1347 : break;
1348 : }
1349 : case IrOpcode::kChangeInt31ToTaggedSigned: {
1350 : // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
1351 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1352 : // Type from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
1353 : // Type to = Type::Intersect(Type::Signed31(), Type::Tagged());
1354 : // CheckValueInputIs(node, 0, from));
1355 : // CheckTypeIs(node, to));
1356 : break;
1357 : }
1358 : case IrOpcode::kChangeInt32ToTagged: {
1359 : // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
1360 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1361 : // Type from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1362 : // Type to = Type::Intersect(Type::Signed32(), Type::Tagged());
1363 : // CheckValueInputIs(node, 0, from));
1364 : // CheckTypeIs(node, to));
1365 : break;
1366 : }
1367 : case IrOpcode::kChangeInt64ToTagged:
1368 : break;
1369 : case IrOpcode::kChangeUint32ToTagged: {
1370 : // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
1371 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1372 : // Type from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
1373 : // Type to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1374 : // CheckValueInputIs(node, 0, from));
1375 : // CheckTypeIs(node, to));
1376 : break;
1377 : }
1378 : case IrOpcode::kChangeUint64ToTagged:
1379 : break;
1380 : case IrOpcode::kChangeFloat64ToTagged: {
1381 : // Number /\ UntaggedFloat64 -> Number /\ Tagged
1382 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1383 : // Type from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1384 : // Type to = Type::Intersect(Type::Number(), Type::Tagged());
1385 : // CheckValueInputIs(node, 0, from));
1386 : // CheckTypeIs(node, to));
1387 : break;
1388 : }
1389 : case IrOpcode::kChangeFloat64ToTaggedPointer:
1390 : break;
1391 : case IrOpcode::kChangeTaggedToBit: {
1392 : // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
1393 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1394 : // Type from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1395 : // Type to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1396 : // CheckValueInputIs(node, 0, from));
1397 : // CheckTypeIs(node, to));
1398 : break;
1399 : }
1400 : case IrOpcode::kChangeBitToTagged: {
1401 : // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
1402 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1403 : // Type from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1404 : // Type to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1405 : // CheckValueInputIs(node, 0, from));
1406 : // CheckTypeIs(node, to));
1407 : break;
1408 : }
1409 : case IrOpcode::kTruncateTaggedToWord32: {
1410 : // Number /\ Tagged -> Signed32 /\ UntaggedInt32
1411 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1412 : // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1413 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedInt32());
1414 : // CheckValueInputIs(node, 0, from));
1415 : // CheckTypeIs(node, to));
1416 : break;
1417 : }
1418 : case IrOpcode::kTruncateTaggedToBit:
1419 : case IrOpcode::kTruncateTaggedPointerToBit:
1420 : break;
1421 :
1422 : case IrOpcode::kCheckBounds:
1423 49 : CheckValueInputIs(node, 0, Type::Any());
1424 49 : CheckValueInputIs(node, 1, TypeCache::Get()->kPositiveSafeInteger);
1425 49 : CheckTypeIs(node, TypeCache::Get()->kPositiveSafeInteger);
1426 49 : break;
1427 : case IrOpcode::kPoisonIndex:
1428 0 : CheckValueInputIs(node, 0, Type::Unsigned32());
1429 0 : CheckTypeIs(node, Type::Unsigned32());
1430 0 : break;
1431 : case IrOpcode::kCheckHeapObject:
1432 119 : CheckValueInputIs(node, 0, Type::Any());
1433 119 : break;
1434 : case IrOpcode::kCheckIf:
1435 70 : CheckValueInputIs(node, 0, Type::Boolean());
1436 70 : CheckNotTyped(node);
1437 70 : break;
1438 : case IrOpcode::kCheckInternalizedString:
1439 0 : CheckValueInputIs(node, 0, Type::Any());
1440 0 : CheckTypeIs(node, Type::InternalizedString());
1441 0 : break;
1442 : case IrOpcode::kCheckMaps:
1443 315 : CheckValueInputIs(node, 0, Type::Any());
1444 315 : CheckNotTyped(node);
1445 315 : break;
1446 : case IrOpcode::kCompareMaps:
1447 0 : CheckValueInputIs(node, 0, Type::Any());
1448 0 : CheckTypeIs(node, Type::Boolean());
1449 0 : break;
1450 : case IrOpcode::kCheckNumber:
1451 21 : CheckValueInputIs(node, 0, Type::Any());
1452 21 : CheckTypeIs(node, Type::Number());
1453 21 : break;
1454 : case IrOpcode::kCheckReceiver:
1455 0 : CheckValueInputIs(node, 0, Type::Any());
1456 0 : CheckTypeIs(node, Type::Receiver());
1457 0 : break;
1458 : case IrOpcode::kCheckReceiverOrNullOrUndefined:
1459 0 : CheckValueInputIs(node, 0, Type::Any());
1460 0 : CheckTypeIs(node, Type::ReceiverOrNullOrUndefined());
1461 0 : break;
1462 : case IrOpcode::kCheckSmi:
1463 21 : CheckValueInputIs(node, 0, Type::Any());
1464 21 : break;
1465 : case IrOpcode::kCheckString:
1466 0 : CheckValueInputIs(node, 0, Type::Any());
1467 0 : CheckTypeIs(node, Type::String());
1468 0 : break;
1469 : case IrOpcode::kCheckSymbol:
1470 0 : CheckValueInputIs(node, 0, Type::Any());
1471 0 : CheckTypeIs(node, Type::Symbol());
1472 0 : break;
1473 : case IrOpcode::kConvertReceiver:
1474 : // (Any, Any) -> Receiver
1475 42 : CheckValueInputIs(node, 0, Type::Any());
1476 42 : CheckValueInputIs(node, 1, Type::Any());
1477 42 : CheckTypeIs(node, Type::Receiver());
1478 42 : break;
1479 :
1480 : case IrOpcode::kCheckedInt32Add:
1481 : case IrOpcode::kCheckedInt32Sub:
1482 : case IrOpcode::kCheckedInt32Div:
1483 : case IrOpcode::kCheckedInt32Mod:
1484 : case IrOpcode::kCheckedUint32Div:
1485 : case IrOpcode::kCheckedUint32Mod:
1486 : case IrOpcode::kCheckedInt32Mul:
1487 : case IrOpcode::kCheckedInt32ToTaggedSigned:
1488 : case IrOpcode::kCheckedInt64ToInt32:
1489 : case IrOpcode::kCheckedInt64ToTaggedSigned:
1490 : case IrOpcode::kCheckedUint32Bounds:
1491 : case IrOpcode::kCheckedUint32ToInt32:
1492 : case IrOpcode::kCheckedUint32ToTaggedSigned:
1493 : case IrOpcode::kCheckedUint64Bounds:
1494 : case IrOpcode::kCheckedUint64ToInt32:
1495 : case IrOpcode::kCheckedUint64ToTaggedSigned:
1496 : case IrOpcode::kCheckedFloat64ToInt32:
1497 : case IrOpcode::kCheckedFloat64ToInt64:
1498 : case IrOpcode::kCheckedTaggedSignedToInt32:
1499 : case IrOpcode::kCheckedTaggedToInt32:
1500 : case IrOpcode::kCheckedTaggedToInt64:
1501 : case IrOpcode::kCheckedTaggedToFloat64:
1502 : case IrOpcode::kCheckedTaggedToTaggedSigned:
1503 : case IrOpcode::kCheckedTaggedToTaggedPointer:
1504 : case IrOpcode::kCheckedTruncateTaggedToWord32:
1505 : break;
1506 :
1507 : case IrOpcode::kCheckFloat64Hole:
1508 0 : CheckValueInputIs(node, 0, Type::NumberOrHole());
1509 0 : CheckTypeIs(node, Type::NumberOrUndefined());
1510 0 : break;
1511 : case IrOpcode::kCheckNotTaggedHole:
1512 0 : CheckValueInputIs(node, 0, Type::Any());
1513 0 : CheckTypeIs(node, Type::NonInternal());
1514 0 : break;
1515 : case IrOpcode::kConvertTaggedHoleToUndefined:
1516 0 : CheckValueInputIs(node, 0, Type::Any());
1517 0 : CheckTypeIs(node, Type::NonInternal());
1518 0 : break;
1519 :
1520 : case IrOpcode::kCheckEqualsInternalizedString:
1521 0 : CheckValueInputIs(node, 0, Type::InternalizedString());
1522 0 : CheckValueInputIs(node, 1, Type::Any());
1523 0 : CheckNotTyped(node);
1524 0 : break;
1525 : case IrOpcode::kCheckEqualsSymbol:
1526 0 : CheckValueInputIs(node, 0, Type::Symbol());
1527 0 : CheckValueInputIs(node, 1, Type::Any());
1528 0 : CheckNotTyped(node);
1529 0 : break;
1530 :
1531 : case IrOpcode::kLoadFieldByIndex:
1532 0 : CheckValueInputIs(node, 0, Type::Any());
1533 0 : CheckValueInputIs(node, 1, Type::SignedSmall());
1534 0 : CheckTypeIs(node, Type::NonInternal());
1535 0 : break;
1536 : case IrOpcode::kLoadField:
1537 : // Object -> fieldtype
1538 : // TODO(rossberg): activate once machine ops are typed.
1539 : // CheckValueInputIs(node, 0, Type::Object());
1540 : // CheckTypeIs(node, FieldAccessOf(node->op()).type));
1541 : break;
1542 : case IrOpcode::kLoadElement:
1543 : // Object -> elementtype
1544 : // TODO(rossberg): activate once machine ops are typed.
1545 : // CheckValueInputIs(node, 0, Type::Object());
1546 : // CheckTypeIs(node, ElementAccessOf(node->op()).type));
1547 : break;
1548 : case IrOpcode::kLoadTypedElement:
1549 : break;
1550 : case IrOpcode::kLoadDataViewElement:
1551 : break;
1552 : case IrOpcode::kStoreField:
1553 : // (Object, fieldtype) -> _|_
1554 : // TODO(rossberg): activate once machine ops are typed.
1555 : // CheckValueInputIs(node, 0, Type::Object());
1556 : // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
1557 3842 : CheckNotTyped(node);
1558 3842 : break;
1559 : case IrOpcode::kStoreElement:
1560 : // (Object, elementtype) -> _|_
1561 : // TODO(rossberg): activate once machine ops are typed.
1562 : // CheckValueInputIs(node, 0, Type::Object());
1563 : // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
1564 91 : CheckNotTyped(node);
1565 91 : break;
1566 : case IrOpcode::kTransitionAndStoreElement:
1567 0 : CheckNotTyped(node);
1568 0 : break;
1569 : case IrOpcode::kTransitionAndStoreNumberElement:
1570 0 : CheckNotTyped(node);
1571 0 : break;
1572 : case IrOpcode::kTransitionAndStoreNonNumberElement:
1573 0 : CheckNotTyped(node);
1574 0 : break;
1575 : case IrOpcode::kStoreSignedSmallElement:
1576 0 : CheckNotTyped(node);
1577 0 : break;
1578 : case IrOpcode::kStoreTypedElement:
1579 0 : CheckNotTyped(node);
1580 0 : break;
1581 : case IrOpcode::kStoreDataViewElement:
1582 0 : CheckNotTyped(node);
1583 0 : break;
1584 : case IrOpcode::kNumberSilenceNaN:
1585 21 : CheckValueInputIs(node, 0, Type::Number());
1586 21 : CheckTypeIs(node, Type::Number());
1587 21 : break;
1588 : case IrOpcode::kMapGuard:
1589 0 : CheckNotTyped(node);
1590 0 : break;
1591 : case IrOpcode::kTypeGuard:
1592 140 : CheckTypeIs(node, TypeGuardTypeOf(node->op()));
1593 140 : break;
1594 : case IrOpcode::kDateNow:
1595 0 : CHECK_EQ(0, value_count);
1596 0 : CheckTypeIs(node, Type::Number());
1597 0 : break;
1598 :
1599 : // Machine operators
1600 : // -----------------------
1601 : case IrOpcode::kLoad:
1602 : case IrOpcode::kPoisonedLoad:
1603 : case IrOpcode::kProtectedLoad:
1604 : case IrOpcode::kProtectedStore:
1605 : case IrOpcode::kStore:
1606 : case IrOpcode::kStackSlot:
1607 : case IrOpcode::kWord32And:
1608 : case IrOpcode::kWord32Or:
1609 : case IrOpcode::kWord32Xor:
1610 : case IrOpcode::kWord32Shl:
1611 : case IrOpcode::kWord32Shr:
1612 : case IrOpcode::kWord32Sar:
1613 : case IrOpcode::kWord32Ror:
1614 : case IrOpcode::kWord32Equal:
1615 : case IrOpcode::kWord32Clz:
1616 : case IrOpcode::kWord32Ctz:
1617 : case IrOpcode::kWord32ReverseBits:
1618 : case IrOpcode::kWord32ReverseBytes:
1619 : case IrOpcode::kInt32AbsWithOverflow:
1620 : case IrOpcode::kWord32Popcnt:
1621 : case IrOpcode::kWord64And:
1622 : case IrOpcode::kWord64Or:
1623 : case IrOpcode::kWord64Xor:
1624 : case IrOpcode::kWord64Shl:
1625 : case IrOpcode::kWord64Shr:
1626 : case IrOpcode::kWord64Sar:
1627 : case IrOpcode::kWord64Ror:
1628 : case IrOpcode::kWord64Clz:
1629 : case IrOpcode::kWord64Popcnt:
1630 : case IrOpcode::kWord64Ctz:
1631 : case IrOpcode::kWord64ReverseBits:
1632 : case IrOpcode::kWord64ReverseBytes:
1633 : case IrOpcode::kInt64AbsWithOverflow:
1634 : case IrOpcode::kWord64Equal:
1635 : case IrOpcode::kInt32Add:
1636 : case IrOpcode::kInt32AddWithOverflow:
1637 : case IrOpcode::kInt32Sub:
1638 : case IrOpcode::kInt32SubWithOverflow:
1639 : case IrOpcode::kInt32Mul:
1640 : case IrOpcode::kInt32MulWithOverflow:
1641 : case IrOpcode::kInt32MulHigh:
1642 : case IrOpcode::kInt32Div:
1643 : case IrOpcode::kInt32Mod:
1644 : case IrOpcode::kInt32LessThan:
1645 : case IrOpcode::kInt32LessThanOrEqual:
1646 : case IrOpcode::kUint32Div:
1647 : case IrOpcode::kUint32Mod:
1648 : case IrOpcode::kUint32MulHigh:
1649 : case IrOpcode::kUint32LessThan:
1650 : case IrOpcode::kUint32LessThanOrEqual:
1651 : case IrOpcode::kInt64Add:
1652 : case IrOpcode::kInt64AddWithOverflow:
1653 : case IrOpcode::kInt64Sub:
1654 : case IrOpcode::kInt64SubWithOverflow:
1655 : case IrOpcode::kInt64Mul:
1656 : case IrOpcode::kInt64Div:
1657 : case IrOpcode::kInt64Mod:
1658 : case IrOpcode::kInt64LessThan:
1659 : case IrOpcode::kInt64LessThanOrEqual:
1660 : case IrOpcode::kUint64Div:
1661 : case IrOpcode::kUint64Mod:
1662 : case IrOpcode::kUint64LessThan:
1663 : case IrOpcode::kUint64LessThanOrEqual:
1664 : case IrOpcode::kFloat32Add:
1665 : case IrOpcode::kFloat32Sub:
1666 : case IrOpcode::kFloat32Neg:
1667 : case IrOpcode::kFloat32Mul:
1668 : case IrOpcode::kFloat32Div:
1669 : case IrOpcode::kFloat32Abs:
1670 : case IrOpcode::kFloat32Sqrt:
1671 : case IrOpcode::kFloat32Equal:
1672 : case IrOpcode::kFloat32LessThan:
1673 : case IrOpcode::kFloat32LessThanOrEqual:
1674 : case IrOpcode::kFloat32Max:
1675 : case IrOpcode::kFloat32Min:
1676 : case IrOpcode::kFloat64Add:
1677 : case IrOpcode::kFloat64Sub:
1678 : case IrOpcode::kFloat64Neg:
1679 : case IrOpcode::kFloat64Mul:
1680 : case IrOpcode::kFloat64Div:
1681 : case IrOpcode::kFloat64Mod:
1682 : case IrOpcode::kFloat64Max:
1683 : case IrOpcode::kFloat64Min:
1684 : case IrOpcode::kFloat64Abs:
1685 : case IrOpcode::kFloat64Acos:
1686 : case IrOpcode::kFloat64Acosh:
1687 : case IrOpcode::kFloat64Asin:
1688 : case IrOpcode::kFloat64Asinh:
1689 : case IrOpcode::kFloat64Atan:
1690 : case IrOpcode::kFloat64Atan2:
1691 : case IrOpcode::kFloat64Atanh:
1692 : case IrOpcode::kFloat64Cbrt:
1693 : case IrOpcode::kFloat64Cos:
1694 : case IrOpcode::kFloat64Cosh:
1695 : case IrOpcode::kFloat64Exp:
1696 : case IrOpcode::kFloat64Expm1:
1697 : case IrOpcode::kFloat64Log:
1698 : case IrOpcode::kFloat64Log1p:
1699 : case IrOpcode::kFloat64Log10:
1700 : case IrOpcode::kFloat64Log2:
1701 : case IrOpcode::kFloat64Pow:
1702 : case IrOpcode::kFloat64Sin:
1703 : case IrOpcode::kFloat64Sinh:
1704 : case IrOpcode::kFloat64Sqrt:
1705 : case IrOpcode::kFloat64Tan:
1706 : case IrOpcode::kFloat64Tanh:
1707 : case IrOpcode::kFloat32RoundDown:
1708 : case IrOpcode::kFloat64RoundDown:
1709 : case IrOpcode::kFloat32RoundUp:
1710 : case IrOpcode::kFloat64RoundUp:
1711 : case IrOpcode::kFloat32RoundTruncate:
1712 : case IrOpcode::kFloat64RoundTruncate:
1713 : case IrOpcode::kFloat64RoundTiesAway:
1714 : case IrOpcode::kFloat32RoundTiesEven:
1715 : case IrOpcode::kFloat64RoundTiesEven:
1716 : case IrOpcode::kFloat64Equal:
1717 : case IrOpcode::kFloat64LessThan:
1718 : case IrOpcode::kFloat64LessThanOrEqual:
1719 : case IrOpcode::kTruncateInt64ToInt32:
1720 : case IrOpcode::kRoundFloat64ToInt32:
1721 : case IrOpcode::kRoundInt32ToFloat32:
1722 : case IrOpcode::kRoundInt64ToFloat32:
1723 : case IrOpcode::kRoundInt64ToFloat64:
1724 : case IrOpcode::kRoundUint32ToFloat32:
1725 : case IrOpcode::kRoundUint64ToFloat64:
1726 : case IrOpcode::kRoundUint64ToFloat32:
1727 : case IrOpcode::kTruncateFloat64ToFloat32:
1728 : case IrOpcode::kTruncateFloat64ToWord32:
1729 : case IrOpcode::kBitcastFloat32ToInt32:
1730 : case IrOpcode::kBitcastFloat64ToInt64:
1731 : case IrOpcode::kBitcastInt32ToFloat32:
1732 : case IrOpcode::kBitcastInt64ToFloat64:
1733 : case IrOpcode::kBitcastTaggedToWord:
1734 : case IrOpcode::kBitcastWordToTagged:
1735 : case IrOpcode::kBitcastWordToTaggedSigned:
1736 : case IrOpcode::kChangeInt32ToInt64:
1737 : case IrOpcode::kChangeUint32ToUint64:
1738 : case IrOpcode::kChangeInt32ToFloat64:
1739 : case IrOpcode::kChangeInt64ToFloat64:
1740 : case IrOpcode::kChangeUint32ToFloat64:
1741 : case IrOpcode::kChangeFloat32ToFloat64:
1742 : case IrOpcode::kChangeFloat64ToInt32:
1743 : case IrOpcode::kChangeFloat64ToInt64:
1744 : case IrOpcode::kChangeFloat64ToUint32:
1745 : case IrOpcode::kChangeFloat64ToUint64:
1746 : case IrOpcode::kFloat64SilenceNaN:
1747 : case IrOpcode::kTruncateFloat64ToInt64:
1748 : case IrOpcode::kTruncateFloat64ToUint32:
1749 : case IrOpcode::kTruncateFloat32ToInt32:
1750 : case IrOpcode::kTruncateFloat32ToUint32:
1751 : case IrOpcode::kTryTruncateFloat32ToInt64:
1752 : case IrOpcode::kTryTruncateFloat64ToInt64:
1753 : case IrOpcode::kTryTruncateFloat32ToUint64:
1754 : case IrOpcode::kTryTruncateFloat64ToUint64:
1755 : case IrOpcode::kFloat64ExtractLowWord32:
1756 : case IrOpcode::kFloat64ExtractHighWord32:
1757 : case IrOpcode::kFloat64InsertLowWord32:
1758 : case IrOpcode::kFloat64InsertHighWord32:
1759 : case IrOpcode::kInt32PairAdd:
1760 : case IrOpcode::kInt32PairSub:
1761 : case IrOpcode::kInt32PairMul:
1762 : case IrOpcode::kWord32PairShl:
1763 : case IrOpcode::kWord32PairShr:
1764 : case IrOpcode::kWord32PairSar:
1765 : case IrOpcode::kTaggedPoisonOnSpeculation:
1766 : case IrOpcode::kWord32PoisonOnSpeculation:
1767 : case IrOpcode::kWord64PoisonOnSpeculation:
1768 : case IrOpcode::kLoadStackPointer:
1769 : case IrOpcode::kLoadFramePointer:
1770 : case IrOpcode::kLoadParentFramePointer:
1771 : case IrOpcode::kUnalignedLoad:
1772 : case IrOpcode::kUnalignedStore:
1773 : case IrOpcode::kWord32AtomicLoad:
1774 : case IrOpcode::kWord32AtomicStore:
1775 : case IrOpcode::kWord32AtomicExchange:
1776 : case IrOpcode::kWord32AtomicCompareExchange:
1777 : case IrOpcode::kWord32AtomicAdd:
1778 : case IrOpcode::kWord32AtomicSub:
1779 : case IrOpcode::kWord32AtomicAnd:
1780 : case IrOpcode::kWord32AtomicOr:
1781 : case IrOpcode::kWord32AtomicXor:
1782 : case IrOpcode::kWord64AtomicLoad:
1783 : case IrOpcode::kWord64AtomicStore:
1784 : case IrOpcode::kWord64AtomicAdd:
1785 : case IrOpcode::kWord64AtomicSub:
1786 : case IrOpcode::kWord64AtomicAnd:
1787 : case IrOpcode::kWord64AtomicOr:
1788 : case IrOpcode::kWord64AtomicXor:
1789 : case IrOpcode::kWord64AtomicExchange:
1790 : case IrOpcode::kWord64AtomicCompareExchange:
1791 : case IrOpcode::kWord32AtomicPairLoad:
1792 : case IrOpcode::kWord32AtomicPairStore:
1793 : case IrOpcode::kWord32AtomicPairAdd:
1794 : case IrOpcode::kWord32AtomicPairSub:
1795 : case IrOpcode::kWord32AtomicPairAnd:
1796 : case IrOpcode::kWord32AtomicPairOr:
1797 : case IrOpcode::kWord32AtomicPairXor:
1798 : case IrOpcode::kWord32AtomicPairExchange:
1799 : case IrOpcode::kWord32AtomicPairCompareExchange:
1800 : case IrOpcode::kSpeculationFence:
1801 : case IrOpcode::kSignExtendWord8ToInt32:
1802 : case IrOpcode::kSignExtendWord16ToInt32:
1803 : case IrOpcode::kSignExtendWord8ToInt64:
1804 : case IrOpcode::kSignExtendWord16ToInt64:
1805 : case IrOpcode::kSignExtendWord32ToInt64:
1806 :
1807 : #define SIMD_MACHINE_OP_CASE(Name) case IrOpcode::k##Name:
1808 : MACHINE_SIMD_OP_LIST(SIMD_MACHINE_OP_CASE)
1809 : #undef SIMD_MACHINE_OP_CASE
1810 :
1811 : // TODO(rossberg): Check.
1812 : break;
1813 : }
1814 20490280 : } // NOLINT(readability/fn_size)
1815 :
1816 201561 : void Verifier::Run(Graph* graph, Typing typing, CheckInputs check_inputs,
1817 : CodeType code_type) {
1818 67187 : CHECK_NOT_NULL(graph->start());
1819 67187 : CHECK_NOT_NULL(graph->end());
1820 67187 : Zone zone(graph->zone()->allocator(), ZONE_NAME);
1821 : Visitor visitor(&zone, typing, check_inputs, code_type);
1822 67187 : AllNodes all(&zone, graph);
1823 20624654 : for (Node* node : all.reachable) visitor.Check(node, all);
1824 :
1825 : // Check the uniqueness of projections.
1826 20646402 : for (Node* proj : all.reachable) {
1827 20490280 : if (proj->opcode() != IrOpcode::kProjection) continue;
1828 0 : Node* node = proj->InputAt(0);
1829 128564 : for (Node* other : node->uses()) {
1830 202300 : if (all.IsLive(other) && other != proj &&
1831 21748 : other->opcode() == IrOpcode::kProjection &&
1832 77788 : other->InputAt(0) == node &&
1833 43496 : ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
1834 0 : FATAL("Node #%d:%s has duplicate projections #%d and #%d", node->id(),
1835 0 : node->op()->mnemonic(), proj->id(), other->id());
1836 : }
1837 : }
1838 67187 : }
1839 67187 : }
1840 :
1841 :
1842 : // -----------------------------------------------------------------------------
1843 :
1844 10476 : static bool HasDominatingDef(Schedule* schedule, Node* node,
1845 : BasicBlock* container, BasicBlock* use_block,
1846 : int use_pos) {
1847 30014 : BasicBlock* block = use_block;
1848 : while (true) {
1849 619563 : while (use_pos >= 0) {
1850 1209112 : if (block->NodeAt(use_pos) == node) return true;
1851 594083 : use_pos--;
1852 : }
1853 : block = block->dominator();
1854 15007 : if (block == nullptr) break;
1855 15007 : use_pos = static_cast<int>(block->NodeCount()) - 1;
1856 15007 : if (node == block->control_input()) return true;
1857 : }
1858 : return false;
1859 : }
1860 :
1861 :
1862 2710 : static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
1863 2710 : BasicBlock* dom = schedule->block(dominator);
1864 3180 : BasicBlock* sub = schedule->block(dominatee);
1865 5890 : while (sub != nullptr) {
1866 3180 : if (sub == dom) {
1867 : return true;
1868 : }
1869 : sub = sub->dominator();
1870 : }
1871 : return false;
1872 : }
1873 :
1874 :
1875 6783 : static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
1876 6783 : Node* node, int use_pos) {
1877 24042 : for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
1878 : BasicBlock* use_block = block;
1879 10476 : if (node->opcode() == IrOpcode::kPhi) {
1880 182 : use_block = use_block->PredecessorAt(j);
1881 182 : use_pos = static_cast<int>(use_block->NodeCount()) - 1;
1882 : }
1883 0 : Node* input = node->InputAt(j);
1884 10476 : if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
1885 10476 : use_pos)) {
1886 0 : FATAL("Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
1887 : node->id(), node->op()->mnemonic(), block->rpo_number(), j,
1888 0 : input->id(), input->op()->mnemonic());
1889 : }
1890 : }
1891 : // Ensure that nodes are dominated by their control inputs;
1892 : // kEnd is an exception, as unreachable blocks resulting from kMerge
1893 : // are not in the RPO.
1894 9525 : if (node->op()->ControlInputCount() == 1 &&
1895 : node->opcode() != IrOpcode::kEnd) {
1896 2710 : Node* ctl = NodeProperties::GetControlInput(node);
1897 2710 : if (!Dominates(schedule, ctl, node)) {
1898 0 : FATAL("Node #%d:%s in B%d is not dominated by control input #%d:%s",
1899 : node->id(), node->op()->mnemonic(), block->rpo_number(), ctl->id(),
1900 0 : ctl->op()->mnemonic());
1901 : }
1902 : }
1903 6783 : }
1904 :
1905 :
1906 153 : void ScheduleVerifier::Run(Schedule* schedule) {
1907 : const size_t count = schedule->BasicBlockCount();
1908 51 : Zone tmp_zone(schedule->zone()->allocator(), ZONE_NAME);
1909 : Zone* zone = &tmp_zone;
1910 51 : BasicBlock* start = schedule->start();
1911 : BasicBlockVector* rpo_order = schedule->rpo_order();
1912 :
1913 : // Verify the RPO order contains only blocks from this schedule.
1914 847 : CHECK_GE(count, rpo_order->size());
1915 745 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1916 : ++b) {
1917 694 : CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
1918 : // All predecessors and successors should be in rpo and in this schedule.
1919 2245 : for (BasicBlock const* predecessor : (*b)->predecessors()) {
1920 857 : CHECK_GE(predecessor->rpo_number(), 0);
1921 857 : CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
1922 : }
1923 2939 : for (BasicBlock const* successor : (*b)->successors()) {
1924 857 : CHECK_GE(successor->rpo_number(), 0);
1925 857 : CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
1926 : }
1927 : }
1928 :
1929 : // Verify RPO numbers of blocks.
1930 51 : CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
1931 1439 : for (size_t b = 0; b < rpo_order->size(); b++) {
1932 1388 : BasicBlock* block = rpo_order->at(b);
1933 694 : CHECK_EQ(static_cast<int>(b), block->rpo_number());
1934 643 : BasicBlock* dom = block->dominator();
1935 694 : if (b == 0) {
1936 : // All blocks except start should have a dominator.
1937 51 : CHECK_NULL(dom);
1938 : } else {
1939 : // Check that the immediate dominator appears somewhere before the block.
1940 643 : CHECK_NOT_NULL(dom);
1941 643 : CHECK_LT(dom->rpo_number(), block->rpo_number());
1942 : }
1943 : }
1944 :
1945 : // Verify that all blocks reachable from start are in the RPO.
1946 51 : BoolVector marked(static_cast<int>(count), false, zone);
1947 : {
1948 51 : ZoneQueue<BasicBlock*> queue(zone);
1949 : queue.push(start);
1950 51 : marked[start->id().ToSize()] = true;
1951 796 : while (!queue.empty()) {
1952 694 : BasicBlock* block = queue.front();
1953 : queue.pop();
1954 3102 : for (size_t s = 0; s < block->SuccessorCount(); s++) {
1955 857 : BasicBlock* succ = block->SuccessorAt(s);
1956 1714 : if (!marked[succ->id().ToSize()]) {
1957 : marked[succ->id().ToSize()] = true;
1958 : queue.push(succ);
1959 : }
1960 : }
1961 : }
1962 : }
1963 : // Verify marked blocks are in the RPO.
1964 746 : for (size_t i = 0; i < count; i++) {
1965 1389 : BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
1966 1390 : if (marked[i]) {
1967 694 : CHECK_GE(block->rpo_number(), 0);
1968 1388 : CHECK_EQ(block, rpo_order->at(block->rpo_number()));
1969 : }
1970 : }
1971 : // Verify RPO blocks are marked.
1972 1439 : for (size_t b = 0; b < rpo_order->size(); b++) {
1973 1388 : CHECK(marked[rpo_order->at(b)->id().ToSize()]);
1974 : }
1975 :
1976 : {
1977 : // Verify the dominance relation.
1978 : ZoneVector<BitVector*> dominators(zone);
1979 51 : dominators.resize(count, nullptr);
1980 :
1981 : // Compute a set of all the nodes that dominate a given node by using
1982 : // a forward fixpoint. O(n^2).
1983 51 : ZoneQueue<BasicBlock*> queue(zone);
1984 : queue.push(start);
1985 51 : dominators[start->id().ToSize()] =
1986 102 : new (zone) BitVector(static_cast<int>(count), zone);
1987 986 : while (!queue.empty()) {
1988 1768 : BasicBlock* block = queue.front();
1989 : queue.pop();
1990 2411 : BitVector* block_doms = dominators[block->id().ToSize()];
1991 0 : BasicBlock* idom = block->dominator();
1992 1717 : if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
1993 : FATAL("Block B%d is not dominated by B%d", block->rpo_number(),
1994 0 : idom->rpo_number());
1995 : }
1996 3118 : for (size_t s = 0; s < block->SuccessorCount(); s++) {
1997 1117 : BasicBlock* succ = block->SuccessorAt(s);
1998 2234 : BitVector* succ_doms = dominators[succ->id().ToSize()];
1999 :
2000 1117 : if (succ_doms == nullptr) {
2001 : // First time visiting the node. S.doms = B U B.doms
2002 643 : succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
2003 : succ_doms->CopyFrom(*block_doms);
2004 : succ_doms->Add(block->id().ToInt());
2005 1286 : dominators[succ->id().ToSize()] = succ_doms;
2006 : queue.push(succ);
2007 : } else {
2008 : // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
2009 : bool had = succ_doms->Contains(block->id().ToInt());
2010 474 : if (had) succ_doms->Remove(block->id().ToInt());
2011 474 : if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
2012 474 : if (had) succ_doms->Add(block->id().ToInt());
2013 : }
2014 : }
2015 : }
2016 :
2017 : // Verify the immediateness of dominators.
2018 796 : for (BasicBlockVector::iterator b = rpo_order->begin();
2019 : b != rpo_order->end(); ++b) {
2020 694 : BasicBlock* block = *b;
2021 0 : BasicBlock* idom = block->dominator();
2022 694 : if (idom == nullptr) continue;
2023 1286 : BitVector* block_doms = dominators[block->id().ToSize()];
2024 :
2025 7792 : for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
2026 : BasicBlock* dom =
2027 6506 : schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
2028 5863 : if (dom != idom &&
2029 5220 : !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
2030 : FATAL("Block B%d is not immediately dominated by B%d",
2031 0 : block->rpo_number(), idom->rpo_number());
2032 : }
2033 : }
2034 : }
2035 : }
2036 :
2037 : // Verify phis are placed in the block of their control input.
2038 796 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2039 : ++b) {
2040 15790 : for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
2041 6507 : Node* phi = *i;
2042 6507 : if (phi->opcode() != IrOpcode::kPhi) continue;
2043 : // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
2044 : // schedules don't have control inputs.
2045 180 : if (phi->InputCount() > phi->op()->ValueInputCount()) {
2046 90 : Node* control = NodeProperties::GetControlInput(phi);
2047 90 : CHECK(control->opcode() == IrOpcode::kMerge ||
2048 : control->opcode() == IrOpcode::kLoop);
2049 90 : CHECK_EQ((*b), schedule->block(control));
2050 : }
2051 : }
2052 : }
2053 :
2054 : // Verify that all uses are dominated by their definitions.
2055 796 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2056 : ++b) {
2057 694 : BasicBlock* block = *b;
2058 :
2059 : // Check inputs to control for this block.
2060 : Node* control = block->control_input();
2061 694 : if (control != nullptr) {
2062 276 : CHECK_EQ(block, schedule->block(control));
2063 : CheckInputsDominate(schedule, block, control,
2064 276 : static_cast<int>(block->NodeCount()) - 1);
2065 : }
2066 : // Check inputs for all nodes in the block.
2067 13708 : for (size_t i = 0; i < block->NodeCount(); i++) {
2068 : Node* node = block->NodeAt(i);
2069 6507 : CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
2070 : }
2071 51 : }
2072 51 : }
2073 :
2074 :
2075 : #ifdef DEBUG
2076 :
2077 : // static
2078 : void Verifier::VerifyNode(Node* node) {
2079 : DCHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
2080 : node->InputCount());
2081 : // If this node has no effect or no control outputs,
2082 : // we check that none of its uses are effect or control inputs.
2083 : bool check_no_control = node->op()->ControlOutputCount() == 0;
2084 : bool check_no_effect = node->op()->EffectOutputCount() == 0;
2085 : bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
2086 : int effect_edges = 0;
2087 : if (check_no_effect || check_no_control) {
2088 : for (Edge edge : node->use_edges()) {
2089 : Node* const user = edge.from();
2090 : DCHECK(!user->IsDead());
2091 : if (NodeProperties::IsControlEdge(edge)) {
2092 : DCHECK(!check_no_control);
2093 : } else if (NodeProperties::IsEffectEdge(edge)) {
2094 : DCHECK(!check_no_effect);
2095 : effect_edges++;
2096 : } else if (NodeProperties::IsFrameStateEdge(edge)) {
2097 : DCHECK(!check_no_frame_state);
2098 : }
2099 : }
2100 : }
2101 :
2102 : // Frame state input should be a frame state (or sentinel).
2103 : if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
2104 : Node* input = NodeProperties::GetFrameStateInput(node);
2105 : DCHECK(input->opcode() == IrOpcode::kFrameState ||
2106 : input->opcode() == IrOpcode::kStart ||
2107 : input->opcode() == IrOpcode::kDead ||
2108 : input->opcode() == IrOpcode::kDeadValue);
2109 : }
2110 : // Effect inputs should be effect-producing nodes (or sentinels).
2111 : for (int i = 0; i < node->op()->EffectInputCount(); i++) {
2112 : Node* input = NodeProperties::GetEffectInput(node, i);
2113 : DCHECK(input->op()->EffectOutputCount() > 0 ||
2114 : input->opcode() == IrOpcode::kDead);
2115 : }
2116 : // Control inputs should be control-producing nodes (or sentinels).
2117 : for (int i = 0; i < node->op()->ControlInputCount(); i++) {
2118 : Node* input = NodeProperties::GetControlInput(node, i);
2119 : DCHECK(input->op()->ControlOutputCount() > 0 ||
2120 : input->opcode() == IrOpcode::kDead);
2121 : }
2122 : }
2123 :
2124 :
2125 : void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
2126 : const Node* replacement) {
2127 : // Check that the user does not misuse the replacement.
2128 : DCHECK(!NodeProperties::IsControlEdge(edge) ||
2129 : replacement->op()->ControlOutputCount() > 0);
2130 : DCHECK(!NodeProperties::IsEffectEdge(edge) ||
2131 : replacement->op()->EffectOutputCount() > 0);
2132 : DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
2133 : replacement->opcode() == IrOpcode::kFrameState ||
2134 : replacement->opcode() == IrOpcode::kDead ||
2135 : replacement->opcode() == IrOpcode::kDeadValue);
2136 : }
2137 :
2138 : #endif // DEBUG
2139 :
2140 : } // namespace compiler
2141 : } // namespace internal
2142 183867 : } // namespace v8
|