| =============================== | 
 | 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. |