LCOV - code coverage report
Current view: top level - src/compiler - machine-graph-verifier.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1 316 0.3 %
Date: 2019-04-17 Functions: 1 16 6.2 %

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

Generated by: LCOV version 1.10