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 66748 : 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 10900911 : void CheckNotTyped(Node* node) {
50 10900911 : 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 10900911 : }
57 1348555 : void CheckTypeIs(Node* node, Type type) {
58 1351546 : 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 1348555 : }
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 1457405 : void CheckValueInputIs(Node* node, int i, Type type) {
74 1457405 : Node* input = NodeProperties::GetValueInput(node, i);
75 1458697 : 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 1457405 : }
84 38283578 : void CheckOutput(Node* node, Node* use, int count, const char* kind) {
85 38283578 : 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 38283578 : }
93 : };
94 :
95 129446709 : void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
96 21929685 : 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 21929685 : int effect_count = node->op()->EffectInputCount();
101 21929685 : int control_count = node->op()->ControlInputCount();
102 :
103 : // Verify number of inputs matches up.
104 21929685 : int input_count = value_count + context_count + frame_state_count;
105 21929685 : if (check_inputs == kAll) {
106 21929685 : input_count += effect_count + control_count;
107 : }
108 21929685 : 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 43859370 : if (code_type != kWasm && node->op()->EffectOutputCount() > 0) {
115 : int effect_edges = 0;
116 31236002 : for (Edge edge : node->use_edges()) {
117 11105893 : 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 10040 : for (int i = 0; i < frame_state_count; i++) {
126 10040 : Node* frame_state = NodeProperties::GetFrameStateInput(node);
127 15275 : 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 19782201 : for (int i = 0; i < value_count; ++i) {
135 39336517 : Node* value = NodeProperties::GetValueInput(node, i);
136 39564402 : CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
137 : // Verify that only parameters and projections can have input nodes with
138 : // multiple outputs.
139 58890833 : 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 2580 : for (int i = 0; i < context_count; ++i) {
146 2580 : Node* context = NodeProperties::GetContextInput(node);
147 5160 : CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
148 : }
149 :
150 21929685 : if (check_inputs == kAll) {
151 : // Verify all effect inputs actually have an effect.
152 6073474 : for (int i = 0; i < effect_count; ++i) {
153 6073474 : Node* effect = NodeProperties::GetEffectInput(node);
154 12146948 : CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
155 : }
156 :
157 : // Verify all control inputs are control nodes.
158 12425323 : for (int i = 0; i < control_count; ++i) {
159 12425323 : Node* control = NodeProperties::GetControlInput(node, i);
160 : CheckOutput(control, node, control->op()->ControlOutputCount(),
161 24850646 : "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 21929685 : if (!node->op()->HasProperty(Operator::kNoThrow)) {
167 0 : Node* discovered_if_exception = nullptr;
168 0 : Node* discovered_if_success = nullptr;
169 0 : Node* discovered_direct_use = nullptr;
170 : int total_number_of_control_uses = 0;
171 2581566 : for (Edge edge : node->use_edges()) {
172 1021534 : if (!NodeProperties::IsControlEdge(edge)) {
173 : continue;
174 : }
175 440961 : total_number_of_control_uses++;
176 440961 : Node* control_use = edge.from();
177 440961 : if (control_use->opcode() == IrOpcode::kIfSuccess) {
178 12403 : CHECK_NULL(discovered_if_success); // Only one allowed.
179 : discovered_if_success = control_use;
180 428558 : } else if (control_use->opcode() == IrOpcode::kIfException) {
181 12403 : 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 269249 : if (discovered_if_success && !discovered_if_exception) {
188 0 : 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 269249 : if (discovered_if_exception && !discovered_if_success) {
195 0 : 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 269249 : if ((discovered_if_success || discovered_if_exception) &&
202 : total_number_of_control_uses != 2) {
203 0 : 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 21929685 : switch (node->opcode()) {
213 : case IrOpcode::kStart:
214 : // Start has no inputs.
215 66748 : CHECK_EQ(0, input_count);
216 : // Type is a tuple.
217 : // TODO(rossberg): Multiple outputs are currently typed as Internal.
218 66748 : CheckTypeIs(node, Type::Internal());
219 66748 : break;
220 : case IrOpcode::kEnd:
221 : // End has no outputs.
222 66748 : CHECK_EQ(0, node->op()->ValueOutputCount());
223 66748 : CHECK_EQ(0, node->op()->EffectOutputCount());
224 66748 : CHECK_EQ(0, node->op()->ControlOutputCount());
225 : // All inputs are graph terminators.
226 812128 : for (const Node* input : node->inputs()) {
227 339316 : CHECK(IrOpcode::IsGraphTerminator(input->opcode()));
228 : }
229 : // Type is empty.
230 66748 : CheckNotTyped(node);
231 66748 : 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 42 : CheckTypeIs(node, Type::None());
241 168 : for (Edge edge : node->use_edges()) {
242 0 : Node* use = edge.from();
243 42 : 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 42 : break;
250 : case IrOpcode::kBranch: {
251 : // Branch uses are IfTrue and IfFalse.
252 : int count_true = 0, count_false = 0;
253 11639960 : for (const Node* use : node->uses()) {
254 5819980 : CHECK(all.IsLive(use) && (use->opcode() == IrOpcode::kIfTrue ||
255 : use->opcode() == IrOpcode::kIfFalse));
256 2909990 : if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
257 2909990 : if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
258 : }
259 1454995 : CHECK_EQ(1, count_true);
260 1454995 : CHECK_EQ(1, count_false);
261 : // The condition must be a Boolean.
262 1454995 : CheckValueInputIs(node, 0, Type::Boolean());
263 : // Type is empty.
264 1454995 : CheckNotTyped(node);
265 1454995 : break;
266 : }
267 : case IrOpcode::kIfTrue:
268 : case IrOpcode::kIfFalse: {
269 2909990 : Node* control = NodeProperties::GetControlInput(node, 0);
270 2909990 : CHECK_EQ(IrOpcode::kBranch, control->opcode());
271 : // Type is empty.
272 2909990 : CheckNotTyped(node);
273 2909990 : break;
274 : }
275 : case IrOpcode::kIfSuccess: {
276 : // IfSuccess and IfException continuation only on throwing nodes.
277 12403 : Node* input = NodeProperties::GetControlInput(node, 0);
278 12403 : CHECK(!input->op()->HasProperty(Operator::kNoThrow));
279 : // Type is empty.
280 12403 : CheckNotTyped(node);
281 12403 : break;
282 : }
283 : case IrOpcode::kIfException: {
284 : // IfSuccess and IfException continuation only on throwing nodes.
285 12403 : Node* input = NodeProperties::GetControlInput(node, 0);
286 12403 : CHECK(!input->op()->HasProperty(Operator::kNoThrow));
287 : // Type can be anything.
288 12403 : CheckTypeIs(node, Type::Any());
289 12403 : break;
290 : }
291 : case IrOpcode::kSwitch: {
292 : // Switch uses are Case and Default.
293 : int count_case = 0, count_default = 0;
294 1064624 : for (const Node* use : node->uses()) {
295 91844 : CHECK(all.IsLive(use));
296 91844 : switch (use->opcode()) {
297 : case IrOpcode::kIfValue: {
298 2989124 : for (const Node* user : node->uses()) {
299 1965556 : if (user != use && user->opcode() == IrOpcode::kIfValue) {
300 1720816 : CHECK_NE(IfValueParametersOf(use->op()).value(),
301 : IfValueParametersOf(user->op()).value());
302 : }
303 : }
304 81580 : ++count_case;
305 81580 : break;
306 : }
307 : case IrOpcode::kIfDefault: {
308 10264 : ++count_default;
309 10264 : break;
310 : }
311 : default: {
312 0 : FATAL("Switch #%d illegally used by #%d:%s", node->id(), use->id(),
313 0 : use->op()->mnemonic());
314 : break;
315 : }
316 : }
317 : }
318 10264 : CHECK_EQ(1, count_default);
319 30792 : CHECK_EQ(node->op()->ControlOutputCount(), count_case + count_default);
320 : // Type is empty.
321 10264 : CheckNotTyped(node);
322 10264 : break;
323 : }
324 : case IrOpcode::kIfValue:
325 : case IrOpcode::kIfDefault:
326 183688 : CHECK_EQ(IrOpcode::kSwitch,
327 : NodeProperties::GetControlInput(node)->opcode());
328 : // Type is empty.
329 91844 : CheckNotTyped(node);
330 91844 : break;
331 : case IrOpcode::kLoop: {
332 97967 : CHECK_EQ(control_count, input_count);
333 : // Type is empty.
334 97967 : 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 1003797 : for (const Node* use : node->uses()) {
339 905830 : if (all.IsLive(use) && use->opcode() == IrOpcode::kTerminate) {
340 : has_terminate = true;
341 : break;
342 : }
343 : }
344 97967 : CHECK(has_terminate);
345 : break;
346 : }
347 : case IrOpcode::kMerge:
348 748467 : CHECK_EQ(control_count, input_count);
349 : // Type is empty.
350 748467 : CheckNotTyped(node);
351 748467 : break;
352 : case IrOpcode::kDeoptimizeIf:
353 : case IrOpcode::kDeoptimizeUnless:
354 : // Type is empty.
355 252 : CheckNotTyped(node);
356 252 : 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 714100 : for (const Node* use : node->uses()) {
367 178525 : if (all.IsLive(use)) {
368 178525 : CHECK_EQ(IrOpcode::kEnd, use->opcode());
369 : }
370 : }
371 : // Type is empty.
372 178525 : CheckNotTyped(node);
373 178525 : break;
374 : case IrOpcode::kTerminate:
375 : // Terminates take one loop and effect.
376 97967 : CHECK_EQ(1, control_count);
377 97967 : CHECK_EQ(1, effect_count);
378 97967 : CHECK_EQ(2, input_count);
379 195934 : CHECK_EQ(IrOpcode::kLoop,
380 : NodeProperties::GetControlInput(node)->opcode());
381 : // Terminate uses are End.
382 391868 : for (const Node* use : node->uses()) {
383 97967 : if (all.IsLive(use)) {
384 97967 : CHECK_EQ(IrOpcode::kEnd, use->opcode());
385 : }
386 : }
387 : // Type is empty.
388 97967 : CheckNotTyped(node);
389 97967 : 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 208605 : CHECK_EQ(1, input_count);
405 : // Parameter has an input that produces enough values.
406 208605 : int const index = ParameterIndexOf(node->op());
407 208605 : Node* const start = NodeProperties::GetValueInput(node, 0);
408 208605 : CHECK_EQ(IrOpcode::kStart, start->opcode());
409 : // Currently, parameter indices start at -1 instead of 0.
410 208605 : CHECK_LE(-1, index);
411 417210 : CHECK_LT(index + 1, start->op()->ValueOutputCount());
412 : // Type can be anything.
413 208605 : CheckTypeIs(node, Type::Any());
414 208605 : 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 5036114 : CHECK_EQ(0, input_count);
424 : // Type is empty.
425 5036114 : CheckNotTyped(node);
426 5036114 : break;
427 : case IrOpcode::kNumberConstant:
428 : // Constants have no inputs.
429 1340 : CHECK_EQ(0, input_count);
430 : // Type is a number.
431 1340 : CheckTypeIs(node, Type::Number());
432 1340 : break;
433 : case IrOpcode::kHeapConstant:
434 : // Constants have no inputs.
435 772695 : CHECK_EQ(0, input_count);
436 : // Type is anything.
437 772695 : CheckTypeIs(node, Type::Any());
438 772695 : break;
439 : case IrOpcode::kExternalConstant:
440 : case IrOpcode::kPointerConstant:
441 : // Constants have no inputs.
442 264509 : CHECK_EQ(0, input_count);
443 : // Type is an external pointer.
444 264509 : CheckTypeIs(node, Type::ExternalPointer());
445 264509 : 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 19280 : int index = static_cast<int>(ProjectionIndexOf(node->op()));
456 19280 : Node* input = NodeProperties::GetValueInput(node, 0);
457 38560 : 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 19280 : CheckTypeIs(node, Type::Any());
462 19280 : break;
463 : }
464 : case IrOpcode::kSelect: {
465 98 : CHECK_EQ(0, effect_count);
466 98 : CHECK_EQ(0, control_count);
467 98 : CHECK_EQ(3, value_count);
468 : // The condition must be a Boolean.
469 98 : CheckValueInputIs(node, 0, Type::Boolean());
470 : // Type can be anything.
471 98 : CheckTypeIs(node, Type::Any());
472 98 : break;
473 : }
474 : case IrOpcode::kPhi: {
475 : // Phi input count matches parent control node.
476 572889 : CHECK_EQ(0, effect_count);
477 572889 : CHECK_EQ(1, control_count);
478 572889 : Node* control = NodeProperties::GetControlInput(node, 0);
479 1145778 : CHECK_EQ(value_count, control->op()->ControlInputCount());
480 572889 : 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 779495 : CHECK_EQ(0, value_count);
498 779495 : CHECK_EQ(1, control_count);
499 779495 : Node* control = NodeProperties::GetControlInput(node, 0);
500 1558990 : CHECK_EQ(effect_count, control->op()->ControlInputCount());
501 779495 : 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 779495 : if (control->opcode() == IrOpcode::kMerge) {
505 : bool non_phi_use_found = false;
506 6863770 : for (Node* use : control->uses()) {
507 5500714 : if (all.IsLive(use) && use->opcode() != IrOpcode::kEffectPhi &&
508 : use->opcode() != IrOpcode::kPhi) {
509 : non_phi_use_found = true;
510 : }
511 : }
512 681528 : 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 2154 : CheckNotTyped(node);
537 2154 : 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 6040 : CHECK_EQ(5, value_count);
553 6040 : CHECK_EQ(0, control_count);
554 6040 : CHECK_EQ(0, effect_count);
555 6040 : CHECK_EQ(6, input_count);
556 : // Check that the parameters and registers are kStateValues or
557 : // kTypedStateValues.
558 12080 : for (int i = 0; i < 2; ++i) {
559 29512 : 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 244 : CheckTypeIs(node, Type::Any());
748 488 : 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 466 : CheckTypeIs(node, Type::Any());
830 466 : 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 188136 : CheckNotTyped(node);
943 188136 : 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 : // (Any, Any) -> Boolean
1189 0 : CheckValueInputIs(node, 0, Type::Any());
1190 0 : CheckValueInputIs(node, 1, Type::Any());
1191 0 : CheckTypeIs(node, Type::Boolean());
1192 0 : break;
1193 :
1194 : case IrOpcode::kObjectIsArrayBufferView:
1195 : case IrOpcode::kObjectIsBigInt:
1196 : case IrOpcode::kObjectIsCallable:
1197 : case IrOpcode::kObjectIsConstructor:
1198 : case IrOpcode::kObjectIsDetectableCallable:
1199 : case IrOpcode::kObjectIsMinusZero:
1200 : case IrOpcode::kObjectIsNaN:
1201 : case IrOpcode::kObjectIsNonCallable:
1202 : case IrOpcode::kObjectIsNumber:
1203 : case IrOpcode::kObjectIsReceiver:
1204 : case IrOpcode::kObjectIsSmi:
1205 : case IrOpcode::kObjectIsString:
1206 : case IrOpcode::kObjectIsSymbol:
1207 : case IrOpcode::kObjectIsUndetectable:
1208 161 : CheckValueInputIs(node, 0, Type::Any());
1209 161 : CheckTypeIs(node, Type::Boolean());
1210 161 : break;
1211 : case IrOpcode::kNumberIsFloat64Hole:
1212 0 : CheckValueInputIs(node, 0, Type::NumberOrHole());
1213 0 : CheckTypeIs(node, Type::Boolean());
1214 0 : break;
1215 : case IrOpcode::kNumberIsFinite:
1216 0 : CheckValueInputIs(node, 0, Type::Number());
1217 0 : CheckTypeIs(node, Type::Boolean());
1218 0 : break;
1219 : case IrOpcode::kNumberIsMinusZero:
1220 : case IrOpcode::kNumberIsNaN:
1221 0 : CheckValueInputIs(node, 0, Type::Number());
1222 0 : CheckTypeIs(node, Type::Boolean());
1223 0 : break;
1224 : case IrOpcode::kObjectIsFiniteNumber:
1225 0 : CheckValueInputIs(node, 0, Type::Any());
1226 0 : CheckTypeIs(node, Type::Boolean());
1227 0 : break;
1228 : case IrOpcode::kNumberIsInteger:
1229 0 : CheckValueInputIs(node, 0, Type::Number());
1230 0 : CheckTypeIs(node, Type::Boolean());
1231 0 : break;
1232 : case IrOpcode::kObjectIsSafeInteger:
1233 0 : CheckValueInputIs(node, 0, Type::Any());
1234 0 : CheckTypeIs(node, Type::Boolean());
1235 0 : break;
1236 : case IrOpcode::kNumberIsSafeInteger:
1237 0 : CheckValueInputIs(node, 0, Type::Number());
1238 0 : CheckTypeIs(node, Type::Boolean());
1239 0 : break;
1240 : case IrOpcode::kObjectIsInteger:
1241 0 : CheckValueInputIs(node, 0, Type::Any());
1242 0 : CheckTypeIs(node, Type::Boolean());
1243 0 : break;
1244 : case IrOpcode::kFindOrderedHashMapEntry:
1245 0 : CheckValueInputIs(node, 0, Type::Any());
1246 0 : CheckTypeIs(node, Type::SignedSmall());
1247 0 : break;
1248 : case IrOpcode::kFindOrderedHashMapEntryForInt32Key:
1249 0 : CheckValueInputIs(node, 0, Type::Any());
1250 0 : CheckValueInputIs(node, 1, Type::Signed32());
1251 0 : CheckTypeIs(node, Type::SignedSmall());
1252 0 : break;
1253 : case IrOpcode::kArgumentsLength:
1254 10 : CheckValueInputIs(node, 0, Type::ExternalPointer());
1255 10 : CheckTypeIs(node, TypeCache::Get()->kArgumentsLengthType);
1256 10 : break;
1257 : case IrOpcode::kArgumentsFrame:
1258 10 : CheckTypeIs(node, Type::ExternalPointer());
1259 10 : break;
1260 : case IrOpcode::kNewDoubleElements:
1261 : case IrOpcode::kNewSmiOrObjectElements:
1262 : CheckValueInputIs(node, 0,
1263 0 : Type::Range(0.0, FixedArray::kMaxLength, zone));
1264 0 : CheckTypeIs(node, Type::OtherInternal());
1265 0 : break;
1266 : case IrOpcode::kNewArgumentsElements:
1267 10 : CheckValueInputIs(node, 0, Type::ExternalPointer());
1268 : CheckValueInputIs(node, 1,
1269 10 : Type::Range(0.0, FixedArray::kMaxLength, zone));
1270 10 : CheckTypeIs(node, Type::OtherInternal());
1271 10 : break;
1272 : case IrOpcode::kNewConsString:
1273 0 : CheckValueInputIs(node, 0, TypeCache::Get()->kStringLengthType);
1274 0 : CheckValueInputIs(node, 1, Type::String());
1275 0 : CheckValueInputIs(node, 2, Type::String());
1276 0 : CheckTypeIs(node, Type::String());
1277 0 : break;
1278 : case IrOpcode::kDelayedStringConstant:
1279 0 : CheckTypeIs(node, Type::String());
1280 0 : break;
1281 : case IrOpcode::kAllocate:
1282 363 : CheckValueInputIs(node, 0, Type::PlainNumber());
1283 363 : break;
1284 : case IrOpcode::kAllocateRaw:
1285 : // CheckValueInputIs(node, 0, Type::PlainNumber());
1286 : break;
1287 : case IrOpcode::kEnsureWritableFastElements:
1288 0 : CheckValueInputIs(node, 0, Type::Any());
1289 0 : CheckValueInputIs(node, 1, Type::Internal());
1290 0 : CheckTypeIs(node, Type::Internal());
1291 0 : break;
1292 : case IrOpcode::kMaybeGrowFastElements:
1293 70 : CheckValueInputIs(node, 0, Type::Any());
1294 70 : CheckValueInputIs(node, 1, Type::Internal());
1295 70 : CheckValueInputIs(node, 2, Type::Unsigned31());
1296 70 : CheckValueInputIs(node, 3, Type::Unsigned31());
1297 70 : CheckTypeIs(node, Type::Internal());
1298 70 : break;
1299 : case IrOpcode::kTransitionElementsKind:
1300 70 : CheckValueInputIs(node, 0, Type::Any());
1301 70 : CheckNotTyped(node);
1302 70 : break;
1303 :
1304 : case IrOpcode::kChangeTaggedSignedToInt32: {
1305 : // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1306 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1307 : // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1308 : // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1309 : // CheckValueInputIs(node, 0, from));
1310 : // CheckTypeIs(node, to));
1311 : break;
1312 : }
1313 : case IrOpcode::kChangeTaggedSignedToInt64:
1314 : break;
1315 : case IrOpcode::kChangeTaggedToInt32: {
1316 : // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
1317 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1318 : // Type from = Type::Intersect(Type::Signed32(), Type::Tagged());
1319 : // Type to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1320 : // CheckValueInputIs(node, 0, from));
1321 : // CheckTypeIs(node, to));
1322 : break;
1323 : }
1324 : case IrOpcode::kChangeTaggedToInt64:
1325 : break;
1326 : case IrOpcode::kChangeTaggedToUint32: {
1327 : // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
1328 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1329 : // Type from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1330 : // Type to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
1331 : // CheckValueInputIs(node, 0, from));
1332 : // CheckTypeIs(node, to));
1333 : break;
1334 : }
1335 : case IrOpcode::kChangeTaggedToFloat64: {
1336 : // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1337 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1338 : // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1339 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1340 : // CheckValueInputIs(node, 0, from));
1341 : // CheckTypeIs(node, to));
1342 : break;
1343 : }
1344 : case IrOpcode::kChangeTaggedToTaggedSigned:
1345 : break;
1346 : case IrOpcode::kTruncateTaggedToFloat64: {
1347 : // NumberOrUndefined /\ Tagged -> Number /\ UntaggedFloat64
1348 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1349 : // Type from = Type::Intersect(Type::NumberOrUndefined(),
1350 : // Type::Tagged());
1351 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1352 : // CheckValueInputIs(node, 0, from));
1353 : // CheckTypeIs(node, to));
1354 : break;
1355 : }
1356 : case IrOpcode::kChangeInt31ToTaggedSigned: {
1357 : // Signed31 /\ UntaggedInt32 -> Signed31 /\ Tagged
1358 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1359 : // Type from =Type::Intersect(Type::Signed31(), Type::UntaggedInt32());
1360 : // Type to = Type::Intersect(Type::Signed31(), Type::Tagged());
1361 : // CheckValueInputIs(node, 0, from));
1362 : // CheckTypeIs(node, to));
1363 : break;
1364 : }
1365 : case IrOpcode::kChangeInt32ToTagged: {
1366 : // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
1367 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1368 : // Type from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
1369 : // Type to = Type::Intersect(Type::Signed32(), Type::Tagged());
1370 : // CheckValueInputIs(node, 0, from));
1371 : // CheckTypeIs(node, to));
1372 : break;
1373 : }
1374 : case IrOpcode::kChangeInt64ToTagged:
1375 : break;
1376 : case IrOpcode::kChangeUint32ToTagged: {
1377 : // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
1378 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1379 : // Type from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
1380 : // Type to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
1381 : // CheckValueInputIs(node, 0, from));
1382 : // CheckTypeIs(node, to));
1383 : break;
1384 : }
1385 : case IrOpcode::kChangeUint64ToTagged:
1386 : break;
1387 : case IrOpcode::kChangeFloat64ToTagged: {
1388 : // Number /\ UntaggedFloat64 -> Number /\ Tagged
1389 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1390 : // Type from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
1391 : // Type to = Type::Intersect(Type::Number(), Type::Tagged());
1392 : // CheckValueInputIs(node, 0, from));
1393 : // CheckTypeIs(node, to));
1394 : break;
1395 : }
1396 : case IrOpcode::kChangeFloat64ToTaggedPointer:
1397 : break;
1398 : case IrOpcode::kChangeTaggedToBit: {
1399 : // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
1400 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1401 : // Type from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1402 : // Type to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1403 : // CheckValueInputIs(node, 0, from));
1404 : // CheckTypeIs(node, to));
1405 : break;
1406 : }
1407 : case IrOpcode::kChangeBitToTagged: {
1408 : // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
1409 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1410 : // Type from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
1411 : // Type to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
1412 : // CheckValueInputIs(node, 0, from));
1413 : // CheckTypeIs(node, to));
1414 : break;
1415 : }
1416 : case IrOpcode::kTruncateTaggedToWord32: {
1417 : // Number /\ Tagged -> Signed32 /\ UntaggedInt32
1418 : // TODO(neis): Activate once ChangeRepresentation works in typer.
1419 : // Type from = Type::Intersect(Type::Number(), Type::Tagged());
1420 : // Type to = Type::Intersect(Type::Number(), Type::UntaggedInt32());
1421 : // CheckValueInputIs(node, 0, from));
1422 : // CheckTypeIs(node, to));
1423 : break;
1424 : }
1425 : case IrOpcode::kTruncateTaggedToBit:
1426 : case IrOpcode::kTruncateTaggedPointerToBit:
1427 : break;
1428 :
1429 : case IrOpcode::kCheckBounds:
1430 49 : CheckValueInputIs(node, 0, Type::Any());
1431 49 : CheckValueInputIs(node, 1, TypeCache::Get()->kPositiveSafeInteger);
1432 49 : CheckTypeIs(node, TypeCache::Get()->kPositiveSafeInteger);
1433 49 : break;
1434 : case IrOpcode::kPoisonIndex:
1435 0 : CheckValueInputIs(node, 0, Type::Unsigned32());
1436 0 : CheckTypeIs(node, Type::Unsigned32());
1437 0 : break;
1438 : case IrOpcode::kCheckHeapObject:
1439 119 : CheckValueInputIs(node, 0, Type::Any());
1440 119 : break;
1441 : case IrOpcode::kCheckIf:
1442 70 : CheckValueInputIs(node, 0, Type::Boolean());
1443 70 : CheckNotTyped(node);
1444 70 : break;
1445 : case IrOpcode::kCheckInternalizedString:
1446 0 : CheckValueInputIs(node, 0, Type::Any());
1447 0 : CheckTypeIs(node, Type::InternalizedString());
1448 0 : break;
1449 : case IrOpcode::kCheckMaps:
1450 315 : CheckValueInputIs(node, 0, Type::Any());
1451 315 : CheckNotTyped(node);
1452 315 : break;
1453 : case IrOpcode::kCompareMaps:
1454 0 : CheckValueInputIs(node, 0, Type::Any());
1455 0 : CheckTypeIs(node, Type::Boolean());
1456 0 : break;
1457 : case IrOpcode::kCheckNumber:
1458 21 : CheckValueInputIs(node, 0, Type::Any());
1459 21 : CheckTypeIs(node, Type::Number());
1460 21 : break;
1461 : case IrOpcode::kCheckReceiver:
1462 0 : CheckValueInputIs(node, 0, Type::Any());
1463 0 : CheckTypeIs(node, Type::Receiver());
1464 0 : break;
1465 : case IrOpcode::kCheckReceiverOrNullOrUndefined:
1466 0 : CheckValueInputIs(node, 0, Type::Any());
1467 0 : CheckTypeIs(node, Type::ReceiverOrNullOrUndefined());
1468 0 : break;
1469 : case IrOpcode::kCheckSmi:
1470 21 : CheckValueInputIs(node, 0, Type::Any());
1471 21 : break;
1472 : case IrOpcode::kCheckString:
1473 0 : CheckValueInputIs(node, 0, Type::Any());
1474 0 : CheckTypeIs(node, Type::String());
1475 0 : break;
1476 : case IrOpcode::kCheckSymbol:
1477 0 : CheckValueInputIs(node, 0, Type::Any());
1478 0 : CheckTypeIs(node, Type::Symbol());
1479 0 : break;
1480 : case IrOpcode::kConvertReceiver:
1481 : // (Any, Any) -> Receiver
1482 42 : CheckValueInputIs(node, 0, Type::Any());
1483 42 : CheckValueInputIs(node, 1, Type::Any());
1484 42 : CheckTypeIs(node, Type::Receiver());
1485 42 : break;
1486 :
1487 : case IrOpcode::kCheckedInt32Add:
1488 : case IrOpcode::kCheckedInt32Sub:
1489 : case IrOpcode::kCheckedInt32Div:
1490 : case IrOpcode::kCheckedInt32Mod:
1491 : case IrOpcode::kCheckedUint32Div:
1492 : case IrOpcode::kCheckedUint32Mod:
1493 : case IrOpcode::kCheckedInt32Mul:
1494 : case IrOpcode::kCheckedInt32ToTaggedSigned:
1495 : case IrOpcode::kCheckedInt64ToInt32:
1496 : case IrOpcode::kCheckedInt64ToTaggedSigned:
1497 : case IrOpcode::kCheckedUint32Bounds:
1498 : case IrOpcode::kCheckedUint32ToInt32:
1499 : case IrOpcode::kCheckedUint32ToTaggedSigned:
1500 : case IrOpcode::kCheckedUint64Bounds:
1501 : case IrOpcode::kCheckedUint64ToInt32:
1502 : case IrOpcode::kCheckedUint64ToTaggedSigned:
1503 : case IrOpcode::kCheckedFloat64ToInt32:
1504 : case IrOpcode::kCheckedFloat64ToInt64:
1505 : case IrOpcode::kCheckedTaggedSignedToInt32:
1506 : case IrOpcode::kCheckedTaggedToInt32:
1507 : case IrOpcode::kCheckedTaggedToInt64:
1508 : case IrOpcode::kCheckedTaggedToFloat64:
1509 : case IrOpcode::kCheckedTaggedToTaggedSigned:
1510 : case IrOpcode::kCheckedTaggedToTaggedPointer:
1511 : case IrOpcode::kCheckedTruncateTaggedToWord32:
1512 : break;
1513 :
1514 : case IrOpcode::kCheckFloat64Hole:
1515 0 : CheckValueInputIs(node, 0, Type::NumberOrHole());
1516 0 : CheckTypeIs(node, Type::NumberOrUndefined());
1517 0 : break;
1518 : case IrOpcode::kCheckNotTaggedHole:
1519 0 : CheckValueInputIs(node, 0, Type::Any());
1520 0 : CheckTypeIs(node, Type::NonInternal());
1521 0 : break;
1522 : case IrOpcode::kConvertTaggedHoleToUndefined:
1523 0 : CheckValueInputIs(node, 0, Type::Any());
1524 0 : CheckTypeIs(node, Type::NonInternal());
1525 0 : break;
1526 :
1527 : case IrOpcode::kCheckEqualsInternalizedString:
1528 0 : CheckValueInputIs(node, 0, Type::InternalizedString());
1529 0 : CheckValueInputIs(node, 1, Type::Any());
1530 0 : CheckNotTyped(node);
1531 0 : break;
1532 : case IrOpcode::kCheckEqualsSymbol:
1533 0 : CheckValueInputIs(node, 0, Type::Symbol());
1534 0 : CheckValueInputIs(node, 1, Type::Any());
1535 0 : CheckNotTyped(node);
1536 0 : break;
1537 :
1538 : case IrOpcode::kLoadFieldByIndex:
1539 0 : CheckValueInputIs(node, 0, Type::Any());
1540 0 : CheckValueInputIs(node, 1, Type::SignedSmall());
1541 0 : CheckTypeIs(node, Type::NonInternal());
1542 0 : break;
1543 : case IrOpcode::kLoadField:
1544 : case IrOpcode::kLoadMessage:
1545 : // Object -> fieldtype
1546 : // TODO(rossberg): activate once machine ops are typed.
1547 : // CheckValueInputIs(node, 0, Type::Object());
1548 : // CheckTypeIs(node, FieldAccessOf(node->op()).type));
1549 : break;
1550 : case IrOpcode::kLoadElement:
1551 : // Object -> elementtype
1552 : // TODO(rossberg): activate once machine ops are typed.
1553 : // CheckValueInputIs(node, 0, Type::Object());
1554 : // CheckTypeIs(node, ElementAccessOf(node->op()).type));
1555 : break;
1556 : case IrOpcode::kLoadTypedElement:
1557 : break;
1558 : case IrOpcode::kLoadDataViewElement:
1559 : break;
1560 : case IrOpcode::kStoreField:
1561 : case IrOpcode::kStoreMessage:
1562 : // (Object, fieldtype) -> _|_
1563 : // TODO(rossberg): activate once machine ops are typed.
1564 : // CheckValueInputIs(node, 0, Type::Object());
1565 : // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
1566 3862 : CheckNotTyped(node);
1567 3862 : break;
1568 : case IrOpcode::kStoreElement:
1569 : // (Object, elementtype) -> _|_
1570 : // TODO(rossberg): activate once machine ops are typed.
1571 : // CheckValueInputIs(node, 0, Type::Object());
1572 : // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
1573 91 : CheckNotTyped(node);
1574 91 : break;
1575 : case IrOpcode::kTransitionAndStoreElement:
1576 0 : CheckNotTyped(node);
1577 0 : break;
1578 : case IrOpcode::kTransitionAndStoreNumberElement:
1579 0 : CheckNotTyped(node);
1580 0 : break;
1581 : case IrOpcode::kTransitionAndStoreNonNumberElement:
1582 0 : CheckNotTyped(node);
1583 0 : break;
1584 : case IrOpcode::kStoreSignedSmallElement:
1585 0 : CheckNotTyped(node);
1586 0 : break;
1587 : case IrOpcode::kStoreTypedElement:
1588 0 : CheckNotTyped(node);
1589 0 : break;
1590 : case IrOpcode::kStoreDataViewElement:
1591 0 : CheckNotTyped(node);
1592 0 : break;
1593 : case IrOpcode::kNumberSilenceNaN:
1594 21 : CheckValueInputIs(node, 0, Type::Number());
1595 21 : CheckTypeIs(node, Type::Number());
1596 21 : break;
1597 : case IrOpcode::kMapGuard:
1598 0 : CheckNotTyped(node);
1599 0 : break;
1600 : case IrOpcode::kTypeGuard:
1601 140 : CheckTypeIs(node, TypeGuardTypeOf(node->op()));
1602 140 : break;
1603 : case IrOpcode::kDateNow:
1604 0 : CHECK_EQ(0, value_count);
1605 0 : CheckTypeIs(node, Type::Number());
1606 0 : break;
1607 :
1608 : // Machine operators
1609 : // -----------------------
1610 : case IrOpcode::kLoad:
1611 : case IrOpcode::kPoisonedLoad:
1612 : case IrOpcode::kProtectedLoad:
1613 : case IrOpcode::kProtectedStore:
1614 : case IrOpcode::kStore:
1615 : case IrOpcode::kStackSlot:
1616 : case IrOpcode::kWord32And:
1617 : case IrOpcode::kWord32Or:
1618 : case IrOpcode::kWord32Xor:
1619 : case IrOpcode::kWord32Shl:
1620 : case IrOpcode::kWord32Shr:
1621 : case IrOpcode::kWord32Sar:
1622 : case IrOpcode::kWord32Ror:
1623 : case IrOpcode::kWord32Equal:
1624 : case IrOpcode::kWord32Clz:
1625 : case IrOpcode::kWord32Ctz:
1626 : case IrOpcode::kWord32ReverseBits:
1627 : case IrOpcode::kWord32ReverseBytes:
1628 : case IrOpcode::kInt32AbsWithOverflow:
1629 : case IrOpcode::kWord32Popcnt:
1630 : case IrOpcode::kWord64And:
1631 : case IrOpcode::kWord64Or:
1632 : case IrOpcode::kWord64Xor:
1633 : case IrOpcode::kWord64Shl:
1634 : case IrOpcode::kWord64Shr:
1635 : case IrOpcode::kWord64Sar:
1636 : case IrOpcode::kWord64Ror:
1637 : case IrOpcode::kWord64Clz:
1638 : case IrOpcode::kWord64Popcnt:
1639 : case IrOpcode::kWord64Ctz:
1640 : case IrOpcode::kWord64ReverseBits:
1641 : case IrOpcode::kWord64ReverseBytes:
1642 : case IrOpcode::kInt64AbsWithOverflow:
1643 : case IrOpcode::kWord64Equal:
1644 : case IrOpcode::kInt32Add:
1645 : case IrOpcode::kInt32AddWithOverflow:
1646 : case IrOpcode::kInt32Sub:
1647 : case IrOpcode::kInt32SubWithOverflow:
1648 : case IrOpcode::kInt32Mul:
1649 : case IrOpcode::kInt32MulWithOverflow:
1650 : case IrOpcode::kInt32MulHigh:
1651 : case IrOpcode::kInt32Div:
1652 : case IrOpcode::kInt32Mod:
1653 : case IrOpcode::kInt32LessThan:
1654 : case IrOpcode::kInt32LessThanOrEqual:
1655 : case IrOpcode::kUint32Div:
1656 : case IrOpcode::kUint32Mod:
1657 : case IrOpcode::kUint32MulHigh:
1658 : case IrOpcode::kUint32LessThan:
1659 : case IrOpcode::kUint32LessThanOrEqual:
1660 : case IrOpcode::kInt64Add:
1661 : case IrOpcode::kInt64AddWithOverflow:
1662 : case IrOpcode::kInt64Sub:
1663 : case IrOpcode::kInt64SubWithOverflow:
1664 : case IrOpcode::kInt64Mul:
1665 : case IrOpcode::kInt64Div:
1666 : case IrOpcode::kInt64Mod:
1667 : case IrOpcode::kInt64LessThan:
1668 : case IrOpcode::kInt64LessThanOrEqual:
1669 : case IrOpcode::kUint64Div:
1670 : case IrOpcode::kUint64Mod:
1671 : case IrOpcode::kUint64LessThan:
1672 : case IrOpcode::kUint64LessThanOrEqual:
1673 : case IrOpcode::kFloat32Add:
1674 : case IrOpcode::kFloat32Sub:
1675 : case IrOpcode::kFloat32Neg:
1676 : case IrOpcode::kFloat32Mul:
1677 : case IrOpcode::kFloat32Div:
1678 : case IrOpcode::kFloat32Abs:
1679 : case IrOpcode::kFloat32Sqrt:
1680 : case IrOpcode::kFloat32Equal:
1681 : case IrOpcode::kFloat32LessThan:
1682 : case IrOpcode::kFloat32LessThanOrEqual:
1683 : case IrOpcode::kFloat32Max:
1684 : case IrOpcode::kFloat32Min:
1685 : case IrOpcode::kFloat64Add:
1686 : case IrOpcode::kFloat64Sub:
1687 : case IrOpcode::kFloat64Neg:
1688 : case IrOpcode::kFloat64Mul:
1689 : case IrOpcode::kFloat64Div:
1690 : case IrOpcode::kFloat64Mod:
1691 : case IrOpcode::kFloat64Max:
1692 : case IrOpcode::kFloat64Min:
1693 : case IrOpcode::kFloat64Abs:
1694 : case IrOpcode::kFloat64Acos:
1695 : case IrOpcode::kFloat64Acosh:
1696 : case IrOpcode::kFloat64Asin:
1697 : case IrOpcode::kFloat64Asinh:
1698 : case IrOpcode::kFloat64Atan:
1699 : case IrOpcode::kFloat64Atan2:
1700 : case IrOpcode::kFloat64Atanh:
1701 : case IrOpcode::kFloat64Cbrt:
1702 : case IrOpcode::kFloat64Cos:
1703 : case IrOpcode::kFloat64Cosh:
1704 : case IrOpcode::kFloat64Exp:
1705 : case IrOpcode::kFloat64Expm1:
1706 : case IrOpcode::kFloat64Log:
1707 : case IrOpcode::kFloat64Log1p:
1708 : case IrOpcode::kFloat64Log10:
1709 : case IrOpcode::kFloat64Log2:
1710 : case IrOpcode::kFloat64Pow:
1711 : case IrOpcode::kFloat64Sin:
1712 : case IrOpcode::kFloat64Sinh:
1713 : case IrOpcode::kFloat64Sqrt:
1714 : case IrOpcode::kFloat64Tan:
1715 : case IrOpcode::kFloat64Tanh:
1716 : case IrOpcode::kFloat32RoundDown:
1717 : case IrOpcode::kFloat64RoundDown:
1718 : case IrOpcode::kFloat32RoundUp:
1719 : case IrOpcode::kFloat64RoundUp:
1720 : case IrOpcode::kFloat32RoundTruncate:
1721 : case IrOpcode::kFloat64RoundTruncate:
1722 : case IrOpcode::kFloat64RoundTiesAway:
1723 : case IrOpcode::kFloat32RoundTiesEven:
1724 : case IrOpcode::kFloat64RoundTiesEven:
1725 : case IrOpcode::kFloat64Equal:
1726 : case IrOpcode::kFloat64LessThan:
1727 : case IrOpcode::kFloat64LessThanOrEqual:
1728 : case IrOpcode::kTruncateInt64ToInt32:
1729 : case IrOpcode::kRoundFloat64ToInt32:
1730 : case IrOpcode::kRoundInt32ToFloat32:
1731 : case IrOpcode::kRoundInt64ToFloat32:
1732 : case IrOpcode::kRoundInt64ToFloat64:
1733 : case IrOpcode::kRoundUint32ToFloat32:
1734 : case IrOpcode::kRoundUint64ToFloat64:
1735 : case IrOpcode::kRoundUint64ToFloat32:
1736 : case IrOpcode::kTruncateFloat64ToFloat32:
1737 : case IrOpcode::kTruncateFloat64ToWord32:
1738 : case IrOpcode::kBitcastFloat32ToInt32:
1739 : case IrOpcode::kBitcastFloat64ToInt64:
1740 : case IrOpcode::kBitcastInt32ToFloat32:
1741 : case IrOpcode::kBitcastInt64ToFloat64:
1742 : case IrOpcode::kBitcastTaggedToWord:
1743 : case IrOpcode::kBitcastWordToTagged:
1744 : case IrOpcode::kBitcastWordToTaggedSigned:
1745 : case IrOpcode::kChangeInt32ToInt64:
1746 : case IrOpcode::kChangeUint32ToUint64:
1747 : case IrOpcode::kChangeInt32ToFloat64:
1748 : case IrOpcode::kChangeInt64ToFloat64:
1749 : case IrOpcode::kChangeUint32ToFloat64:
1750 : case IrOpcode::kChangeFloat32ToFloat64:
1751 : case IrOpcode::kChangeFloat64ToInt32:
1752 : case IrOpcode::kChangeFloat64ToInt64:
1753 : case IrOpcode::kChangeFloat64ToUint32:
1754 : case IrOpcode::kChangeFloat64ToUint64:
1755 : case IrOpcode::kFloat64SilenceNaN:
1756 : case IrOpcode::kTruncateFloat64ToInt64:
1757 : case IrOpcode::kTruncateFloat64ToUint32:
1758 : case IrOpcode::kTruncateFloat32ToInt32:
1759 : case IrOpcode::kTruncateFloat32ToUint32:
1760 : case IrOpcode::kTryTruncateFloat32ToInt64:
1761 : case IrOpcode::kTryTruncateFloat64ToInt64:
1762 : case IrOpcode::kTryTruncateFloat32ToUint64:
1763 : case IrOpcode::kTryTruncateFloat64ToUint64:
1764 : case IrOpcode::kFloat64ExtractLowWord32:
1765 : case IrOpcode::kFloat64ExtractHighWord32:
1766 : case IrOpcode::kFloat64InsertLowWord32:
1767 : case IrOpcode::kFloat64InsertHighWord32:
1768 : case IrOpcode::kInt32PairAdd:
1769 : case IrOpcode::kInt32PairSub:
1770 : case IrOpcode::kInt32PairMul:
1771 : case IrOpcode::kWord32PairShl:
1772 : case IrOpcode::kWord32PairShr:
1773 : case IrOpcode::kWord32PairSar:
1774 : case IrOpcode::kTaggedPoisonOnSpeculation:
1775 : case IrOpcode::kWord32PoisonOnSpeculation:
1776 : case IrOpcode::kWord64PoisonOnSpeculation:
1777 : case IrOpcode::kLoadStackPointer:
1778 : case IrOpcode::kLoadFramePointer:
1779 : case IrOpcode::kLoadParentFramePointer:
1780 : case IrOpcode::kUnalignedLoad:
1781 : case IrOpcode::kUnalignedStore:
1782 : case IrOpcode::kWord32AtomicLoad:
1783 : case IrOpcode::kWord32AtomicStore:
1784 : case IrOpcode::kWord32AtomicExchange:
1785 : case IrOpcode::kWord32AtomicCompareExchange:
1786 : case IrOpcode::kWord32AtomicAdd:
1787 : case IrOpcode::kWord32AtomicSub:
1788 : case IrOpcode::kWord32AtomicAnd:
1789 : case IrOpcode::kWord32AtomicOr:
1790 : case IrOpcode::kWord32AtomicXor:
1791 : case IrOpcode::kWord64AtomicLoad:
1792 : case IrOpcode::kWord64AtomicStore:
1793 : case IrOpcode::kWord64AtomicAdd:
1794 : case IrOpcode::kWord64AtomicSub:
1795 : case IrOpcode::kWord64AtomicAnd:
1796 : case IrOpcode::kWord64AtomicOr:
1797 : case IrOpcode::kWord64AtomicXor:
1798 : case IrOpcode::kWord64AtomicExchange:
1799 : case IrOpcode::kWord64AtomicCompareExchange:
1800 : case IrOpcode::kWord32AtomicPairLoad:
1801 : case IrOpcode::kWord32AtomicPairStore:
1802 : case IrOpcode::kWord32AtomicPairAdd:
1803 : case IrOpcode::kWord32AtomicPairSub:
1804 : case IrOpcode::kWord32AtomicPairAnd:
1805 : case IrOpcode::kWord32AtomicPairOr:
1806 : case IrOpcode::kWord32AtomicPairXor:
1807 : case IrOpcode::kWord32AtomicPairExchange:
1808 : case IrOpcode::kWord32AtomicPairCompareExchange:
1809 : case IrOpcode::kSpeculationFence:
1810 : case IrOpcode::kSignExtendWord8ToInt32:
1811 : case IrOpcode::kSignExtendWord16ToInt32:
1812 : case IrOpcode::kSignExtendWord8ToInt64:
1813 : case IrOpcode::kSignExtendWord16ToInt64:
1814 : case IrOpcode::kSignExtendWord32ToInt64:
1815 :
1816 : #define SIMD_MACHINE_OP_CASE(Name) case IrOpcode::k##Name:
1817 : MACHINE_SIMD_OP_LIST(SIMD_MACHINE_OP_CASE)
1818 : #undef SIMD_MACHINE_OP_CASE
1819 :
1820 : // TODO(rossberg): Check.
1821 : break;
1822 : }
1823 21929685 : } // NOLINT(readability/fn_size)
1824 :
1825 200244 : void Verifier::Run(Graph* graph, Typing typing, CheckInputs check_inputs,
1826 : CodeType code_type) {
1827 66748 : CHECK_NOT_NULL(graph->start());
1828 66748 : CHECK_NOT_NULL(graph->end());
1829 66748 : Zone zone(graph->zone()->allocator(), ZONE_NAME);
1830 : Visitor visitor(&zone, typing, check_inputs, code_type);
1831 66748 : AllNodes all(&zone, graph);
1832 22063181 : for (Node* node : all.reachable) visitor.Check(node, all);
1833 :
1834 : // Check the uniqueness of projections.
1835 22085037 : for (Node* proj : all.reachable) {
1836 21929685 : if (proj->opcode() != IrOpcode::kProjection) continue;
1837 0 : Node* node = proj->InputAt(0);
1838 131120 : for (Node* other : node->uses()) {
1839 207088 : if (all.IsLive(other) && other != proj &&
1840 21856 : other->opcode() == IrOpcode::kProjection &&
1841 79120 : other->InputAt(0) == node &&
1842 43712 : ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
1843 0 : FATAL("Node #%d:%s has duplicate projections #%d and #%d", node->id(),
1844 0 : node->op()->mnemonic(), proj->id(), other->id());
1845 : }
1846 : }
1847 66748 : }
1848 66748 : }
1849 :
1850 :
1851 : // -----------------------------------------------------------------------------
1852 :
1853 11398 : static bool HasDominatingDef(Schedule* schedule, Node* node,
1854 : BasicBlock* container, BasicBlock* use_block,
1855 : int use_pos) {
1856 33888 : BasicBlock* block = use_block;
1857 : while (true) {
1858 784329 : while (use_pos >= 0) {
1859 1534770 : if (block->NodeAt(use_pos) == node) return true;
1860 755996 : use_pos--;
1861 : }
1862 : block = block->dominator();
1863 16944 : if (block == nullptr) break;
1864 16944 : use_pos = static_cast<int>(block->NodeCount()) - 1;
1865 16944 : if (node == block->control_input()) return true;
1866 : }
1867 : return false;
1868 : }
1869 :
1870 :
1871 2856 : static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
1872 2856 : BasicBlock* dom = schedule->block(dominator);
1873 3348 : BasicBlock* sub = schedule->block(dominatee);
1874 6204 : while (sub != nullptr) {
1875 3348 : if (sub == dom) {
1876 : return true;
1877 : }
1878 : sub = sub->dominator();
1879 : }
1880 : return false;
1881 : }
1882 :
1883 :
1884 7143 : static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
1885 7143 : Node* node, int use_pos) {
1886 25684 : for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
1887 : BasicBlock* use_block = block;
1888 11398 : if (node->opcode() == IrOpcode::kPhi) {
1889 182 : use_block = use_block->PredecessorAt(j);
1890 182 : use_pos = static_cast<int>(use_block->NodeCount()) - 1;
1891 : }
1892 0 : Node* input = node->InputAt(j);
1893 11398 : if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
1894 11398 : use_pos)) {
1895 0 : FATAL("Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
1896 : node->id(), node->op()->mnemonic(), block->rpo_number(), j,
1897 0 : input->id(), input->op()->mnemonic());
1898 : }
1899 : }
1900 : // Ensure that nodes are dominated by their control inputs;
1901 : // kEnd is an exception, as unreachable blocks resulting from kMerge
1902 : // are not in the RPO.
1903 10031 : if (node->op()->ControlInputCount() == 1 &&
1904 : node->opcode() != IrOpcode::kEnd) {
1905 2856 : Node* ctl = NodeProperties::GetControlInput(node);
1906 2856 : if (!Dominates(schedule, ctl, node)) {
1907 0 : FATAL("Node #%d:%s in B%d is not dominated by control input #%d:%s",
1908 : node->id(), node->op()->mnemonic(), block->rpo_number(), ctl->id(),
1909 0 : ctl->op()->mnemonic());
1910 : }
1911 : }
1912 7143 : }
1913 :
1914 :
1915 153 : void ScheduleVerifier::Run(Schedule* schedule) {
1916 : const size_t count = schedule->BasicBlockCount();
1917 51 : Zone tmp_zone(schedule->zone()->allocator(), ZONE_NAME);
1918 : Zone* zone = &tmp_zone;
1919 51 : BasicBlock* start = schedule->start();
1920 : BasicBlockVector* rpo_order = schedule->rpo_order();
1921 :
1922 : // Verify the RPO order contains only blocks from this schedule.
1923 878 : CHECK_GE(count, rpo_order->size());
1924 776 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1925 : ++b) {
1926 725 : CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
1927 : // All predecessors and successors should be in rpo and in this schedule.
1928 2349 : for (BasicBlock const* predecessor : (*b)->predecessors()) {
1929 899 : CHECK_GE(predecessor->rpo_number(), 0);
1930 899 : CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
1931 : }
1932 3074 : for (BasicBlock const* successor : (*b)->successors()) {
1933 899 : CHECK_GE(successor->rpo_number(), 0);
1934 899 : CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
1935 : }
1936 : }
1937 :
1938 : // Verify RPO numbers of blocks.
1939 51 : CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
1940 1501 : for (size_t b = 0; b < rpo_order->size(); b++) {
1941 1450 : BasicBlock* block = rpo_order->at(b);
1942 725 : CHECK_EQ(static_cast<int>(b), block->rpo_number());
1943 674 : BasicBlock* dom = block->dominator();
1944 725 : if (b == 0) {
1945 : // All blocks except start should have a dominator.
1946 51 : CHECK_NULL(dom);
1947 : } else {
1948 : // Check that the immediate dominator appears somewhere before the block.
1949 674 : CHECK_NOT_NULL(dom);
1950 674 : CHECK_LT(dom->rpo_number(), block->rpo_number());
1951 : }
1952 : }
1953 :
1954 : // Verify that all blocks reachable from start are in the RPO.
1955 51 : BoolVector marked(static_cast<int>(count), false, zone);
1956 : {
1957 51 : ZoneQueue<BasicBlock*> queue(zone);
1958 : queue.push(start);
1959 51 : marked[start->id().ToSize()] = true;
1960 827 : while (!queue.empty()) {
1961 725 : BasicBlock* block = queue.front();
1962 : queue.pop();
1963 3248 : for (size_t s = 0; s < block->SuccessorCount(); s++) {
1964 899 : BasicBlock* succ = block->SuccessorAt(s);
1965 1798 : if (!marked[succ->id().ToSize()]) {
1966 : marked[succ->id().ToSize()] = true;
1967 : queue.push(succ);
1968 : }
1969 : }
1970 : }
1971 : }
1972 : // Verify marked blocks are in the RPO.
1973 777 : for (size_t i = 0; i < count; i++) {
1974 1451 : BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
1975 1452 : if (marked[i]) {
1976 725 : CHECK_GE(block->rpo_number(), 0);
1977 1450 : CHECK_EQ(block, rpo_order->at(block->rpo_number()));
1978 : }
1979 : }
1980 : // Verify RPO blocks are marked.
1981 1501 : for (size_t b = 0; b < rpo_order->size(); b++) {
1982 1450 : CHECK(marked[rpo_order->at(b)->id().ToSize()]);
1983 : }
1984 :
1985 : {
1986 : // Verify the dominance relation.
1987 : ZoneVector<BitVector*> dominators(zone);
1988 51 : dominators.resize(count, nullptr);
1989 :
1990 : // Compute a set of all the nodes that dominate a given node by using
1991 : // a forward fixpoint. O(n^2).
1992 51 : ZoneQueue<BasicBlock*> queue(zone);
1993 : queue.push(start);
1994 51 : dominators[start->id().ToSize()] =
1995 102 : new (zone) BitVector(static_cast<int>(count), zone);
1996 1026 : while (!queue.empty()) {
1997 1848 : BasicBlock* block = queue.front();
1998 : queue.pop();
1999 2522 : BitVector* block_doms = dominators[block->id().ToSize()];
2000 0 : BasicBlock* idom = block->dominator();
2001 1797 : if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
2002 : FATAL("Block B%d is not dominated by B%d", block->rpo_number(),
2003 0 : idom->rpo_number());
2004 : }
2005 3274 : for (size_t s = 0; s < block->SuccessorCount(); s++) {
2006 1175 : BasicBlock* succ = block->SuccessorAt(s);
2007 2350 : BitVector* succ_doms = dominators[succ->id().ToSize()];
2008 :
2009 1175 : if (succ_doms == nullptr) {
2010 : // First time visiting the node. S.doms = B U B.doms
2011 674 : succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
2012 : succ_doms->CopyFrom(*block_doms);
2013 : succ_doms->Add(block->id().ToInt());
2014 1348 : dominators[succ->id().ToSize()] = succ_doms;
2015 : queue.push(succ);
2016 : } else {
2017 : // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
2018 : bool had = succ_doms->Contains(block->id().ToInt());
2019 501 : if (had) succ_doms->Remove(block->id().ToInt());
2020 501 : if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
2021 501 : if (had) succ_doms->Add(block->id().ToInt());
2022 : }
2023 : }
2024 : }
2025 :
2026 : // Verify the immediateness of dominators.
2027 827 : for (BasicBlockVector::iterator b = rpo_order->begin();
2028 : b != rpo_order->end(); ++b) {
2029 725 : BasicBlock* block = *b;
2030 0 : BasicBlock* idom = block->dominator();
2031 725 : if (idom == nullptr) continue;
2032 1348 : BitVector* block_doms = dominators[block->id().ToSize()];
2033 :
2034 8592 : for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
2035 : BasicBlock* dom =
2036 7244 : schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
2037 6570 : if (dom != idom &&
2038 5896 : !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
2039 : FATAL("Block B%d is not immediately dominated by B%d",
2040 0 : block->rpo_number(), idom->rpo_number());
2041 : }
2042 : }
2043 : }
2044 : }
2045 :
2046 : // Verify phis are placed in the block of their control input.
2047 827 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2048 : ++b) {
2049 16612 : for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
2050 6856 : Node* phi = *i;
2051 6856 : if (phi->opcode() != IrOpcode::kPhi) continue;
2052 : // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
2053 : // schedules don't have control inputs.
2054 180 : if (phi->InputCount() > phi->op()->ValueInputCount()) {
2055 90 : Node* control = NodeProperties::GetControlInput(phi);
2056 90 : CHECK(control->opcode() == IrOpcode::kMerge ||
2057 : control->opcode() == IrOpcode::kLoop);
2058 90 : CHECK_EQ((*b), schedule->block(control));
2059 : }
2060 : }
2061 : }
2062 :
2063 : // Verify that all uses are dominated by their definitions.
2064 827 : for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
2065 : ++b) {
2066 725 : BasicBlock* block = *b;
2067 :
2068 : // Check inputs to control for this block.
2069 : Node* control = block->control_input();
2070 725 : if (control != nullptr) {
2071 287 : CHECK_EQ(block, schedule->block(control));
2072 : CheckInputsDominate(schedule, block, control,
2073 287 : static_cast<int>(block->NodeCount()) - 1);
2074 : }
2075 : // Check inputs for all nodes in the block.
2076 14437 : for (size_t i = 0; i < block->NodeCount(); i++) {
2077 : Node* node = block->NodeAt(i);
2078 6856 : CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
2079 : }
2080 51 : }
2081 51 : }
2082 :
2083 :
2084 : #ifdef DEBUG
2085 :
2086 : // static
2087 : void Verifier::VerifyNode(Node* node) {
2088 : DCHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
2089 : node->InputCount());
2090 : // If this node has no effect or no control outputs,
2091 : // we check that none of its uses are effect or control inputs.
2092 : bool check_no_control = node->op()->ControlOutputCount() == 0;
2093 : bool check_no_effect = node->op()->EffectOutputCount() == 0;
2094 : bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
2095 : int effect_edges = 0;
2096 : if (check_no_effect || check_no_control) {
2097 : for (Edge edge : node->use_edges()) {
2098 : Node* const user = edge.from();
2099 : DCHECK(!user->IsDead());
2100 : if (NodeProperties::IsControlEdge(edge)) {
2101 : DCHECK(!check_no_control);
2102 : } else if (NodeProperties::IsEffectEdge(edge)) {
2103 : DCHECK(!check_no_effect);
2104 : effect_edges++;
2105 : } else if (NodeProperties::IsFrameStateEdge(edge)) {
2106 : DCHECK(!check_no_frame_state);
2107 : }
2108 : }
2109 : }
2110 :
2111 : // Frame state input should be a frame state (or sentinel).
2112 : if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
2113 : Node* input = NodeProperties::GetFrameStateInput(node);
2114 : DCHECK(input->opcode() == IrOpcode::kFrameState ||
2115 : input->opcode() == IrOpcode::kStart ||
2116 : input->opcode() == IrOpcode::kDead ||
2117 : input->opcode() == IrOpcode::kDeadValue);
2118 : }
2119 : // Effect inputs should be effect-producing nodes (or sentinels).
2120 : for (int i = 0; i < node->op()->EffectInputCount(); i++) {
2121 : Node* input = NodeProperties::GetEffectInput(node, i);
2122 : DCHECK(input->op()->EffectOutputCount() > 0 ||
2123 : input->opcode() == IrOpcode::kDead);
2124 : }
2125 : // Control inputs should be control-producing nodes (or sentinels).
2126 : for (int i = 0; i < node->op()->ControlInputCount(); i++) {
2127 : Node* input = NodeProperties::GetControlInput(node, i);
2128 : DCHECK(input->op()->ControlOutputCount() > 0 ||
2129 : input->opcode() == IrOpcode::kDead);
2130 : }
2131 : }
2132 :
2133 :
2134 : void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
2135 : const Node* replacement) {
2136 : // Check that the user does not misuse the replacement.
2137 : DCHECK(!NodeProperties::IsControlEdge(edge) ||
2138 : replacement->op()->ControlOutputCount() > 0);
2139 : DCHECK(!NodeProperties::IsEffectEdge(edge) ||
2140 : replacement->op()->EffectOutputCount() > 0);
2141 : DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
2142 : replacement->opcode() == IrOpcode::kFrameState ||
2143 : replacement->opcode() == IrOpcode::kDead ||
2144 : replacement->opcode() == IrOpcode::kDeadValue);
2145 : }
2146 :
2147 : #endif // DEBUG
2148 :
2149 : } // namespace compiler
2150 : } // namespace internal
2151 178779 : } // namespace v8
|