brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · da763df Raw
245 lines · cpp
1//==------------------------------------------------------------------------==//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/CodeGen/SDNodeInfo.h"10#include "llvm/CodeGen/SelectionDAG.h"11#include "llvm/CodeGen/SelectionDAGNodes.h"12#include "llvm/CodeGen/TargetLowering.h"13#include "llvm/CodeGen/TargetSubtargetInfo.h"14 15using namespace llvm;16 17static void reportNodeError(const SelectionDAG &DAG, const SDNode *N,18                            const Twine &Msg) {19  std::string S;20  raw_string_ostream SS(S);21  SS << "invalid node: " << Msg << '\n';22  N->printrWithDepth(SS, &DAG, 2);23  report_fatal_error(StringRef(S));24}25 26static void checkResultType(const SelectionDAG &DAG, const SDNode *N,27                            unsigned ResIdx, EVT ExpectedVT) {28  EVT ActualVT = N->getValueType(ResIdx);29  if (ActualVT != ExpectedVT)30    reportNodeError(31        DAG, N,32        "result #" + Twine(ResIdx) + " has invalid type; expected " +33            ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());34}35 36static void checkOperandType(const SelectionDAG &DAG, const SDNode *N,37                             unsigned OpIdx, EVT ExpectedVT) {38  EVT ActualVT = N->getOperand(OpIdx).getValueType();39  if (ActualVT != ExpectedVT)40    reportNodeError(41        DAG, N,42        "operand #" + Twine(OpIdx) + " has invalid type; expected " +43            ExpectedVT.getEVTString() + ", got " + ActualVT.getEVTString());44}45 46namespace {47 48/// Similar to SDValue, but also records whether it is a result or an operand49/// of a node so we can provide more precise diagnostics.50class SDNodeValue {51  const SDNode *N;52  unsigned Idx;53  bool IsRes;54 55public:56  SDNodeValue(const SDNode *N, unsigned Idx, bool IsRes)57      : N(N), Idx(Idx), IsRes(IsRes) {}58 59  SDValue getValue() const {60    return IsRes ? SDValue(const_cast<SDNode *>(N), Idx) : N->getOperand(Idx);61  }62 63  EVT getValueType() const { return getValue().getValueType(); }64 65  friend raw_ostream &operator<<(raw_ostream &OS, const SDNodeValue &Op) {66    return OS << (Op.IsRes ? "result" : "operand") << " #" << Op.Idx;67  }68};69 70} // namespace71 72void SDNodeInfo::verifyNode(const SelectionDAG &DAG, const SDNode *N) const {73  const SDNodeDesc &Desc = getDesc(N->getOpcode());74  bool HasChain = Desc.hasProperty(SDNPHasChain);75  bool HasOutGlue = Desc.hasProperty(SDNPOutGlue);76  bool HasInGlue = Desc.hasProperty(SDNPInGlue);77  bool HasOptInGlue = Desc.hasProperty(SDNPOptInGlue);78  bool IsVariadic = Desc.hasProperty(SDNPVariadic);79 80  unsigned ActualNumResults = N->getNumValues();81  unsigned ExpectedNumResults = Desc.NumResults + HasChain + HasOutGlue;82 83  if (ActualNumResults != ExpectedNumResults)84    reportNodeError(DAG, N,85                    "invalid number of results; expected " +86                        Twine(ExpectedNumResults) + ", got " +87                        Twine(ActualNumResults));88 89  // Chain result comes after all normal results.90  if (HasChain) {91    unsigned ChainResIdx = Desc.NumResults;92    checkResultType(DAG, N, ChainResIdx, MVT::Other);93  }94 95  // Glue result comes last.96  if (HasOutGlue) {97    unsigned GlueResIdx = Desc.NumResults + HasChain;98    checkResultType(DAG, N, GlueResIdx, MVT::Glue);99  }100 101  // In the most general case, the operands of a node go in the following order:102  //   chain, fix#0, ..., fix#M-1, var#0, ... var#N-1, glue103  // If the number of operands is < 0, M can be any;104  // If the node has SDNPVariadic property, N can be any.105  bool HasOptionalOperands = Desc.NumOperands < 0 || IsVariadic;106 107  unsigned ActualNumOperands = N->getNumOperands();108  unsigned ExpectedMinNumOperands =109      (Desc.NumOperands >= 0 ? Desc.NumOperands : 0) + HasChain + HasInGlue;110 111  // Check the lower bound.112  if (ActualNumOperands < ExpectedMinNumOperands) {113    StringRef How = HasOptionalOperands ? "at least " : "";114    reportNodeError(DAG, N,115                    "invalid number of operands; expected " + How +116                        Twine(ExpectedMinNumOperands) + ", got " +117                        Twine(ActualNumOperands));118  }119 120  // Check the upper bound. We can only do this if the number of fixed operands121  // is known and there are no variadic operands.122  if (Desc.NumOperands >= 0 && !IsVariadic) {123    // Account for optional input glue.124    unsigned ExpectedMaxNumOperands = ExpectedMinNumOperands + HasOptInGlue;125    if (ActualNumOperands > ExpectedMaxNumOperands) {126      StringRef How = HasOptInGlue ? "at most " : "";127      reportNodeError(DAG, N,128                      "invalid number of operands; expected " + How +129                          Twine(ExpectedMaxNumOperands) + ", got " +130                          Twine(ActualNumOperands));131    }132  }133 134  // Chain operand comes first.135  if (HasChain)136    checkOperandType(DAG, N, 0, MVT::Other);137 138  // Glue operand comes last.139  if (HasInGlue)140    checkOperandType(DAG, N, ActualNumOperands - 1, MVT::Glue);141  if (HasOptInGlue && ActualNumOperands >= 1 &&142      N->getOperand(ActualNumOperands - 1).getValueType() == MVT::Glue)143    HasInGlue = true;144 145  // Check variadic operands. These should be Register or RegisterMask.146  if (IsVariadic && Desc.NumOperands >= 0) {147    unsigned VarOpStart = HasChain + Desc.NumOperands;148    unsigned VarOpEnd = ActualNumOperands - HasInGlue;149    for (unsigned OpIdx = VarOpStart; OpIdx != VarOpEnd; ++OpIdx) {150      unsigned OpOpcode = N->getOperand(OpIdx).getOpcode();151      if (OpOpcode != ISD::Register && OpOpcode != ISD::RegisterMask)152        reportNodeError(DAG, N,153                        "variadic operand #" + Twine(OpIdx) +154                            " must be Register or RegisterMask");155    }156  }157 158  unsigned VTHwMode =159      DAG.getSubtarget().getHwMode(MCSubtargetInfo::HwMode_ValueType);160 161  // Returns a constrained or constraining value (result or operand) of a node.162  // ValIdx is the index of a node's value, as defined by SDTypeConstraint;163  // that is, it indexes a node's operands after its results and ignores164  // chain/glue values.165  auto GetConstraintValue = [&](unsigned ValIdx) {166    if (ValIdx < Desc.NumResults)167      return SDNodeValue(N, ValIdx, /*IsRes=*/true);168    return SDNodeValue(N, HasChain + (ValIdx - Desc.NumResults),169                       /*IsRes=*/false);170  };171 172  auto GetConstraintVT = [&](const SDTypeConstraint &C) {173    if (!C.NumHwModes)174      return static_cast<MVT::SimpleValueType>(C.VT);175    for (auto [Mode, VT] : ArrayRef(&VTByHwModeTable[C.VT], C.NumHwModes))176      if (Mode == VTHwMode)177        return VT;178    llvm_unreachable("No value type for this HW mode");179  };180 181  SmallString<128> ES;182  raw_svector_ostream SS(ES);183 184  for (const SDTypeConstraint &C : getConstraints(N->getOpcode())) {185    SDNodeValue Val = GetConstraintValue(C.ConstrainedValIdx);186    EVT VT = Val.getValueType();187 188    switch (C.Kind) {189    case SDTCisVT: {190      EVT ExpectedVT = GetConstraintVT(C);191 192      bool IsPtr = ExpectedVT == MVT::iPTR;193      if (IsPtr)194        ExpectedVT =195            DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());196 197      if (VT != ExpectedVT) {198        SS << Val << " must have type " << ExpectedVT;199        if (IsPtr)200          SS << " (iPTR)";201        SS << ", but has type " << VT;202        reportNodeError(DAG, N, SS.str());203      }204      break;205    }206    case SDTCisPtrTy:207      break;208    case SDTCisInt:209      break;210    case SDTCisFP:211      break;212    case SDTCisVec:213      break;214    case SDTCisSameAs:215      break;216    case SDTCisVTSmallerThanOp:217      break;218    case SDTCisOpSmallerThanOp:219      break;220    case SDTCisEltOfVec:221      break;222    case SDTCisSubVecOfVec:223      break;224    case SDTCVecEltisVT: {225      EVT ExpectedVT = GetConstraintVT(C);226 227      if (!VT.isVector()) {228        SS << Val << " must have vector type";229        reportNodeError(DAG, N, SS.str());230      }231      if (VT.getVectorElementType() != ExpectedVT) {232        SS << Val << " must have " << ExpectedVT << " element type, but has "233           << VT.getVectorElementType() << " element type";234        reportNodeError(DAG, N, SS.str());235      }236      break;237    }238    case SDTCisSameNumEltsAs:239      break;240    case SDTCisSameSizeAs:241      break;242    }243  }244}245