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