Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Unified Diff: src/compiler/machine-graph-verifier.cc

Issue 2388313003: [turbofan] Introduces a step to verify the machine graph. (Closed)
Patch Set: Fix win build. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/machine-operator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/machine-graph-verifier.cc
diff --git a/src/compiler/machine-graph-verifier.cc b/src/compiler/machine-graph-verifier.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d33ee4ec28d989e96c4195369fcb710b875ff5a9
--- /dev/null
+++ b/src/compiler/machine-graph-verifier.cc
@@ -0,0 +1,667 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/machine-graph-verifier.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node-properties.h"
+#include "src/compiler/node.h"
+#include "src/compiler/schedule.h"
+#include "src/zone/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+class MachineRepresentationInferrer {
+ public:
+ MachineRepresentationInferrer(Schedule const* schedule, Graph const* graph,
+ Linkage* linkage, Zone* zone)
+ : schedule_(schedule),
+ linkage_(linkage),
+ representation_vector_(graph->NodeCount(), zone) {
Jarin 2016/10/05 08:16:17 Explicit initialization with MachineRepresentation
+ Run();
+ }
+
+ MachineRepresentation GetRepresentation(Node const* node) const {
+ return representation_vector_.at(node->id());
+ }
+
+ private:
+ MachineRepresentation GetProjectionType(Node const* projection) {
+ size_t index = ProjectionIndexOf(projection->op());
+ Node* input = projection->InputAt(0);
+ switch (input->opcode()) {
+ case IrOpcode::kInt32AddWithOverflow:
+ case IrOpcode::kInt32SubWithOverflow:
+ case IrOpcode::kInt32MulWithOverflow:
+ CHECK_LE(index, static_cast<size_t>(1));
+ return index == 0 ? MachineRepresentation::kWord32
+ : MachineRepresentation::kBit;
+ case IrOpcode::kInt64AddWithOverflow:
+ case IrOpcode::kInt64SubWithOverflow:
+ CHECK_LE(index, static_cast<size_t>(1));
+ return index == 0 ? MachineRepresentation::kWord64
+ : MachineRepresentation::kBit;
+ case IrOpcode::kTryTruncateFloat32ToInt64:
+ case IrOpcode::kTryTruncateFloat64ToInt64:
+ case IrOpcode::kTryTruncateFloat32ToUint64:
+ case IrOpcode::kTryTruncateFloat64ToUint64:
+ CHECK_LE(index, static_cast<size_t>(1));
+ return index == 0 ? MachineRepresentation::kWord64
+ : MachineRepresentation::kBit;
+ case IrOpcode::kCall: {
+ CallDescriptor const* desc = CallDescriptorOf(input->op());
+ return desc->GetReturnType(index).representation();
+ }
+ default:
+ return MachineRepresentation::kNone;
+ }
+ }
+
+ void Run() {
+ auto blocks = schedule_->all_blocks();
+ for (BasicBlock* block : *blocks) {
+ for (size_t i = 0; i <= block->NodeCount(); ++i) {
+ Node const* node =
+ i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
+ if (node == nullptr) {
+ DCHECK_EQ(block->NodeCount(), i);
+ break;
+ }
+ switch (node->opcode()) {
+ case IrOpcode::kParameter:
+ representation_vector_[node->id()] =
+ linkage_->GetParameterType(ParameterIndexOf(node->op()))
+ .representation();
+ break;
+ case IrOpcode::kProjection: {
+ representation_vector_[node->id()] = GetProjectionType(node);
+ } break;
+ case IrOpcode::kTypedStateValues:
+ representation_vector_[node->id()] = MachineRepresentation::kNone;
+ break;
+ case IrOpcode::kAtomicLoad:
+ case IrOpcode::kLoad:
+ case IrOpcode::kProtectedLoad:
+ representation_vector_[node->id()] =
+ LoadRepresentationOf(node->op()).representation();
+ break;
+ case IrOpcode::kCheckedLoad:
+ representation_vector_[node->id()] =
+ CheckedLoadRepresentationOf(node->op()).representation();
+ break;
+ case IrOpcode::kLoadStackPointer:
+ case IrOpcode::kLoadFramePointer:
+ case IrOpcode::kLoadParentFramePointer:
+ representation_vector_[node->id()] =
+ MachineType::PointerRepresentation();
+ break;
+ case IrOpcode::kPhi:
+ representation_vector_[node->id()] =
+ PhiRepresentationOf(node->op());
+ break;
+ case IrOpcode::kCall: {
+ CallDescriptor const* desc = CallDescriptorOf(node->op());
+ if (desc->ReturnCount() > 0) {
+ representation_vector_[node->id()] =
+ desc->GetReturnType(0).representation();
+ } else {
+ representation_vector_[node->id()] =
+ MachineRepresentation::kTagged;
+ }
+ break;
+ }
+ case IrOpcode::kUnalignedLoad:
+ representation_vector_[node->id()] =
+ UnalignedLoadRepresentationOf(node->op()).representation();
+ break;
+ case IrOpcode::kHeapConstant:
+ case IrOpcode::kNumberConstant:
+ case IrOpcode::kChangeBitToTagged:
+ case IrOpcode::kIfException:
+ case IrOpcode::kOsrValue:
+ case IrOpcode::kChangeInt32ToTagged:
+ case IrOpcode::kChangeUint32ToTagged:
+ case IrOpcode::kBitcastWordToTagged:
+ representation_vector_[node->id()] = MachineRepresentation::kTagged;
+ break;
+ case IrOpcode::kExternalConstant:
+ representation_vector_[node->id()] =
+ MachineType::PointerRepresentation();
+ break;
+ case IrOpcode::kBitcastTaggedToWord:
+ representation_vector_[node->id()] =
+ MachineType::PointerRepresentation();
+ break;
+ case IrOpcode::kBitcastWordToTaggedSigned:
+ representation_vector_[node->id()] =
+ MachineRepresentation::kTaggedSigned;
+ break;
+ case IrOpcode::kWord32Equal:
+ case IrOpcode::kInt32LessThan:
+ case IrOpcode::kInt32LessThanOrEqual:
+ case IrOpcode::kUint32LessThan:
+ case IrOpcode::kUint32LessThanOrEqual:
+ case IrOpcode::kWord64Equal:
+ case IrOpcode::kInt64LessThan:
+ case IrOpcode::kInt64LessThanOrEqual:
+ case IrOpcode::kUint64LessThan:
+ case IrOpcode::kUint64LessThanOrEqual:
+ case IrOpcode::kFloat32Equal:
+ case IrOpcode::kFloat32LessThan:
+ case IrOpcode::kFloat32LessThanOrEqual:
+ case IrOpcode::kFloat64Equal:
+ case IrOpcode::kFloat64LessThan:
+ case IrOpcode::kFloat64LessThanOrEqual:
+ case IrOpcode::kChangeTaggedToBit:
+ representation_vector_[node->id()] = MachineRepresentation::kBit;
+ break;
+#define LABEL(opcode) case IrOpcode::k##opcode:
+ case IrOpcode::kTruncateInt64ToInt32:
+ case IrOpcode::kTruncateFloat32ToInt32:
+ case IrOpcode::kTruncateFloat32ToUint32:
+ case IrOpcode::kBitcastFloat32ToInt32:
+ case IrOpcode::kInt32x4ExtractLane:
+ case IrOpcode::kInt32Constant:
+ case IrOpcode::kRelocatableInt32Constant:
+ case IrOpcode::kTruncateFloat64ToWord32:
+ case IrOpcode::kTruncateFloat64ToUint32:
+ case IrOpcode::kChangeFloat64ToInt32:
+ case IrOpcode::kChangeFloat64ToUint32:
+ case IrOpcode::kRoundFloat64ToInt32:
+ case IrOpcode::kFloat64ExtractLowWord32:
+ case IrOpcode::kFloat64ExtractHighWord32:
+ MACHINE_UNOP_32_LIST(LABEL)
+ MACHINE_BINOP_32_LIST(LABEL) {
+ representation_vector_[node->id()] =
+ MachineRepresentation::kWord32;
+ }
+ break;
+ case IrOpcode::kChangeInt32ToInt64:
+ case IrOpcode::kChangeUint32ToUint64:
+ case IrOpcode::kInt64Constant:
+ case IrOpcode::kRelocatableInt64Constant:
+ case IrOpcode::kBitcastFloat64ToInt64:
+ MACHINE_BINOP_64_LIST(LABEL) {
+ representation_vector_[node->id()] =
+ MachineRepresentation::kWord64;
+ }
+ break;
+ case IrOpcode::kRoundInt32ToFloat32:
+ case IrOpcode::kRoundUint32ToFloat32:
+ case IrOpcode::kRoundInt64ToFloat32:
+ case IrOpcode::kRoundUint64ToFloat32:
+ case IrOpcode::kFloat32Constant:
+ case IrOpcode::kTruncateFloat64ToFloat32:
+ MACHINE_FLOAT32_BINOP_LIST(LABEL)
+ MACHINE_FLOAT32_UNOP_LIST(LABEL) {
+ representation_vector_[node->id()] =
+ MachineRepresentation::kFloat32;
+ }
+ break;
+ case IrOpcode::kRoundInt64ToFloat64:
+ case IrOpcode::kRoundUint64ToFloat64:
+ case IrOpcode::kChangeFloat32ToFloat64:
+ case IrOpcode::kChangeInt32ToFloat64:
+ case IrOpcode::kChangeUint32ToFloat64:
+ case IrOpcode::kFloat64Constant:
+ case IrOpcode::kFloat64SilenceNaN:
+ MACHINE_FLOAT64_BINOP_LIST(LABEL)
+ MACHINE_FLOAT64_UNOP_LIST(LABEL) {
+ representation_vector_[node->id()] =
+ MachineRepresentation::kFloat64;
+ }
+ break;
+#undef LABEL
+ default:
+ break;
Jarin 2016/10/05 08:16:17 As discussed offline, it could be nicer to have a
+ }
+ }
+ }
+ }
+
+ Schedule const* const schedule_;
+ Linkage const* const linkage_;
+ ZoneVector<MachineRepresentation> representation_vector_;
+};
+
+class MachineRepresentationChecker {
+ public:
+ MachineRepresentationChecker(Schedule const* const schedule,
+ MachineRepresentationInferrer const* const typer)
+ : schedule_(schedule), typer_(typer) {}
+
+ void Run() {
+ BasicBlockVector const* blocks = schedule_->all_blocks();
+ for (BasicBlock* block : *blocks) {
+ for (size_t i = 0; i <= block->NodeCount(); ++i) {
+ Node const* node =
+ i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
+ if (node == nullptr) {
+ DCHECK_EQ(block->NodeCount(), i);
+ break;
+ }
+ switch (node->opcode()) {
+ case IrOpcode::kCall:
+ case IrOpcode::kTailCall:
+ CheckCallInputs(node);
+ break;
+ case IrOpcode::kChangeBitToTagged:
+ CHECK_EQ(MachineRepresentation::kBit,
+ typer_->GetRepresentation(node->InputAt(0)));
+ break;
+ case IrOpcode::kChangeTaggedToBit:
+ CHECK_EQ(MachineRepresentation::kTagged,
+ typer_->GetRepresentation(node->InputAt(0)));
+ break;
+ case IrOpcode::kRoundInt64ToFloat64:
+ case IrOpcode::kRoundUint64ToFloat64:
+ case IrOpcode::kRoundInt64ToFloat32:
+ case IrOpcode::kRoundUint64ToFloat32:
+ case IrOpcode::kTruncateInt64ToInt32:
+ CheckValueInputForInt64Op(node, 0);
+ break;
+ case IrOpcode::kBitcastWordToTagged:
+ case IrOpcode::kBitcastWordToTaggedSigned:
+ CheckValueInputRepresentationIs(
+ node, 0, MachineType::PointerRepresentation());
+ break;
+ case IrOpcode::kBitcastTaggedToWord:
+ CheckValueInputIsTagged(node, 0);
+ break;
+ case IrOpcode::kTruncateFloat64ToWord32:
+ case IrOpcode::kTruncateFloat64ToUint32:
+ case IrOpcode::kTruncateFloat64ToFloat32:
+ case IrOpcode::kChangeFloat64ToInt32:
+ case IrOpcode::kChangeFloat64ToUint32:
+ case IrOpcode::kRoundFloat64ToInt32:
+ case IrOpcode::kFloat64ExtractLowWord32:
+ case IrOpcode::kFloat64ExtractHighWord32:
+ case IrOpcode::kBitcastFloat64ToInt64:
+ CheckValueInputForFloat64Op(node, 0);
+ break;
+ case IrOpcode::kWord64Equal:
+ CheckValueInputIsTaggedOrPointer(node, 0);
+ CheckValueInputRepresentationIs(
+ node, 1, typer_->GetRepresentation(node->InputAt(0)));
+ break;
+ case IrOpcode::kInt64LessThan:
+ case IrOpcode::kInt64LessThanOrEqual:
+ case IrOpcode::kUint64LessThan:
+ case IrOpcode::kUint64LessThanOrEqual:
+ CheckValueInputForInt64Op(node, 0);
+ CheckValueInputForInt64Op(node, 1);
+ break;
+ case IrOpcode::kInt32x4ExtractLane:
+ CheckValueInputRepresentationIs(node, 0,
+ MachineRepresentation::kSimd128);
+ break;
+#define LABEL(opcode) case IrOpcode::k##opcode:
+ case IrOpcode::kChangeInt32ToTagged:
+ case IrOpcode::kChangeUint32ToTagged:
+ case IrOpcode::kChangeInt32ToFloat64:
+ case IrOpcode::kChangeUint32ToFloat64:
+ case IrOpcode::kRoundInt32ToFloat32:
+ case IrOpcode::kRoundUint32ToFloat32:
+ case IrOpcode::kChangeInt32ToInt64:
+ case IrOpcode::kChangeUint32ToUint64:
+ MACHINE_UNOP_32_LIST(LABEL) { CheckValueInputForInt32Op(node, 0); }
+ break;
+ case IrOpcode::kWord32Equal:
+ case IrOpcode::kInt32LessThan:
+ case IrOpcode::kInt32LessThanOrEqual:
+ case IrOpcode::kUint32LessThan:
+ case IrOpcode::kUint32LessThanOrEqual:
+ MACHINE_BINOP_32_LIST(LABEL) {
+ CheckValueInputForInt32Op(node, 0);
+ CheckValueInputForInt32Op(node, 1);
+ }
+ break;
+ MACHINE_BINOP_64_LIST(LABEL) {
+ CheckValueInputForInt64Op(node, 0);
+ CheckValueInputForInt64Op(node, 1);
+ }
+ break;
+ case IrOpcode::kFloat32Equal:
+ case IrOpcode::kFloat32LessThan:
+ case IrOpcode::kFloat32LessThanOrEqual:
+ MACHINE_FLOAT32_BINOP_LIST(LABEL) {
+ CheckValueInputForFloat32Op(node, 0);
+ CheckValueInputForFloat32Op(node, 1);
+ }
+ break;
+ case IrOpcode::kChangeFloat32ToFloat64:
+ case IrOpcode::kTruncateFloat32ToInt32:
+ case IrOpcode::kTruncateFloat32ToUint32:
+ case IrOpcode::kBitcastFloat32ToInt32:
+ MACHINE_FLOAT32_UNOP_LIST(LABEL) {
+ CheckValueInputForFloat32Op(node, 0);
+ }
+ break;
+ case IrOpcode::kFloat64Equal:
+ case IrOpcode::kFloat64LessThan:
+ case IrOpcode::kFloat64LessThanOrEqual:
+ MACHINE_FLOAT64_BINOP_LIST(LABEL) {
+ CheckValueInputForFloat64Op(node, 0);
+ CheckValueInputForFloat64Op(node, 1);
+ }
+ break;
+ case IrOpcode::kFloat64SilenceNaN:
+ MACHINE_FLOAT64_UNOP_LIST(LABEL) {
+ CheckValueInputForFloat64Op(node, 0);
+ }
+ break;
+#undef LABEL
+ case IrOpcode::kParameter:
+ case IrOpcode::kProjection:
+ break;
+ case IrOpcode::kLoad:
+ case IrOpcode::kAtomicLoad:
+ CheckValueInputIsTaggedOrPointer(node, 0);
+ CheckValueInputRepresentationIs(
+ node, 1, MachineType::PointerRepresentation());
+ break;
+ case IrOpcode::kStore:
+ CheckValueInputIsTaggedOrPointer(node, 0);
+ CheckValueInputRepresentationIs(
+ node, 1, MachineType::PointerRepresentation());
+ switch (StoreRepresentationOf(node->op()).representation()) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kTaggedSigned:
+ CheckValueInputIsTagged(node, 2);
+ break;
+ default:
+ CheckValueInputRepresentationIs(
+ node, 2,
+ StoreRepresentationOf(node->op()).representation());
+ }
+ break;
+ case IrOpcode::kAtomicStore:
+ CheckValueInputIsTaggedOrPointer(node, 0);
+ CheckValueInputRepresentationIs(
+ node, 1, MachineType::PointerRepresentation());
+ switch (AtomicStoreRepresentationOf(node->op())) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kTaggedSigned:
+ CheckValueInputIsTagged(node, 2);
+ break;
+ default:
+ CheckValueInputRepresentationIs(
+ node, 2, AtomicStoreRepresentationOf(node->op()));
+ }
+ break;
+ case IrOpcode::kPhi:
+ switch (typer_->GetRepresentation(node)) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kTaggedSigned:
+ for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+ CheckValueInputIsTagged(node, i);
+ }
+ break;
+ default:
+ for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+ CheckValueInputRepresentationIs(
+ node, i, typer_->GetRepresentation(node));
+ }
+ break;
+ }
+ break;
+ case IrOpcode::kBranch:
+ case IrOpcode::kSwitch:
+ CheckValueInputForInt32Op(node, 0);
+ break;
+ case IrOpcode::kReturn:
+ // TODO(epertoso): use the linkage to determine which tipe we
+ // should have here.
+ break;
+ case IrOpcode::kTypedStateValues:
+ case IrOpcode::kFrameState:
+ break;
+ default:
+ if (node->op()->ValueInputCount() != 0) {
+ std::stringstream str;
+ str << "Node #" << node->id() << ":" << *node->op()
+ << " in the machine graph is not being checked.";
+ FATAL(str.str().c_str());
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private:
+ void CheckValueInputRepresentationIs(Node const* node, int index,
+ MachineRepresentation representation) {
+ Node const* input = node->InputAt(index);
+ if (typer_->GetRepresentation(input) != representation) {
+ std::stringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a " << MachineReprToString(representation)
+ << " representation.";
+ FATAL(str.str().c_str());
+ }
+ }
+
+ void CheckValueInputIsTagged(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ switch (typer_->GetRepresentation(input)) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kTaggedSigned:
+ return;
+ default:
+ break;
+ }
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a tagged representation.";
+ FATAL(str.str().c_str());
+ }
+
+ void CheckValueInputIsTaggedOrPointer(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ switch (typer_->GetRepresentation(input)) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kTaggedSigned:
+ return;
+ default:
+ break;
+ }
+ if (typer_->GetRepresentation(input) !=
+ MachineType::PointerRepresentation()) {
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a tagged or pointer representation.";
+ FATAL(str.str().c_str());
+ }
+ }
+
+ void CheckValueInputForInt32Op(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ switch (typer_->GetRepresentation(input)) {
+ case MachineRepresentation::kBit:
+ case MachineRepresentation::kWord8:
+ case MachineRepresentation::kWord16:
+ case MachineRepresentation::kWord32:
+ return;
+ case MachineRepresentation::kNone: {
+ std::ostringstream str;
+ str << "TypeError: node #" << input->id() << ":" << *input->op()
+ << " is untyped.";
+ FATAL(str.str().c_str());
+ break;
+ }
+ default:
+ break;
+ }
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have an int32-compatible representation.";
+ FATAL(str.str().c_str());
+ }
+
+ void CheckValueInputForInt64Op(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ switch (typer_->GetRepresentation(input)) {
+ case MachineRepresentation::kWord64:
+ return;
+ case MachineRepresentation::kNone: {
+ std::ostringstream str;
+ str << "TypeError: node #" << input->id() << ":" << *input->op()
+ << " is untyped.";
+ FATAL(str.str().c_str());
+ break;
+ }
+
+ default:
+ break;
+ }
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a kWord64 representation.";
+ FATAL(str.str().c_str());
+ }
+
+ void CheckValueInputForFloat32Op(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ if (MachineRepresentation::kFloat32 == typer_->GetRepresentation(input)) {
+ return;
+ }
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a kFloat32 representation.";
+ FATAL(str.str().c_str());
+ }
+
+ void CheckValueInputForFloat64Op(Node const* node, int index) {
+ Node const* input = node->InputAt(index);
+ if (MachineRepresentation::kFloat64 == typer_->GetRepresentation(input)) {
+ return;
+ }
+ std::ostringstream str;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " uses node #" << input->id() << ":" << *input->op()
+ << " which doesn't have a kFloat64 representation.";
+ FATAL(str.str().c_str());
+ }
+
+ void CheckCallInputs(Node const* node) {
+ CallDescriptor const* desc = CallDescriptorOf(node->op());
+ std::ostringstream str;
+ bool should_log_error = false;
+ for (size_t i = 0; i < desc->InputCount(); ++i) {
+ Node const* input = node->InputAt(static_cast<int>(i));
+ MachineRepresentation const input_type = typer_->GetRepresentation(input);
+ MachineRepresentation const expected_input_type =
+ desc->GetInputType(i).representation();
+ if (!IsCompatible(expected_input_type, input_type)) {
+ if (!should_log_error) {
+ should_log_error = true;
+ str << "TypeError: node #" << node->id() << ":" << *node->op()
+ << " has wrong type for:" << std::endl;
+ } else {
+ str << std::endl;
+ }
+ str << " * input " << i << " (" << input->id() << ":" << *input->op()
+ << ") doesn't have a " << MachineReprToString(expected_input_type)
+ << " representation.";
+ }
+ }
+ if (should_log_error) {
+ FATAL(str.str().c_str());
+ }
+ }
+
+ bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) {
+ return (GetRepresentationProperties(lhs) &
+ GetRepresentationProperties(rhs)) != 0;
+ }
+
+ enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 };
+
+ int GetRepresentationProperties(MachineRepresentation representation) {
+ switch (representation) {
+ case MachineRepresentation::kTagged:
+ case MachineRepresentation::kTaggedPointer:
+ return kIsPointer | kIsTagged;
+ case MachineRepresentation::kTaggedSigned:
+ return kIsTagged;
+ case MachineRepresentation::kWord32:
+ return MachineRepresentation::kWord32 ==
+ MachineType::PointerRepresentation()
+ ? kIsPointer
+ : 0;
+ case MachineRepresentation::kWord64:
+ return MachineRepresentation::kWord64 ==
+ MachineType::PointerRepresentation()
+ ? kIsPointer
+ : 0;
+ default:
+ return 0;
+ }
+ }
+
+ bool IsCompatible(MachineRepresentation expected,
+ MachineRepresentation actual) {
+ switch (expected) {
+ case MachineRepresentation::kTagged:
+ return (actual == MachineRepresentation::kTagged ||
+ actual == MachineRepresentation::kTaggedSigned ||
+ actual == MachineRepresentation::kTaggedPointer);
+ case MachineRepresentation::kTaggedSigned:
+ case MachineRepresentation::kTaggedPointer:
+ case MachineRepresentation::kFloat32:
+ case MachineRepresentation::kFloat64:
+ case MachineRepresentation::kSimd128:
+ case MachineRepresentation::kBit:
+ case MachineRepresentation::kWord8:
+ case MachineRepresentation::kWord16:
+ case MachineRepresentation::kWord64:
+ return expected == actual;
+ break;
+ case MachineRepresentation::kWord32:
+ return (actual == MachineRepresentation::kBit ||
+ actual == MachineRepresentation::kWord8 ||
+ actual == MachineRepresentation::kWord16 ||
+ actual == MachineRepresentation::kWord32);
+ case MachineRepresentation::kNone:
+ UNREACHABLE();
+ }
+ return false;
+ }
+
+ Schedule const* const schedule_;
+ MachineRepresentationInferrer const* const typer_;
+};
+
+} // namespace
+
+void MachineGraphVerifier::Run(Graph* graph, Schedule const* const schedule,
+ Linkage* linkage, Zone* temp_zone) {
+ MachineRepresentationInferrer representation_inferrer(schedule, graph,
+ linkage, temp_zone);
+ MachineRepresentationChecker checker(schedule, &representation_inferrer);
+ checker.Run();
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/machine-operator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698