1*0fca6ea1SDimitry Andric //===- PatternParser.h ------------------------------------------*- C++ -*-===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric /// \file Contains tools to parse MIR patterns from TableGen DAG elements. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_GLOBALISEL_PATTERNPARSER_H 14*0fca6ea1SDimitry Andric #define LLVM_UTILS_GLOBALISEL_PATTERNPARSER_H 15*0fca6ea1SDimitry Andric 16*0fca6ea1SDimitry Andric #include "llvm/ADT/ArrayRef.h" 17*0fca6ea1SDimitry Andric #include "llvm/ADT/STLFunctionalExtras.h" 18*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 19*0fca6ea1SDimitry Andric #include "llvm/Support/SMLoc.h" 20*0fca6ea1SDimitry Andric #include <memory> 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric namespace llvm { 23*0fca6ea1SDimitry Andric class CodeGenTarget; 24*0fca6ea1SDimitry Andric class DagInit; 25*0fca6ea1SDimitry Andric class Init; 26*0fca6ea1SDimitry Andric class Record; 27*0fca6ea1SDimitry Andric class StringRef; 28*0fca6ea1SDimitry Andric class StringInit; 29*0fca6ea1SDimitry Andric 30*0fca6ea1SDimitry Andric namespace gi { 31*0fca6ea1SDimitry Andric class InstructionPattern; 32*0fca6ea1SDimitry Andric class Pattern; 33*0fca6ea1SDimitry Andric class PatFrag; 34*0fca6ea1SDimitry Andric 35*0fca6ea1SDimitry Andric /// Helper class to parse MIR Pattern lists. 36*0fca6ea1SDimitry Andric /// 37*0fca6ea1SDimitry Andric /// e.g., `(match (G_FADD $x, $y, $z), (G_FNEG $y, $z))` 38*0fca6ea1SDimitry Andric class PatternParser { 39*0fca6ea1SDimitry Andric const CodeGenTarget &CGT; 40*0fca6ea1SDimitry Andric ArrayRef<SMLoc> DiagLoc; 41*0fca6ea1SDimitry Andric 42*0fca6ea1SDimitry Andric mutable SmallPtrSet<const PatFrag *, 2> SeenPatFrags; 43*0fca6ea1SDimitry Andric 44*0fca6ea1SDimitry Andric public: 45*0fca6ea1SDimitry Andric PatternParser(const CodeGenTarget &CGT, ArrayRef<SMLoc> DiagLoc) 46*0fca6ea1SDimitry Andric : CGT(CGT), DiagLoc(DiagLoc) {} 47*0fca6ea1SDimitry Andric 48*0fca6ea1SDimitry Andric /// Parses a list of patterns such as: 49*0fca6ea1SDimitry Andric /// (Operator (Pattern1 ...), (Pattern2 ...)) 50*0fca6ea1SDimitry Andric /// \param List DagInit of the expected pattern list. 51*0fca6ea1SDimitry Andric /// \param ParseAction Callback to handle a succesfully parsed pattern. 52*0fca6ea1SDimitry Andric /// \param Operator The name of the operator, e.g. "match" 53*0fca6ea1SDimitry Andric /// \param AnonPatNamePrefix Prefix for anonymous pattern names. 54*0fca6ea1SDimitry Andric /// \return true on success, false on failure. 55*0fca6ea1SDimitry Andric bool 56*0fca6ea1SDimitry Andric parsePatternList(const DagInit &List, 57*0fca6ea1SDimitry Andric function_ref<bool(std::unique_ptr<Pattern>)> ParseAction, 58*0fca6ea1SDimitry Andric StringRef Operator, StringRef AnonPatNamePrefix); 59*0fca6ea1SDimitry Andric 60*0fca6ea1SDimitry Andric /// \returns all PatFrags encountered by this PatternParser. 61*0fca6ea1SDimitry Andric const auto &getSeenPatFrags() const { return SeenPatFrags; } 62*0fca6ea1SDimitry Andric 63*0fca6ea1SDimitry Andric private: 64*0fca6ea1SDimitry Andric /// Parse any InstructionPattern from a TableGen Init. 65*0fca6ea1SDimitry Andric /// \param Arg Init to parse. 66*0fca6ea1SDimitry Andric /// \param PatName Name of the pattern that will be parsed. 67*0fca6ea1SDimitry Andric /// \return the parsed pattern on success, nullptr on failure. 68*0fca6ea1SDimitry Andric std::unique_ptr<Pattern> parseInstructionPattern(const Init &Arg, 69*0fca6ea1SDimitry Andric StringRef PatName); 70*0fca6ea1SDimitry Andric 71*0fca6ea1SDimitry Andric /// Parse a WipOpcodeMatcher from a TableGen Init. 72*0fca6ea1SDimitry Andric /// \param Arg Init to parse. 73*0fca6ea1SDimitry Andric /// \param PatName Name of the pattern that will be parsed. 74*0fca6ea1SDimitry Andric /// \return the parsed pattern on success, nullptr on failure. 75*0fca6ea1SDimitry Andric std::unique_ptr<Pattern> parseWipMatchOpcodeMatcher(const Init &Arg, 76*0fca6ea1SDimitry Andric StringRef PatName); 77*0fca6ea1SDimitry Andric 78*0fca6ea1SDimitry Andric /// Parses an Operand of an InstructionPattern from a TableGen Init. 79*0fca6ea1SDimitry Andric /// \param IP InstructionPattern for which we're parsing. 80*0fca6ea1SDimitry Andric /// \param OpInit Init to parse. 81*0fca6ea1SDimitry Andric /// \param OpName Name of the operand to parse. 82*0fca6ea1SDimitry Andric /// \return true on success, false on failure. 83*0fca6ea1SDimitry Andric bool parseInstructionPatternOperand(InstructionPattern &IP, 84*0fca6ea1SDimitry Andric const Init *OpInit, 85*0fca6ea1SDimitry Andric const StringInit *OpName); 86*0fca6ea1SDimitry Andric 87*0fca6ea1SDimitry Andric /// Parses a MIFlag for an InstructionPattern from a TableGen Init. 88*0fca6ea1SDimitry Andric /// \param IP InstructionPattern for which we're parsing. 89*0fca6ea1SDimitry Andric /// \param Op Init to parse. 90*0fca6ea1SDimitry Andric /// \return true on success, false on failure. 91*0fca6ea1SDimitry Andric bool parseInstructionPatternMIFlags(InstructionPattern &IP, 92*0fca6ea1SDimitry Andric const DagInit *Op); 93*0fca6ea1SDimitry Andric 94*0fca6ea1SDimitry Andric /// (Uncached) PatFrag parsing implementation. 95*0fca6ea1SDimitry Andric /// \param Def PatFrag def to parsee. 96*0fca6ea1SDimitry Andric /// \return the parsed PatFrag on success, nullptr on failure. 97*0fca6ea1SDimitry Andric std::unique_ptr<PatFrag> parsePatFragImpl(const Record *Def); 98*0fca6ea1SDimitry Andric 99*0fca6ea1SDimitry Andric /// Parses the in or out parameter list of a PatFrag. 100*0fca6ea1SDimitry Andric /// \param OpsList Init to parse. 101*0fca6ea1SDimitry Andric /// \param ParseAction Callback on successful parse, with the name of 102*0fca6ea1SDimitry Andric /// the parameter and its \ref PatFrag::ParamKind 103*0fca6ea1SDimitry Andric /// \return true on success, false on failure. 104*0fca6ea1SDimitry Andric bool 105*0fca6ea1SDimitry Andric parsePatFragParamList(const DagInit &OpsList, 106*0fca6ea1SDimitry Andric function_ref<bool(StringRef, unsigned)> ParseAction); 107*0fca6ea1SDimitry Andric 108*0fca6ea1SDimitry Andric /// Cached PatFrag parser. This avoids duplicate work by keeping track of 109*0fca6ea1SDimitry Andric /// already-parsed PatFrags. 110*0fca6ea1SDimitry Andric /// \param Def PatFrag def to parsee. 111*0fca6ea1SDimitry Andric /// \return the parsed PatFrag on success, nullptr on failure. 112*0fca6ea1SDimitry Andric const PatFrag *parsePatFrag(const Record *Def); 113*0fca6ea1SDimitry Andric }; 114*0fca6ea1SDimitry Andric 115*0fca6ea1SDimitry Andric } // namespace gi 116*0fca6ea1SDimitry Andric } // namespace llvm 117*0fca6ea1SDimitry Andric 118*0fca6ea1SDimitry Andric #endif 119