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