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

Generated by: LCOV version 1.10