Path: blob/main/contrib/llvm-project/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
35313 views
//===- GlobalISelMatchTableExecutorEmitter.h ------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file9/// This file contains common code related to emitting10/// GIMatchTableExecutor-derived classes.11///12//===----------------------------------------------------------------------===//1314#ifndef LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLEEXECUTOREMITTER_H15#define LLVM_UTILS_TABLEGEN_GLOBALISELMATCHTABLEEXECUTOREMITTER_H1617#include "Common/SubtargetFeatureInfo.h"18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/ADT/Twine.h"21#include <functional>2223namespace llvm {24class CodeGenTarget;2526namespace gi {27class RuleMatcher;28class LLTCodeGen;29class MatchTable;30} // namespace gi3132/// Abstract base class for TableGen backends that emit a33/// `GIMatchTableExecutor`-derived class.34class GlobalISelMatchTableExecutorEmitter {35/// Emits logic to check features required by \p Rules using the3637/// SubtargetFeatures map.38void emitSubtargetFeatureBitsetImpl(raw_ostream &OS,39ArrayRef<gi::RuleMatcher> Rules);4041/// Emits an enum + an array that stores references to42/// \p ComplexOperandMatchers.43void emitComplexPredicates(raw_ostream &OS,44ArrayRef<Record *> ComplexOperandMatchers);4546/// Emits an enum + an array that stores references to47/// \p CustomOperandRenderers.48void emitCustomOperandRenderers(raw_ostream &OS,49ArrayRef<StringRef> CustomOperandRenderers);5051/// Emits an enum + an array to reference \p TypeObjects (LLTs) in the match52/// table.53void emitTypeObjects(raw_ostream &OS, ArrayRef<gi::LLTCodeGen> TypeObjects);5455/// Emits the getMatchTable function which contains all of the match table's56/// opcodes.57void emitMatchTable(raw_ostream &OS, const gi::MatchTable &Table);5859/// Helper function to emit `test` functions for the executor. This emits both60/// an enum to reference predicates in the MatchTable, and a function to61/// switch over the enum & execute the predicate's C++ code.62///63/// \tparam PredicateObject An object representing a predicate to emit.64/// \param OS Output stream65/// \param TypeIdentifier Identifier used for the type of the predicate,66/// e.g. `MI` for MachineInstrs.67/// \param ArgType Full type of the argument, e.g. `const MachineInstr &`68/// \param ArgName Name of the argument, e.g. `MI` for MachineInstrs.69/// \param AdditionalArgs Optional additional argument declarations.70/// \param AdditionalDeclarations Optional declarations to write at the start71/// of the function, before switching over the predicates enum.72/// \param Predicates Predicates to emit.73/// \param GetPredEnumName Returns an enum name for a given predicate.74/// \param GetPredCode Returns the C++ code of a given predicate.75/// \param Comment Optional comment for the enum declaration.76template <typename PredicateObject>77void emitCxxPredicateFns(78raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,79StringRef ArgName, StringRef AdditionalArgs,80StringRef AdditionalDeclarations, ArrayRef<PredicateObject> Predicates,81std::function<StringRef(PredicateObject)> GetPredEnumName,82std::function<StringRef(PredicateObject)> GetPredCode,83StringRef Comment) {84if (!Comment.empty())85OS << "// " << Comment << "\n";86if (!Predicates.empty()) {87OS << "enum {\n";88StringRef EnumeratorSeparator = " = GICXXPred_Invalid + 1,\n";89for (const auto &Pred : Predicates) {90OS << " GICXXPred_" << TypeIdentifier << "_Predicate_"91<< GetPredEnumName(Pred) << EnumeratorSeparator;92EnumeratorSeparator = ",\n";93}94OS << "};\n";95}9697OS << "bool " << getClassName() << "::test" << ArgName << "Predicate_"98<< TypeIdentifier << "(unsigned PredicateID, " << ArgType << " "99<< ArgName << AdditionalArgs << ") const {\n"100<< AdditionalDeclarations;101if (!AdditionalDeclarations.empty())102OS << "\n";103if (!Predicates.empty()) {104OS << " switch (PredicateID) {\n";105for (const auto &Pred : Predicates) {106// Ensure all code is indented.107const auto Code = join(split(GetPredCode(Pred).str(), "\n"), "\n ");108OS << " case GICXXPred_" << TypeIdentifier << "_Predicate_"109<< GetPredEnumName(Pred) << ": {\n"110<< " " << Code << "\n";111if (!StringRef(Code).ltrim().starts_with("return")) {112OS << " llvm_unreachable(\"" << GetPredEnumName(Pred)113<< " should have returned\");\n";114}115OS << " }\n";116}117OS << " }\n";118}119OS << " llvm_unreachable(\"Unknown predicate\");\n"120<< " return false;\n"121<< "}\n";122}123124protected:125/// Emits `testMIPredicate_MI`.126/// \tparam PredicateObject An object representing a predicate to emit.127/// \param OS Output stream128/// \param AdditionalDecls Additional C++ variable declarations.129/// \param Predicates Predicates to emit.130/// \param GetPredEnumName Returns an enum name for a given predicate.131/// \param GetPredCode Returns the C++ code of a given predicate.132/// \param Comment Optional comment for the enum declaration.133template <typename PredicateObject>134void emitMIPredicateFnsImpl(135raw_ostream &OS, StringRef AdditionalDecls,136ArrayRef<PredicateObject> Predicates,137std::function<StringRef(PredicateObject)> GetPredEnumName,138std::function<StringRef(PredicateObject)> GetPredCode,139StringRef Comment = "") {140return emitCxxPredicateFns(141OS, "MI", "const MachineInstr &", "MI", ", const MatcherState &State",142AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);143}144145/// Helper function to emit the following executor functions:146/// * testImmPredicate_I64 (TypeIdentifier=I64)147/// * testImmPredicate_APInt (TypeIdentifier=APInt)148/// * testImmPredicate_APFloat (TypeIdentifier=APFloat)149///150/// \tparam PredicateObject An object representing a predicate to emit.151/// \param OS Output stream152/// \param TypeIdentifier Identifier used for the type of the predicate153/// \param ArgType Full type of the argument154/// \param Predicates Predicates to emit.155/// \param GetPredEnumName Returns an enum name for a given predicate.156/// \param GetPredCode Returns the C++ code of a given predicate.157/// \param Comment Optional comment for the enum declaration.158template <typename PredicateObject>159void emitImmPredicateFnsImpl(160raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,161ArrayRef<PredicateObject> Predicates,162std::function<StringRef(PredicateObject)> GetPredEnumName,163std::function<StringRef(PredicateObject)> GetPredCode,164StringRef Comment = "") {165return emitCxxPredicateFns(OS, TypeIdentifier, ArgType, "Imm", "", "",166Predicates, GetPredEnumName, GetPredCode,167Comment);168}169170GlobalISelMatchTableExecutorEmitter() = default;171172public:173virtual ~GlobalISelMatchTableExecutorEmitter() = default;174175virtual const CodeGenTarget &getTarget() const = 0;176177/// \returns the name of the class being emitted including any prefixes, e.g.178/// `AMDGPUInstructionSelector`.179virtual StringRef getClassName() const = 0;180181/// Emit additional content in emitExecutorImpl182virtual void emitAdditionalImpl(raw_ostream &OS) {}183184/// Emit additional content in emitTemporariesInit.185virtual void emitAdditionalTemporariesInit(raw_ostream &OS) {}186187/// Emit the `testMIPredicate_MI` function.188/// Note: `emitMIPredicateFnsImpl` can be used to do most of the work.189virtual void emitMIPredicateFns(raw_ostream &OS) = 0;190191/// Emit the `testImmPredicate_I64` function.192/// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.193virtual void emitI64ImmPredicateFns(raw_ostream &OS) = 0;194195/// Emit the `testImmPredicate_APFloat` function.196/// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.197virtual void emitAPFloatImmPredicateFns(raw_ostream &OS) = 0;198199/// Emit the `testImmPredicate_APInt` function.200/// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.201virtual void emitAPIntImmPredicateFns(raw_ostream &OS) = 0;202virtual void emitTestSimplePredicate(raw_ostream &OS) = 0;203virtual void emitRunCustomAction(raw_ostream &OS) = 0;204205void emitExecutorImpl(raw_ostream &OS, const gi::MatchTable &Table,206ArrayRef<gi::LLTCodeGen> TypeObjects,207ArrayRef<gi::RuleMatcher> Rules,208ArrayRef<Record *> ComplexOperandMatchers,209ArrayRef<StringRef> CustomOperandRenderers,210StringRef IfDefName);211void emitPredicateBitset(raw_ostream &OS, StringRef IfDefName);212void emitTemporariesDecl(raw_ostream &OS, StringRef IfDefName);213void emitTemporariesInit(raw_ostream &OS, unsigned MaxTemporaries,214StringRef IfDefName);215void emitPredicatesDecl(raw_ostream &OS, StringRef IfDefName);216void emitPredicatesInit(raw_ostream &OS, StringRef IfDefName);217218// Map of predicates to their subtarget features.219SubtargetFeatureInfoMap SubtargetFeatures;220221std::map<std::string, unsigned> HwModes;222};223} // namespace llvm224225#endif226227228