llvm.org GIT mirror llvm / becdf4d
add TableGen support to create relationship maps between instructions Relationship maps are represented as InstrMapping records which are parsed by TableGen and the information is used to construct mapping tables to represent appropriate relations between instructions. These tables are emitted into XXXGenInstrInfo.inc file along with the functions to query them. Patch by Jyotsna Verma <jverma@codeaurora.org>. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166685 91177308-0d34-0410-b5e6-96231b3b80d8 Sebastian Pop 8 years ago
6 changed file(s) with 864 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 .. _how_to_use_instruction_mappings:
1
2 ===============================
3 How To Use Instruction Mappings
4 ===============================
5
6 .. sectionauthor:: Jyotsna Verma
7
8 .. contents::
9 :local:
10
11 Introduction
12 ============
13
14 This document contains information about adding instruction mapping support
15 for a target. The motivation behind this feature comes from the need to switch
16 between different instruction formats during various optimizations. One approach
17 could be to use switch cases which list all the instructions along with formats
18 they can transition to. However, it has large maintenance overhead
19 because of the hardcoded instruction names. Also, whenever a new instruction is
20 added in the .td files, all the relevant switch cases should be modified
21 accordingly. Instead, the same functionality could be achieved with TableGen and
22 some support from the .td files for a fraction of maintenance cost.
23
24 ``InstrMapping`` Class Overview
25 ===============================
26
27 TableGen uses relationship models to map instructions with each other. These
28 models are described using ``InstrMapping`` class as a base. Each model sets
29 various fields of the ``InstrMapping`` class such that they can uniquely
30 describe all the instructions using that model. TableGen parses all the relation
31 models and uses the information to construct relation tables which relate
32 instructions with each other. These tables are emitted in the
33 ``XXXInstrInfo.inc`` file along with the functions to query them. Following
34 is the definition of ``InstrMapping`` class definied in Target.td file:
35
36 .. code-block:: llvm
37
38 class InstrMapping {
39 // Used to reduce search space only to the instructions using this
40 // relation model.
41 string FilterClass;
42
43 // List of fields/attributes that should be same for all the instructions in
44 // a row of the relation table. Think of this as a set of properties shared
45 // by all the instructions related by this relationship.
46 list RowFields = [];
47
48 // List of fields/attributes that are same for all the instructions
49 // in a column of the relation table.
50 list ColFields = [];
51
52 // Values for the fields/attributes listed in 'ColFields' corresponding to
53 // the key instruction. This is the instruction that will be transformed
54 // using this relation model.
55 list KeyCol = [];
56
57 // List of values for the fields/attributes listed in 'ColFields', one for
58 // each column in the relation table. These are the instructions a key
59 // instruction will be transformed into.
60 list > ValueCols = [];
61 }
62
63 Sample Example
64 --------------
65
66 Let's say that we want to have a function
67 ``int getPredOpcode(uint16_t Opcode, enum PredSense inPredSense)`` which
68 takes a non-predicated instruction and returns its predicated true or false form
69 depending on some input flag, ``inPredSense``. The first step in the process is
70 to define a relationship model that relates predicated instructions to their
71 non-predicated form by assigning appropriate values to the ``InstrMapping``
72 fields. For this relationship, non-predicated instructions are treated as key
73 instruction since they are the one used to query the interface function.
74
75 .. code-block:: llvm
76
77 def getPredOpcode : InstrMapping {
78 // Choose a FilterClass that is used as a base class for all the
79 // instructions modeling this relationship. This is done to reduce the
80 // search space only to these set of instructions.
81 let FilterClass = "PredRel";
82
83 // Instructions with same values for all the fields in RowFields form a
84 // row in the resulting relation table.
85 // For example, if we want to relate 'ADD' (non-predicated) with 'Add_pt'
86 // (predicated true) and 'Add_pf' (predicated false), then all 3
87 // instructions need to have same value for BaseOpcode field. It can be any
88 // unique value (Ex: XYZ) and should not be shared with any other
89 // instruction not related to 'add'.
90 let RowFields = ["BaseOpcode"];
91
92 // List of attributes that can be used to define key and column instructions
93 // for a relation. Key instruction is passed as an argument
94 // to the function used for querying relation tables. Column instructions
95 // are the instructions they (key) can transform into.
96 //
97 // Here, we choose 'PredSense' as ColFields since this is the unique
98 // attribute of the key (non-predicated) and column (true/false)
99 // instructions involved in this relationship model.
100 let ColFields = ["PredSense"];
101
102 // The key column contains non-predicated instructions.
103 let KeyCol = ["none"];
104
105 // Two value columns - first column contains instructions with
106 // PredSense=true while second column has instructions with PredSense=false.
107 let ValueCols = [["true"], ["false"]];
108 }
109
110 TableGen uses the above relationship model to emit relation table that maps
111 non-predicated instructions with their predicated forms. It also outputs the
112 interface function
113 ``int getPredOpcode(uint16_t Opcode, enum PredSense inPredSense)`` to query
114 the table. Here, Function ``getPredOpcode`` takes two arguments, opcode of the
115 current instruction and PredSense of the desired instruction, and returns
116 predicated form of the instruction, if found in the relation table.
117 In order for an instruction to be added into the relation table, it needs
118 to include relevant information in its definition. For example, consider
119 following to be the current definitions of ADD, ADD_pt (true) and ADD_pf (false)
120 instructions:
121
122 .. code-block::llvm
123
124 def ADD : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$a, IntRegs:$b),
125 "$dst = add($a, $b)",
126 [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$a),
127 (i32 IntRegs:$b)))]>;
128
129 def ADD_Pt : ALU32_rr<(outs IntRegs:$dst),
130 (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
131 "if ($p) $dst = add($a, $b)",
132 []>;
133
134 def ADD_Pf : ALU32_rr<(outs IntRegs:$dst),
135 (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
136 "if (!$p) $dst = add($a, $b)",
137 []>;
138
139 In this step, we modify these instructions to include the information
140 required by the relationship model, getPredOpcode, so that they can
141 be related.
142
143 .. code-block::llvm
144
145 def ADD : PredRel, ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$a, IntRegs:$b),
146 "$dst = add($a, $b)",
147 [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$a),
148 (i32 IntRegs:$b)))]> {
149 let BaseOpcode = "ADD";
150 let PredSense = "none";
151 }
152
153 def ADD_Pt : PredRel, ALU32_rr<(outs IntRegs:$dst),
154 (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
155 "if ($p) $dst = add($a, $b)",
156 []> {
157 let BaseOpcode = "ADD";
158 let PredSense = "true";
159 }
160
161 def ADD_Pf : PredRel, ALU32_rr<(outs IntRegs:$dst),
162 (ins PredRegs:$p, IntRegs:$a, IntRegs:$b),
163 "if (!$p) $dst = add($a, $b)",
164 []> {
165 let BaseOpcode = "ADD";
166 let PredSense = "false";
167 }
168
169 Please note that all the above instructions use ``PredRel`` as a base class.
170 This is extremely important since TableGen uses it as a filter for selecting
171 instructions for ``getPredOpcode`` model. Any instruction not derived from
172 ``PredRel`` is excluded from the analysis. ``BaseOpcode`` is another important
173 field. Since it's selected as a ``RowFields`` of the model, it is required
174 to have the same value for all 3 instructions in order to be related. Next,
175 ``PredSense`` is used to determine their column positions by comparing its value
176 with ``KeyCol`` and ``ValueCols``. If an instruction sets its ``PredSense``
177 value to something not used in the relation model, it will not be assigned
178 a column in the relation table.
3131
  • Instruction Set
  • 3232
    3333
  • Instruction Operand Mapping
  • 34
  • Instruction Relation Mapping
  • 3435
  • Implement a subclass of TargetInstrInfo
  • 3536
  • Branch Folding and If Conversion
  • 3637
    12541255 the rd, rs1, and rs2 fields respectively.
    12551256

    12561257
    1258
    1259
    1260
    1261

    1262 Instruction Relation Mapping
    1263
    1264
    1265
    1266
    1267

    1268 This TableGen feature is used to relate instructions with each other. It is
    1269 particularly useful when you have multiple instruction formats and need to
    1270 switch between them after instruction selection. This entire feature is driven
    1271 by relation models which can be defined in XXXInstrInfo.td files
    1272 according to the target-specific instruction set. Relation models are defined
    1273 using InstrMapping class as a base. TableGen parses all the models
    1274 and generates instruction relation maps using the specified information.
    1275 Relation maps are emitted as tables in the XXXGenInstrInfo.inc file
    1276 along with the functions to query them. For the detailed information on how to
    1277 use this feature, please refer to
    1278 How to add Instruction Mappings
    1279 document.
    1280

    12571281
    12581282
    12591283
    997997 }
    998998
    999999 //===----------------------------------------------------------------------===//
    1000 // InstrMapping - This class is used to create mapping tables to relate
    1001 // instructions with each other based on the values specified in RowFields,
    1002 // ColFields, KeyCol and ValueCols.
    1003 //
    1004 class InstrMapping {
    1005 // FilterClass - Used to limit search space only to the instructions that
    1006 // define the relationship modeled by this InstrMapping record.
    1007 string FilterClass;
    1008
    1009 // RowFields - List of fields/attributes that should be same for all the
    1010 // instructions in a row of the relation table. Think of this as a set of
    1011 // properties shared by all the instructions related by this relationship
    1012 // model and is used to categorize instructions into subgroups. For instance,
    1013 // if we want to define a relation that maps 'Add' instruction to its
    1014 // predicated forms, we can define RowFields like this:
    1015 //
    1016 // let RowFields = BaseOp
    1017 // All add instruction predicated/non-predicated will have to set their BaseOp
    1018 // to the same value.
    1019 //
    1020 // def Add: { let BaseOp = 'ADD'; let predSense = 'nopred' }
    1021 // def Add_predtrue: { let BaseOp = 'ADD'; let predSense = 'true' }
    1022 // def Add_predfalse: { let BaseOp = 'ADD'; let predSense = 'false' }
    1023 list RowFields = [];
    1024
    1025 // List of fields/attributes that are same for all the instructions
    1026 // in a column of the relation table.
    1027 // Ex: let ColFields = 'predSense' -- It means that the columns are arranged
    1028 // based on the 'predSense' values. All the instruction in a specific
    1029 // column have the same value and it is fixed for the column according
    1030 // to the values set in 'ValueCols'.
    1031 list ColFields = [];
    1032
    1033 // Values for the fields/attributes listed in 'ColFields'.
    1034 // Ex: let KeyCol = 'nopred' -- It means that the key instruction (instruction
    1035 // that models this relation) should be non-predicated.
    1036 // In the example above, 'Add' is the key instruction.
    1037 list KeyCol = [];
    1038
    1039 // List of values for the fields/attributes listed in 'ColFields', one for
    1040 // each column in the relation table.
    1041 //
    1042 // Ex: let ValueCols = [['true'],['false']] -- It adds two columns in the
    1043 // table. First column requires all the instructions to have predSense
    1044 // set to 'true' and second column requires it to be 'false'.
    1045 list > ValueCols = [];
    1046 }
    1047
    1048 //===----------------------------------------------------------------------===//
    10001049 // Pull in the common support for calling conventions.
    10011050 //
    10021051 include "llvm/Target/TargetCallingConv.td"
    0 //===- CodeGenMapTable.cpp - Instruction Mapping Table Generator ----------===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 // CodeGenMapTable provides functionality for the TabelGen to create
    9 // relation mapping between instructions. Relation models are defined using
    10 // InstrMapping as a base class. This file implements the functionality which
    11 // parses these definitions and generates relation maps using the information
    12 // specified there. These maps are emitted as tables in the XXXGenInstrInfo.inc
    13 // file along with the functions to query them.
    14 //
    15 // A relationship model to relate non-predicate instructions with their
    16 // predicated true/false forms can be defined as follows:
    17 //
    18 // def getPredOpcode : InstrMapping {
    19 // let FilterClass = "PredRel";
    20 // let RowFields = ["BaseOpcode"];
    21 // let ColFields = ["PredSense"];
    22 // let KeyCol = ["none"];
    23 // let ValueCols = [["true"], ["false"]]; }
    24 //
    25 // CodeGenMapTable parses this map and generates a table in XXXGenInstrInfo.inc
    26 // file that contains the instructions modeling this relationship. This table
    27 // is defined in the function
    28 // "int getPredOpcode(uint16_t Opcode, enum PredSense inPredSense)"
    29 // that can be used to retrieve the predicated form of the instruction by
    30 // passing its opcode value and the predicate sense (true/false) of the desired
    31 // instruction as arguments.
    32 //
    33 // Short description of the algorithm:
    34 //
    35 // 1) Iterate through all the records that derive from "InstrMapping" class.
    36 // 2) For each record, filter out instructions based on the FilterClass value.
    37 // 3) Iterate through this set of instructions and insert them into
    38 // RowInstrMap map based on their RowFields values. RowInstrMap is keyed by the
    39 // vector of RowFields values and contains vectors of Records (instructions) as
    40 // values. RowFields is a list of fields that are required to have the same
    41 // values for all the instructions appearing in the same row of the relation
    42 // table. All the instructions in a given row of the relation table have some
    43 // sort of relationship with the key instruction defined by the corresponding
    44 // relationship model.
    45 //
    46 // Ex: RowInstrMap(RowVal1, RowVal2, ...) -> [Instr1, Instr2, Instr3, ... ]
    47 // Here Instr1, Instr2, Instr3 have same values (RowVal1, RowVal2) for
    48 // RowFields. These groups of instructions are later matched against ValueCols
    49 // to determine the column they belong to, if any.
    50 //
    51 // While building the RowInstrMap map, collect all the key instructions in
    52 // KeyInstrVec. These are the instructions having the same values as KeyCol
    53 // for all the fields listed in ColFields.
    54 //
    55 // For Example:
    56 //
    57 // Relate non-predicate instructions with their predicated true/false forms.
    58 //
    59 // def getPredOpcode : InstrMapping {
    60 // let FilterClass = "PredRel";
    61 // let RowFields = ["BaseOpcode"];
    62 // let ColFields = ["PredSense"];
    63 // let KeyCol = ["none"];
    64 // let ValueCols = [["true"], ["false"]]; }
    65 //
    66 // Here, only instructions that have "none" as PredSense will be selected as key
    67 // instructions.
    68 //
    69 // 4) For each key instruction, get the group of instructions that share the
    70 // same key-value as the key instruction from RowInstrMap. Iterate over the list
    71 // of columns in ValueCols (it is defined as a list >. Therefore,
    72 // it can specify multi-column relationships). For each column, find the
    73 // instruction from the group that matches all the values for the column.
    74 // Multiple matches are not allowed.
    75 //
    76 //===----------------------------------------------------------------------===//
    77
    78 #include "CodeGenTarget.h"
    79 #include "llvm/Support/Format.h"
    80 using namespace llvm;
    81 typedef std::map > InstrRelMapTy;
    82
    83 typedef std::map, std::vector > RowInstrMapTy;
    84
    85 namespace {
    86
    87 //===----------------------------------------------------------------------===//
    88 // This class is used to represent InstrMapping class defined in Target.td file.
    89 class InstrMap {
    90 private:
    91 std::string Name;
    92 std::string FilterClass;
    93 ListInit *RowFields;
    94 ListInit *ColFields;
    95 ListInit *KeyCol;
    96 std::vector ValueCols;
    97
    98 public:
    99 InstrMap(Record* MapRec) {
    100 Name = MapRec->getName();
    101
    102 // FilterClass - It's used to reduce the search space only to the
    103 // instructions that define the kind of relationship modeled by
    104 // this InstrMapping object/record.
    105 const RecordVal *Filter = MapRec->getValue("FilterClass");
    106 FilterClass = Filter->getValue()->getAsUnquotedString();
    107
    108 // List of fields/attributes that need to be same across all the
    109 // instructions in a row of the relation table.
    110 RowFields = MapRec->getValueAsListInit("RowFields");
    111
    112 // List of fields/attributes that are constant across all the instruction
    113 // in a column of the relation table. Ex: ColFields = 'predSense'
    114 ColFields = MapRec->getValueAsListInit("ColFields");
    115
    116 // Values for the fields/attributes listed in 'ColFields'.
    117 // Ex: KeyCol = 'noPred' -- key instruction is non predicated
    118 KeyCol = MapRec->getValueAsListInit("KeyCol");
    119
    120 // List of values for the fields/attributes listed in 'ColFields', one for
    121 // each column in the relation table.
    122 //
    123 // Ex: ValueCols = [['true'],['false']] -- it results two columns in the
    124 // table. First column requires all the instructions to have predSense
    125 // set to 'true' and second column requires it to be 'false'.
    126 ListInit *ColValList = MapRec->getValueAsListInit("ValueCols");
    127
    128 // Each instruction map must specify at least one column for it to be valid.
    129 if (ColValList->getSize() == 0)
    130 throw "InstrMapping record `" + MapRec->getName() + "' has empty " +
    131 "`ValueCols' field!";
    132
    133 for (unsigned i = 0, e = ColValList->getSize(); i < e; i++) {
    134 ListInit *ColI = dyn_cast(ColValList->getElement(i));
    135
    136 // Make sure that all the sub-lists in 'ValueCols' have same number of
    137 // elements as the fields in 'ColFields'.
    138 if (ColI->getSize() == ColFields->getSize())
    139 ValueCols.push_back(ColI);
    140 else {
    141 throw "Record `" + MapRec->getName() + "', field `" + "ValueCols" +
    142 "' entries don't match with the entries in 'ColFields'!";
    143 }
    144 }
    145 }
    146
    147 std::string getName() const {
    148 return Name;
    149 }
    150
    151 std::string getFilterClass() {
    152 return FilterClass;
    153 }
    154
    155 ListInit *getRowFields() const {
    156 return RowFields;
    157 }
    158
    159 ListInit *getColFields() const {
    160 return ColFields;
    161 }
    162
    163 ListInit *getKeyCol() const {
    164 return KeyCol;
    165 }
    166
    167 const std::vector &getValueCols() const {
    168 return ValueCols;
    169 }
    170 };
    171 } // End anonymous namespace.
    172
    173
    174 //===----------------------------------------------------------------------===//
    175 // class MapTableEmitter : It builds the instruction relation maps using
    176 // the information provided in InstrMapping records. It outputs these
    177 // relationship maps as tables into XXXGenInstrInfo.inc file along with the
    178 // functions to query them.
    179
    180 namespace {
    181 class MapTableEmitter {
    182 private:
    183 // std::string TargetName;
    184 const CodeGenTarget &Target;
    185 RecordKeeper &Records;
    186 // InstrMapDesc - InstrMapping record to be processed.
    187 InstrMap InstrMapDesc;
    188
    189 // InstrDefs - list of instructions filtered using FilterClass defined
    190 // in InstrMapDesc.
    191 std::vector InstrDefs;
    192
    193 // RowInstrMap - maps RowFields values to the instructions. It's keyed by the
    194 // values of the row fields and contains vector of records as values.
    195 RowInstrMapTy RowInstrMap;
    196
    197 // KeyInstrVec - list of key instructions.
    198 std::vector KeyInstrVec;
    199 DenseMap > MapTable;
    200
    201 public:
    202 MapTableEmitter(CodeGenTarget &Target, RecordKeeper &Records, Record *IMRec):
    203 Target(Target), Records(Records), InstrMapDesc(IMRec) {
    204 const std::string FilterClass = InstrMapDesc.getFilterClass();
    205 InstrDefs = Records.getAllDerivedDefinitions(FilterClass);
    206 };
    207
    208 void buildRowInstrMap();
    209
    210 // Returns true if an instruction is a key instruction, i.e., its ColFields
    211 // have same values as KeyCol.
    212 bool isKeyColInstr(Record* CurInstr);
    213
    214 // Find column instruction corresponding to a key instruction based on the
    215 // constraints for that column.
    216 Record *getInstrForColumn(Record *KeyInstr, ListInit *CurValueCol);
    217
    218 // Find column instructions for each key instruction based
    219 // on ValueCols and store them into MapTable.
    220 void buildMapTable();
    221
    222 void emitBinSearch(raw_ostream &OS, unsigned TableSize);
    223 void emitTablesWithFunc(raw_ostream &OS);
    224 unsigned emitBinSearchTable(raw_ostream &OS);
    225
    226 // Lookup functions to query binary search tables.
    227 void emitMapFuncBody(raw_ostream &OS, unsigned TableSize);
    228
    229 };
    230 } // End anonymous namespace.
    231
    232
    233 //===----------------------------------------------------------------------===//
    234 // Process all the instructions that model this relation (alreday present in
    235 // InstrDefs) and insert them into RowInstrMap which is keyed by the values of
    236 // the fields listed as RowFields. It stores vectors of records as values.
    237 // All the related instructions have the same values for the RowFields thus are
    238 // part of the same key-value pair.
    239 //===----------------------------------------------------------------------===//
    240
    241 void MapTableEmitter::buildRowInstrMap() {
    242 for (unsigned i = 0, e = InstrDefs.size(); i < e; i++) {
    243 std::vector InstrList;
    244 Record *CurInstr = InstrDefs[i];
    245 std::vector KeyValue;
    246 ListInit *RowFields = InstrMapDesc.getRowFields();
    247 for (unsigned j = 0, endRF = RowFields->getSize(); j < endRF; j++) {
    248 Init *RowFieldsJ = RowFields->getElement(j);
    249 Init *CurInstrVal = CurInstr->getValue(RowFieldsJ)->getValue();
    250 KeyValue.push_back(CurInstrVal);
    251 }
    252
    253 // Collect key instructions into KeyInstrVec. Later, these instructions are
    254 // processed to assign column position to the instructions sharing
    255 // their KeyValue in RowInstrMap.
    256 if (isKeyColInstr(CurInstr))
    257 KeyInstrVec.push_back(CurInstr);
    258
    259 RowInstrMap[KeyValue].push_back(CurInstr);
    260 }
    261 }
    262
    263 //===----------------------------------------------------------------------===//
    264 // Return true if an instruction is a KeyCol instruction.
    265 //===----------------------------------------------------------------------===//
    266
    267 bool MapTableEmitter::isKeyColInstr(Record* CurInstr) {
    268 ListInit *ColFields = InstrMapDesc.getColFields();
    269 ListInit *KeyCol = InstrMapDesc.getKeyCol();
    270
    271 // Check if the instruction is a KeyCol instruction.
    272 bool MatchFound = true;
    273 for (unsigned j = 0, endCF = ColFields->getSize();
    274 (j < endCF) && MatchFound; j++) {
    275 RecordVal *ColFieldName = CurInstr->getValue(ColFields->getElement(j));
    276 std::string CurInstrVal = ColFieldName->getValue()->getAsUnquotedString();
    277 std::string KeyColValue = KeyCol->getElement(j)->getAsUnquotedString();
    278 MatchFound = (CurInstrVal == KeyColValue);
    279 }
    280 return MatchFound;
    281 }
    282
    283 //===----------------------------------------------------------------------===//
    284 // Build a map to link key instructions with the column instructions arranged
    285 // according to their column positions.
    286 //===----------------------------------------------------------------------===//
    287
    288 void MapTableEmitter::buildMapTable() {
    289 // Find column instructions for a given key based on the ColField
    290 // constraints.
    291 const std::vector &ValueCols = InstrMapDesc.getValueCols();
    292 unsigned NumOfCols = ValueCols.size();
    293 for (unsigned j = 0, endKI = KeyInstrVec.size(); j < endKI; j++) {
    294 Record *CurKeyInstr = KeyInstrVec[j];
    295 std::vector ColInstrVec(NumOfCols);
    296
    297 // Find the column instruction based on the constraints for the column.
    298 for (unsigned ColIdx = 0; ColIdx < NumOfCols; ColIdx++) {
    299 ListInit *CurValueCol = ValueCols[ColIdx];
    300 Record *ColInstr = getInstrForColumn(CurKeyInstr, CurValueCol);
    301 ColInstrVec[ColIdx] = ColInstr;
    302 }
    303 MapTable[CurKeyInstr] = ColInstrVec;
    304 }
    305 }
    306
    307 //===----------------------------------------------------------------------===//
    308 // Find column instruction based on the constraints for that column.
    309 //===----------------------------------------------------------------------===//
    310
    311 Record *MapTableEmitter::getInstrForColumn(Record *KeyInstr,
    312 ListInit *CurValueCol) {
    313 ListInit *RowFields = InstrMapDesc.getRowFields();
    314 std::vector KeyValue;
    315
    316 // Construct KeyValue using KeyInstr's values for RowFields.
    317 for (unsigned j = 0, endRF = RowFields->getSize(); j < endRF; j++) {
    318 Init *RowFieldsJ = RowFields->getElement(j);
    319 Init *KeyInstrVal = KeyInstr->getValue(RowFieldsJ)->getValue();
    320 KeyValue.push_back(KeyInstrVal);
    321 }
    322
    323 // Get all the instructions that share the same KeyValue as the KeyInstr
    324 // in RowInstrMap. We search through these instructions to find a match
    325 // for the current column, i.e., the instruction which has the same values
    326 // as CurValueCol for all the fields in ColFields.
    327 const std::vector &RelatedInstrVec = RowInstrMap[KeyValue];
    328
    329 ListInit *ColFields = InstrMapDesc.getColFields();
    330 Record *MatchInstr = NULL;
    331
    332 for (unsigned i = 0, e = RelatedInstrVec.size(); i < e; i++) {
    333 bool MatchFound = true;
    334 Record *CurInstr = RelatedInstrVec[i];
    335 for (unsigned j = 0, endCF = ColFields->getSize();
    336 (j < endCF) && MatchFound; j++) {
    337 Init *ColFieldJ = ColFields->getElement(j);
    338 Init *CurInstrInit = CurInstr->getValue(ColFieldJ)->getValue();
    339 std::string CurInstrVal = CurInstrInit->getAsUnquotedString();
    340 Init *ColFieldJVallue = CurValueCol->getElement(j);
    341 MatchFound = (CurInstrVal == ColFieldJVallue->getAsUnquotedString());
    342 }
    343
    344 if (MatchFound) {
    345 if (MatchInstr) // Already had a match
    346 // Error if multiple matches are found for a column.
    347 throw "Multiple matches found for `" + KeyInstr->getName() +
    348 "', for the relation `" + InstrMapDesc.getName();
    349 else
    350 MatchInstr = CurInstr;
    351 }
    352 }
    353 return MatchInstr;
    354 }
    355
    356 //===----------------------------------------------------------------------===//
    357 // Emit one table per relation. Only instructions with a valid relation of a
    358 // given type are included in the table sorted by their enum values (opcodes).
    359 // Binary search is used for locating instructions in the table.
    360 //===----------------------------------------------------------------------===//
    361
    362 unsigned MapTableEmitter::emitBinSearchTable(raw_ostream &OS) {
    363
    364 const std::vector &NumberedInstructions =
    365 Target.getInstructionsByEnumValue();
    366 std::string TargetName = Target.getName();
    367 const std::vector &ValueCols = InstrMapDesc.getValueCols();
    368 unsigned NumCol = ValueCols.size();
    369 unsigned TotalNumInstr = NumberedInstructions.size();
    370 unsigned TableSize = 0;
    371
    372 OS << "static const uint16_t "<
    373 // Number of columns in the table are NumCol+1 because key instructions are
    374 // emitted as first column.
    375 OS << "Table[]["<< NumCol+1 << "] = {\n";
    376 for (unsigned i = 0; i < TotalNumInstr; i++) {
    377 Record *CurInstr = NumberedInstructions[i]->TheDef;
    378 std::vector ColInstrs = MapTable[CurInstr];
    379 std::string OutStr("");
    380 unsigned RelExists = 0;
    381 if (ColInstrs.size()) {
    382 for (unsigned j = 0; j < NumCol; j++) {
    383 if (ColInstrs[j] != NULL) {
    384 RelExists = 1;
    385 OutStr += ", ";
    386 OutStr += TargetName;
    387 OutStr += "::";
    388 OutStr += ColInstrs[j]->getName();
    389 } else { OutStr += ", -1";}
    390 }
    391
    392 if (RelExists) {
    393 OS << " { " << TargetName << "::" << CurInstr->getName();
    394 OS << OutStr <<" },\n";
    395 TableSize++;
    396 }
    397 }
    398 }
    399 if (!TableSize) {
    400 OS << " { " << TargetName << "::" << "INSTRUCTION_LIST_END, ";
    401 OS << TargetName << "::" << "INSTRUCTION_LIST_END }";
    402 }
    403 OS << "}; // End of " << InstrMapDesc.getName() << "Table\n\n";
    404 return TableSize;
    405 }
    406
    407 //===----------------------------------------------------------------------===//
    408 // Emit binary search algorithm as part of the functions used to query
    409 // relation tables.
    410 //===----------------------------------------------------------------------===//
    411
    412 void MapTableEmitter::emitBinSearch(raw_ostream &OS, unsigned TableSize) {
    413 OS << " unsigned mid;\n";
    414 OS << " unsigned start = 0;\n";
    415 OS << " unsigned end = " << TableSize << ";\n";
    416 OS << " while (start < end) {\n";
    417 OS << " mid = start + (end - start)/2;\n";
    418 OS << " if (Opcode == " << InstrMapDesc.getName() << "Table[mid][0]) {\n";
    419 OS << " break;\n";
    420 OS << " }\n";
    421 OS << " if (Opcode < " << InstrMapDesc.getName() << "Table[mid][0])\n";
    422 OS << " end = mid;\n";
    423 OS << " else\n";
    424 OS << " start = mid + 1;\n";
    425 OS << " }\n";
    426 OS << " if (start == end)\n";
    427 OS << " return -1; // Instruction doesn't exist in this table.\n\n";
    428 }
    429
    430 //===----------------------------------------------------------------------===//
    431 // Emit functions to query relation tables.
    432 //===----------------------------------------------------------------------===//
    433
    434 void MapTableEmitter::emitMapFuncBody(raw_ostream &OS,
    435 unsigned TableSize) {
    436
    437 ListInit *ColFields = InstrMapDesc.getColFields();
    438 const std::vector &ValueCols = InstrMapDesc.getValueCols();
    439
    440 // Emit binary search algorithm to locate instructions in the
    441 // relation table. If found, return opcode value from the appropriate column
    442 // of the table.
    443 emitBinSearch(OS, TableSize);
    444
    445 if (ValueCols.size() > 1) {
    446 for (unsigned i = 0, e = ValueCols.size(); i < e; i++) {
    447 ListInit *ColumnI = ValueCols[i];
    448 for (unsigned j = 0, ColSize = ColumnI->getSize(); j < ColSize; j++) {
    449 std::string ColName = ColFields->getElement(j)->getAsUnquotedString();
    450 OS << " if (in" << ColName;
    451 OS << " == ";
    452 OS << ColName << "_" << ColumnI->getElement(j)->getAsUnquotedString();
    453 if (j < ColumnI->getSize() - 1) OS << " && ";
    454 else OS << ")\n";
    455 }
    456 OS << " return " << InstrMapDesc.getName();
    457 OS << "Table[mid]["<
    458 }
    459 OS << " return -1;";
    460 }
    461 else
    462 OS << " return " << InstrMapDesc.getName() << "Table[mid][1];\n";
    463
    464 OS <<"}\n\n";
    465 }
    466
    467 //===----------------------------------------------------------------------===//
    468 // Emit relation tables and the functions to query them.
    469 //===----------------------------------------------------------------------===//
    470
    471 void MapTableEmitter::emitTablesWithFunc(raw_ostream &OS) {
    472
    473 // Emit function name and the input parameters : mostly opcode value of the
    474 // current instruction. However, if a table has multiple columns (more than 2
    475 // since first column is used for the key instructions), then we also need
    476 // to pass another input to indicate the column to be selected.
    477
    478 ListInit *ColFields = InstrMapDesc.getColFields();
    479 const std::vector &ValueCols = InstrMapDesc.getValueCols();
    480 OS << "// "<< InstrMapDesc.getName() << "\n";
    481 OS << "int "<< InstrMapDesc.getName() << "(uint16_t Opcode";
    482 if (ValueCols.size() > 1) {
    483 for (unsigned i = 0, e = ColFields->getSize(); i < e; i++) {
    484 std::string ColName = ColFields->getElement(i)->getAsUnquotedString();
    485 OS << ", enum " << ColName << " in" << ColName << ") {\n";
    486 }
    487 } else { OS << ") {\n"; }
    488
    489 // Emit map table.
    490 unsigned TableSize = emitBinSearchTable(OS);
    491
    492 // Emit rest of the function body.
    493 emitMapFuncBody(OS, TableSize);
    494 }
    495
    496 //===----------------------------------------------------------------------===//
    497 // Emit enums for the column fields across all the instruction maps.
    498 //===----------------------------------------------------------------------===//
    499
    500 static void emitEnums(raw_ostream &OS, RecordKeeper &Records) {
    501
    502 std::vector InstrMapVec;
    503 InstrMapVec = Records.getAllDerivedDefinitions("InstrMapping");
    504 std::map > ColFieldValueMap;
    505
    506 // Iterate over all InstrMapping records and create a map between column
    507 // fields and their possible values across all records.
    508 for (unsigned i = 0, e = InstrMapVec.size(); i < e; i++) {
    509 Record *CurMap = InstrMapVec[i];
    510 ListInit *ColFields;
    511 ColFields = CurMap->getValueAsListInit("ColFields");
    512 ListInit *List = CurMap->getValueAsListInit("ValueCols");
    513 std::vector ValueCols;
    514 unsigned ListSize = List->getSize();
    515
    516 for (unsigned j = 0; j < ListSize; j++) {
    517 ListInit *ListJ = dyn_cast(List->getElement(j));
    518
    519 if (ListJ->getSize() != ColFields->getSize()) {
    520 throw "Record `" + CurMap->getName() + "', field `" + "ValueCols" +
    521 "' entries don't match with the entries in 'ColFields' !";
    522 }
    523 ValueCols.push_back(ListJ);
    524 }
    525
    526 for (unsigned j = 0, endCF = ColFields->getSize(); j < endCF; j++) {
    527 for (unsigned k = 0; k < ListSize; k++){
    528 std::string ColName = ColFields->getElement(j)->getAsUnquotedString();
    529 ColFieldValueMap[ColName].push_back((ValueCols[k])->getElement(j));
    530 }
    531 }
    532 }
    533
    534 for (std::map >::iterator
    535 II = ColFieldValueMap.begin(), IE = ColFieldValueMap.end();
    536 II != IE; II++) {
    537 std::vector FieldValues = (*II).second;
    538 unsigned FieldSize = FieldValues.size();
    539
    540 // Delete duplicate entries from ColFieldValueMap
    541 for (unsigned i = 0; i < FieldSize - 1; i++) {
    542 Init *CurVal = FieldValues[i];
    543 for (unsigned j = i+1; j < FieldSize; j++) {
    544 if (CurVal == FieldValues[j]) {
    545 FieldValues.erase(FieldValues.begin()+j);
    546 }
    547 }
    548 }
    549
    550 // Emit enumerated values for the column fields.
    551 OS << "enum " << (*II).first << " {\n";
    552 for (unsigned i = 0; i < FieldSize; i++) {
    553 OS << "\t" << (*II).first << "_" << FieldValues[i]->getAsUnquotedString();
    554 if (i != FieldValues.size() - 1)
    555 OS << ",\n";
    556 else
    557 OS << "\n};\n\n";
    558 }
    559 }
    560 }
    561
    562 namespace llvm {
    563 //===----------------------------------------------------------------------===//
    564 // Parse 'InstrMapping' records and use the information to form relationship
    565 // between instructions. These relations are emitted as a tables along with the
    566 // functions to query them.
    567 //===----------------------------------------------------------------------===//
    568 void EmitMapTable(RecordKeeper &Records, raw_ostream &OS) {
    569 CodeGenTarget Target(Records);
    570 std::string TargetName = Target.getName();
    571 std::vector InstrMapVec;
    572 InstrMapVec = Records.getAllDerivedDefinitions("InstrMapping");
    573
    574 if (!InstrMapVec.size())
    575 return;
    576
    577 OS << "#ifdef GET_INSTRMAP_INFO\n";
    578 OS << "#undef GET_INSTRMAP_INFO\n";
    579 OS << "namespace llvm {\n\n";
    580 OS << "namespace " << TargetName << " {\n\n";
    581
    582 // Emit coulumn field names and their values as enums.
    583 emitEnums(OS, Records);
    584
    585 // Iterate over all instruction mapping records and construct relationship
    586 // maps based on the information specified there.
    587 //
    588 for (unsigned i = 0, e = InstrMapVec.size(); i < e; i++) {
    589 MapTableEmitter IMap(Target, Records, InstrMapVec[i]);
    590
    591 // Build RowInstrMap to group instructions based on their values for
    592 // RowFields. In the process, also collect key instructions into
    593 // KeyInstrVec.
    594 IMap.buildRowInstrMap();
    595
    596 // Build MapTable to map key instructions with the corresponding column
    597 // instructions.
    598 IMap.buildMapTable();
    599
    600 // Emit map tables and the functions to query them.
    601 IMap.emitTablesWithFunc(OS);
    602 }
    603 OS << "} // End " << TargetName << " namespace\n";
    604 OS << "} // End llvm namespace\n";
    605 OS << "#endif // GET_INSTRMAP_INFO\n\n";
    606 }
    607
    608 } // End llvm namespace
    1515 #include "CodeGenDAGPatterns.h"
    1616 #include "CodeGenSchedule.h"
    1717 #include "CodeGenTarget.h"
    18 #include "TableGenBackends.h"
    1819 #include "SequenceToOffsetTable.h"
    1920 #include "llvm/ADT/StringExtras.h"
    2021 #include "llvm/TableGen/Record.h"
    414415
    415416 void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
    416417 InstrInfoEmitter(RK).run(OS);
    418 EmitMapTable(RK, OS);
    417419 }
    418420
    419421 } // End llvm namespace
    7373 void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS);
    7474 void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS);
    7575 void EmitSubtarget(RecordKeeper &RK, raw_ostream &OS);
    76 void EmitMapTable(RecordKeeper &RK, raw_ostream &OS);
    7677
    7778 } // End llvm namespace