blob: a69ace94808d3850444f86eb15be3c9c5c3a8986 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include <algorithm>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include <deque>
9#include <queue>
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include <sstream>
11#include <string>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012
Emily Bernierd0a1eb72015-03-24 16:35:39 -040013#include "src/bit-vector.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000014#include "src/compiler/all-nodes.h"
15#include "src/compiler/common-operator.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/compiler/graph.h"
17#include "src/compiler/node.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018#include "src/compiler/node-properties.h"
19#include "src/compiler/opcodes.h"
20#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000021#include "src/compiler/operator-properties.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022#include "src/compiler/schedule.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023#include "src/compiler/simplified-operator.h"
24#include "src/ostreams.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025
26namespace v8 {
27namespace internal {
28namespace compiler {
29
30
31static bool IsDefUseChainLinkPresent(Node* def, Node* use) {
Ben Murdochda12d292016-06-02 14:46:10 +010032 const Node::Uses uses = def->uses();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000033 return std::find(uses.begin(), uses.end(), use) != uses.end();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034}
35
36
37static bool IsUseDefChainLinkPresent(Node* def, Node* use) {
Ben Murdochda12d292016-06-02 14:46:10 +010038 const Node::Inputs inputs = use->inputs();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 return std::find(inputs.begin(), inputs.end(), def) != inputs.end();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040}
41
42
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043class Verifier::Visitor {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044 public:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040045 Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 void Check(Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048
Emily Bernierd0a1eb72015-03-24 16:35:39 -040049 Zone* zone;
50 Typing typing;
51
52 private:
Emily Bernierd0a1eb72015-03-24 16:35:39 -040053 void CheckNotTyped(Node* node) {
54 if (NodeProperties::IsTyped(node)) {
55 std::ostringstream str;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000056 str << "TypeError: node #" << node->id() << ":" << *node->op()
57 << " should never have a type";
58 FATAL(str.str().c_str());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040059 }
60 }
61 void CheckUpperIs(Node* node, Type* type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 if (typing == TYPED && !NodeProperties::GetType(node)->Is(type)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040063 std::ostringstream str;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 str << "TypeError: node #" << node->id() << ":" << *node->op()
65 << " type ";
66 NodeProperties::GetType(node)->PrintTo(str);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040067 str << " is not ";
68 type->PrintTo(str);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069 FATAL(str.str().c_str());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040070 }
71 }
72 void CheckUpperMaybe(Node* node, Type* type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 if (typing == TYPED && !NodeProperties::GetType(node)->Maybe(type)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040074 std::ostringstream str;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075 str << "TypeError: node #" << node->id() << ":" << *node->op()
76 << " type ";
77 NodeProperties::GetType(node)->PrintTo(str);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040078 str << " must intersect ";
79 type->PrintTo(str);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 FATAL(str.str().c_str());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040081 }
82 }
83 void CheckValueInputIs(Node* node, int i, Type* type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 Node* input = NodeProperties::GetValueInput(node, i);
85 if (typing == TYPED && !NodeProperties::GetType(input)->Is(type)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040086 std::ostringstream str;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 str << "TypeError: node #" << node->id() << ":" << *node->op()
88 << "(input @" << i << " = " << input->opcode() << ":"
89 << input->op()->mnemonic() << ") type ";
90 NodeProperties::GetType(input)->PrintTo(str);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040091 str << " is not ";
92 type->PrintTo(str);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 FATAL(str.str().c_str());
94 }
95 }
96 void CheckOutput(Node* node, Node* use, int count, const char* kind) {
97 if (count <= 0) {
98 std::ostringstream str;
99 str << "GraphError: node #" << node->id() << ":" << *node->op()
100 << " does not produce " << kind << " output used by node #"
101 << use->id() << ":" << *use->op();
102 FATAL(str.str().c_str());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 }
104 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105};
106
107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108void Verifier::Visitor::Check(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109 int value_count = node->op()->ValueInputCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 int context_count = OperatorProperties::GetContextInputCount(node->op());
111 int frame_state_count =
112 OperatorProperties::GetFrameStateInputCount(node->op());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 int effect_count = node->op()->EffectInputCount();
114 int control_count = node->op()->ControlInputCount();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115
116 // Verify number of inputs matches up.
117 int input_count = value_count + context_count + frame_state_count +
118 effect_count + control_count;
119 CHECK_EQ(input_count, node->InputCount());
120
121 // Verify that frame state has been inserted for the nodes that need it.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 for (int i = 0; i < frame_state_count; i++) {
123 Node* frame_state = NodeProperties::GetFrameStateInput(node, i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 // kFrameState uses Start as a sentinel.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126 (node->opcode() == IrOpcode::kFrameState &&
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000127 frame_state->opcode() == IrOpcode::kStart));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128 CHECK(IsDefUseChainLinkPresent(frame_state, node));
129 CHECK(IsUseDefChainLinkPresent(frame_state, node));
130 }
131
132 // Verify all value inputs actually produce a value.
133 for (int i = 0; i < value_count; ++i) {
134 Node* value = NodeProperties::GetValueInput(node, i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 CheckOutput(value, node, value->op()->ValueOutputCount(), "value");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 CHECK(IsDefUseChainLinkPresent(value, node));
137 CHECK(IsUseDefChainLinkPresent(value, node));
Ben Murdochda12d292016-06-02 14:46:10 +0100138 // Verify that only parameters and projections can have input nodes with
139 // multiple outputs.
140 CHECK(node->opcode() == IrOpcode::kParameter ||
141 node->opcode() == IrOpcode::kProjection ||
142 value->op()->ValueOutputCount() <= 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 }
144
145 // Verify all context inputs are value nodes.
146 for (int i = 0; i < context_count; ++i) {
147 Node* context = NodeProperties::GetContextInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148 CheckOutput(context, node, context->op()->ValueOutputCount(), "context");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 CHECK(IsDefUseChainLinkPresent(context, node));
150 CHECK(IsUseDefChainLinkPresent(context, node));
151 }
152
153 // Verify all effect inputs actually have an effect.
154 for (int i = 0; i < effect_count; ++i) {
155 Node* effect = NodeProperties::GetEffectInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 CheckOutput(effect, node, effect->op()->EffectOutputCount(), "effect");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 CHECK(IsDefUseChainLinkPresent(effect, node));
158 CHECK(IsUseDefChainLinkPresent(effect, node));
159 }
160
161 // Verify all control inputs are control nodes.
162 for (int i = 0; i < control_count; ++i) {
163 Node* control = NodeProperties::GetControlInput(node, i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 CheckOutput(control, node, control->op()->ControlOutputCount(), "control");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165 CHECK(IsDefUseChainLinkPresent(control, node));
166 CHECK(IsUseDefChainLinkPresent(control, node));
167 }
168
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 switch (node->opcode()) {
170 case IrOpcode::kStart:
171 // Start has no inputs.
172 CHECK_EQ(0, input_count);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400173 // Type is a tuple.
174 // TODO(rossberg): Multiple outputs are currently typed as Internal.
175 CheckUpperIs(node, Type::Internal());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 break;
177 case IrOpcode::kEnd:
178 // End has no outputs.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179 CHECK(node->op()->ValueOutputCount() == 0);
180 CHECK(node->op()->EffectOutputCount() == 0);
181 CHECK(node->op()->ControlOutputCount() == 0);
182 // Type is empty.
183 CheckNotTyped(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 break;
185 case IrOpcode::kDead:
186 // Dead is never connected to the graph.
187 UNREACHABLE();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 case IrOpcode::kBranch: {
190 // Branch uses are IfTrue and IfFalse.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400191 int count_true = 0, count_false = 0;
Ben Murdochda12d292016-06-02 14:46:10 +0100192 for (const Node* use : node->uses()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000193 CHECK(use->opcode() == IrOpcode::kIfTrue ||
194 use->opcode() == IrOpcode::kIfFalse);
195 if (use->opcode() == IrOpcode::kIfTrue) ++count_true;
196 if (use->opcode() == IrOpcode::kIfFalse) ++count_false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000198 CHECK_EQ(1, count_true);
199 CHECK_EQ(1, count_false);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200 // Type is empty.
201 CheckNotTyped(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202 break;
203 }
204 case IrOpcode::kIfTrue:
205 case IrOpcode::kIfFalse:
206 CHECK_EQ(IrOpcode::kBranch,
207 NodeProperties::GetControlInput(node, 0)->opcode());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400208 // Type is empty.
209 CheckNotTyped(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 case IrOpcode::kIfSuccess: {
212 // IfSuccess and IfException continuation only on throwing nodes.
213 Node* input = NodeProperties::GetControlInput(node, 0);
214 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
215 // Type is empty.
216 CheckNotTyped(node);
217 break;
218 }
219 case IrOpcode::kIfException: {
220 // IfSuccess and IfException continuation only on throwing nodes.
221 Node* input = NodeProperties::GetControlInput(node, 0);
222 CHECK(!input->op()->HasProperty(Operator::kNoThrow));
223 // Type can be anything.
224 CheckUpperIs(node, Type::Any());
225 break;
226 }
227 case IrOpcode::kSwitch: {
228 // Switch uses are Case and Default.
229 int count_case = 0, count_default = 0;
Ben Murdochda12d292016-06-02 14:46:10 +0100230 for (const Node* use : node->uses()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 switch (use->opcode()) {
232 case IrOpcode::kIfValue: {
Ben Murdochda12d292016-06-02 14:46:10 +0100233 for (const Node* user : node->uses()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 if (user != use && user->opcode() == IrOpcode::kIfValue) {
235 CHECK_NE(OpParameter<int32_t>(use->op()),
236 OpParameter<int32_t>(user->op()));
237 }
238 }
239 ++count_case;
240 break;
241 }
242 case IrOpcode::kIfDefault: {
243 ++count_default;
244 break;
245 }
246 default: {
247 V8_Fatal(__FILE__, __LINE__, "Switch #%d illegally used by #%d:%s",
248 node->id(), use->id(), use->op()->mnemonic());
249 break;
250 }
251 }
252 }
253 CHECK_EQ(1, count_default);
254 CHECK_EQ(node->op()->ControlOutputCount(), count_case + count_default);
255 // Type is empty.
256 CheckNotTyped(node);
257 break;
258 }
259 case IrOpcode::kIfValue:
260 case IrOpcode::kIfDefault:
261 CHECK_EQ(IrOpcode::kSwitch,
262 NodeProperties::GetControlInput(node)->opcode());
263 // Type is empty.
264 CheckNotTyped(node);
265 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000266 case IrOpcode::kLoop:
267 case IrOpcode::kMerge:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400268 CHECK_EQ(control_count, input_count);
269 // Type is empty.
270 CheckNotTyped(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100272 case IrOpcode::kDeoptimizeIf:
273 case IrOpcode::kDeoptimizeUnless:
274 // Type is empty.
275 CheckNotTyped(node);
276 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277 case IrOpcode::kDeoptimize:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000278 case IrOpcode::kReturn:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 case IrOpcode::kThrow:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280 // Deoptimize, Return and Throw uses are End.
Ben Murdochda12d292016-06-02 14:46:10 +0100281 for (const Node* use : node->uses()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282 CHECK_EQ(IrOpcode::kEnd, use->opcode());
283 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400284 // Type is empty.
285 CheckNotTyped(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400287 case IrOpcode::kTerminate:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000288 // Terminates take one loop and effect.
289 CHECK_EQ(1, control_count);
290 CHECK_EQ(1, effect_count);
291 CHECK_EQ(2, input_count);
292 CHECK_EQ(IrOpcode::kLoop,
293 NodeProperties::GetControlInput(node)->opcode());
294 // Terminate uses are End.
Ben Murdochda12d292016-06-02 14:46:10 +0100295 for (const Node* use : node->uses()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000296 CHECK_EQ(IrOpcode::kEnd, use->opcode());
297 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400298 // Type is empty.
299 CheckNotTyped(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 break;
301 case IrOpcode::kOsrNormalEntry:
302 case IrOpcode::kOsrLoopEntry:
303 // Osr entries take one control and effect.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400304 CHECK_EQ(1, control_count);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 CHECK_EQ(1, effect_count);
306 CHECK_EQ(2, input_count);
307 // Type is empty.
308 CheckNotTyped(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400309 break;
310
311 // Common operators
312 // ----------------
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000313 case IrOpcode::kParameter: {
314 // Parameters have the start node as inputs.
315 CHECK_EQ(1, input_count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316 // Parameter has an input that produces enough values.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317 int const index = ParameterIndexOf(node->op());
318 Node* const start = NodeProperties::GetValueInput(node, 0);
319 CHECK_EQ(IrOpcode::kStart, start->opcode());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320 // Currently, parameter indices start at -1 instead of 0.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000321 CHECK_LE(-1, index);
322 CHECK_LT(index + 1, start->op()->ValueOutputCount());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400323 // Type can be anything.
324 CheckUpperIs(node, Type::Any());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325 break;
326 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400327 case IrOpcode::kInt32Constant: // TODO(rossberg): rename Word32Constant?
328 // Constants have no inputs.
329 CHECK_EQ(0, input_count);
330 // Type is a 32 bit integer, signed or unsigned.
331 CheckUpperIs(node, Type::Integral32());
332 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333 case IrOpcode::kInt64Constant:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400334 // Constants have no inputs.
335 CHECK_EQ(0, input_count);
336 // Type is internal.
337 // TODO(rossberg): Introduce proper Int64 type.
338 CheckUpperIs(node, Type::Internal());
339 break;
340 case IrOpcode::kFloat32Constant:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 case IrOpcode::kFloat64Constant:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342 case IrOpcode::kNumberConstant:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400343 // Constants have no inputs.
344 CHECK_EQ(0, input_count);
345 // Type is a number.
346 CheckUpperIs(node, Type::Number());
347 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 case IrOpcode::kHeapConstant:
349 // Constants have no inputs.
350 CHECK_EQ(0, input_count);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400351 // Type can be anything represented as a heap pointer.
352 CheckUpperIs(node, Type::TaggedPointer());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400354 case IrOpcode::kExternalConstant:
355 // Constants have no inputs.
356 CHECK_EQ(0, input_count);
357 // Type is considered internal.
358 CheckUpperIs(node, Type::Internal());
359 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 case IrOpcode::kOsrValue:
361 // OSR values have a value and a control input.
362 CHECK_EQ(1, control_count);
363 CHECK_EQ(1, input_count);
364 // Type is merged from other values in the graph and could be any.
365 CheckUpperIs(node, Type::Any());
366 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400367 case IrOpcode::kProjection: {
368 // Projection has an input that produces enough values.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 int index = static_cast<int>(ProjectionIndexOf(node->op()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400370 Node* input = NodeProperties::GetValueInput(node, 0);
371 CHECK_GT(input->op()->ValueOutputCount(), index);
372 // Type can be anything.
373 // TODO(rossberg): Introduce tuple types for this.
374 // TODO(titzer): Convince rossberg not to.
375 CheckUpperIs(node, Type::Any());
376 break;
377 }
378 case IrOpcode::kSelect: {
379 CHECK_EQ(0, effect_count);
380 CHECK_EQ(0, control_count);
381 CHECK_EQ(3, value_count);
382 break;
383 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384 case IrOpcode::kPhi: {
385 // Phi input count matches parent control node.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400386 CHECK_EQ(0, effect_count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 CHECK_EQ(1, control_count);
388 Node* control = NodeProperties::GetControlInput(node, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400389 CHECK_EQ(value_count, control->op()->ControlInputCount());
390 CHECK_EQ(input_count, 1 + value_count);
391 // Type must be subsumed by all input types.
392 // TODO(rossberg): for now at least, narrowing does not really hold.
393 /*
394 for (int i = 0; i < value_count; ++i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395 CHECK(type_of(ValueInput(node, i))->Is(type_of(node)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400396 }
397 */
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398 break;
399 }
400 case IrOpcode::kEffectPhi: {
401 // EffectPhi input count matches parent control node.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400402 CHECK_EQ(0, value_count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000403 CHECK_EQ(1, control_count);
404 Node* control = NodeProperties::GetControlInput(node, 0);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400405 CHECK_EQ(effect_count, control->op()->ControlInputCount());
406 CHECK_EQ(input_count, 1 + effect_count);
407 break;
408 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 case IrOpcode::kEffectSet: {
410 CHECK_EQ(0, value_count);
411 CHECK_EQ(0, control_count);
412 CHECK_LT(1, effect_count);
413 break;
414 }
415 case IrOpcode::kGuard:
416 // TODO(bmeurer): what are the constraints on these?
417 break;
418 case IrOpcode::kBeginRegion:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400419 // TODO(rossberg): what are the constraints on these?
420 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 case IrOpcode::kFinishRegion: {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400422 // TODO(rossberg): what are the constraints on these?
423 // Type must be subsumed by input type.
424 if (typing == TYPED) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425 Node* val = NodeProperties::GetValueInput(node, 0);
426 CHECK(NodeProperties::GetType(val)->Is(NodeProperties::GetType(node)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400427 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428 break;
429 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100430 case IrOpcode::kFrameState: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431 // TODO(jarin): what are the constraints on these?
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000432 CHECK_EQ(5, value_count);
433 CHECK_EQ(0, control_count);
434 CHECK_EQ(0, effect_count);
435 CHECK_EQ(6, input_count);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100436 for (int i = 0; i < 3; ++i) {
437 CHECK(NodeProperties::GetValueInput(node, i)->opcode() ==
438 IrOpcode::kStateValues ||
439 NodeProperties::GetValueInput(node, i)->opcode() ==
440 IrOpcode::kTypedStateValues);
441 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100443 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400444 case IrOpcode::kStateValues:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000445 case IrOpcode::kObjectState:
446 case IrOpcode::kTypedStateValues:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400447 // TODO(jarin): what are the constraints on these?
448 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 case IrOpcode::kCall:
450 // TODO(rossberg): what are the constraints on these?
451 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000452 case IrOpcode::kTailCall:
453 // TODO(bmeurer): what are the constraints on these?
454 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400455
456 // JavaScript operators
457 // --------------------
458 case IrOpcode::kJSEqual:
459 case IrOpcode::kJSNotEqual:
460 case IrOpcode::kJSStrictEqual:
461 case IrOpcode::kJSStrictNotEqual:
462 case IrOpcode::kJSLessThan:
463 case IrOpcode::kJSGreaterThan:
464 case IrOpcode::kJSLessThanOrEqual:
465 case IrOpcode::kJSGreaterThanOrEqual:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400466 // Type is Boolean.
467 CheckUpperIs(node, Type::Boolean());
468 break;
469
470 case IrOpcode::kJSBitwiseOr:
471 case IrOpcode::kJSBitwiseXor:
472 case IrOpcode::kJSBitwiseAnd:
473 case IrOpcode::kJSShiftLeft:
474 case IrOpcode::kJSShiftRight:
475 case IrOpcode::kJSShiftRightLogical:
476 // Type is 32 bit integral.
477 CheckUpperIs(node, Type::Integral32());
478 break;
479 case IrOpcode::kJSAdd:
480 // Type is Number or String.
481 CheckUpperIs(node, Type::NumberOrString());
482 break;
483 case IrOpcode::kJSSubtract:
484 case IrOpcode::kJSMultiply:
485 case IrOpcode::kJSDivide:
486 case IrOpcode::kJSModulus:
487 // Type is Number.
488 CheckUpperIs(node, Type::Number());
489 break;
490
491 case IrOpcode::kJSToBoolean:
492 // Type is Boolean.
493 CheckUpperIs(node, Type::Boolean());
494 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100495 case IrOpcode::kJSToInteger:
496 // Type is OrderedNumber.
497 CheckUpperIs(node, Type::OrderedNumber());
498 break;
499 case IrOpcode::kJSToLength:
500 // Type is OrderedNumber.
501 CheckUpperIs(node, Type::OrderedNumber());
502 break;
503 case IrOpcode::kJSToName:
504 // Type is Name.
505 CheckUpperIs(node, Type::Name());
506 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400507 case IrOpcode::kJSToNumber:
508 // Type is Number.
509 CheckUpperIs(node, Type::Number());
510 break;
511 case IrOpcode::kJSToString:
512 // Type is String.
513 CheckUpperIs(node, Type::String());
514 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400515 case IrOpcode::kJSToObject:
516 // Type is Receiver.
517 CheckUpperIs(node, Type::Receiver());
518 break;
519
520 case IrOpcode::kJSCreate:
521 // Type is Object.
522 CheckUpperIs(node, Type::Object());
523 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000524 case IrOpcode::kJSCreateArguments:
525 // Type is OtherObject.
526 CheckUpperIs(node, Type::OtherObject());
527 break;
528 case IrOpcode::kJSCreateArray:
529 // Type is OtherObject.
530 CheckUpperIs(node, Type::OtherObject());
531 break;
532 case IrOpcode::kJSCreateClosure:
533 // Type is Function.
534 CheckUpperIs(node, Type::Function());
535 break;
536 case IrOpcode::kJSCreateIterResultObject:
537 // Type is OtherObject.
538 CheckUpperIs(node, Type::OtherObject());
539 break;
540 case IrOpcode::kJSCreateLiteralArray:
541 case IrOpcode::kJSCreateLiteralObject:
542 case IrOpcode::kJSCreateLiteralRegExp:
543 // Type is OtherObject.
544 CheckUpperIs(node, Type::OtherObject());
545 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400546 case IrOpcode::kJSLoadProperty:
547 case IrOpcode::kJSLoadNamed:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 case IrOpcode::kJSLoadGlobal:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400549 // Type can be anything.
550 CheckUpperIs(node, Type::Any());
551 break;
552 case IrOpcode::kJSStoreProperty:
553 case IrOpcode::kJSStoreNamed:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000554 case IrOpcode::kJSStoreGlobal:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400555 // Type is empty.
556 CheckNotTyped(node);
557 break;
558 case IrOpcode::kJSDeleteProperty:
559 case IrOpcode::kJSHasProperty:
560 case IrOpcode::kJSInstanceOf:
561 // Type is Boolean.
562 CheckUpperIs(node, Type::Boolean());
563 break;
564 case IrOpcode::kJSTypeOf:
565 // Type is String.
566 CheckUpperIs(node, Type::String());
567 break;
568
569 case IrOpcode::kJSLoadContext:
570 // Type can be anything.
571 CheckUpperIs(node, Type::Any());
572 break;
573 case IrOpcode::kJSStoreContext:
574 // Type is empty.
575 CheckNotTyped(node);
576 break;
577 case IrOpcode::kJSCreateFunctionContext:
578 case IrOpcode::kJSCreateCatchContext:
579 case IrOpcode::kJSCreateWithContext:
580 case IrOpcode::kJSCreateBlockContext:
581 case IrOpcode::kJSCreateModuleContext:
582 case IrOpcode::kJSCreateScriptContext: {
583 // Type is Context, and operand is Internal.
584 Node* context = NodeProperties::GetContextInput(node);
585 // TODO(rossberg): This should really be Is(Internal), but the typer
586 // currently can't do backwards propagation.
587 CheckUpperMaybe(context, Type::Internal());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000588 if (typing == TYPED) CHECK(NodeProperties::GetType(node)->IsContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000589 break;
590 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400591
592 case IrOpcode::kJSCallConstruct:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000593 case IrOpcode::kJSConvertReceiver:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400594 // Type is Receiver.
595 CheckUpperIs(node, Type::Receiver());
596 break;
597 case IrOpcode::kJSCallFunction:
598 case IrOpcode::kJSCallRuntime:
599 case IrOpcode::kJSYield:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400600 // Type can be anything.
601 CheckUpperIs(node, Type::Any());
602 break;
603
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000604 case IrOpcode::kJSForInPrepare: {
605 // TODO(bmeurer): What are the constraints on thse?
606 CheckUpperIs(node, Type::Any());
607 break;
608 }
609 case IrOpcode::kJSForInDone: {
610 // TODO(bmeurer): OSR breaks this invariant, although the node is not user
611 // visible, so we know it is safe (fullcodegen has an unsigned smi there).
612 // CheckValueInputIs(node, 0, Type::UnsignedSmall());
613 break;
614 }
615 case IrOpcode::kJSForInNext: {
616 CheckUpperIs(node, Type::Union(Type::Name(), Type::Undefined(), zone));
617 break;
618 }
619 case IrOpcode::kJSForInStep: {
620 // TODO(bmeurer): OSR breaks this invariant, although the node is not user
621 // visible, so we know it is safe (fullcodegen has an unsigned smi there).
622 // CheckValueInputIs(node, 0, Type::UnsignedSmall());
623 CheckUpperIs(node, Type::UnsignedSmall());
624 break;
625 }
626
627 case IrOpcode::kJSLoadMessage:
628 case IrOpcode::kJSStoreMessage:
629 break;
630
631 case IrOpcode::kJSStackCheck:
632 // Type is empty.
633 CheckNotTyped(node);
634 break;
635
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400636 // Simplified operators
637 // -------------------------------
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400638 case IrOpcode::kBooleanNot:
639 // Boolean -> Boolean
640 CheckValueInputIs(node, 0, Type::Boolean());
641 CheckUpperIs(node, Type::Boolean());
642 break;
643 case IrOpcode::kBooleanToNumber:
644 // Boolean -> Number
645 CheckValueInputIs(node, 0, Type::Boolean());
646 CheckUpperIs(node, Type::Number());
647 break;
648 case IrOpcode::kNumberEqual:
649 case IrOpcode::kNumberLessThan:
650 case IrOpcode::kNumberLessThanOrEqual:
651 // (Number, Number) -> Boolean
652 CheckValueInputIs(node, 0, Type::Number());
653 CheckValueInputIs(node, 1, Type::Number());
654 CheckUpperIs(node, Type::Boolean());
655 break;
656 case IrOpcode::kNumberAdd:
657 case IrOpcode::kNumberSubtract:
658 case IrOpcode::kNumberMultiply:
659 case IrOpcode::kNumberDivide:
660 case IrOpcode::kNumberModulus:
661 // (Number, Number) -> Number
662 CheckValueInputIs(node, 0, Type::Number());
663 CheckValueInputIs(node, 1, Type::Number());
664 // TODO(rossberg): activate once we retype after opcode changes.
665 // CheckUpperIs(node, Type::Number());
666 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 case IrOpcode::kNumberBitwiseOr:
668 case IrOpcode::kNumberBitwiseXor:
669 case IrOpcode::kNumberBitwiseAnd:
670 // (Signed32, Signed32) -> Signed32
671 CheckValueInputIs(node, 0, Type::Signed32());
672 CheckValueInputIs(node, 1, Type::Signed32());
673 CheckUpperIs(node, Type::Signed32());
674 break;
675 case IrOpcode::kNumberShiftLeft:
676 case IrOpcode::kNumberShiftRight:
677 // (Signed32, Unsigned32) -> Signed32
678 CheckValueInputIs(node, 0, Type::Signed32());
679 CheckValueInputIs(node, 1, Type::Unsigned32());
680 CheckUpperIs(node, Type::Signed32());
681 break;
682 case IrOpcode::kNumberShiftRightLogical:
683 // (Unsigned32, Unsigned32) -> Unsigned32
684 CheckValueInputIs(node, 0, Type::Unsigned32());
685 CheckValueInputIs(node, 1, Type::Unsigned32());
686 CheckUpperIs(node, Type::Unsigned32());
687 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100688 case IrOpcode::kNumberImul:
689 // (Unsigned32, Unsigned32) -> Signed32
690 CheckValueInputIs(node, 0, Type::Unsigned32());
691 CheckValueInputIs(node, 1, Type::Unsigned32());
692 CheckUpperIs(node, Type::Signed32());
693 break;
694 case IrOpcode::kNumberClz32:
695 // Unsigned32 -> Unsigned32
696 CheckValueInputIs(node, 0, Type::Unsigned32());
697 CheckUpperIs(node, Type::Unsigned32());
698 break;
699 case IrOpcode::kNumberCeil:
700 case IrOpcode::kNumberFloor:
701 case IrOpcode::kNumberRound:
702 case IrOpcode::kNumberTrunc:
703 // Number -> Number
704 CheckValueInputIs(node, 0, Type::Number());
705 CheckUpperIs(node, Type::Number());
706 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400707 case IrOpcode::kNumberToInt32:
708 // Number -> Signed32
709 CheckValueInputIs(node, 0, Type::Number());
710 CheckUpperIs(node, Type::Signed32());
711 break;
712 case IrOpcode::kNumberToUint32:
713 // Number -> Unsigned32
714 CheckValueInputIs(node, 0, Type::Number());
715 CheckUpperIs(node, Type::Unsigned32());
716 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000717 case IrOpcode::kNumberIsHoleNaN:
718 // Number -> Boolean
719 CheckValueInputIs(node, 0, Type::Number());
720 CheckUpperIs(node, Type::Boolean());
721 break;
722 case IrOpcode::kPlainPrimitiveToNumber:
723 // PlainPrimitive -> Number
724 CheckValueInputIs(node, 0, Type::PlainPrimitive());
725 CheckUpperIs(node, Type::Number());
726 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400727 case IrOpcode::kStringEqual:
728 case IrOpcode::kStringLessThan:
729 case IrOpcode::kStringLessThanOrEqual:
730 // (String, String) -> Boolean
731 CheckValueInputIs(node, 0, Type::String());
732 CheckValueInputIs(node, 1, Type::String());
733 CheckUpperIs(node, Type::Boolean());
734 break;
Ben Murdochda12d292016-06-02 14:46:10 +0100735 case IrOpcode::kStringToNumber:
736 // String -> Number
737 CheckValueInputIs(node, 0, Type::String());
738 CheckUpperIs(node, Type::Number());
739 break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400740 case IrOpcode::kReferenceEqual: {
741 // (Unique, Any) -> Boolean and
742 // (Any, Unique) -> Boolean
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400743 CheckUpperIs(node, Type::Boolean());
744 break;
745 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000746 case IrOpcode::kObjectIsNumber:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100747 case IrOpcode::kObjectIsReceiver:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400748 case IrOpcode::kObjectIsSmi:
Ben Murdochda12d292016-06-02 14:46:10 +0100749 case IrOpcode::kObjectIsUndetectable:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400750 CheckValueInputIs(node, 0, Type::Any());
751 CheckUpperIs(node, Type::Boolean());
752 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000753 case IrOpcode::kAllocate:
754 CheckValueInputIs(node, 0, Type::PlainNumber());
755 CheckUpperIs(node, Type::TaggedPointer());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400756 break;
757
758 case IrOpcode::kChangeTaggedToInt32: {
759 // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
760 // TODO(neis): Activate once ChangeRepresentation works in typer.
761 // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
762 // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
763 // CheckValueInputIs(node, 0, from));
764 // CheckUpperIs(node, to));
765 break;
766 }
767 case IrOpcode::kChangeTaggedToUint32: {
768 // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
769 // TODO(neis): Activate once ChangeRepresentation works in typer.
770 // Type* from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
771 // Type* to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
772 // CheckValueInputIs(node, 0, from));
773 // CheckUpperIs(node, to));
774 break;
775 }
776 case IrOpcode::kChangeTaggedToFloat64: {
777 // Number /\ Tagged -> Number /\ UntaggedFloat64
778 // TODO(neis): Activate once ChangeRepresentation works in typer.
779 // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
780 // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
781 // CheckValueInputIs(node, 0, from));
782 // CheckUpperIs(node, to));
783 break;
784 }
785 case IrOpcode::kChangeInt32ToTagged: {
786 // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
787 // TODO(neis): Activate once ChangeRepresentation works in typer.
788 // Type* from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
789 // Type* to = Type::Intersect(Type::Signed32(), Type::Tagged());
790 // CheckValueInputIs(node, 0, from));
791 // CheckUpperIs(node, to));
792 break;
793 }
794 case IrOpcode::kChangeUint32ToTagged: {
795 // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
796 // TODO(neis): Activate once ChangeRepresentation works in typer.
797 // Type* from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
798 // Type* to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
799 // CheckValueInputIs(node, 0, from));
800 // CheckUpperIs(node, to));
801 break;
802 }
803 case IrOpcode::kChangeFloat64ToTagged: {
804 // Number /\ UntaggedFloat64 -> Number /\ Tagged
805 // TODO(neis): Activate once ChangeRepresentation works in typer.
806 // Type* from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
807 // Type* to = Type::Intersect(Type::Number(), Type::Tagged());
808 // CheckValueInputIs(node, 0, from));
809 // CheckUpperIs(node, to));
810 break;
811 }
812 case IrOpcode::kChangeBoolToBit: {
813 // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
814 // TODO(neis): Activate once ChangeRepresentation works in typer.
815 // Type* from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
816 // Type* to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
817 // CheckValueInputIs(node, 0, from));
818 // CheckUpperIs(node, to));
819 break;
820 }
821 case IrOpcode::kChangeBitToBool: {
822 // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
823 // TODO(neis): Activate once ChangeRepresentation works in typer.
824 // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
825 // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
826 // CheckValueInputIs(node, 0, from));
827 // CheckUpperIs(node, to));
828 break;
829 }
830
831 case IrOpcode::kLoadField:
832 // Object -> fieldtype
833 // TODO(rossberg): activate once machine ops are typed.
834 // CheckValueInputIs(node, 0, Type::Object());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000835 // CheckUpperIs(node, FieldAccessOf(node->op()).type));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400836 break;
837 case IrOpcode::kLoadBuffer:
838 break;
839 case IrOpcode::kLoadElement:
840 // Object -> elementtype
841 // TODO(rossberg): activate once machine ops are typed.
842 // CheckValueInputIs(node, 0, Type::Object());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843 // CheckUpperIs(node, ElementAccessOf(node->op()).type));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400844 break;
845 case IrOpcode::kStoreField:
846 // (Object, fieldtype) -> _|_
847 // TODO(rossberg): activate once machine ops are typed.
848 // CheckValueInputIs(node, 0, Type::Object());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000849 // CheckValueInputIs(node, 1, FieldAccessOf(node->op()).type));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400850 CheckNotTyped(node);
851 break;
852 case IrOpcode::kStoreBuffer:
853 break;
854 case IrOpcode::kStoreElement:
855 // (Object, elementtype) -> _|_
856 // TODO(rossberg): activate once machine ops are typed.
857 // CheckValueInputIs(node, 0, Type::Object());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000858 // CheckValueInputIs(node, 1, ElementAccessOf(node->op()).type));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400859 CheckNotTyped(node);
860 break;
861
862 // Machine operators
863 // -----------------------
864 case IrOpcode::kLoad:
865 case IrOpcode::kStore:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100866 case IrOpcode::kStackSlot:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400867 case IrOpcode::kWord32And:
868 case IrOpcode::kWord32Or:
869 case IrOpcode::kWord32Xor:
870 case IrOpcode::kWord32Shl:
871 case IrOpcode::kWord32Shr:
872 case IrOpcode::kWord32Sar:
873 case IrOpcode::kWord32Ror:
874 case IrOpcode::kWord32Equal:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000875 case IrOpcode::kWord32Clz:
876 case IrOpcode::kWord32Ctz:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100877 case IrOpcode::kWord32ReverseBits:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878 case IrOpcode::kWord32Popcnt:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400879 case IrOpcode::kWord64And:
880 case IrOpcode::kWord64Or:
881 case IrOpcode::kWord64Xor:
882 case IrOpcode::kWord64Shl:
883 case IrOpcode::kWord64Shr:
884 case IrOpcode::kWord64Sar:
885 case IrOpcode::kWord64Ror:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 case IrOpcode::kWord64Clz:
887 case IrOpcode::kWord64Popcnt:
888 case IrOpcode::kWord64Ctz:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100889 case IrOpcode::kWord64ReverseBits:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400890 case IrOpcode::kWord64Equal:
891 case IrOpcode::kInt32Add:
892 case IrOpcode::kInt32AddWithOverflow:
893 case IrOpcode::kInt32Sub:
894 case IrOpcode::kInt32SubWithOverflow:
895 case IrOpcode::kInt32Mul:
896 case IrOpcode::kInt32MulHigh:
897 case IrOpcode::kInt32Div:
898 case IrOpcode::kInt32Mod:
899 case IrOpcode::kInt32LessThan:
900 case IrOpcode::kInt32LessThanOrEqual:
901 case IrOpcode::kUint32Div:
902 case IrOpcode::kUint32Mod:
903 case IrOpcode::kUint32MulHigh:
904 case IrOpcode::kUint32LessThan:
905 case IrOpcode::kUint32LessThanOrEqual:
906 case IrOpcode::kInt64Add:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000907 case IrOpcode::kInt64AddWithOverflow:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400908 case IrOpcode::kInt64Sub:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000909 case IrOpcode::kInt64SubWithOverflow:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400910 case IrOpcode::kInt64Mul:
911 case IrOpcode::kInt64Div:
912 case IrOpcode::kInt64Mod:
913 case IrOpcode::kInt64LessThan:
914 case IrOpcode::kInt64LessThanOrEqual:
915 case IrOpcode::kUint64Div:
916 case IrOpcode::kUint64Mod:
917 case IrOpcode::kUint64LessThan:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000918 case IrOpcode::kUint64LessThanOrEqual:
919 case IrOpcode::kFloat32Add:
920 case IrOpcode::kFloat32Sub:
921 case IrOpcode::kFloat32Mul:
922 case IrOpcode::kFloat32Div:
923 case IrOpcode::kFloat32Max:
924 case IrOpcode::kFloat32Min:
925 case IrOpcode::kFloat32Abs:
926 case IrOpcode::kFloat32Sqrt:
927 case IrOpcode::kFloat32Equal:
928 case IrOpcode::kFloat32LessThan:
929 case IrOpcode::kFloat32LessThanOrEqual:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400930 case IrOpcode::kFloat64Add:
931 case IrOpcode::kFloat64Sub:
932 case IrOpcode::kFloat64Mul:
933 case IrOpcode::kFloat64Div:
934 case IrOpcode::kFloat64Mod:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000935 case IrOpcode::kFloat64Max:
936 case IrOpcode::kFloat64Min:
937 case IrOpcode::kFloat64Abs:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400938 case IrOpcode::kFloat64Sqrt:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000939 case IrOpcode::kFloat32RoundDown:
940 case IrOpcode::kFloat64RoundDown:
941 case IrOpcode::kFloat32RoundUp:
942 case IrOpcode::kFloat64RoundUp:
943 case IrOpcode::kFloat32RoundTruncate:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400944 case IrOpcode::kFloat64RoundTruncate:
945 case IrOpcode::kFloat64RoundTiesAway:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000946 case IrOpcode::kFloat32RoundTiesEven:
947 case IrOpcode::kFloat64RoundTiesEven:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400948 case IrOpcode::kFloat64Equal:
949 case IrOpcode::kFloat64LessThan:
950 case IrOpcode::kFloat64LessThanOrEqual:
951 case IrOpcode::kTruncateInt64ToInt32:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100952 case IrOpcode::kRoundInt32ToFloat32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000953 case IrOpcode::kRoundInt64ToFloat32:
954 case IrOpcode::kRoundInt64ToFloat64:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100955 case IrOpcode::kRoundUint32ToFloat32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000956 case IrOpcode::kRoundUint64ToFloat64:
957 case IrOpcode::kRoundUint64ToFloat32:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400958 case IrOpcode::kTruncateFloat64ToFloat32:
959 case IrOpcode::kTruncateFloat64ToInt32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000960 case IrOpcode::kBitcastFloat32ToInt32:
961 case IrOpcode::kBitcastFloat64ToInt64:
962 case IrOpcode::kBitcastInt32ToFloat32:
963 case IrOpcode::kBitcastInt64ToFloat64:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400964 case IrOpcode::kChangeInt32ToInt64:
965 case IrOpcode::kChangeUint32ToUint64:
966 case IrOpcode::kChangeInt32ToFloat64:
967 case IrOpcode::kChangeUint32ToFloat64:
968 case IrOpcode::kChangeFloat32ToFloat64:
969 case IrOpcode::kChangeFloat64ToInt32:
970 case IrOpcode::kChangeFloat64ToUint32:
Ben Murdochda12d292016-06-02 14:46:10 +0100971 case IrOpcode::kTruncateFloat64ToUint32:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100972 case IrOpcode::kTruncateFloat32ToInt32:
973 case IrOpcode::kTruncateFloat32ToUint32:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000974 case IrOpcode::kTryTruncateFloat32ToInt64:
975 case IrOpcode::kTryTruncateFloat64ToInt64:
976 case IrOpcode::kTryTruncateFloat32ToUint64:
977 case IrOpcode::kTryTruncateFloat64ToUint64:
978 case IrOpcode::kFloat64ExtractLowWord32:
979 case IrOpcode::kFloat64ExtractHighWord32:
980 case IrOpcode::kFloat64InsertLowWord32:
981 case IrOpcode::kFloat64InsertHighWord32:
Ben Murdochda12d292016-06-02 14:46:10 +0100982 case IrOpcode::kInt32PairAdd:
983 case IrOpcode::kInt32PairSub:
984 case IrOpcode::kInt32PairMul:
985 case IrOpcode::kWord32PairShl:
986 case IrOpcode::kWord32PairShr:
987 case IrOpcode::kWord32PairSar:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400988 case IrOpcode::kLoadStackPointer:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000989 case IrOpcode::kLoadFramePointer:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100990 case IrOpcode::kLoadParentFramePointer:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400991 case IrOpcode::kCheckedLoad:
992 case IrOpcode::kCheckedStore:
993 // TODO(rossberg): Check.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000994 break;
995 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000996} // NOLINT(readability/fn_size)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000997
998
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400999void Verifier::Run(Graph* graph, Typing typing) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001000 CHECK_NOT_NULL(graph->start());
1001 CHECK_NOT_NULL(graph->end());
Ben Murdochda12d292016-06-02 14:46:10 +01001002 Zone zone(graph->zone()->allocator());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001003 Visitor visitor(&zone, typing);
1004 AllNodes all(&zone, graph);
1005 for (Node* node : all.live) visitor.Check(node);
1006
1007 // Check the uniqueness of projections.
1008 for (Node* proj : all.live) {
1009 if (proj->opcode() != IrOpcode::kProjection) continue;
1010 Node* node = proj->InputAt(0);
1011 for (Node* other : node->uses()) {
1012 if (all.IsLive(other) && other != proj &&
1013 other->opcode() == IrOpcode::kProjection &&
1014 ProjectionIndexOf(other->op()) == ProjectionIndexOf(proj->op())) {
1015 V8_Fatal(__FILE__, __LINE__,
1016 "Node #%d:%s has duplicate projections #%d and #%d",
1017 node->id(), node->op()->mnemonic(), proj->id(), other->id());
1018 }
1019 }
1020 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001021}
1022
1023
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001024// -----------------------------------------------------------------------------
1025
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001026static bool HasDominatingDef(Schedule* schedule, Node* node,
1027 BasicBlock* container, BasicBlock* use_block,
1028 int use_pos) {
1029 BasicBlock* block = use_block;
1030 while (true) {
1031 while (use_pos >= 0) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001032 if (block->NodeAt(use_pos) == node) return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001033 use_pos--;
1034 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001035 block = block->dominator();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001036 if (block == nullptr) break;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001037 use_pos = static_cast<int>(block->NodeCount()) - 1;
1038 if (node == block->control_input()) return true;
1039 }
1040 return false;
1041}
1042
1043
1044static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
1045 BasicBlock* dom = schedule->block(dominator);
1046 BasicBlock* sub = schedule->block(dominatee);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001047 while (sub != nullptr) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001048 if (sub == dom) {
1049 return true;
1050 }
1051 sub = sub->dominator();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001052 }
1053 return false;
1054}
1055
1056
1057static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
1058 Node* node, int use_pos) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001059 for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001060 BasicBlock* use_block = block;
1061 if (node->opcode() == IrOpcode::kPhi) {
1062 use_block = use_block->PredecessorAt(j);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001063 use_pos = static_cast<int>(use_block->NodeCount()) - 1;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001064 }
1065 Node* input = node->InputAt(j);
1066 if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
1067 use_pos)) {
1068 V8_Fatal(__FILE__, __LINE__,
1069 "Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 node->id(), node->op()->mnemonic(), block->rpo_number(), j,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001071 input->id(), input->op()->mnemonic());
1072 }
1073 }
1074 // Ensure that nodes are dominated by their control inputs;
1075 // kEnd is an exception, as unreachable blocks resulting from kMerge
1076 // are not in the RPO.
1077 if (node->op()->ControlInputCount() == 1 &&
1078 node->opcode() != IrOpcode::kEnd) {
1079 Node* ctl = NodeProperties::GetControlInput(node);
1080 if (!Dominates(schedule, ctl, node)) {
1081 V8_Fatal(__FILE__, __LINE__,
1082 "Node #%d:%s in B%d is not dominated by control input #%d:%s",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001083 node->id(), node->op()->mnemonic(), block->rpo_number(),
1084 ctl->id(), ctl->op()->mnemonic());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001085 }
1086 }
1087}
1088
1089
1090void ScheduleVerifier::Run(Schedule* schedule) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001091 const size_t count = schedule->BasicBlockCount();
Ben Murdochda12d292016-06-02 14:46:10 +01001092 Zone tmp_zone(schedule->zone()->allocator());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001093 Zone* zone = &tmp_zone;
1094 BasicBlock* start = schedule->start();
1095 BasicBlockVector* rpo_order = schedule->rpo_order();
1096
1097 // Verify the RPO order contains only blocks from this schedule.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001098 CHECK_GE(count, rpo_order->size());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001099 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1100 ++b) {
1101 CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001102 // All predecessors and successors should be in rpo and in this schedule.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001103 for (BasicBlock const* predecessor : (*b)->predecessors()) {
1104 CHECK_GE(predecessor->rpo_number(), 0);
1105 CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001106 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001107 for (BasicBlock const* successor : (*b)->successors()) {
1108 CHECK_GE(successor->rpo_number(), 0);
1109 CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001110 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001111 }
1112
1113 // Verify RPO numbers of blocks.
1114 CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
1115 for (size_t b = 0; b < rpo_order->size(); b++) {
1116 BasicBlock* block = rpo_order->at(b);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001117 CHECK_EQ(static_cast<int>(b), block->rpo_number());
1118 BasicBlock* dom = block->dominator();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001119 if (b == 0) {
1120 // All blocks except start should have a dominator.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001121 CHECK_NULL(dom);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001122 } else {
1123 // Check that the immediate dominator appears somewhere before the block.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001124 CHECK_NOT_NULL(dom);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001125 CHECK_LT(dom->rpo_number(), block->rpo_number());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001126 }
1127 }
1128
1129 // Verify that all blocks reachable from start are in the RPO.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001130 BoolVector marked(static_cast<int>(count), false, zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001131 {
1132 ZoneQueue<BasicBlock*> queue(zone);
1133 queue.push(start);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001134 marked[start->id().ToSize()] = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001135 while (!queue.empty()) {
1136 BasicBlock* block = queue.front();
1137 queue.pop();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001138 for (size_t s = 0; s < block->SuccessorCount(); s++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001139 BasicBlock* succ = block->SuccessorAt(s);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001140 if (!marked[succ->id().ToSize()]) {
1141 marked[succ->id().ToSize()] = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001142 queue.push(succ);
1143 }
1144 }
1145 }
1146 }
1147 // Verify marked blocks are in the RPO.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001148 for (size_t i = 0; i < count; i++) {
1149 BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001150 if (marked[i]) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001151 CHECK_GE(block->rpo_number(), 0);
1152 CHECK_EQ(block, rpo_order->at(block->rpo_number()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001153 }
1154 }
1155 // Verify RPO blocks are marked.
1156 for (size_t b = 0; b < rpo_order->size(); b++) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001157 CHECK(marked[rpo_order->at(b)->id().ToSize()]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158 }
1159
1160 {
1161 // Verify the dominance relation.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001162 ZoneVector<BitVector*> dominators(zone);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001163 dominators.resize(count, nullptr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001164
1165 // Compute a set of all the nodes that dominate a given node by using
1166 // a forward fixpoint. O(n^2).
1167 ZoneQueue<BasicBlock*> queue(zone);
1168 queue.push(start);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001169 dominators[start->id().ToSize()] =
1170 new (zone) BitVector(static_cast<int>(count), zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001171 while (!queue.empty()) {
1172 BasicBlock* block = queue.front();
1173 queue.pop();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001174 BitVector* block_doms = dominators[block->id().ToSize()];
1175 BasicBlock* idom = block->dominator();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176 if (idom != nullptr && !block_doms->Contains(idom->id().ToInt())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001177 V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001178 block->rpo_number(), idom->rpo_number());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001179 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001180 for (size_t s = 0; s < block->SuccessorCount(); s++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001181 BasicBlock* succ = block->SuccessorAt(s);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001182 BitVector* succ_doms = dominators[succ->id().ToSize()];
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001184 if (succ_doms == nullptr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001185 // First time visiting the node. S.doms = B U B.doms
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001186 succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001187 succ_doms->CopyFrom(*block_doms);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001188 succ_doms->Add(block->id().ToInt());
1189 dominators[succ->id().ToSize()] = succ_doms;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001190 queue.push(succ);
1191 } else {
1192 // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001193 bool had = succ_doms->Contains(block->id().ToInt());
1194 if (had) succ_doms->Remove(block->id().ToInt());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001195 if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001196 if (had) succ_doms->Add(block->id().ToInt());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001197 }
1198 }
1199 }
1200
1201 // Verify the immediateness of dominators.
1202 for (BasicBlockVector::iterator b = rpo_order->begin();
1203 b != rpo_order->end(); ++b) {
1204 BasicBlock* block = *b;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001205 BasicBlock* idom = block->dominator();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001206 if (idom == nullptr) continue;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001207 BitVector* block_doms = dominators[block->id().ToSize()];
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001208
1209 for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001210 BasicBlock* dom =
1211 schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
1212 if (dom != idom &&
1213 !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001214 V8_Fatal(__FILE__, __LINE__,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001215 "Block B%d is not immediately dominated by B%d",
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216 block->rpo_number(), idom->rpo_number());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001217 }
1218 }
1219 }
1220 }
1221
1222 // Verify phis are placed in the block of their control input.
1223 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1224 ++b) {
1225 for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
1226 Node* phi = *i;
1227 if (phi->opcode() != IrOpcode::kPhi) continue;
1228 // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
1229 // schedules don't have control inputs.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001230 if (phi->InputCount() > phi->op()->ValueInputCount()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001231 Node* control = NodeProperties::GetControlInput(phi);
1232 CHECK(control->opcode() == IrOpcode::kMerge ||
1233 control->opcode() == IrOpcode::kLoop);
1234 CHECK_EQ((*b), schedule->block(control));
1235 }
1236 }
1237 }
1238
1239 // Verify that all uses are dominated by their definitions.
1240 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
1241 ++b) {
1242 BasicBlock* block = *b;
1243
1244 // Check inputs to control for this block.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001245 Node* control = block->control_input();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001246 if (control != nullptr) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001247 CHECK_EQ(block, schedule->block(control));
1248 CheckInputsDominate(schedule, block, control,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001249 static_cast<int>(block->NodeCount()) - 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001250 }
1251 // Check inputs for all nodes in the block.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001252 for (size_t i = 0; i < block->NodeCount(); i++) {
1253 Node* node = block->NodeAt(i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001254 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
1255 }
1256 }
1257}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258
1259
1260#ifdef DEBUG
1261
1262// static
1263void Verifier::VerifyNode(Node* node) {
1264 CHECK_EQ(OperatorProperties::GetTotalInputCount(node->op()),
1265 node->InputCount());
1266 // If this node has no effect or no control outputs,
1267 // we check that no its uses are effect or control inputs.
1268 bool check_no_control = node->op()->ControlOutputCount() == 0;
1269 bool check_no_effect = node->op()->EffectOutputCount() == 0;
1270 bool check_no_frame_state = node->opcode() != IrOpcode::kFrameState;
1271 if (check_no_effect || check_no_control) {
1272 for (Edge edge : node->use_edges()) {
1273 Node* const user = edge.from();
1274 CHECK(!user->IsDead());
1275 if (NodeProperties::IsControlEdge(edge)) {
1276 CHECK(!check_no_control);
1277 } else if (NodeProperties::IsEffectEdge(edge)) {
1278 CHECK(!check_no_effect);
1279 } else if (NodeProperties::IsFrameStateEdge(edge)) {
1280 CHECK(!check_no_frame_state);
1281 }
1282 }
1283 }
1284 // Frame state inputs should be frame states (or sentinels).
1285 for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(node->op());
1286 i++) {
1287 Node* input = NodeProperties::GetFrameStateInput(node, i);
1288 CHECK(input->opcode() == IrOpcode::kFrameState ||
1289 input->opcode() == IrOpcode::kStart ||
1290 input->opcode() == IrOpcode::kDead);
1291 }
1292 // Effect inputs should be effect-producing nodes (or sentinels).
1293 for (int i = 0; i < node->op()->EffectInputCount(); i++) {
1294 Node* input = NodeProperties::GetEffectInput(node, i);
1295 CHECK(input->op()->EffectOutputCount() > 0 ||
1296 input->opcode() == IrOpcode::kDead);
1297 }
1298 // Control inputs should be control-producing nodes (or sentinels).
1299 for (int i = 0; i < node->op()->ControlInputCount(); i++) {
1300 Node* input = NodeProperties::GetControlInput(node, i);
1301 CHECK(input->op()->ControlOutputCount() > 0 ||
1302 input->opcode() == IrOpcode::kDead);
1303 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001304}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001305
1306
1307void Verifier::VerifyEdgeInputReplacement(const Edge& edge,
1308 const Node* replacement) {
1309 // Check that the user does not misuse the replacement.
1310 DCHECK(!NodeProperties::IsControlEdge(edge) ||
1311 replacement->op()->ControlOutputCount() > 0);
1312 DCHECK(!NodeProperties::IsEffectEdge(edge) ||
1313 replacement->op()->EffectOutputCount() > 0);
1314 DCHECK(!NodeProperties::IsFrameStateEdge(edge) ||
1315 replacement->opcode() == IrOpcode::kFrameState);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001316}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001317
1318#endif // DEBUG
1319
1320} // namespace compiler
1321} // namespace internal
1322} // namespace v8