LCOV - code coverage report
Current view: top level - src/compiler - machine-graph-verifier.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 0 301 0.0 %
Date: 2017-10-20 Functions: 0 15 0.0 %

          Line data    Source code
       1             : // Copyright 2016 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/machine-graph-verifier.h"
       6             : 
       7             : #include "src/compiler/common-operator.h"
       8             : #include "src/compiler/graph.h"
       9             : #include "src/compiler/linkage.h"
      10             : #include "src/compiler/machine-operator.h"
      11             : #include "src/compiler/node-properties.h"
      12             : #include "src/compiler/node.h"
      13             : #include "src/compiler/schedule.h"
      14             : #include "src/zone/zone.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : namespace compiler {
      19             : 
      20             : namespace {
      21             : 
      22             : class MachineRepresentationInferrer {
      23             :  public:
      24           0 :   MachineRepresentationInferrer(Schedule const* schedule, Graph const* graph,
      25             :                                 Linkage* linkage, Zone* zone)
      26             :       : schedule_(schedule),
      27             :         linkage_(linkage),
      28             :         representation_vector_(graph->NodeCount(), MachineRepresentation::kNone,
      29           0 :                                zone) {
      30           0 :     Run();
      31           0 :   }
      32             : 
      33             :   CallDescriptor* call_descriptor() const {
      34             :     return linkage_->GetIncomingDescriptor();
      35             :   }
      36             : 
      37           0 :   MachineRepresentation GetRepresentation(Node const* node) const {
      38           0 :     return representation_vector_.at(node->id());
      39             :   }
      40             : 
      41             :  private:
      42           0 :   MachineRepresentation GetProjectionType(Node const* projection) {
      43           0 :     size_t index = ProjectionIndexOf(projection->op());
      44           0 :     Node* input = projection->InputAt(0);
      45           0 :     switch (input->opcode()) {
      46             :       case IrOpcode::kInt32AddWithOverflow:
      47             :       case IrOpcode::kInt32SubWithOverflow:
      48             :       case IrOpcode::kInt32MulWithOverflow:
      49           0 :         CHECK_LE(index, static_cast<size_t>(1));
      50             :         return index == 0 ? MachineRepresentation::kWord32
      51           0 :                           : MachineRepresentation::kBit;
      52             :       case IrOpcode::kInt64AddWithOverflow:
      53             :       case IrOpcode::kInt64SubWithOverflow:
      54           0 :         CHECK_LE(index, static_cast<size_t>(1));
      55             :         return index == 0 ? MachineRepresentation::kWord64
      56           0 :                           : MachineRepresentation::kBit;
      57             :       case IrOpcode::kTryTruncateFloat32ToInt64:
      58             :       case IrOpcode::kTryTruncateFloat64ToInt64:
      59             :       case IrOpcode::kTryTruncateFloat32ToUint64:
      60           0 :         CHECK_LE(index, static_cast<size_t>(1));
      61             :         return index == 0 ? MachineRepresentation::kWord64
      62           0 :                           : MachineRepresentation::kBit;
      63             :       case IrOpcode::kCall:
      64             :       case IrOpcode::kCallWithCallerSavedRegisters: {
      65           0 :         CallDescriptor const* desc = CallDescriptorOf(input->op());
      66             :         return desc->GetReturnType(index).representation();
      67             :       }
      68             :       default:
      69             :         return MachineRepresentation::kNone;
      70             :     }
      71             :   }
      72             : 
      73             :   MachineRepresentation PromoteRepresentation(MachineRepresentation rep) {
      74           0 :     switch (rep) {
      75             :       case MachineRepresentation::kWord8:
      76             :       case MachineRepresentation::kWord16:
      77             :       case MachineRepresentation::kWord32:
      78             :         return MachineRepresentation::kWord32;
      79             :       default:
      80             :         break;
      81             :     }
      82             :     return rep;
      83             :   }
      84             : 
      85           0 :   void Run() {
      86           0 :     auto blocks = schedule_->all_blocks();
      87           0 :     for (BasicBlock* block : *blocks) {
      88           0 :       current_block_ = block;
      89           0 :       for (size_t i = 0; i <= block->NodeCount(); ++i) {
      90           0 :         Node const* node =
      91           0 :             i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
      92           0 :         if (node == nullptr) {
      93             :           DCHECK_EQ(block->NodeCount(), i);
      94             :           break;
      95             :         }
      96           0 :         switch (node->opcode()) {
      97             :           case IrOpcode::kParameter:
      98           0 :             representation_vector_[node->id()] =
      99           0 :                 linkage_->GetParameterType(ParameterIndexOf(node->op()))
     100           0 :                     .representation();
     101           0 :             break;
     102             :           case IrOpcode::kReturn: {
     103           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     104           0 :                 linkage_->GetReturnType().representation());
     105           0 :             break;
     106             :           }
     107             :           case IrOpcode::kProjection: {
     108           0 :             representation_vector_[node->id()] = GetProjectionType(node);
     109           0 :           } break;
     110             :           case IrOpcode::kTypedStateValues:
     111           0 :             representation_vector_[node->id()] = MachineRepresentation::kNone;
     112           0 :             break;
     113             :           case IrOpcode::kAtomicLoad:
     114             :           case IrOpcode::kLoad:
     115             :           case IrOpcode::kProtectedLoad:
     116           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     117           0 :                 LoadRepresentationOf(node->op()).representation());
     118           0 :             break;
     119             :           case IrOpcode::kCheckedLoad:
     120           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     121           0 :                 CheckedLoadRepresentationOf(node->op()).representation());
     122           0 :             break;
     123             :           case IrOpcode::kLoadStackPointer:
     124             :           case IrOpcode::kLoadFramePointer:
     125             :           case IrOpcode::kLoadParentFramePointer:
     126           0 :             representation_vector_[node->id()] =
     127           0 :                 MachineType::PointerRepresentation();
     128           0 :             break;
     129             :           case IrOpcode::kUnalignedLoad:
     130           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     131           0 :                 UnalignedLoadRepresentationOf(node->op()).representation());
     132           0 :             break;
     133             :           case IrOpcode::kPhi:
     134           0 :             representation_vector_[node->id()] =
     135           0 :                 PhiRepresentationOf(node->op());
     136           0 :             break;
     137             :           case IrOpcode::kCall:
     138             :           case IrOpcode::kCallWithCallerSavedRegisters: {
     139           0 :             CallDescriptor const* desc = CallDescriptorOf(node->op());
     140           0 :             if (desc->ReturnCount() > 0) {
     141           0 :               representation_vector_[node->id()] =
     142           0 :                   desc->GetReturnType(0).representation();
     143             :             } else {
     144           0 :               representation_vector_[node->id()] =
     145           0 :                   MachineRepresentation::kTagged;
     146             :             }
     147             :             break;
     148             :           }
     149             :           case IrOpcode::kAtomicStore:
     150           0 :             representation_vector_[node->id()] =
     151           0 :                 PromoteRepresentation(AtomicStoreRepresentationOf(node->op()));
     152           0 :             break;
     153             :           case IrOpcode::kAtomicExchange:
     154             :           case IrOpcode::kAtomicCompareExchange:
     155             :           case IrOpcode::kAtomicAdd:
     156             :           case IrOpcode::kAtomicSub:
     157             :           case IrOpcode::kAtomicAnd:
     158             :           case IrOpcode::kAtomicOr:
     159             :           case IrOpcode::kAtomicXor:
     160           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     161           0 :                 AtomicOpRepresentationOf(node->op()).representation());
     162           0 :             break;
     163             :           case IrOpcode::kStore:
     164             :           case IrOpcode::kProtectedStore:
     165           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     166           0 :                 StoreRepresentationOf(node->op()).representation());
     167           0 :             break;
     168             :           case IrOpcode::kCheckedStore:
     169           0 :             representation_vector_[node->id()] =
     170           0 :                 PromoteRepresentation(CheckedStoreRepresentationOf(node->op()));
     171           0 :             break;
     172             :           case IrOpcode::kUnalignedStore:
     173           0 :             representation_vector_[node->id()] = PromoteRepresentation(
     174           0 :                 UnalignedStoreRepresentationOf(node->op()));
     175           0 :             break;
     176             :           case IrOpcode::kHeapConstant:
     177             :           case IrOpcode::kNumberConstant:
     178             :           case IrOpcode::kChangeBitToTagged:
     179             :           case IrOpcode::kIfException:
     180             :           case IrOpcode::kOsrValue:
     181             :           case IrOpcode::kChangeInt32ToTagged:
     182             :           case IrOpcode::kChangeUint32ToTagged:
     183             :           case IrOpcode::kBitcastWordToTagged:
     184           0 :             representation_vector_[node->id()] = MachineRepresentation::kTagged;
     185           0 :             break;
     186             :           case IrOpcode::kExternalConstant:
     187           0 :             representation_vector_[node->id()] =
     188           0 :                 MachineType::PointerRepresentation();
     189           0 :             break;
     190             :           case IrOpcode::kBitcastTaggedToWord:
     191           0 :             representation_vector_[node->id()] =
     192           0 :                 MachineType::PointerRepresentation();
     193           0 :             break;
     194             :           case IrOpcode::kBitcastWordToTaggedSigned:
     195           0 :             representation_vector_[node->id()] =
     196           0 :                 MachineRepresentation::kTaggedSigned;
     197           0 :             break;
     198             :           case IrOpcode::kWord32Equal:
     199             :           case IrOpcode::kInt32LessThan:
     200             :           case IrOpcode::kInt32LessThanOrEqual:
     201             :           case IrOpcode::kUint32LessThan:
     202             :           case IrOpcode::kUint32LessThanOrEqual:
     203             :           case IrOpcode::kWord64Equal:
     204             :           case IrOpcode::kInt64LessThan:
     205             :           case IrOpcode::kInt64LessThanOrEqual:
     206             :           case IrOpcode::kUint64LessThan:
     207             :           case IrOpcode::kUint64LessThanOrEqual:
     208             :           case IrOpcode::kFloat32Equal:
     209             :           case IrOpcode::kFloat32LessThan:
     210             :           case IrOpcode::kFloat32LessThanOrEqual:
     211             :           case IrOpcode::kFloat64Equal:
     212             :           case IrOpcode::kFloat64LessThan:
     213             :           case IrOpcode::kFloat64LessThanOrEqual:
     214             :           case IrOpcode::kChangeTaggedToBit:
     215           0 :             representation_vector_[node->id()] = MachineRepresentation::kBit;
     216           0 :             break;
     217             : #define LABEL(opcode) case IrOpcode::k##opcode:
     218             :           case IrOpcode::kTruncateInt64ToInt32:
     219             :           case IrOpcode::kTruncateFloat32ToInt32:
     220             :           case IrOpcode::kTruncateFloat32ToUint32:
     221             :           case IrOpcode::kBitcastFloat32ToInt32:
     222             :           case IrOpcode::kI32x4ExtractLane:
     223             :           case IrOpcode::kI16x8ExtractLane:
     224             :           case IrOpcode::kI8x16ExtractLane:
     225             :           case IrOpcode::kInt32Constant:
     226             :           case IrOpcode::kRelocatableInt32Constant:
     227             :           case IrOpcode::kTruncateFloat64ToWord32:
     228             :           case IrOpcode::kTruncateFloat64ToUint32:
     229             :           case IrOpcode::kChangeFloat64ToInt32:
     230             :           case IrOpcode::kChangeFloat64ToUint32:
     231             :           case IrOpcode::kRoundFloat64ToInt32:
     232             :           case IrOpcode::kFloat64ExtractLowWord32:
     233             :           case IrOpcode::kFloat64ExtractHighWord32:
     234             :             MACHINE_UNOP_32_LIST(LABEL)
     235             :             MACHINE_BINOP_32_LIST(LABEL) {
     236           0 :               representation_vector_[node->id()] =
     237           0 :                   MachineRepresentation::kWord32;
     238             :             }
     239           0 :             break;
     240             :           case IrOpcode::kChangeInt32ToInt64:
     241             :           case IrOpcode::kChangeUint32ToUint64:
     242             :           case IrOpcode::kInt64Constant:
     243             :           case IrOpcode::kRelocatableInt64Constant:
     244             :           case IrOpcode::kBitcastFloat64ToInt64:
     245             :           case IrOpcode::kChangeFloat64ToUint64:
     246             :             MACHINE_BINOP_64_LIST(LABEL) {
     247           0 :               representation_vector_[node->id()] =
     248           0 :                   MachineRepresentation::kWord64;
     249             :             }
     250           0 :             break;
     251             :           case IrOpcode::kRoundInt32ToFloat32:
     252             :           case IrOpcode::kRoundUint32ToFloat32:
     253             :           case IrOpcode::kRoundInt64ToFloat32:
     254             :           case IrOpcode::kRoundUint64ToFloat32:
     255             :           case IrOpcode::kFloat32Constant:
     256             :           case IrOpcode::kTruncateFloat64ToFloat32:
     257             :             MACHINE_FLOAT32_BINOP_LIST(LABEL)
     258             :             MACHINE_FLOAT32_UNOP_LIST(LABEL) {
     259           0 :               representation_vector_[node->id()] =
     260           0 :                   MachineRepresentation::kFloat32;
     261             :             }
     262           0 :             break;
     263             :           case IrOpcode::kRoundInt64ToFloat64:
     264             :           case IrOpcode::kRoundUint64ToFloat64:
     265             :           case IrOpcode::kChangeFloat32ToFloat64:
     266             :           case IrOpcode::kChangeInt32ToFloat64:
     267             :           case IrOpcode::kChangeUint32ToFloat64:
     268             :           case IrOpcode::kFloat64Constant:
     269             :           case IrOpcode::kFloat64SilenceNaN:
     270             :             MACHINE_FLOAT64_BINOP_LIST(LABEL)
     271             :             MACHINE_FLOAT64_UNOP_LIST(LABEL) {
     272           0 :               representation_vector_[node->id()] =
     273           0 :                   MachineRepresentation::kFloat64;
     274             :             }
     275           0 :             break;
     276             : #undef LABEL
     277             :           default:
     278             :             break;
     279             :         }
     280             :       }
     281             :     }
     282           0 :   }
     283             : 
     284             :   Schedule const* const schedule_;
     285             :   Linkage const* const linkage_;
     286             :   ZoneVector<MachineRepresentation> representation_vector_;
     287             :   BasicBlock* current_block_;
     288             : };
     289             : 
     290             : class MachineRepresentationChecker {
     291             :  public:
     292             :   MachineRepresentationChecker(
     293             :       Schedule const* const schedule,
     294             :       MachineRepresentationInferrer const* const inferrer, bool is_stub,
     295             :       const char* name)
     296             :       : schedule_(schedule),
     297             :         inferrer_(inferrer),
     298             :         is_stub_(is_stub),
     299             :         name_(name),
     300           0 :         current_block_(nullptr) {}
     301             : 
     302           0 :   void Run() {
     303           0 :     BasicBlockVector const* blocks = schedule_->all_blocks();
     304           0 :     for (BasicBlock* block : *blocks) {
     305           0 :       current_block_ = block;
     306           0 :       for (size_t i = 0; i <= block->NodeCount(); ++i) {
     307           0 :         Node const* node =
     308           0 :             i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
     309           0 :         if (node == nullptr) {
     310             :           DCHECK_EQ(block->NodeCount(), i);
     311             :           break;
     312             :         }
     313           0 :         switch (node->opcode()) {
     314             :           case IrOpcode::kCall:
     315             :           case IrOpcode::kCallWithCallerSavedRegisters:
     316             :           case IrOpcode::kTailCall:
     317           0 :             CheckCallInputs(node);
     318           0 :             break;
     319             :           case IrOpcode::kChangeBitToTagged:
     320           0 :             CHECK_EQ(MachineRepresentation::kBit,
     321             :                      inferrer_->GetRepresentation(node->InputAt(0)));
     322             :             break;
     323             :           case IrOpcode::kChangeTaggedToBit:
     324           0 :             CHECK_EQ(MachineRepresentation::kTagged,
     325             :                      inferrer_->GetRepresentation(node->InputAt(0)));
     326             :             break;
     327             :           case IrOpcode::kRoundInt64ToFloat64:
     328             :           case IrOpcode::kRoundUint64ToFloat64:
     329             :           case IrOpcode::kRoundInt64ToFloat32:
     330             :           case IrOpcode::kRoundUint64ToFloat32:
     331             :           case IrOpcode::kTruncateInt64ToInt32:
     332           0 :             CheckValueInputForInt64Op(node, 0);
     333           0 :             break;
     334             :           case IrOpcode::kBitcastWordToTagged:
     335             :           case IrOpcode::kBitcastWordToTaggedSigned:
     336             :             CheckValueInputRepresentationIs(
     337           0 :                 node, 0, MachineType::PointerRepresentation());
     338           0 :             break;
     339             :           case IrOpcode::kBitcastTaggedToWord:
     340           0 :             CheckValueInputIsTagged(node, 0);
     341           0 :             break;
     342             :           case IrOpcode::kTruncateFloat64ToWord32:
     343             :           case IrOpcode::kTruncateFloat64ToUint32:
     344             :           case IrOpcode::kTruncateFloat64ToFloat32:
     345             :           case IrOpcode::kChangeFloat64ToInt32:
     346             :           case IrOpcode::kChangeFloat64ToUint32:
     347             :           case IrOpcode::kRoundFloat64ToInt32:
     348             :           case IrOpcode::kFloat64ExtractLowWord32:
     349             :           case IrOpcode::kFloat64ExtractHighWord32:
     350             :           case IrOpcode::kBitcastFloat64ToInt64:
     351             :           case IrOpcode::kTryTruncateFloat64ToInt64:
     352           0 :             CheckValueInputForFloat64Op(node, 0);
     353           0 :             break;
     354             :           case IrOpcode::kWord64Equal:
     355             :             if (Is64()) {
     356           0 :               CheckValueInputIsTaggedOrPointer(node, 0);
     357           0 :               CheckValueInputIsTaggedOrPointer(node, 1);
     358           0 :               if (!is_stub_) {
     359             :                 CheckValueInputRepresentationIs(
     360           0 :                     node, 1, inferrer_->GetRepresentation(node->InputAt(0)));
     361             :               }
     362             :             } else {
     363             :               CheckValueInputForInt64Op(node, 0);
     364             :               CheckValueInputForInt64Op(node, 1);
     365             :             }
     366             :             break;
     367             :           case IrOpcode::kInt64LessThan:
     368             :           case IrOpcode::kInt64LessThanOrEqual:
     369             :           case IrOpcode::kUint64LessThan:
     370             :           case IrOpcode::kUint64LessThanOrEqual:
     371           0 :             CheckValueInputForInt64Op(node, 0);
     372           0 :             CheckValueInputForInt64Op(node, 1);
     373           0 :             break;
     374             :           case IrOpcode::kI32x4ExtractLane:
     375             :           case IrOpcode::kI16x8ExtractLane:
     376             :           case IrOpcode::kI8x16ExtractLane:
     377             :             CheckValueInputRepresentationIs(node, 0,
     378           0 :                                             MachineRepresentation::kSimd128);
     379           0 :             break;
     380             : #define LABEL(opcode) case IrOpcode::k##opcode:
     381             :           case IrOpcode::kChangeInt32ToTagged:
     382             :           case IrOpcode::kChangeUint32ToTagged:
     383             :           case IrOpcode::kChangeInt32ToFloat64:
     384             :           case IrOpcode::kChangeUint32ToFloat64:
     385             :           case IrOpcode::kRoundInt32ToFloat32:
     386             :           case IrOpcode::kRoundUint32ToFloat32:
     387             :           case IrOpcode::kChangeInt32ToInt64:
     388             :           case IrOpcode::kChangeUint32ToUint64:
     389           0 :             MACHINE_UNOP_32_LIST(LABEL) { CheckValueInputForInt32Op(node, 0); }
     390           0 :             break;
     391             :           case IrOpcode::kWord32Equal:
     392             :             if (Is32()) {
     393             :               CheckValueInputIsTaggedOrPointer(node, 0);
     394             :               CheckValueInputIsTaggedOrPointer(node, 1);
     395             :               if (!is_stub_) {
     396             :                 CheckValueInputRepresentationIs(
     397             :                     node, 1, inferrer_->GetRepresentation(node->InputAt(0)));
     398             :               }
     399             :             } else {
     400           0 :               CheckValueInputForInt32Op(node, 0);
     401           0 :               CheckValueInputForInt32Op(node, 1);
     402             :             }
     403             :             break;
     404             : 
     405             :           case IrOpcode::kInt32LessThan:
     406             :           case IrOpcode::kInt32LessThanOrEqual:
     407             :           case IrOpcode::kUint32LessThan:
     408             :           case IrOpcode::kUint32LessThanOrEqual:
     409             :             MACHINE_BINOP_32_LIST(LABEL) {
     410           0 :               CheckValueInputForInt32Op(node, 0);
     411           0 :               CheckValueInputForInt32Op(node, 1);
     412             :             }
     413           0 :             break;
     414             :             MACHINE_BINOP_64_LIST(LABEL) {
     415           0 :               CheckValueInputForInt64Op(node, 0);
     416           0 :               CheckValueInputForInt64Op(node, 1);
     417             :             }
     418           0 :             break;
     419             :           case IrOpcode::kFloat32Equal:
     420             :           case IrOpcode::kFloat32LessThan:
     421             :           case IrOpcode::kFloat32LessThanOrEqual:
     422             :             MACHINE_FLOAT32_BINOP_LIST(LABEL) {
     423           0 :               CheckValueInputForFloat32Op(node, 0);
     424           0 :               CheckValueInputForFloat32Op(node, 1);
     425             :             }
     426           0 :             break;
     427             :           case IrOpcode::kChangeFloat32ToFloat64:
     428             :           case IrOpcode::kTruncateFloat32ToInt32:
     429             :           case IrOpcode::kTruncateFloat32ToUint32:
     430             :           case IrOpcode::kBitcastFloat32ToInt32:
     431             :             MACHINE_FLOAT32_UNOP_LIST(LABEL) {
     432           0 :               CheckValueInputForFloat32Op(node, 0);
     433             :             }
     434           0 :             break;
     435             :           case IrOpcode::kFloat64Equal:
     436             :           case IrOpcode::kFloat64LessThan:
     437             :           case IrOpcode::kFloat64LessThanOrEqual:
     438             :             MACHINE_FLOAT64_BINOP_LIST(LABEL) {
     439           0 :               CheckValueInputForFloat64Op(node, 0);
     440           0 :               CheckValueInputForFloat64Op(node, 1);
     441             :             }
     442           0 :             break;
     443             :           case IrOpcode::kFloat64SilenceNaN:
     444             :           case IrOpcode::kChangeFloat64ToUint64:
     445             :             MACHINE_FLOAT64_UNOP_LIST(LABEL) {
     446           0 :               CheckValueInputForFloat64Op(node, 0);
     447             :             }
     448           0 :             break;
     449             : #undef LABEL
     450             :           case IrOpcode::kParameter:
     451             :           case IrOpcode::kProjection:
     452             :             break;
     453             :           case IrOpcode::kDebugAbort:
     454           0 :             CheckValueInputIsTagged(node, 0);
     455           0 :             break;
     456             :           case IrOpcode::kLoad:
     457             :           case IrOpcode::kAtomicLoad:
     458           0 :             CheckValueInputIsTaggedOrPointer(node, 0);
     459             :             CheckValueInputRepresentationIs(
     460           0 :                 node, 1, MachineType::PointerRepresentation());
     461           0 :             break;
     462             :           case IrOpcode::kStore:
     463             :           case IrOpcode::kAtomicStore:
     464             :           case IrOpcode::kAtomicExchange:
     465             :           case IrOpcode::kAtomicAdd:
     466             :           case IrOpcode::kAtomicSub:
     467             :           case IrOpcode::kAtomicAnd:
     468             :           case IrOpcode::kAtomicOr:
     469             :           case IrOpcode::kAtomicXor:
     470           0 :             CheckValueInputIsTaggedOrPointer(node, 0);
     471             :             CheckValueInputRepresentationIs(
     472           0 :                 node, 1, MachineType::PointerRepresentation());
     473           0 :             switch (inferrer_->GetRepresentation(node)) {
     474             :               case MachineRepresentation::kTagged:
     475             :               case MachineRepresentation::kTaggedPointer:
     476             :               case MachineRepresentation::kTaggedSigned:
     477           0 :                 CheckValueInputIsTagged(node, 2);
     478           0 :                 break;
     479             :               default:
     480             :                 CheckValueInputRepresentationIs(
     481           0 :                     node, 2, inferrer_->GetRepresentation(node));
     482             :             }
     483             :             break;
     484             :           case IrOpcode::kAtomicCompareExchange:
     485           0 :             CheckValueInputIsTaggedOrPointer(node, 0);
     486             :             CheckValueInputRepresentationIs(
     487           0 :                 node, 1, MachineType::PointerRepresentation());
     488           0 :             switch (inferrer_->GetRepresentation(node)) {
     489             :               case MachineRepresentation::kTagged:
     490             :               case MachineRepresentation::kTaggedPointer:
     491             :               case MachineRepresentation::kTaggedSigned:
     492           0 :                 CheckValueInputIsTagged(node, 2);
     493           0 :                 CheckValueInputIsTagged(node, 3);
     494           0 :                 break;
     495             :               default:
     496             :                 CheckValueInputRepresentationIs(
     497           0 :                     node, 2, inferrer_->GetRepresentation(node));
     498             :                 CheckValueInputRepresentationIs(
     499           0 :                     node, 3, inferrer_->GetRepresentation(node));
     500             :             }
     501             :             break;
     502             :           case IrOpcode::kPhi:
     503           0 :             switch (inferrer_->GetRepresentation(node)) {
     504             :               case MachineRepresentation::kTagged:
     505             :               case MachineRepresentation::kTaggedPointer:
     506             :               case MachineRepresentation::kTaggedSigned:
     507           0 :                 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
     508           0 :                   CheckValueInputIsTagged(node, i);
     509             :                 }
     510             :                 break;
     511             :               case MachineRepresentation::kWord32:
     512           0 :                 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
     513           0 :                   CheckValueInputForInt32Op(node, i);
     514             :                 }
     515             :                 break;
     516             :               default:
     517           0 :                 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
     518             :                   CheckValueInputRepresentationIs(
     519           0 :                       node, i, inferrer_->GetRepresentation(node));
     520             :                 }
     521             :                 break;
     522             :             }
     523             :             break;
     524             :           case IrOpcode::kBranch:
     525             :           case IrOpcode::kSwitch:
     526           0 :             CheckValueInputForInt32Op(node, 0);
     527           0 :             break;
     528             :           case IrOpcode::kReturn: {
     529             :             // TODO(ishell): enable once the pop count parameter type becomes
     530             :             // MachineType::PointerRepresentation(). Currently it's int32 or
     531             :             // word-size.
     532             :             // CheckValueInputRepresentationIs(
     533             :             //     node, 0, MachineType::PointerRepresentation());  // Pop count
     534           0 :             size_t return_count = inferrer_->call_descriptor()->ReturnCount();
     535           0 :             for (size_t i = 0; i < return_count; i++) {
     536           0 :               MachineType type = inferrer_->call_descriptor()->GetReturnType(i);
     537           0 :               int input_index = static_cast<int>(i + 1);
     538           0 :               switch (type.representation()) {
     539             :                 case MachineRepresentation::kTagged:
     540             :                 case MachineRepresentation::kTaggedPointer:
     541             :                 case MachineRepresentation::kTaggedSigned:
     542           0 :                   CheckValueInputIsTagged(node, input_index);
     543           0 :                   break;
     544             :                 case MachineRepresentation::kWord32:
     545           0 :                   CheckValueInputForInt32Op(node, input_index);
     546           0 :                   break;
     547             :                 default:
     548             :                   CheckValueInputRepresentationIs(node, input_index,
     549           0 :                                                   type.representation());
     550           0 :                   break;
     551             :               }
     552             :             }
     553             :             break;
     554             :           }
     555             :           case IrOpcode::kThrow:
     556             :           case IrOpcode::kTypedStateValues:
     557             :           case IrOpcode::kFrameState:
     558             :             break;
     559             :           default:
     560           0 :             if (node->op()->ValueInputCount() != 0) {
     561           0 :               std::stringstream str;
     562           0 :               str << "Node #" << node->id() << ":" << *node->op()
     563           0 :                   << " in the machine graph is not being checked.";
     564             :               PrintDebugHelp(str, node);
     565           0 :               FATAL(str.str().c_str());
     566             :             }
     567             :             break;
     568             :         }
     569             :       }
     570             :     }
     571           0 :   }
     572             : 
     573             :  private:
     574             :   static bool Is32() {
     575             :     return MachineType::PointerRepresentation() ==
     576             :            MachineRepresentation::kWord32;
     577             :   }
     578             :   static bool Is64() {
     579             :     return MachineType::PointerRepresentation() ==
     580             :            MachineRepresentation::kWord64;
     581             :   }
     582             : 
     583           0 :   void CheckValueInputRepresentationIs(Node const* node, int index,
     584             :                                        MachineRepresentation representation) {
     585           0 :     Node const* input = node->InputAt(index);
     586             :     MachineRepresentation input_representation =
     587           0 :         inferrer_->GetRepresentation(input);
     588           0 :     if (input_representation != representation) {
     589           0 :       std::stringstream str;
     590           0 :       str << "TypeError: node #" << node->id() << ":" << *node->op()
     591           0 :           << " uses node #" << input->id() << ":" << *input->op() << ":"
     592           0 :           << input_representation << " which doesn't have a " << representation
     593           0 :           << " representation.";
     594             :       PrintDebugHelp(str, node);
     595           0 :       FATAL(str.str().c_str());
     596             :     }
     597           0 :   }
     598             : 
     599           0 :   void CheckValueInputIsTagged(Node const* node, int index) {
     600           0 :     Node const* input = node->InputAt(index);
     601           0 :     switch (inferrer_->GetRepresentation(input)) {
     602             :       case MachineRepresentation::kTagged:
     603             :       case MachineRepresentation::kTaggedPointer:
     604             :       case MachineRepresentation::kTaggedSigned:
     605           0 :         return;
     606             :       default:
     607             :         break;
     608             :     }
     609           0 :     std::ostringstream str;
     610           0 :     str << "TypeError: node #" << node->id() << ":" << *node->op()
     611           0 :         << " uses node #" << input->id() << ":" << *input->op()
     612           0 :         << " which doesn't have a tagged representation.";
     613             :     PrintDebugHelp(str, node);
     614           0 :     FATAL(str.str().c_str());
     615             :   }
     616             : 
     617           0 :   void CheckValueInputIsTaggedOrPointer(Node const* node, int index) {
     618           0 :     Node const* input = node->InputAt(index);
     619           0 :     switch (inferrer_->GetRepresentation(input)) {
     620             :       case MachineRepresentation::kTagged:
     621             :       case MachineRepresentation::kTaggedPointer:
     622             :       case MachineRepresentation::kTaggedSigned:
     623             :         return;
     624             :       case MachineRepresentation::kBit:
     625             :       case MachineRepresentation::kWord8:
     626             :       case MachineRepresentation::kWord16:
     627             :       case MachineRepresentation::kWord32:
     628             :         if (Is32()) {
     629             :           return;
     630             :         }
     631             :         break;
     632             :       case MachineRepresentation::kWord64:
     633             :         if (Is64()) {
     634             :           return;
     635             :         }
     636             :         break;
     637             :       default:
     638             :         break;
     639             :     }
     640           0 :     if (inferrer_->GetRepresentation(input) !=
     641             :         MachineType::PointerRepresentation()) {
     642           0 :       std::ostringstream str;
     643           0 :       str << "TypeError: node #" << node->id() << ":" << *node->op()
     644           0 :           << " uses node #" << input->id() << ":" << *input->op()
     645           0 :           << " which doesn't have a tagged or pointer representation.";
     646             :       PrintDebugHelp(str, node);
     647           0 :       FATAL(str.str().c_str());
     648             :     }
     649             :   }
     650             : 
     651           0 :   void CheckValueInputForInt32Op(Node const* node, int index) {
     652           0 :     Node const* input = node->InputAt(index);
     653           0 :     switch (inferrer_->GetRepresentation(input)) {
     654             :       case MachineRepresentation::kBit:
     655             :       case MachineRepresentation::kWord8:
     656             :       case MachineRepresentation::kWord16:
     657             :       case MachineRepresentation::kWord32:
     658           0 :         return;
     659             :       case MachineRepresentation::kNone: {
     660           0 :         std::ostringstream str;
     661           0 :         str << "TypeError: node #" << input->id() << ":" << *input->op()
     662           0 :             << " is untyped.";
     663             :         PrintDebugHelp(str, node);
     664           0 :         FATAL(str.str().c_str());
     665             :         break;
     666             :       }
     667             :       default:
     668             :         break;
     669             :     }
     670           0 :     std::ostringstream str;
     671           0 :     str << "TypeError: node #" << node->id() << ":" << *node->op()
     672           0 :         << " uses node #" << input->id() << ":" << *input->op()
     673           0 :         << " which doesn't have an int32-compatible representation.";
     674             :     PrintDebugHelp(str, node);
     675           0 :     FATAL(str.str().c_str());
     676             :   }
     677             : 
     678           0 :   void CheckValueInputForInt64Op(Node const* node, int index) {
     679           0 :     Node const* input = node->InputAt(index);
     680             :     MachineRepresentation input_representation =
     681           0 :         inferrer_->GetRepresentation(input);
     682           0 :     switch (input_representation) {
     683             :       case MachineRepresentation::kWord64:
     684           0 :         return;
     685             :       case MachineRepresentation::kNone: {
     686           0 :         std::ostringstream str;
     687           0 :         str << "TypeError: node #" << input->id() << ":" << *input->op()
     688           0 :             << " is untyped.";
     689             :         PrintDebugHelp(str, node);
     690           0 :         FATAL(str.str().c_str());
     691             :         break;
     692             :       }
     693             : 
     694             :       default:
     695             :         break;
     696             :     }
     697           0 :     std::ostringstream str;
     698           0 :     str << "TypeError: node #" << node->id() << ":" << *node->op()
     699           0 :         << " uses node #" << input->id() << ":" << *input->op() << ":"
     700           0 :         << input_representation
     701           0 :         << " which doesn't have a kWord64 representation.";
     702             :     PrintDebugHelp(str, node);
     703           0 :     FATAL(str.str().c_str());
     704             :   }
     705             : 
     706           0 :   void CheckValueInputForFloat32Op(Node const* node, int index) {
     707           0 :     Node const* input = node->InputAt(index);
     708           0 :     if (MachineRepresentation::kFloat32 ==
     709           0 :         inferrer_->GetRepresentation(input)) {
     710           0 :       return;
     711             :     }
     712           0 :     std::ostringstream str;
     713           0 :     str << "TypeError: node #" << node->id() << ":" << *node->op()
     714           0 :         << " uses node #" << input->id() << ":" << *input->op()
     715           0 :         << " which doesn't have a kFloat32 representation.";
     716             :     PrintDebugHelp(str, node);
     717           0 :     FATAL(str.str().c_str());
     718             :   }
     719             : 
     720           0 :   void CheckValueInputForFloat64Op(Node const* node, int index) {
     721           0 :     Node const* input = node->InputAt(index);
     722           0 :     if (MachineRepresentation::kFloat64 ==
     723           0 :         inferrer_->GetRepresentation(input)) {
     724           0 :       return;
     725             :     }
     726           0 :     std::ostringstream str;
     727           0 :     str << "TypeError: node #" << node->id() << ":" << *node->op()
     728           0 :         << " uses node #" << input->id() << ":" << *input->op()
     729           0 :         << " which doesn't have a kFloat64 representation.";
     730             :     PrintDebugHelp(str, node);
     731           0 :     FATAL(str.str().c_str());
     732             :   }
     733             : 
     734           0 :   void CheckCallInputs(Node const* node) {
     735           0 :     CallDescriptor const* desc = CallDescriptorOf(node->op());
     736           0 :     std::ostringstream str;
     737             :     bool should_log_error = false;
     738           0 :     for (size_t i = 0; i < desc->InputCount(); ++i) {
     739           0 :       Node const* input = node->InputAt(static_cast<int>(i));
     740             :       MachineRepresentation const input_type =
     741           0 :           inferrer_->GetRepresentation(input);
     742             :       MachineRepresentation const expected_input_type =
     743             :           desc->GetInputType(i).representation();
     744           0 :       if (!IsCompatible(expected_input_type, input_type)) {
     745           0 :         if (!should_log_error) {
     746             :           should_log_error = true;
     747           0 :           str << "TypeError: node #" << node->id() << ":" << *node->op()
     748           0 :               << " has wrong type for:" << std::endl;
     749             :         } else {
     750             :           str << std::endl;
     751             :         }
     752           0 :         str << " * input " << i << " (" << input->id() << ":" << *input->op()
     753           0 :             << ") doesn't have a " << expected_input_type << " representation.";
     754             :       }
     755             :     }
     756           0 :     if (should_log_error) {
     757             :       PrintDebugHelp(str, node);
     758           0 :       FATAL(str.str().c_str());
     759           0 :     }
     760           0 :   }
     761             : 
     762             :   bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) {
     763             :     return (GetRepresentationProperties(lhs) &
     764             :             GetRepresentationProperties(rhs)) != 0;
     765             :   }
     766             : 
     767             :   enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 };
     768             : 
     769             :   int GetRepresentationProperties(MachineRepresentation representation) {
     770             :     switch (representation) {
     771             :       case MachineRepresentation::kTagged:
     772             :       case MachineRepresentation::kTaggedPointer:
     773             :         return kIsPointer | kIsTagged;
     774             :       case MachineRepresentation::kTaggedSigned:
     775             :         return kIsTagged;
     776             :       case MachineRepresentation::kWord32:
     777             :         return MachineRepresentation::kWord32 ==
     778             :                        MachineType::PointerRepresentation()
     779             :                    ? kIsPointer
     780             :                    : 0;
     781             :       case MachineRepresentation::kWord64:
     782             :         return MachineRepresentation::kWord64 ==
     783             :                        MachineType::PointerRepresentation()
     784             :                    ? kIsPointer
     785             :                    : 0;
     786             :       default:
     787             :         return 0;
     788             :     }
     789             :   }
     790             : 
     791           0 :   bool IsCompatible(MachineRepresentation expected,
     792             :                     MachineRepresentation actual) {
     793           0 :     switch (expected) {
     794             :       case MachineRepresentation::kTagged:
     795           0 :         return (actual == MachineRepresentation::kTagged ||
     796           0 :                 actual == MachineRepresentation::kTaggedSigned ||
     797             :                 actual == MachineRepresentation::kTaggedPointer);
     798             :       case MachineRepresentation::kTaggedSigned:
     799             :       case MachineRepresentation::kTaggedPointer:
     800             :       case MachineRepresentation::kFloat32:
     801             :       case MachineRepresentation::kFloat64:
     802             :       case MachineRepresentation::kSimd128:
     803             :       case MachineRepresentation::kBit:
     804             :       case MachineRepresentation::kWord8:
     805             :       case MachineRepresentation::kWord16:
     806             :       case MachineRepresentation::kWord64:
     807           0 :         return expected == actual;
     808             :         break;
     809             :       case MachineRepresentation::kWord32:
     810             :         return (actual == MachineRepresentation::kBit ||
     811             :                 actual == MachineRepresentation::kWord8 ||
     812           0 :                 actual == MachineRepresentation::kWord16 ||
     813           0 :                 actual == MachineRepresentation::kWord32);
     814             :       case MachineRepresentation::kNone:
     815           0 :         UNREACHABLE();
     816             :     }
     817             :     return false;
     818             :   }
     819             : 
     820             :   void PrintDebugHelp(std::ostream& out, Node const* node) {
     821             :     if (DEBUG_BOOL) {
     822             :       out << "\n#     Current block: " << *current_block_;
     823             :       out << "\n#\n#     Specify option --csa-trap-on-node=" << name_ << ","
     824             :           << node->id() << " for debugging.";
     825             :     }
     826             :   }
     827             : 
     828             :   Schedule const* const schedule_;
     829             :   MachineRepresentationInferrer const* const inferrer_;
     830             :   bool is_stub_;
     831             :   const char* name_;
     832             :   BasicBlock* current_block_;
     833             : };
     834             : 
     835             : }  // namespace
     836             : 
     837           0 : void MachineGraphVerifier::Run(Graph* graph, Schedule const* const schedule,
     838             :                                Linkage* linkage, bool is_stub, const char* name,
     839             :                                Zone* temp_zone) {
     840             :   MachineRepresentationInferrer representation_inferrer(schedule, graph,
     841           0 :                                                         linkage, temp_zone);
     842             :   MachineRepresentationChecker checker(schedule, &representation_inferrer,
     843             :                                        is_stub, name);
     844           0 :   checker.Run();
     845           0 : }
     846             : 
     847             : }  // namespace compiler
     848             : }  // namespace internal
     849             : }  // namespace v8

Generated by: LCOV version 1.10