//===- Patterns.h ----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // /// \file Contains the Pattern hierarchy alongside helper classes such as /// PatFrag, MIFlagsInfo, PatternType, etc. /// /// These classes are used by the GlobalISel Combiner backend to help parse, /// process and emit MIR patterns. // //===----------------------------------------------------------------------===// #ifndef LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H #define LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include <memory> #include <optional> #include <string> namespace llvm { class Record; class SMLoc; class StringInit; class CodeExpansions; class CodeGenInstruction; struct CodeGenIntrinsic; namespace gi { class CXXPredicateCode; class LLTCodeGen; class LLTCodeGenOrTempType; class RuleMatcher; //===- PatternType --------------------------------------------------------===// struct VariadicPackTypeInfo { … }; /// Represent the type of a Pattern Operand. /// /// Types have two form: /// - LLTs, which are straightforward. /// - Special types, e.g. GITypeOf, Variadic arguments list. class PatternType { … }; //===- Pattern Base Class -------------------------------------------------===// /// Base class for all patterns that can be written in an `apply`, `match` or /// `pattern` DAG operator. /// /// For example: /// /// (apply (G_ZEXT $x, $y), (G_ZEXT $y, $z), "return isFoo(${z})") /// /// Creates 3 Pattern objects: /// - Two CodeGenInstruction Patterns /// - A CXXPattern class Pattern { … }; //===- AnyOpcodePattern ---------------------------------------------------===// /// `wip_match_opcode` patterns. /// This matches one or more opcodes, and does not check any operands /// whatsoever. /// /// TODO: Long-term, this needs to be removed. It's a hack around MIR /// pattern matching limitations. class AnyOpcodePattern : public Pattern { … }; //===- CXXPattern ---------------------------------------------------------===// /// Represents raw C++ code which may need some expansions. /// /// e.g. [{ return isFooBux(${src}.getReg()); }] /// /// For the expanded code, \see CXXPredicateCode. CXXPredicateCode objects are /// created through `expandCode`. /// /// \see CodeExpander and \see CodeExpansions for more information on code /// expansions. /// /// This object has two purposes: /// - Represent C++ code as a pattern entry. /// - Be a factory for expanded C++ code. /// - It's immutable and only holds the raw code so we can expand the same /// CXX pattern multiple times if we need to. /// /// Note that the code is always trimmed in the constructor, so leading and /// trailing whitespaces are removed. This removes bloat in the output, avoids /// formatting issues, but also allows us to check things like /// `.startswith("return")` trivially without worrying about spaces. class CXXPattern : public Pattern { … }; //===- InstructionPattern ---------------------------------------------===// /// An operand for an InstructionPattern. /// /// Operands are composed of three elements: /// - (Optional) Value /// - (Optional) Name /// - (Optional) Type /// /// Some examples: /// (i32 0):$x -> V=int(0), Name='x', Type=i32 /// 0:$x -> V=int(0), Name='x' /// $x -> Name='x' /// i32:$x -> Name='x', Type = i32 class InstructionOperand { … }; /// Base class for CodeGenInstructionPattern & PatFragPattern, which handles all /// the boilerplate for patterns that have a list of operands for some (pseudo) /// instruction. class InstructionPattern : public Pattern { … }; //===- OperandTable -------------------------------------------------------===// /// Maps InstructionPattern operands to their definitions. This allows us to tie /// different patterns of a (apply), (match) or (patterns) set of patterns /// together. class OperandTable { … }; //===- MIFlagsInfo --------------------------------------------------------===// /// Helper class to contain data associated with a MIFlags operand. class MIFlagsInfo { … }; //===- CodeGenInstructionPattern ------------------------------------------===// /// Matches an instruction or intrinsic: /// e.g. `G_ADD $x, $y, $z` or `int_amdgcn_cos $a` /// /// Intrinsics are just normal instructions with a special operand for intrinsic /// ID. Despite G_INTRINSIC opcodes being variadic, we consider that the /// Intrinsic's info takes priority. This means we return: /// - false for isVariadic() and other variadic-related queries. /// - getNumInstDefs and getNumInstOperands use the intrinsic's in/out /// operands. class CodeGenInstructionPattern : public InstructionPattern { … }; //===- OperandTypeChecker -------------------------------------------------===// /// This is a trivial type checker for all operands in a set of /// InstructionPatterns. /// /// It infers the type of each operand, check it's consistent with the known /// type of the operand, and then sets all of the types in all operands in /// propagateTypes. /// /// It also handles verifying correctness of special types. class OperandTypeChecker { … }; //===- PatFrag ------------------------------------------------------------===// /// Represents a parsed GICombinePatFrag. This can be thought of as the /// equivalent of a CodeGenInstruction, but for PatFragPatterns. /// /// PatFrags are made of 3 things: /// - Out parameters (defs) /// - In parameters /// - A set of pattern lists (alternatives). /// /// If the PatFrag uses instruction patterns, the root must be one of the defs. /// /// Note that this DOES NOT represent the use of the PatFrag, only its /// definition. The use of the PatFrag in a Pattern is represented by /// PatFragPattern. /// /// PatFrags use the term "parameter" instead of operand because they're /// essentially macros, and using that name avoids confusion. Other than that, /// they're structured similarly to a MachineInstruction - all parameters /// (operands) are in the same list, with defs at the start. This helps mapping /// parameters to values, because, param N of a PatFrag is always operand N of a /// PatFragPattern. class PatFrag { … }; //===- PatFragPattern -----------------------------------------------------===// /// Represents a use of a GICombinePatFrag. class PatFragPattern : public InstructionPattern { … }; //===- BuiltinPattern -----------------------------------------------------===// /// Represents builtin instructions such as "GIReplaceReg" and "GIEraseRoot". enum BuiltinKind { … }; class BuiltinPattern : public InstructionPattern { … }; } // namespace gi } // end namespace llvm #endif // LLVM_UTILS_TABLEGEN_COMMON_GLOBALISEL_PATTERNS_H