| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/verifier.h" | 5 #include "src/compiler/verifier.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <deque> | 8 #include <deque> |
| 8 #include <queue> | 9 #include <queue> |
| 9 #include <sstream> | 10 #include <sstream> |
| 10 #include <string> | 11 #include <string> |
| 11 | 12 |
| 12 #include "src/bit-vector.h" | 13 #include "src/bit-vector.h" |
| 13 #include "src/compiler/generic-algorithm.h" | 14 #include "src/compiler/generic-algorithm.h" |
| 14 #include "src/compiler/graph-inl.h" | 15 #include "src/compiler/graph-inl.h" |
| 15 #include "src/compiler/graph.h" | 16 #include "src/compiler/graph.h" |
| 16 #include "src/compiler/node.h" | 17 #include "src/compiler/node.h" |
| 17 #include "src/compiler/node-properties-inl.h" | 18 #include "src/compiler/node-properties-inl.h" |
| 18 #include "src/compiler/node-properties.h" | 19 #include "src/compiler/node-properties.h" |
| 19 #include "src/compiler/opcodes.h" | 20 #include "src/compiler/opcodes.h" |
| 20 #include "src/compiler/operator.h" | 21 #include "src/compiler/operator.h" |
| 21 #include "src/compiler/schedule.h" | 22 #include "src/compiler/schedule.h" |
| 22 #include "src/compiler/simplified-operator.h" | 23 #include "src/compiler/simplified-operator.h" |
| 23 #include "src/ostreams.h" | 24 #include "src/ostreams.h" |
| 24 | 25 |
| 25 namespace v8 { | 26 namespace v8 { |
| 26 namespace internal { | 27 namespace internal { |
| 27 namespace compiler { | 28 namespace compiler { |
| 28 | 29 |
| 29 | 30 |
| 30 static bool IsDefUseChainLinkPresent(Node* def, Node* use) { | 31 static bool IsDefUseChainLinkPresent(Node* def, Node* use) { |
| 31 Node::Uses uses = def->uses(); | 32 auto const uses = def->uses(); |
| 32 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) { | 33 return std::find(uses.begin(), uses.end(), use) != uses.end(); |
| 33 if (*it == use) return true; | |
| 34 } | |
| 35 return false; | |
| 36 } | 34 } |
| 37 | 35 |
| 38 | 36 |
| 39 static bool IsUseDefChainLinkPresent(Node* def, Node* use) { | 37 static bool IsUseDefChainLinkPresent(Node* def, Node* use) { |
| 40 Node::Inputs inputs = use->inputs(); | 38 auto const inputs = use->inputs(); |
| 41 for (Node::Inputs::iterator it = inputs.begin(); it != inputs.end(); ++it) { | 39 return std::find(inputs.begin(), inputs.end(), def) != inputs.end(); |
| 42 if (*it == def) return true; | |
| 43 } | |
| 44 return false; | |
| 45 } | 40 } |
| 46 | 41 |
| 47 | 42 |
| 48 class Verifier::Visitor : public NullNodeVisitor { | 43 class Verifier::Visitor : public NullNodeVisitor { |
| 49 public: | 44 public: |
| 50 Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {} | 45 Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {} |
| 51 | 46 |
| 52 // Fulfills the PreNodeCallback interface. | 47 // Fulfills the PreNodeCallback interface. |
| 53 void Pre(Node* node); | 48 void Pre(Node* node); |
| 54 | 49 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 CHECK(node->op()->EffectOutputCount() == 0); | 193 CHECK(node->op()->EffectOutputCount() == 0); |
| 199 CHECK(node->op()->ControlOutputCount() == 0); | 194 CHECK(node->op()->ControlOutputCount() == 0); |
| 200 // Type is empty. | 195 // Type is empty. |
| 201 CheckNotTyped(node); | 196 CheckNotTyped(node); |
| 202 break; | 197 break; |
| 203 case IrOpcode::kDead: | 198 case IrOpcode::kDead: |
| 204 // Dead is never connected to the graph. | 199 // Dead is never connected to the graph. |
| 205 UNREACHABLE(); | 200 UNREACHABLE(); |
| 206 case IrOpcode::kBranch: { | 201 case IrOpcode::kBranch: { |
| 207 // Branch uses are IfTrue and IfFalse. | 202 // Branch uses are IfTrue and IfFalse. |
| 208 Node::Uses uses = node->uses(); | |
| 209 int count_true = 0, count_false = 0; | 203 int count_true = 0, count_false = 0; |
| 210 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) { | 204 for (auto use : node->uses()) { |
| 211 CHECK((*it)->opcode() == IrOpcode::kIfTrue || | 205 CHECK(use->opcode() == IrOpcode::kIfTrue || |
| 212 (*it)->opcode() == IrOpcode::kIfFalse); | 206 use->opcode() == IrOpcode::kIfFalse); |
| 213 if ((*it)->opcode() == IrOpcode::kIfTrue) ++count_true; | 207 if (use->opcode() == IrOpcode::kIfTrue) ++count_true; |
| 214 if ((*it)->opcode() == IrOpcode::kIfFalse) ++count_false; | 208 if (use->opcode() == IrOpcode::kIfFalse) ++count_false; |
| 215 } | 209 } |
| 216 CHECK(count_true == 1 && count_false == 1); | 210 CHECK(count_true == 1 && count_false == 1); |
| 217 // Type is empty. | 211 // Type is empty. |
| 218 CheckNotTyped(node); | 212 CheckNotTyped(node); |
| 219 break; | 213 break; |
| 220 } | 214 } |
| 221 case IrOpcode::kIfTrue: | 215 case IrOpcode::kIfTrue: |
| 222 case IrOpcode::kIfFalse: | 216 case IrOpcode::kIfFalse: |
| 223 CHECK_EQ(IrOpcode::kBranch, | 217 CHECK_EQ(IrOpcode::kBranch, |
| 224 NodeProperties::GetControlInput(node, 0)->opcode()); | 218 NodeProperties::GetControlInput(node, 0)->opcode()); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 break; | 301 break; |
| 308 case IrOpcode::kOsrValue: | 302 case IrOpcode::kOsrValue: |
| 309 // OSR values have a value and a control input. | 303 // OSR values have a value and a control input. |
| 310 CHECK_EQ(1, control_count); | 304 CHECK_EQ(1, control_count); |
| 311 CHECK_EQ(1, input_count); | 305 CHECK_EQ(1, input_count); |
| 312 // Type is merged from other values in the graph and could be any. | 306 // Type is merged from other values in the graph and could be any. |
| 313 CheckUpperIs(node, Type::Any()); | 307 CheckUpperIs(node, Type::Any()); |
| 314 break; | 308 break; |
| 315 case IrOpcode::kProjection: { | 309 case IrOpcode::kProjection: { |
| 316 // Projection has an input that produces enough values. | 310 // Projection has an input that produces enough values. |
| 317 int index = static_cast<int>(OpParameter<size_t>(node->op())); | 311 int index = static_cast<int>(ProjectionIndexOf(node->op())); |
| 318 Node* input = NodeProperties::GetValueInput(node, 0); | 312 Node* input = NodeProperties::GetValueInput(node, 0); |
| 319 CHECK_GT(input->op()->ValueOutputCount(), index); | 313 CHECK_GT(input->op()->ValueOutputCount(), index); |
| 320 // Type can be anything. | 314 // Type can be anything. |
| 321 // TODO(rossberg): Introduce tuple types for this. | 315 // TODO(rossberg): Introduce tuple types for this. |
| 322 // TODO(titzer): Convince rossberg not to. | 316 // TODO(titzer): Convince rossberg not to. |
| 323 CheckUpperIs(node, Type::Any()); | 317 CheckUpperIs(node, Type::Any()); |
| 324 break; | 318 break; |
| 325 } | 319 } |
| 326 case IrOpcode::kSelect: { | 320 case IrOpcode::kSelect: { |
| 327 CHECK_EQ(0, effect_count); | 321 CHECK_EQ(0, effect_count); |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 // Check inputs for all nodes in the block. | 993 // Check inputs for all nodes in the block. |
| 1000 for (size_t i = 0; i < block->NodeCount(); i++) { | 994 for (size_t i = 0; i < block->NodeCount(); i++) { |
| 1001 Node* node = block->NodeAt(i); | 995 Node* node = block->NodeAt(i); |
| 1002 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1); | 996 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1); |
| 1003 } | 997 } |
| 1004 } | 998 } |
| 1005 } | 999 } |
| 1006 } | 1000 } |
| 1007 } | 1001 } |
| 1008 } // namespace v8::internal::compiler | 1002 } // namespace v8::internal::compiler |
| OLD | NEW |