brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · 1f66d73 Raw
251 lines · c
1//===- GlobalISelMatchTableExecutorEmitter.h ------------------------------===//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/// \file10/// This file contains common code related to emitting11/// GIMatchTableExecutor-derived classes.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H16#define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H17 18#include "Common/SubtargetFeatureInfo.h"19#include "llvm/ADT/ArrayRef.h"20#include "llvm/ADT/StringRef.h"21#include "llvm/ADT/Twine.h"22#include <functional>23 24namespace llvm {25class CodeGenTarget;26 27namespace gi {28class RuleMatcher;29class LLTCodeGen;30class MatchTable;31} // namespace gi32 33/// Abstract base class for TableGen backends that emit a34/// `GIMatchTableExecutor`-derived class.35class GlobalISelMatchTableExecutorEmitter {36  /// Emits logic to check features required by \p Rules using the37 38  /// SubtargetFeatures map.39  void emitSubtargetFeatureBitsetImpl(raw_ostream &OS,40                                      ArrayRef<gi::RuleMatcher> Rules);41 42  /// Emits an enum + an array that stores references to43  /// \p ComplexOperandMatchers.44  void emitComplexPredicates(raw_ostream &OS,45                             ArrayRef<const Record *> ComplexOperandMatchers);46 47  /// Emits an enum + an array that stores references to48  /// \p CustomOperandRenderers.49  void emitCustomOperandRenderers(raw_ostream &OS,50                                  ArrayRef<StringRef> CustomOperandRenderers);51 52  /// Emits an enum + an array to reference \p TypeObjects (LLTs) in the match53  /// table.54  void emitTypeObjects(raw_ostream &OS, ArrayRef<gi::LLTCodeGen> TypeObjects);55 56  /// Emits the getMatchTable function which contains all of the match table's57  /// opcodes.58  void emitMatchTable(raw_ostream &OS, const gi::MatchTable &Table);59 60  /// Helper function to emit `test` functions for the executor. This emits both61  /// an enum to reference predicates in the MatchTable, and a function to62  /// switch over the enum & execute the predicate's C++ code.63  ///64  /// \tparam PredicateObject An object representing a predicate to emit.65  /// \param OS Output stream66  /// \param TypeIdentifier Identifier used for the type of the predicate,67  ///        e.g. `MI` for MachineInstrs.68  /// \param ArgType Full type of the argument, e.g. `const MachineInstr &`69  /// \param ArgName Name of the argument, e.g. `MI` for MachineInstrs.70  /// \param AdditionalArgs Optional additional argument declarations.71  /// \param AdditionalDeclarations Optional declarations to write at the start72  ///        of the function, before switching over the predicates enum.73  /// \param Predicates Predicates to emit.74  /// \param GetPredEnumName Returns an enum name for a given predicate.75  /// \param GetPredCode Returns the C++ code of a given predicate.76  /// \param Comment Optional comment for the enum declaration.77  template <typename PredicateObject>78  void emitCxxPredicateFns(79      raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,80      StringRef ArgName, StringRef AdditionalArgs,81      StringRef AdditionalDeclarations, ArrayRef<PredicateObject> Predicates,82      llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,83      llvm::function_ref<StringRef(PredicateObject)> GetPredCode,84      StringRef Comment) {85    if (!Comment.empty())86      OS << "// " << Comment << "\n";87    if (!Predicates.empty()) {88      OS << "enum {\n";89      StringRef EnumeratorSeparator = " = GICXXPred_Invalid + 1,\n";90      for (const auto &Pred : Predicates) {91        OS << "  GICXXPred_" << TypeIdentifier << "_Predicate_"92           << GetPredEnumName(Pred) << EnumeratorSeparator;93        EnumeratorSeparator = ",\n";94      }95      OS << "};\n";96    }97 98    OS << "bool " << getClassName() << "::test" << ArgName << "Predicate_"99       << TypeIdentifier << "(unsigned PredicateID, " << ArgType << " "100       << ArgName << AdditionalArgs << ") const {\n"101       << AdditionalDeclarations;102    if (!AdditionalDeclarations.empty())103      OS << "\n";104    if (!Predicates.empty()) {105      OS << "  switch (PredicateID) {\n";106      for (const auto &Pred : Predicates) {107        // Ensure all code is indented.108        const auto Code = join(split(GetPredCode(Pred).str(), "\n"), "\n    ");109        OS << "  case GICXXPred_" << TypeIdentifier << "_Predicate_"110           << GetPredEnumName(Pred) << ": {\n"111           << "    " << Code << "\n";112        if (!StringRef(Code).ltrim().starts_with("return")) {113          OS << "    llvm_unreachable(\"" << GetPredEnumName(Pred)114             << " should have returned\");\n";115        }116        OS << "  }\n";117      }118      OS << "  }\n";119    }120    OS << "  llvm_unreachable(\"Unknown predicate\");\n"121       << "  return false;\n"122       << "}\n";123  }124 125protected:126  /// Emits `testMIPredicate_MI`.127  /// \tparam PredicateObject An object representing a predicate to emit.128  /// \param OS Output stream129  /// \param AdditionalDecls Additional C++ variable declarations.130  /// \param Predicates Predicates to emit.131  /// \param GetPredEnumName Returns an enum name for a given predicate.132  /// \param GetPredCode Returns the C++ code of a given predicate.133  /// \param Comment Optional comment for the enum declaration.134  template <typename PredicateObject>135  void emitMIPredicateFnsImpl(136      raw_ostream &OS, StringRef AdditionalDecls,137      ArrayRef<PredicateObject> Predicates,138      llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,139      llvm::function_ref<StringRef(PredicateObject)> GetPredCode,140      StringRef Comment = "") {141    return emitCxxPredicateFns(142        OS, "MI", "const MachineInstr &", "MI", ", const MatcherState &State",143        AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);144  }145 146  /// Emits `testMOPredicate_MO`.147  /// \tparam PredicateObject An object representing a predicate to emit.148  /// \param OS Output stream.149  /// \param AdditionalDecls Additional C++ variable declarations.150  /// \param Predicates Predicates to emit.151  /// \param GetPredEnumName Returns an enum name for a given predicate.152  /// \param GetPredCode Returns the C++ code of a given predicate.153  /// \param Comment Optional comment for the enum declaration.154  template <typename PredicateObject>155  void emitLeafPredicateFnsImpl(156      raw_ostream &OS, StringRef AdditionalDecls,157      ArrayRef<PredicateObject> Predicates,158      llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,159      llvm::function_ref<StringRef(PredicateObject)> GetPredCode,160      StringRef Comment = "") {161    return emitCxxPredicateFns(162        OS, "MO", "const MachineOperand &", "MO", ", const MatcherState &State",163        AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);164  }165 166  /// Helper function to emit the following executor functions:167  ///   * testImmPredicate_I64      (TypeIdentifier=I64)168  ///   * testImmPredicate_APInt    (TypeIdentifier=APInt)169  ///   * testImmPredicate_APFloat  (TypeIdentifier=APFloat)170  ///171  /// \tparam PredicateObject An object representing a predicate to emit.172  /// \param OS Output stream173  /// \param TypeIdentifier Identifier used for the type of the predicate174  /// \param ArgType Full type of the argument175  /// \param Predicates Predicates to emit.176  /// \param GetPredEnumName Returns an enum name for a given predicate.177  /// \param GetPredCode Returns the C++ code of a given predicate.178  /// \param Comment Optional comment for the enum declaration.179  template <typename PredicateObject>180  void emitImmPredicateFnsImpl(181      raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,182      ArrayRef<PredicateObject> Predicates,183      llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,184      llvm::function_ref<StringRef(PredicateObject)> GetPredCode,185      StringRef Comment = "") {186    return emitCxxPredicateFns(OS, TypeIdentifier, ArgType, "Imm", "", "",187                               Predicates, GetPredEnumName, GetPredCode,188                               Comment);189  }190 191  GlobalISelMatchTableExecutorEmitter() = default;192 193public:194  virtual ~GlobalISelMatchTableExecutorEmitter() = default;195 196  virtual const CodeGenTarget &getTarget() const = 0;197 198  /// \returns the name of the class being emitted including any prefixes, e.g.199  /// `AMDGPUInstructionSelector`.200  virtual StringRef getClassName() const = 0;201 202  /// Emit additional content in emitExecutorImpl203  virtual void emitAdditionalImpl(raw_ostream &OS) {}204 205  /// Emit additional content in emitTemporariesInit.206  virtual void emitAdditionalTemporariesInit(raw_ostream &OS) {}207 208  /// Emit the `testMIPredicate_MI` function.209  /// Note: `emitMIPredicateFnsImpl` can be used to do most of the work.210  virtual void emitMIPredicateFns(raw_ostream &OS) = 0;211 212  /// Emit the `testLeafPredicate` function213  /// Note `emitLeafPredicateFnsImpl` can be used to do most of the work.214  virtual void emitLeafPredicateFns(raw_ostream &OS) = 0;215 216  /// Emit the `testImmPredicate_I64` function.217  /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.218  virtual void emitI64ImmPredicateFns(raw_ostream &OS) = 0;219 220  /// Emit the `testImmPredicate_APFloat` function.221  /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.222  virtual void emitAPFloatImmPredicateFns(raw_ostream &OS) = 0;223 224  /// Emit the `testImmPredicate_APInt` function.225  /// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.226  virtual void emitAPIntImmPredicateFns(raw_ostream &OS) = 0;227  virtual void emitTestSimplePredicate(raw_ostream &OS) = 0;228  virtual void emitRunCustomAction(raw_ostream &OS) = 0;229 230  void emitExecutorImpl(raw_ostream &OS, const gi::MatchTable &Table,231                        ArrayRef<gi::LLTCodeGen> TypeObjects,232                        ArrayRef<gi::RuleMatcher> Rules,233                        ArrayRef<const Record *> ComplexOperandMatchers,234                        ArrayRef<StringRef> CustomOperandRenderers,235                        StringRef IfDefName);236  void emitPredicateBitset(raw_ostream &OS, StringRef IfDefName);237  void emitTemporariesDecl(raw_ostream &OS, StringRef IfDefName);238  void emitTemporariesInit(raw_ostream &OS, unsigned MaxTemporaries,239                           StringRef IfDefName);240  void emitPredicatesDecl(raw_ostream &OS, StringRef IfDefName);241  void emitPredicatesInit(raw_ostream &OS, StringRef IfDefName);242 243  // Map of predicates to their subtarget features.244  SubtargetFeatureInfoMap SubtargetFeatures;245 246  std::map<std::string, unsigned> HwModes;247};248} // namespace llvm249 250#endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_GLOBALISELMATCHTABLEEXECUTOREMITTER_H251