[llvm] [Docs] Describe Tablegen Selection Structures (PR #178518)

Sam Elliott via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 23:47:14 PST 2026


https://github.com/lenary updated https://github.com/llvm/llvm-project/pull/178518

>From 50d4eca46d4f10c6c47bd985703ee25a76103494 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 13:30:43 -0800
Subject: [PATCH 1/6] [Docs] Describe Tablegen Selection Structures

This change adds documentation for some of the advanced parts of
the TableGen Selection structures:
- The `set`, `node` and `srcvalue` special DAG nodes
- The `SDNodeXForm` C++ snippet.
- The `PatFrags` predicate C++ snippet, and documentation for how the
  `OperandTransform` item works in a little more detail.
- The `ImmLeaf` predicate code.
---
 .../include/llvm/Target/TargetSelectionDAG.td | 108 +++++++++++++++++-
 1 file changed, 107 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index b297fd06711a5..c736c5b3afaf5 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -371,11 +371,32 @@ class SDNode<string opcode, SDTypeProfile typeprof,
   bits<32> TSFlags = 0;
 }
 
-// Special TableGen-recognized dag nodes
+/// Special TableGen-recognized dag nodes
+
+// `set` is used to name outputs of a match pattern. For instance, in:
+//   `(set GPR:$out, (add GPR:$in1, GPR:$in2))`.
+//
+// `set` has to be used for patterns defined directly on Instructions, where the
+// `(outs)` have names which need to match something in the pattern.
+//
+// `set` can also be used for Nodes which create multiple values (though chain
+// and glue do not need to be handled with this, and are handled with node
+// properties). A pattern with multiple outputs might look like:
+//   `(set GPR:$RdLo, GPR:$RdHi, (smullohi GPR:$Rn, GPR:$Rm))`
 def set;
+
+// `node` is used when defining pattern fragments, to represent "holes" in the
+// fragment that should be instantated with dags when the fragment is used. For
+// instance in the `def fmul_contract` below.
 def node;
+
+// `srcvalue` is used in patterns when an argument of the pattern is not needed
+// in the result. A named value `ty:$name` could not be used in these cases
+// because all names in the pattern must appear in pattern output dag.
 def srcvalue;
 
+/// dag nodes for specific SDNodes
+
 def imm        : SDNode<"ISD::Constant"  , SDTIntLeaf , [], "ConstantSDNode">;
 def timm       : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">;
 def fpimm      : SDNode<"ISD::ConstantFP", SDTFPLeaf  , [], "ConstantFPSDNode">;
@@ -956,10 +977,30 @@ def SETNE : CondCode<"", "ICMP_NE">;
 // values.
 //
 class SDNodeXForm<SDNode opc, code xformFunction> {
+  // The underlying node type to match and transform.
   SDNode Opcode = opc;
+
+  // This C++ snippet will transform the associated node into a new node.
+  //
+  // The following variables are in scope:
+  // - `<opc.SDClass>* N` representing the node producing the value being
+  //   transformed (already cast to the type of `opc.SDClass`, which is usually
+  //   `SDNode`).
+  // - `SelectionDAG *CurDAG` representing the current DAG (really a member of
+  //   the current DAGToDAGISel instance, documented here because this is how
+  //   new nodes are made).
+  // - `SDValue V` representing the value being transformed (usually accessed
+  //    with `N` instead).
+  // - `GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel instance.
+  //
+  // It should `return` an `SDValue` for the transformation result.
   code XFormFunction = xformFunction;
+
+  // The GlobalISel equivalent is defined using a `GICustomOperandRenderer` and
+  // a `GISDNodeXFormEquiv`.
 }
 
+// The default transform does not change the matched node.
 def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
 
 //===----------------------------------------------------------------------===//
