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