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