brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.0 KiB · 333d956 Raw
285 lines · cpp
1//===- GlobalISelMatchTableExecutorEmitter.cpp ----------------------------===//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 "GlobalISelMatchTableExecutorEmitter.h"10#include "GlobalISelMatchTable.h"11 12using namespace llvm;13using namespace llvm::gi;14 15void GlobalISelMatchTableExecutorEmitter::emitSubtargetFeatureBitsetImpl(16    raw_ostream &OS, ArrayRef<RuleMatcher> Rules) {17  SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,18                                                           OS, &HwModes);19 20  // Separate subtarget features by how often they must be recomputed.21  SubtargetFeatureInfoMap ModuleFeatures;22  llvm::copy_if(SubtargetFeatures,23                std::inserter(ModuleFeatures, ModuleFeatures.end()),24                [](const SubtargetFeatureInfoMap::value_type &X) {25                  return !X.second.mustRecomputePerFunction();26                });27  SubtargetFeatureInfoMap FunctionFeatures;28  llvm::copy_if(SubtargetFeatures,29                std::inserter(FunctionFeatures, FunctionFeatures.end()),30                [](const SubtargetFeatureInfoMap::value_type &X) {31                  return X.second.mustRecomputePerFunction();32                });33 34  SubtargetFeatureInfo::emitComputeAvailableFeatures(35      getTarget().getName(), getClassName(), "computeAvailableModuleFeatures",36      ModuleFeatures, OS, "", &HwModes);37 38  OS << "void " << getClassName()39     << "::setupGeneratedPerFunctionState(MachineFunction &MF) {\n"40        "  AvailableFunctionFeatures = computeAvailableFunctionFeatures("41        "(const "42     << getTarget().getName()43     << "Subtarget *)&MF.getSubtarget(), &MF);\n"44        "}\n";45 46  SubtargetFeatureInfo::emitComputeAvailableFeatures(47      getTarget().getName(), getClassName(), "computeAvailableFunctionFeatures",48      FunctionFeatures, OS, "const MachineFunction *MF");49 50  // Emit a table containing the PredicateBitsets objects needed by the matcher51  // and an enum for the matcher to reference them with.52  std::vector<std::pair<std::vector<const Record *>, int>> FeatureBitsets;53  FeatureBitsets.reserve(Rules.size());54  for (auto &Rule : Rules)55    FeatureBitsets.emplace_back(Rule.getRequiredFeatures(),56                                Rule.getHwModeIdx());57  llvm::sort(FeatureBitsets,58             [&](const std::pair<std::vector<const Record *>, int> &A,59                 const std::pair<std::vector<const Record *>, int> &B) {60               if (A.first.size() < B.first.size())61                 return true;62               if (A.first.size() > B.first.size())63                 return false;64               for (auto [First, Second] : zip(A.first, B.first)) {65                 if (First->getName() < Second->getName())66                   return true;67                 if (First->getName() > Second->getName())68                   return false;69               }70 71               return (A.second < B.second);72             });73  FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());74  OS << "// Feature bitsets.\n"75     << "enum {\n"76     << "  GIFBS_Invalid,\n";77  for (const auto &FeatureBitset : FeatureBitsets) {78    if (FeatureBitset.first.empty() && FeatureBitset.second < 0)79      continue;80    OS << "  "81       << getNameForFeatureBitset(FeatureBitset.first, FeatureBitset.second)82       << ",\n";83  }84  OS << "};\n"85     << "constexpr static PredicateBitset FeatureBitsets[] {\n"86     << "  {}, // GIFBS_Invalid\n";87  for (const auto &FeatureBitset : FeatureBitsets) {88    if (FeatureBitset.first.empty() && FeatureBitset.second < 0)89      continue;90    OS << "  {";91    for (const auto &Feature : FeatureBitset.first) {92      const auto &I = SubtargetFeatures.find(Feature);93      assert(I != SubtargetFeatures.end() && "Didn't import predicate?");94      OS << I->second.getEnumBitName() << ", ";95    }96    // HwModeIdx97    if (FeatureBitset.second >= 0) {98      OS << "Feature_HwMode" << FeatureBitset.second << "Bit, ";99    }100    OS << "},\n";101  }102  OS << "};\n\n";103}104 105void GlobalISelMatchTableExecutorEmitter::emitComplexPredicates(106    raw_ostream &OS, ArrayRef<const Record *> ComplexOperandMatchers) {107  // Emit complex predicate table and an enum to reference them with.108  OS << "// ComplexPattern predicates.\n"109     << "enum {\n"110     << "  GICP_Invalid,\n";111  for (const auto &Record : ComplexOperandMatchers)112    OS << "  GICP_" << Record->getName() << ",\n";113  OS << "};\n"114     << "// See constructor for table contents\n\n";115 116  OS << getClassName() << "::ComplexMatcherMemFn\n"117     << getClassName() << "::ComplexPredicateFns[] = {\n"118     << "  nullptr, // GICP_Invalid\n";119  for (const auto &Record : ComplexOperandMatchers)120    OS << "  &" << getClassName()121       << "::" << Record->getValueAsString("MatcherFn") << ", // "122       << Record->getName() << "\n";123  OS << "};\n\n";124}125 126void GlobalISelMatchTableExecutorEmitter::emitCustomOperandRenderers(127    raw_ostream &OS, ArrayRef<StringRef> CustomOperandRenderers) {128  OS << "// Custom renderers.\n"129     << "enum {\n"130     << "  GICR_Invalid,\n";131  for (const auto &Fn : CustomOperandRenderers)132    OS << "  GICR_" << Fn << ",\n";133  OS << "};\n";134 135  OS << getClassName() << "::CustomRendererFn\n"136     << getClassName() << "::CustomRenderers[] = {\n"137     << "  nullptr, // GICR_Invalid\n";138  for (const auto &Fn : CustomOperandRenderers)139    OS << "  &" << getClassName() << "::" << Fn << ",\n";140  OS << "};\n\n";141}142 143void GlobalISelMatchTableExecutorEmitter::emitTypeObjects(144    raw_ostream &OS, ArrayRef<LLTCodeGen> TypeObjects) {145  OS << "// LLT Objects.\n"146     << "enum {\n";147  for (const auto &TypeObject : TypeObjects) {148    OS << "  ";149    TypeObject.emitCxxEnumValue(OS);150    OS << ",\n";151  }152  OS << "};\n"153     << "const static size_t NumTypeObjects = " << TypeObjects.size() << ";\n"154     << "const static LLT TypeObjects[] = {\n";155  for (const auto &TypeObject : TypeObjects) {156    OS << "  ";157    TypeObject.emitCxxConstructorCall(OS);158    OS << ",\n";159  }160  OS << "};\n\n";161}162 163void GlobalISelMatchTableExecutorEmitter::emitMatchTable(164    raw_ostream &OS, const MatchTable &Table) {165  emitEncodingMacrosDef(OS);166  OS << "const uint8_t *" << getClassName() << "::getMatchTable() const {\n";167  Table.emitDeclaration(OS);168  OS << "  return ";169  Table.emitUse(OS);170  OS << ";\n}\n";171  emitEncodingMacrosUndef(OS);172  OS << "\n";173}174 175void GlobalISelMatchTableExecutorEmitter::emitExecutorImpl(176    raw_ostream &OS, const MatchTable &Table, ArrayRef<LLTCodeGen> TypeObjects,177    ArrayRef<RuleMatcher> Rules,178    ArrayRef<const Record *> ComplexOperandMatchers,179    ArrayRef<StringRef> CustomOperandRenderers, StringRef IfDefName) {180  OS << "#ifdef " << IfDefName << "\n";181  emitTypeObjects(OS, TypeObjects);182  emitSubtargetFeatureBitsetImpl(OS, Rules);183  emitComplexPredicates(OS, ComplexOperandMatchers);184  emitMIPredicateFns(OS);185  emitLeafPredicateFns(OS);186  emitI64ImmPredicateFns(OS);187  emitAPFloatImmPredicateFns(OS);188  emitAPIntImmPredicateFns(OS);189  emitTestSimplePredicate(OS);190  emitCustomOperandRenderers(OS, CustomOperandRenderers);191  emitAdditionalImpl(OS);192  emitRunCustomAction(OS);193 194  emitMatchTable(OS, Table);195 196  OS << "#endif // ifdef " << IfDefName << "\n\n";197}198 199void GlobalISelMatchTableExecutorEmitter::emitPredicateBitset(200    raw_ostream &OS, StringRef IfDefName) {201  unsigned Size = SubtargetFeatures.size() + HwModes.size();202  OS << "#ifdef " << IfDefName << "\n"203     << "const unsigned MAX_SUBTARGET_PREDICATES = " << Size << ";\n"204     << "using PredicateBitset = "205        "llvm::Bitset<MAX_SUBTARGET_PREDICATES>;\n"206     << "#endif // ifdef " << IfDefName << "\n\n";207}208 209void GlobalISelMatchTableExecutorEmitter::emitTemporariesDecl(210    raw_ostream &OS, StringRef IfDefName) {211  OS << "#ifdef " << IfDefName << "\n"212     << "  mutable MatcherState State;\n"213     << "  typedef "214        "ComplexRendererFns("215     << getClassName() << "::*ComplexMatcherMemFn)(MachineOperand &) const;\n"216 217     << "  typedef void(" << getClassName()218     << "::*CustomRendererFn)(MachineInstrBuilder &, const "219        "MachineInstr &, int) "220        "const;\n"221     << "  const ExecInfoTy<PredicateBitset, ComplexMatcherMemFn, "222        "CustomRendererFn> "223        "ExecInfo;\n"224     << "  static " << getClassName()225     << "::ComplexMatcherMemFn ComplexPredicateFns[];\n"226     << "  static " << getClassName()227     << "::CustomRendererFn CustomRenderers[];\n"228     << "  bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "229        "override;\n"230     << "  bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "231        "const override;\n"232     << "  bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "233        "&Imm) const override;\n"234     << "  const uint8_t *getMatchTable() const override;\n"235     << "  bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"236        ", const MatcherState &State) "237        "const override;\n"238     << "  bool testMOPredicate_MO(unsigned PredicateID, const MachineOperand "239        "&MO, const MatcherState &State) "240        "const override;\n"241     << "  bool testSimplePredicate(unsigned PredicateID) const override;\n"242     << "  bool runCustomAction(unsigned FnID, const MatcherState &State, "243        "NewMIVector &OutMIs) "244        "const override;\n"245     << "#endif // ifdef " << IfDefName << "\n\n";246}247 248void GlobalISelMatchTableExecutorEmitter::emitTemporariesInit(249    raw_ostream &OS, unsigned MaxTemporaries, StringRef IfDefName) {250  OS << "#ifdef " << IfDefName << "\n"251     << ", State(" << MaxTemporaries << "),\n"252     << "ExecInfo(TypeObjects, NumTypeObjects, FeatureBitsets"253     << ", ComplexPredicateFns, CustomRenderers)\n"254     << "#endif // ifdef " << IfDefName << "\n\n";255 256  emitAdditionalTemporariesInit(OS);257}258 259void GlobalISelMatchTableExecutorEmitter::emitPredicatesDecl(260    raw_ostream &OS, StringRef IfDefName) {261  OS << "#ifdef " << IfDefName << "\n"262     << "PredicateBitset AvailableModuleFeatures;\n"263     << "mutable PredicateBitset AvailableFunctionFeatures;\n"264     << "PredicateBitset getAvailableFeatures() const {\n"265     << "  return AvailableModuleFeatures | AvailableFunctionFeatures;\n"266     << "}\n"267     << "PredicateBitset\n"268     << "computeAvailableModuleFeatures(const " << getTarget().getName()269     << "Subtarget *Subtarget) const;\n"270     << "PredicateBitset\n"271     << "computeAvailableFunctionFeatures(const " << getTarget().getName()272     << "Subtarget *Subtarget,\n"273     << "                                 const MachineFunction *MF) const;\n"274     << "void setupGeneratedPerFunctionState(MachineFunction &MF) override;\n"275     << "#endif // ifdef " << IfDefName << "\n";276}277 278void GlobalISelMatchTableExecutorEmitter::emitPredicatesInit(279    raw_ostream &OS, StringRef IfDefName) {280  OS << "#ifdef " << IfDefName << "\n"281     << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n"282     << "AvailableFunctionFeatures()\n"283     << "#endif // ifdef " << IfDefName << "\n";284}285