===============================
How To Use Instruction Mappings
===============================

.. contents::
   :local:

Introduction
============

This document contains information about adding instruction mapping support
for a target. The motivation behind this feature comes from the need to switch
between different instruction formats during various optimizations. One approach
could be to use switch cases which list all the instructions along with formats
they can transition to. However, it has large maintenance overhead
because of the hardcoded instruction names. Also, whenever a new instruction is
added in the .td files, all the relevant switch cases should be modified
accordingly. Instead, the same functionality could be achieved with TableGen and
some support from the .td files for a fraction of maintenance cost.

``InstrMapping`` Class Overview
===============================

TableGen uses relationship models to map instructions with each other. These
models are described using ``InstrMapping`` class as a base. Each model sets
various fields of the ``InstrMapping`` class such that they can uniquely
describe all the instructions using that model. TableGen parses all the relation
models and uses the information to construct relation tables which relate
instructions with each other. These tables are emitted in the
``XXXInstrInfo.inc`` file along with the functions to query them. Following
is the definition of ``InstrMapping`` class definied in Target.td file:

.. code-block:: text

  class InstrMapping {
    // Used to reduce search space only to the instructions using this
    // relation model.
    string FilterClass;

    // List of fields/attributes that should be same for all the instructions in
    // a row of the relation table. Think of this as a set of properties shared
    // by all the instructions related by this relationship.
    list<string> RowFields = [];

    // List of fields/attributes that are same for all the instructions
    // in a column of the relation table.
    list<string> ColFields = [];

    // Values for the fields/attributes listed in 'ColFields' corresponding to
    // the key instruction. This is the instruction that will be transformed
    // using this relation model.
    list<string> KeyCol = [];

    // List of values for the fields/attributes listed in 'ColFields', one for
    // each column in the relation table. These are the instructions a key
    // instruction will be transformed into.
    list<list<string> > ValueCols = [];
  }

Sample Example
--------------

Let's say that we want to have a function
``int getPredOpcode(uint16_t Opcode, enum PredSense inPredSense)`` which
takes a non-predicated instruction and returns its predicated true or false form
depending on some input flag, ``inPredSense``. The first step in the process is
to define a relationship model that relates predicated instructions to their
non-predicated form by assigning appropriate values to the ``InstrMapping``
fields. For this relationship, non-predicated instructions are treated as key
instruction since they are the one used to query the interface function.

.. code-block:: text

  def getPredOpcode : InstrMapping {
    // Choose a FilterClass that is used as a base class for all the
    // instructions modeling this relationship. This is done to reduce the
    // search space only to these set of instructions.
    let FilterClass = "PredRel";

    // Instructions with same values for all the fields in RowFields form a
    // row in the resulting relation table.
    // For example, if we want to relate 'ADD' (non-predicated) with 'Add_pt'
    // (predicated true) and 'Add_pf' (predicated false), then all 3
    // instructions need to have same value for BaseOpcode field. It can be any
    // unique value (Ex: XYZ) and should not be shared with any other
    // instruction not related to 'add'.
    let RowFields = ["BaseOpcode"];

    // List of attributes that can be used to define key and column instructions
    // for a relation. Key instruction is passed as an argument
    // to the function used for querying relation tables. Column instructions
    // are the instructions they (key) can transform into.
    //
    // Here, we choose 'PredSense' as ColFields since this is the unique
    // attribute of the key (non-predicated) and column (true/false)
    // instructions involved in this relationship model.
    let ColFields = ["PredSense"];

    // The key column contains non-predicated instructions.
    let KeyCol = ["none"];

    // Two value columns - first column contains instructions with
    // PredSense=true while second column has instructions with PredSense=false.
    let ValueCols = [["true"], ["false"]];
  }

TableGen uses the above relationship model to emit relation table that maps
non-predicated instructions with their predicated forms. It also outputs the
interface function
``int getPredOpcode(uint16_t Opcode, enum PredSense inPredSense)`` to query
the table. Here, Function ``getPredOpcode`` takes two arguments, opcode of the
current instruction and PredSense of the desired instruction, and returns
predicated form of the instruction, if found in the relation table.
In order for an instruction to be added into the relation table, it needs
to include relevant information in its definition. For example, consider
following to be the current definitions of ADD, ADD_pt (true) and ADD_pf (false)
instructions:

.. code-block:: text

  def ADD : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$a, IntRegs:$b),
              "$dst = add($a, $b)",
              [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$a),
                                             (i32 IntRegs:$b)))]>;

  def ADD_Pt : ALU32_rr<(outs IntRegs:$dst),
                         (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
              "if ($p) $dst = add($a, $b)",
              []>;

  def ADD_Pf : ALU32_rr<(outs IntRegs:$dst),
                         (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
              "if (!$p) $dst = add($a, $b)",
              []>;

In this step, we modify these instructions to include the information
required by the relationship model, <tt>getPredOpcode</tt>, so that they can
be related.

.. code-block:: text

  def ADD : PredRel, ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$a, IntRegs:$b),
              "$dst = add($a, $b)",
              [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$a),
                                             (i32 IntRegs:$b)))]> {
    let BaseOpcode = "ADD";
    let PredSense = "none";
  }

  def ADD_Pt : PredRel, ALU32_rr<(outs IntRegs:$dst),
                         (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
              "if ($p) $dst = add($a, $b)",
              []> {
    let BaseOpcode = "ADD";
    let PredSense = "true";
  }

  def ADD_Pf : PredRel, ALU32_rr<(outs IntRegs:$dst),
                         (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
              "if (!$p) $dst = add($a, $b)",
              []> {
    let BaseOpcode = "ADD";
    let PredSense = "false";
  }

Please note that all the above instructions use ``PredRel`` as a base class.
This is extremely important since TableGen uses it as a filter for selecting
instructions for ``getPredOpcode`` model. Any instruction not derived from
``PredRel`` is excluded from the analysis. ``BaseOpcode`` is another important
field. Since it's selected as a ``RowFields`` of the model, it is required
to have the same value for all 3 instructions in order to be related. Next,
``PredSense`` is used to determine their column positions by comparing its value
with ``KeyCol`` and ``ValueCols``. If an instruction sets its ``PredSense``
value to something not used in the relation model, it will not be assigned
a column in the relation table.