@@ -979,11 +1020,65 @@ def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
 ///
 class PatFrags<dag ops, list<dag> frags, code pred = [{}],
                SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator {
+
+  // Named nested patterns
   dag Operands = ops;
+
+  // The fragment matches *any* pattern in this list that matches. The patterns
+  // in this list should contain references to the named nested patterns in
+  // `ops`.
   list<dag> Fragments = frags;
+
+  // This C++ snippet will be run against a matched node to ensure that it was
+  // intended to match. Some Predicates don't use this snippet and instead use
+  // the `bit`s below to generate the right C++.
+  //
+  // The following variables are in scope:
+  // - `SDNode *N` representing the node being checked. This might actually be
+  //   of a more specific SDNode type - derived from the head nodes of the
+  //   fragments.
+  // - `ArrayRef<SDValue> Operands` representing the operands, only if
+  //   `PredicateCodeUsesOperands` (below) is true.
+  // - `SDValue Op` representing the value being checked (usually accessed with
+  //   `N` instead).
+  // - `const GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel
+  //   instance.
+  //
+  // This should `return` a `bool` for whether the predicate matches or not.
   code PredicateCode = pred;
+
+  // The equivalent of `PredicateCode` for GlobalISel.
+  //
+  // The following variables are in scope:
+  // - `const MachineInstr &MI` representing the MI being checked.
+  // - `std::array<const MachineOperand *, _>` representing the operands of the
+  //   current fragment.
+  // - `const MachineFunction &MF` the current function.
+  // - `const MachineRegisterInfo &MRI` for the current function.
+  // - `const <target>InstructionSelector *this` representing the target's
+  //   `InstructionSelector` instance.
+  // - `const MatcherState &State`
+  //
+  // This should `return` a `bool` for whether the predicate matches or not.
   code GISelPredicateCode = [{}];
+
+  // Specific C++ Checks for Immediate Values. This code is shared between
+  // SDISel and GlobalISel. See `ImmLeaf` below.
+  //
+  // The following variables are in scope:
+  // - `int64_t Imm` representing the value of the immediate.
+  //
+  // This should return a `bool` for whether the predicate matches or not.
   code ImmediateCode = [{}];
+
+  // After this node is matched as `NAME:$val`, `$val` is stored so it can be
+  // used later in the pattern result. This implicit transform means that `$val`
+  // will store the result of transforming the node, instead of the original
+  // node.
+  //
+  // PatFrags with OperandTransforms are most useful when defining a pattern
+  // directly on an instruction, where the transform cannot be written on the
+  // output of the pattern (which is implicit).
   SDNodeXForm OperandTransform = xform;
 
   // When this is set, the PredicateCode may refer to a constant Operands
@@ -1106,7 +1201,18 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
 class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
               SDNode ImmNode = imm>
   : PatFrag<(ops), (vt ImmNode), [{}], xform> {
+
+  // Specific C++ Checks for Immediate Values. This code is shared between
+  // SDISel and GlobalISel.
+  //
+  // The following variables are in scope:
+  // - `Imm` representing the sign-extended value of the immediate. This might
+  //   be an APInt, an APFloat, or a sign-extended int64_t, depending on the
+  //   `IsAPInt` and `IsAPFloat` fields below.
+  //
+  // This should return a `bool` for whether the predicate matches or not.
   let ImmediateCode = pred;
+
   bit FastIselShouldIgnore = false;
 
   // Is the data type of the immediate an APInt?

>From a66e3fc15488d36af4749d34b704f82c2162dd8d Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 14:56:12 -0800
Subject: [PATCH 2/6] Review Suggestions

---
 .../include/llvm/Target/TargetSelectionDAG.td | 29 ++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index c736c5b3afaf5..0979eda438b73 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -386,7 +386,7 @@ class SDNode<string opcode, SDTypeProfile typeprof,
 def set;
 
 // `node` is used when defining pattern fragments, to represent "holes" in the
-// fragment that should be instantated with dags when the fragment is used. For
+// fragment that should be instantiated with dags when the fragment is used. For
 // instance in the `def fmul_contract` below.
 def node;
 
@@ -1185,15 +1185,15 @@ class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
 }
 
 
-// ImmLeaf is a pattern fragment with a constraint on the immediate.  The
-// constraint is a function that is run on the immediate (always with the value
-// sign extended out to an int64_t) as Imm.  For example:
+// ImmLeaf is a pattern fragment for immediates that match a constraint.  The
+// constraint is a C++ snippet that is run on the immediate (always with the
+// value sign extended out to an int64_t) as Imm.  For example:
 //
 //  def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>;
 //
 // this is a more convenient form to match 'imm' nodes in than PatLeaf and also
 // is preferred over using PatLeaf because it allows the code generator to
-// reason more about the constraint.
+// reason more about the constraint, and port the constraint to GlobalISel.
 //
 // If FastIsel should ignore all instructions that have an operand of this type,
 // the FastIselShouldIgnore flag can be set.  This is an optimization to reduce
@@ -1202,13 +1202,12 @@ class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
               SDNode ImmNode = imm>
   : PatFrag<(ops), (vt ImmNode), [{}], xform> {
 
-  // Specific C++ Checks for Immediate Values. This code is shared between
-  // SDISel and GlobalISel.
+  // Specific C++ Check for the Immediate Values.
   //
   // The following variables are in scope:
-  // - `Imm` representing the sign-extended value of the immediate. This might
-  //   be an APInt, an APFloat, or a sign-extended int64_t, depending on the
-  //   `IsAPInt` and `IsAPFloat` fields below.
+  // - `Imm` representing the value of the immediate. The type of this variable
+  //   depends on whether you are instantiating a `ImmLeaf`, a `IntImmLeaf`, or
+  //   a `FPImmLeaf`.
   //
   // This should return a `bool` for whether the predicate matches or not.
   let ImmediateCode = pred;
@@ -1224,11 +1223,15 @@ class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
 
 // Convenience wrapper for ImmLeaf to use timm/TargetConstant instead
 // of imm/Constant.
+//
+// `Imm` in the snippet is the value sign-extended to `int64_t`.
 class TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm,
   SDNode ImmNode = timm> : ImmLeaf<vt, pred, xform, ImmNode>;
 
-// An ImmLeaf except that Imm is an APInt. This is useful when you need to
-// zero-extend the immediate instead of sign-extend it.
+// An ImmLeaf where the `Imm` in the C++ predicate is an `APInt`.
+//
+// This is useful when you need to zero-extend the immediate instead of
+// sign-extend it, or when the value does not fit into an `int64_t`.
 //
 // Note that FastISel does not currently understand IntImmLeaf and will not
 // generate code for rules that make use of it. As such, it does not make sense
@@ -1240,7 +1243,7 @@ class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm>
   let FastIselShouldIgnore = true;
 }
 
-// An ImmLeaf except that Imm is an APFloat.
+// An ImmLeaf where the `Imm` in the C++ predicate is an `APFloat`.
 //
 // Note that FastISel does not currently understand FPImmLeaf and will not
 // generate code for rules that make use of it.

>From 7d98e734ec242ec3c1e58f24494b503c16643952 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 15:21:20 -0800
Subject: [PATCH 3/6] Add docs for PatLeaf.GISelLeafPredicateCode

---
 .../include/llvm/Target/TargetSelectionDAG.td | 21 +++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 0979eda438b73..25cd2418cc5be 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1050,14 +1050,13 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
   // The equivalent of `PredicateCode` for GlobalISel.
   //
   // The following variables are in scope:
-  // - `const MachineInstr &MI` representing the MI being checked.
-  // - `std::array<const MachineOperand *, _>` representing the operands of the
-  //   current fragment.
+  // - `const MachineInstr &MI` representing the instruction being checked.
   // - `const MachineFunction &MF` the current function.
   // - `const MachineRegisterInfo &MRI` for the current function.
   // - `const <target>InstructionSelector *this` representing the target's
   //   `InstructionSelector` instance.
   // - `const MatcherState &State`
+  // - `std::array<const MachineOperand *, _> Operands`
   //
   // This should `return` a `bool` for whether the predicate matches or not.
   code GISelPredicateCode = [{}];
@@ -1180,7 +1179,21 @@ class OutPatFrag<dag ops, dag frag>
 // PatLeaf's are pattern fragments that have no operands.  This is just a helper
 // to define immediates and other common things concisely.
 class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm>
- : PatFrag<(ops), frag, pred, xform> {
+  : PatFrag<(ops), frag, pred, xform> {
+
+  // The equivalent of `PredicateCode` for GlobalISel. Unlike with `PatFrag`,
+  // this is examining a `MachineOperand` rather than a `MachineInstruction`.
+  //
+  // The following variables are in scope:
+  // - `const MachineOperand &MO` representing the Operand being checked.
+  // - `const MachineFunction &MF` the current function.
+  // - `const MachineRegisterInfo &MRI` for the current function.
+  // - `const <target>InstructionSelector *this` representing the target's
+  //   `InstructionSelector` instance.
+  // - `const MatcherState &State`
+  // - `std::array<const MachineOperand *, _> Operands`
+  //
+  // This should `return` a `bool` for whether the predicate matches or not.
   code GISelLeafPredicateCode = ?;
 }
 

>From 22d286be647f103c8effee48a92877be3740176e Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Wed, 28 Jan 2026 22:14:54 -0800
Subject: [PATCH 4/6] Document how to bind when the fragment has nested
 patterns

---
 llvm/include/llvm/Target/TargetSelectionDAG.td | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 25cd2418cc5be..28908ed65a6a0 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1070,10 +1070,14 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
   // This should return a `bool` for whether the predicate matches or not.
   code ImmediateCode = [{}];
 
-  // After this node is matched as `NAME:$val`, `$val` is stored so it can be
-  // used later in the pattern result. This implicit transform means that `$val`
-  // will store the result of transforming the node, instead of the original
-  // node.
+  // When a node is matched as `frag:$name`, the matched node is bound to
+  // `$name` so it can be used in the pattern result. This implicit transform
+  // means that `$name` will store the result of transforming the matched node,
+  // instead of the original node.
+  //
+  // The syntax for binding in a pattern can be:
+  // - `(frag:$name <patterns...>)` when `frag` has nested patterns
+  // - `frag:$name` when `frag` is a `PatLeaf` (no nested patterns)
   //
   // PatFrags with OperandTransforms are most useful when defining a pattern
   // directly on an instruction, where the transform cannot be written on the

>From 25c8b1bf5a45ffb588c8773fd156d330fe79a395 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Fri, 30 Jan 2026 13:22:16 -0800
Subject: [PATCH 5/6] Add docs for ComplexPattern

---
 .../include/llvm/Target/TargetSelectionDAG.td | 40 +++++++++++++++----
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index 28908ed65a6a0..12ecb59de5717 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1065,7 +1065,8 @@ class PatFrags<dag ops, list<dag> frags, code pred = [{}],
   // SDISel and GlobalISel. See `ImmLeaf` below.
   //
   // The following variables are in scope:
-  // - `int64_t Imm` representing the value of the immediate.
+  // - `Imm` representing the value of the immediate. The type of `Imm` depends
+  //   on what kind of `ImmLeaf` is being instantiated.
   //
   // This should return a `bool` for whether the predicate matches or not.
   code ImmediateCode = [{}];
@@ -2388,20 +2389,42 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
 //
 
 // Complex patterns, e.g. X86 addressing mode, requires pattern matching code
-// in C++. Ty is the type of return value; NumOperands is the number of operands
-// returned by the select function; SelectFunc is the name of the function used
-// to pattern match the max. pattern; RootNodes are the list of possible root nodes
-// of the sub-dags to match.
-// e.g. X86 addressing mode - def addr : ComplexPattern<iPTR, 4, "SelectAddr", [add]>;
-//
+// in C++: def addr : ComplexPattern<iPTR, 4, "SelectAddr", [add]>;
 class ComplexPattern<ValueType ty, int numops, string fn,
                      list<SDNode> roots = [], list<SDNodeProperty> props = [],
                      int complexity = -1> {
+
+  // Type of the return value of the Pattern
   ValueType Ty = ty;
+
+  // Number of operands returned by select function
   int NumOperands = numops;
+
+  // Name of the select function in C++ used to pattern match. This should be
+  // defined on your `GET_DAGISEL_BODY` class (usually the DAGToDAGISel class
+  // for your target).
+  //
+  // The arguments to this function are:
+  // - `SDValue Root` for the root of the match if `WantsRoot` is true
+  // - `SDValue *Parent` for the parent of the operand, if `WantsParent` is
+  //   true. This may be null if `N` is the root node.
+  // - `SDValue N` for the value being matched
+  // - one `SDValue &Out` for each operand returned
+  // - `SDValue &OutChain` for the output chain if `SDNPHasChain` is in `Properties`.
+  //
+  // This function should return a `bool` representing whether the pattern
+  // matched or not.
   string SelectFunc = fn;
+
+  // The list of possible root nodes of the sub-dags to match
   list<SDNode> RootNodes = roots;
+
+  // These properties are used to verify that the result instruction has similar
+  // properties to the pattern.
   list<SDNodeProperty> Properties = props;
+
+  // Complexity of this pattern relative to others. Patterns with higher
+  // complexity are matched before those with lower complexity.
   int Complexity = complexity;
 
   // Set this to true if SelectFunc wants an additional argument
@@ -2411,4 +2434,7 @@ class ComplexPattern<ValueType ty, int numops, string fn,
   // Set this to true if SelectFunc wants an additional argument
   // that is the parent of the matched node.
   bit WantsParent = false;
+
+  // The GlobalISel equivalent is defined using a `GIComplexOperandMatcher` and
+  // a `GIComplexPatternEquiv`.
 }

>From c3e100bdd42b80b997950994102978fc19b73f01 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Tue, 10 Feb 2026 23:46:57 -0800
Subject: [PATCH 6/6] Add more Method/Code Docs

---
 llvm/include/llvm/Target/Target.td | 126 +++++++++++++++++++++++++----
 1 file changed, 112 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 3d3cfe6948ded..9b3b4509da6bd 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -254,7 +254,24 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
 // RegisterClass's and other Operand's.
 class DAGOperand {
   string OperandNamespace = "MCOI";
+
+  // Per-operand equivalent of InstructionEncoding's `DecoderMethod`.
+  //
+  // This will be called with one of the following signatures:
+  // ```
+  //   // If the operand is decoded from a field in the instruction. `TmpType`
+  //   // will either be the same as `InsnType` (if it's integral), or it will
+  //   // be `uint64_t`. `InsnType` is templated type the generated
+  //   // `decodeToMCInst` is used with.
+  //   DecodeStatus DecoderMethod(MCInst &Inst, TmpType Field, int64_t Address,
+  //                              const MCDisassembler *Decoder)
+  //   // If the operand does not appear in the instruction encoding
+  //   DecodeStatus DecoderMethod(MCInst &Inst, const MCDisassembler *Decoder)
+  // ```
   string DecoderMethod = "";
+
+  // Operand equivalent of InstructionEncoding's `hasCompleteDecoder`; if this
+  // is true, then other instructions will be tried before decoding fails.
   bit hasCompleteDecoder = true;
 }
 
@@ -560,6 +577,18 @@ class InstructionEncoding {
   // List of predicates which will be turned into isel matching code.
   list<Predicate> Predicates = [];
 
+  // The name of a custom C++ decoder method to use to decode this instruction.
+  //
+  // If the instruction has a `DecoderMethod`, then the fields for its operands
+  // are not automatically decoded, and the decoder method is responsible for
+  // constructing all the MCInst's operands.
+  //
+  // Will be called with the following signature (where `InsnType` is the
+  // template type that `decodeToMCInst` is called with):
+  // ```
+  //   DecodeStatus DecoderMethod(MCInst &Inst, InsnType insn, int64_t Address,
+  //                              const MCDisassembler *Decoder)
+  // ```
   string DecoderMethod = "";
 
   // Is the instruction decoder method able to completely determine if the
@@ -747,6 +776,14 @@ class Instruction : InstructionEncoding {
   ///   discussion of inline assembly constraint strings.
   string Constraints = "";
 
+  /// This is used by `getBinaryCodeForInstr` to fixup the instruction encoding
+  /// for the instruction.
+  /// It is called with the following signature, expecting to return the new
+  /// value of `Value`, after the operand has been encoded into `Value`:
+  /// ```
+  ///   InstType = PostEncoderMethod(const MCInst &MI, InstType Value,
+  ///                                const MCSubtargetInfo &STI);
+  /// ```
   string PostEncoderMethod = "";
 
   /// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.
@@ -755,6 +792,14 @@ class Instruction : InstructionEncoding {
   ///@name Assembler Parser Support
   ///@{
 
+  /// Custom Assembly Converter. If non-zero, this is used for converting the
+  /// matched mnemonic's operand tokens into MCOperands and adding them to the
+  /// MCInst.
+  ///
+  /// Will be called as:
+  /// `void AsmMatchConverter(MCInst &Inst, const OperandVector &Operands);`
+  ///
+  /// See also: InstAlias.UseInstAsmMatchConverter.
   string AsmMatchConverter = "";
 
   /// TwoOperandAliasConstraint - Enable TableGen to auto-generate a
@@ -828,8 +873,15 @@ class PseudoInstExpansion<dag Result> {
 
 /// Predicates - These are extra conditionals which are turned into instruction
 /// selector matching code. Currently each predicate is just a string.
-class Predicate<string cond> {
-  string CondString = cond;
+class Predicate<code cond> {
+
+  /// This is a C++ expression which can be evaluated to return a bool,
+  /// representing whether the predicate is satisifed.
+  ///
+  /// The following variables are in scope:
+  /// - `const GET_DAGISEL_BODY *this` representing the target's DAGToDAGISel
+  ///   instance.
+  code CondString = cond;
 
   /// AssemblerMatcherPredicate - If this feature can be used by the assembler
   /// matcher, this is true. Targets should set this by inheriting their
@@ -989,7 +1041,9 @@ class AsmOperandClass {
   /// The name of the method on the target specific operand to call to custom
   /// handle the operand parsing. This is useful when the operands do not relate
   /// to immediates or registers and are very instruction specific (as flags to
-  /// set in a processor register, coprocessor number, ...).
+  /// set in a processor register, coprocessor number, ...). The method
+  /// signature should be:
+  ///   ParseStatus ParserMethod(OperandVector &Operands);
   string ParserMethod = ?;
 
   // The diagnostic type to present when referencing this operand in a
@@ -1025,14 +1079,41 @@ def ImmAsmOperand : AsmOperandClass {
 /// needed, though this should not be needed for RISC targets.
 class Operand<ValueType ty> : DAGOperand {
   ValueType Type = ty;
+
+  // Custom method for printing the current operand.
+  //
+  // This will be invoked with the following signature, on the class denoted
+  // by `TargetName # AsmWriter.AsmWriterClassName`
+  // ```
+  //   void Class::PrintMethod(const MCInst *MI, unsigned OpNo,
+  //                           const MCSubtargetInfo &STI, raw_ostream &O);
+  // ```
   string PrintMethod = "printOperand";
+
+  /// This method will be used to encode the operand into bits, which will be
+  /// placed into the final instruction according to the Encoding information.
+  ///
+  /// This will be called with the following signature:
+  /// ```
+  ///   uint64_t MCCodeEmitter::EncoderMethod(const MCInst &MI, unsigned OpNo,
+  ///                                         SmallVectorImpl<MCFixup> &Fixups,
+  ///                                         const MCSubtargetInfo &STI) const;
+  /// ```
   string EncoderMethod = "";
+
   string OperandType = "OPERAND_UNKNOWN";
+
+  /// This operand may have sub-operands. Their use is complex, but this is
+  /// where they would be described.
   dag MIOperandInfo = (ops);
 
-  // MCOperandPredicate - Optionally, a code fragment operating on
-  // const MCOperand &MCOp, and returning a bool, to indicate if
-  // the value of MCOp is valid for the specific subclass of Operand
+  // MCOperandPredicate - Optionally, a C++ fragment returning a bool to
+  // indicate if the value of the operand is valid for this specific subclass of
+  // Operand.
+  //
+  // The following variables are in scope:
+  // - `const MCOperand &MCOp` representing the current Operand
+  // - `const MCSubtargetInfo &STI` representing the current subtarget.
   code MCOperandPredicate;
 
   // ParserMatchClass - The "match class" that operands of this type fit
@@ -1050,13 +1131,14 @@ class RegisterOperand<RegisterClassLike regclass, string pm = "printOperand">
   : DAGOperand {
   // RegClass - The register class of the operand.
   RegisterClassLike RegClass = regclass;
+
   // PrintMethod - The target method to call to print register operands of
   // this type. The method normally will just use an alt-name index to look
   // up the name to print. Default to the generic printOperand().
   string PrintMethod = pm;
 
   // EncoderMethod - The target method name to call to encode this register
-  // operand.
+  // operand. See `Operand.EncoderMethod`.
   string EncoderMethod = "";
 
   // ParserMatchClass - The "match class" that operands of this type fit
@@ -1699,6 +1781,11 @@ class AsmParser {
   // AsmParserInstCleanup - If non-empty, this is the name of a custom member
   // function of the AsmParser class to call on every matched instruction.
   // This can be used to perform target specific instruction post-processing.
+  //
+  // This will be invoked with the following signature:
+  // ```
+  //   void AsmParserInstCleanup(MCInst &Inst);
+  // ```
   string AsmParserInstCleanup  = "";
 
   // ShouldEmitMatchRegisterName - Set to false if the target needs a hand
@@ -1734,8 +1821,16 @@ class AsmParser {
   bit ReportMultipleNearMisses = false;
 
   // OperandParserMethod - If non-empty, this is the name of a custom
-  // member function of the AsmParser class to call for every instruction
-  // operand to be parsed.
+  // member function of the AsmParser class to call for every custom instruction
+  // operand to be parsed. If unset, this defaults to calling the generated
+  // `tryCustomParseOperand` implementation.
+  //
+  // This will be invoked with the following signature, on the target's
+  // `AsmParser` subclass. The `MCK` operand represents the generated
+  // Match Class Kind.
+  // ```
+  //   ParseStatus OperandParserMethod(OperandVector &Operands, unsigned MCK);
+  // ```
   string OperandParserMethod = "";
 
   // CallCustomParserForAllOperands - Set to true if the custom parser
@@ -1745,15 +1840,15 @@ class AsmParser {
 
   // PreferSmallerInstructions - Should the assembly matcher prefer the smaller
   // instructions.
-  // 
+  //
   // This is useful for the ARM instructions set where smaller encodings must
   // be preferentially selected.
   //
-  // The preference order is: 
+  // The preference order is:
   //    Instrution size (if this option is enabled, smallest first)
-  //    Number of Operands (least first), 
-  //    Operand Classes (lexicographically by operand), 
-  //    (Optional) Instruction id (see AsmMatcherEmitter.cpp for details), 
+  //    Number of Operands (least first),
+  //    Operand Classes (lexicographically by operand),
+  //    (Optional) Instruction id (see AsmMatcherEmitter.cpp for details),
   //    Number of required features (least first)
   bit PreferSmallerInstructions = false;
 }
@@ -1802,8 +1897,11 @@ def all_of;
 /// AssemblerPredicate - This is a Predicate that can be used when the assembler
 /// matches instructions and aliases.
 class AssemblerPredicate<dag cond, string name = ""> {
+  // See `Predicate.AssemblerMatcherPredicate`
   bit AssemblerMatcherPredicate = true;
+  // See: Predicate.AssemblerCondDag`
   dag AssemblerCondDag = cond;
+  // See: Predicate.PredicateName
   string PredicateName = name;
 }
 



More information about the llvm-commits mailing list