40
40
41
41
using namespace llvm ;
42
42
43
- cl::OptionCategory InstrInfoEmitterCat (" Options for -gen-instr-info" );
43
+ static cl::OptionCategory InstrInfoEmitterCat (" Options for -gen-instr-info" );
44
44
static cl::opt<bool > ExpandMIOperandInfo (
45
45
" instr-info-expand-mi-operand-info" ,
46
46
cl::desc (" Expand operand's MIOperandInfo DAG into suboperands" ),
@@ -67,13 +67,6 @@ class InstrInfoEmitter {
67
67
typedef std::vector<OperandInfoTy> OperandInfoListTy;
68
68
typedef std::map<OperandInfoTy, unsigned > OperandInfoMapTy;
69
69
70
- // / The keys of this map are maps which have OpName enum values as their keys
71
- // / and instruction operand indices as their values. The values of this map
72
- // / are lists of instruction names.
73
- typedef std::map<std::map<unsigned , unsigned >, std::vector<std::string>>
74
- OpNameMapTy;
75
- typedef std::map<std::string, unsigned >::iterator StrUintMapIter;
76
-
77
70
// / Generate member functions in the target-specific GenInstrInfo class.
78
71
// /
79
72
// / This method is used to custom expand TIIPredicate definitions.
@@ -95,15 +88,9 @@ class InstrInfoEmitter {
95
88
void emitOperandTypeMappings (
96
89
raw_ostream &OS, const CodeGenTarget &Target,
97
90
ArrayRef<const CodeGenInstruction *> NumberedInstructions);
98
- void
99
- initOperandMapData (ArrayRef<const CodeGenInstruction *> NumberedInstructions,
100
- StringRef Namespace,
101
- std::map<std::string, unsigned > &Operands,
102
- OpNameMapTy &OperandMap);
103
91
void emitOperandNameMappings (
104
92
raw_ostream &OS, const CodeGenTarget &Target,
105
93
ArrayRef<const CodeGenInstruction *> NumberedInstructions);
106
-
107
94
void emitLogicalOperandSizeMappings (
108
95
raw_ostream &OS, StringRef Namespace,
109
96
ArrayRef<const CodeGenInstruction *> NumberedInstructions);
@@ -239,35 +226,6 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
239
226
}
240
227
}
241
228
242
- // / Initialize data structures for generating operand name mappings.
243
- // /
244
- // / \param Operands [out] A map used to generate the OpName enum with operand
245
- // / names as its keys and operand enum values as its values.
246
- // / \param OperandMap [out] A map for representing the operand name mappings for
247
- // / each instructions. This is used to generate the OperandMap table as
248
- // / well as the getNamedOperandIdx() function.
249
- void InstrInfoEmitter::initOperandMapData (
250
- ArrayRef<const CodeGenInstruction *> NumberedInstructions,
251
- StringRef Namespace, std::map<std::string, unsigned > &Operands,
252
- OpNameMapTy &OperandMap) {
253
- unsigned NumOperands = 0 ;
254
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
255
- if (!Inst->TheDef ->getValueAsBit (" UseNamedOperandTable" ))
256
- continue ;
257
- std::map<unsigned , unsigned > OpList;
258
- for (const auto &Info : Inst->Operands ) {
259
- StrUintMapIter I = Operands.find (Info.Name );
260
-
261
- if (I == Operands.end ()) {
262
- I = Operands.insert (Operands.begin (), {Info.Name , NumOperands++});
263
- }
264
- OpList[I->second ] = Info.MIOperandNo ;
265
- }
266
- OperandMap[OpList].push_back (Namespace.str () +
267
- " ::" + Inst->TheDef ->getName ().str ());
268
- }
269
- }
270
-
271
229
// / Generate a table and function for looking up the indices of operands by
272
230
// / name.
273
231
// /
@@ -283,22 +241,52 @@ void InstrInfoEmitter::emitOperandNameMappings(
283
241
raw_ostream &OS, const CodeGenTarget &Target,
284
242
ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
285
243
StringRef Namespace = Target.getInstNamespace ();
286
- // Map of operand names to their enumeration value. This will be used to
287
- // generate the OpName enum.
288
- std::map<std::string, unsigned > Operands;
289
- OpNameMapTy OperandMap;
290
244
291
- initOperandMapData (NumberedInstructions, Namespace, Operands, OperandMap);
245
+ // / To facilitate assigning OpName enum values in the sorted alphabetical
246
+ // / order, we go through an indirection from OpName -> ID, and Enum -> ID.
247
+ // / This allows us to build the OpList and assign IDs to OpNames in a single
248
+ // / scan of the instructions below.
249
+
250
+ // Map of operand names to their ID.
251
+ std::map<StringRef, unsigned > OperandNameToID;
252
+ // Map from operand name enum value -> ID.
253
+ std::vector<unsigned > OperandEnumToID;
254
+
255
+ // / The keys of this map is a map which have OpName ID values as their keys
256
+ // / and instruction operand indices as their values. The values of this map
257
+ // / are lists of instruction names. This map helps to unique entries among
258
+ // / instructions that have identical OpName -> Operand index mapping.
259
+ std::map<std::map<unsigned , unsigned >, std::vector<StringRef>> OperandMap;
260
+
261
+ // Max operand index seen.
262
+ unsigned MaxOperandNo = 0 ;
263
+
264
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
265
+ if (!Inst->TheDef ->getValueAsBit (" UseNamedOperandTable" ))
266
+ continue ;
267
+ std::map<unsigned , unsigned > OpList;
268
+ for (const auto &Info : Inst->Operands ) {
269
+ unsigned ID =
270
+ OperandNameToID.try_emplace (Info.Name , OperandNameToID.size ())
271
+ .first ->second ;
272
+ OpList[ID] = Info.MIOperandNo ;
273
+ MaxOperandNo = std::max (MaxOperandNo, Info.MIOperandNo );
274
+ }
275
+ OperandMap[OpList].push_back (Inst->TheDef ->getName ());
276
+ }
277
+
278
+ const size_t NumOperandNames = OperandNameToID.size ();
279
+ OperandEnumToID.reserve (NumOperandNames);
280
+ for (const auto &Op : OperandNameToID)
281
+ OperandEnumToID.push_back (Op.second );
292
282
293
283
OS << " #ifdef GET_INSTRINFO_OPERAND_ENUM\n " ;
294
284
OS << " #undef GET_INSTRINFO_OPERAND_ENUM\n " ;
295
285
OS << " namespace llvm::" << Namespace << " ::OpName {\n " ;
296
286
OS << " enum {\n " ;
297
- for (const auto &Op : Operands)
298
- OS << " " << Op.first << " = " << Op.second << " ,\n " ;
299
-
300
- OS << " OPERAND_LAST" ;
301
- OS << " \n };\n " ;
287
+ for (const auto &[I, Op] : enumerate(OperandNameToID))
288
+ OS << " " << Op.first << " = " << I << " ,\n " ;
289
+ OS << " };\n " ;
302
290
OS << " } // end namespace llvm::" << Namespace << " ::OpName\n " ;
303
291
OS << " #endif //GET_INSTRINFO_OPERAND_ENUM\n\n " ;
304
292
@@ -307,28 +295,30 @@ void InstrInfoEmitter::emitOperandNameMappings(
307
295
OS << " namespace llvm::" << Namespace << " {\n " ;
308
296
OS << " LLVM_READONLY\n " ;
309
297
OS << " int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx) {\n " ;
310
- if (!Operands.empty ()) {
311
- OS << " static const int16_t OperandMap [][" << Operands.size ()
298
+ if (NumOperandNames != 0 ) {
299
+ assert (MaxOperandNo <= INT16_MAX &&
300
+ " Too many operands for the operand name -> index table" );
301
+ StringRef Type = MaxOperandNo <= INT8_MAX ? " int8_t" : " int16_t" ;
302
+ OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames
312
303
<< " ] = {\n " ;
313
304
for (const auto &Entry : OperandMap) {
314
305
const std::map<unsigned , unsigned > &OpList = Entry.first ;
315
- OS << " {" ;
316
-
317
- // Emit a row of the OperandMap table
318
- for (unsigned i = 0 , e = Operands.size (); i != e; ++i)
319
- OS << (OpList.count (i) == 0 ? -1 : (int )OpList.find (i)->second ) << " , " ;
320
306
307
+ // Emit a row of the OperandMap table.
308
+ OS << " {" ;
309
+ for (unsigned ID : OperandEnumToID) {
310
+ auto Iter = OpList.find (ID);
311
+ OS << (Iter != OpList.end () ? (int )Iter->second : -1 ) << " , " ;
312
+ }
321
313
OS << " },\n " ;
322
314
}
323
- OS << " };\n " ;
315
+ OS << " };\n " ;
324
316
325
317
OS << " switch(Opcode) {\n " ;
326
- unsigned TableIndex = 0 ;
327
- for (const auto &Entry : OperandMap) {
328
- for (const std::string &Name : Entry.second )
329
- OS << " case " << Name << " :\n " ;
330
-
331
- OS << " return OperandMap[" << TableIndex++ << " ][NamedIdx];\n " ;
318
+ for (const auto &[TableIndex, Entry] : enumerate(OperandMap)) {
319
+ for (StringRef Name : Entry.second )
320
+ OS << " case " << Namespace << " ::" << Name << " :\n " ;
321
+ OS << " return OperandMap[" << TableIndex << " ][NamedIdx];\n " ;
332
322
}
333
323
OS << " default: return -1;\n " ;
334
324
OS << " }\n " ;
0 commit comments