@@ -54,10 +54,23 @@ using namespace llvm;
54
54
55
55
extern cl::OptionCategory DisassemblerEmitterCat;
56
56
57
- cl::opt<bool > DecoderEmitterSuppressDuplicates (
57
+ enum SuppressLevel {
58
+ SUPPRESSION_DISABLE,
59
+ SUPPRESSION_LEVEL1,
60
+ SUPPRESSION_LEVEL2
61
+ };
62
+
63
+ cl::opt<SuppressLevel> DecoderEmitterSuppressDuplicates (
58
64
" suppress-per-hwmode-duplicates" ,
59
65
cl::desc (" Suppress duplication of instrs into per-HwMode decoder tables" ),
60
- cl::init(false ), cl::cat(DisassemblerEmitterCat));
66
+ cl::values(clEnumValN(SUPPRESSION_DISABLE, " O0" ,
67
+ " Do not prevent DecoderTable duplications caused by HwModes" ),
68
+ clEnumValN(SUPPRESSION_LEVEL1, " O1" ,
69
+ " Remove duplicate DecoderTable entries generated due to HwModes" ),
70
+ clEnumValN(SUPPRESSION_LEVEL2, " O2" ,
71
+ " Extract HwModes-specific instructions into new DecoderTables, "
72
+ " significantly reducing Table Duplications" )),
73
+ cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
61
74
62
75
namespace {
63
76
@@ -128,6 +141,8 @@ struct EncodingIDAndOpcode {
128
141
};
129
142
130
143
using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
144
+ using NamespacesHwModesMap =
145
+ std::map<std::string, std::map<StringRef, unsigned >>;
131
146
132
147
raw_ostream &operator <<(raw_ostream &OS, const EncodingAndInst &Value) {
133
148
if (Value.EncodingDef != Value.Inst ->TheDef )
@@ -2417,21 +2432,63 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) {
2417
2432
2418
2433
// Collect all HwModes referenced by the target for encoding purposes,
2419
2434
// returning a vector of corresponding names.
2420
- static void
2421
- collectHwModesReferencedForEncodings ( const CodeGenHwModes &HWM,
2422
- std::vector<StringRef> &Names ) {
2435
+ static void collectHwModesReferencedForEncodings (
2436
+ const CodeGenHwModes &HWM, std::vector<StringRef> &Names ,
2437
+ NamespacesHwModesMap &NamespacesWithHwModes ) {
2423
2438
SmallBitVector BV (HWM.getNumModeIds ());
2424
2439
for (const auto &MS : HWM.getHwModeSelects ()) {
2425
2440
for (const HwModeSelect::PairType &P : MS.second .Items ) {
2426
- if (P.second ->isSubClassOf (" InstructionEncoding" ))
2441
+ if (P.second ->isSubClassOf (" InstructionEncoding" )) {
2442
+ std::string DecoderNamespace =
2443
+ std::string (P.second ->getValueAsString (" DecoderNamespace" ));
2444
+ if (P.first == DefaultMode) {
2445
+ NamespacesWithHwModes[DecoderNamespace][" " ] = 1 ;
2446
+ } else {
2447
+ NamespacesWithHwModes[DecoderNamespace][HWM.getMode (P.first ).Name ] =
2448
+ 1 ;
2449
+ }
2427
2450
BV.set (P.first );
2451
+ }
2428
2452
}
2429
2453
}
2430
2454
transform (BV.set_bits (), std::back_inserter (Names), [&HWM](const int &M) {
2455
+ if (M == DefaultMode)
2456
+ return StringRef (" " );
2431
2457
return HWM.getModeName (M, /* IncludeDefault=*/ true );
2432
2458
});
2433
2459
}
2434
2460
2461
+ static void handleHwModesUnrelatedEncodings (
2462
+ const CodeGenInstruction *Instr, const std::vector<StringRef> &HwModeNames,
2463
+ NamespacesHwModesMap &NamespacesWithHwModes, std::vector<EncodingAndInst> &GlobalEncodings) {
2464
+ const Record *InstDef = Instr->TheDef ;
2465
+
2466
+ switch (DecoderEmitterSuppressDuplicates) {
2467
+ case SUPPRESSION_DISABLE: {
2468
+ for (StringRef HwModeName : HwModeNames)
2469
+ GlobalEncodings.emplace_back (InstDef, Instr, HwModeName);
2470
+ break ;
2471
+ }
2472
+ case SUPPRESSION_LEVEL1: {
2473
+ std::string DecoderNamespace = std::string (
2474
+ InstDef->getValueAsString (" DecoderNamespace" ));
2475
+ for (StringRef HwModeName : HwModeNames) {
2476
+ if (NamespacesWithHwModes.count (DecoderNamespace) > 0 &&
2477
+ NamespacesWithHwModes[DecoderNamespace].count (HwModeName) > 0 ) {
2478
+ GlobalEncodings.emplace_back (InstDef, Instr, HwModeName);
2479
+ } else {
2480
+ GlobalEncodings.emplace_back (InstDef, Instr, " " );
2481
+ break ;
2482
+ }
2483
+ }
2484
+ break ;
2485
+ }
2486
+ case SUPPRESSION_LEVEL2:
2487
+ GlobalEncodings.emplace_back (InstDef, Instr, " " );
2488
+ break ;
2489
+ }
2490
+ }
2491
+
2435
2492
// Emits disassembler code for instruction decoding.
2436
2493
void DecoderEmitter::run (raw_ostream &o) {
2437
2494
formatted_raw_ostream OS (o);
@@ -2457,10 +2514,12 @@ namespace llvm {
2457
2514
// Parameterize the decoders based on namespace and instruction width.
2458
2515
2459
2516
// First, collect all encoding-related HwModes referenced by the target.
2517
+ // And establish a mapping table between DecoderNamespace and HwMode.
2460
2518
// If HwModeNames is empty, add the empty string so we always have one HwMode.
2461
2519
const CodeGenHwModes &HWM = Target.getHwModes ();
2462
2520
std::vector<StringRef> HwModeNames;
2463
- collectHwModesReferencedForEncodings (HWM, HwModeNames);
2521
+ NamespacesHwModesMap NamespacesWithHwModes;
2522
+ collectHwModesReferencedForEncodings (HWM, HwModeNames, NamespacesWithHwModes);
2464
2523
if (HwModeNames.empty ())
2465
2524
HwModeNames.push_back (" " );
2466
2525
@@ -2471,22 +2530,22 @@ namespace llvm {
2471
2530
if (const RecordVal *RV = InstDef->getValue (" EncodingInfos" )) {
2472
2531
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue ())) {
2473
2532
EncodingInfoByHwMode EBM (DI->getDef (), HWM);
2474
- for (auto &KV : EBM)
2475
- NumberedEncodings.emplace_back (
2476
- KV.second , NumberedInstruction,
2477
- HWM.getModeName (KV.first , /* IncludeDefault=*/ true ));
2533
+ for (auto &[ModeId, Encoding] : EBM) {
2534
+ // DecoderTables with DefaultMode should not have any suffix.
2535
+ if (ModeId == DefaultMode) {
2536
+ NumberedEncodings.emplace_back (Encoding, NumberedInstruction, " " );
2537
+ } else {
2538
+ NumberedEncodings.emplace_back (Encoding, NumberedInstruction,
2539
+ HWM.getMode (ModeId).Name );
2540
+ }
2541
+ }
2478
2542
continue ;
2479
2543
}
2480
2544
}
2481
- // This instruction is encoded the same on all HwModes. Emit it for all
2482
- // HwModes by default, otherwise leave it in a single common table.
2483
- if (DecoderEmitterSuppressDuplicates) {
2484
- NumberedEncodings.emplace_back (InstDef, NumberedInstruction, " AllModes" );
2485
- } else {
2486
- for (StringRef HwModeName : HwModeNames)
2487
- NumberedEncodings.emplace_back (InstDef, NumberedInstruction,
2488
- HwModeName);
2489
- }
2545
+ // This instruction is encoded the same on all HwModes.
2546
+ // According to user needs, provide varying degrees of suppression.
2547
+ handleHwModesUnrelatedEncodings (NumberedInstruction, HwModeNames,
2548
+ NamespacesWithHwModes, NumberedEncodings);
2490
2549
}
2491
2550
for (const auto &NumberedAlias :
2492
2551
RK.getAllDerivedDefinitions (" AdditionalEncoding" ))
0 commit comments