@@ -54,10 +54,27 @@ 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(
67
+ clEnumValN (
68
+ SUPPRESSION_DISABLE, " O0" ,
69
+ " Do not prevent DecoderTable duplications caused by HwModes" ),
70
+ clEnumValN(
71
+ SUPPRESSION_LEVEL1, " O1" ,
72
+ " Remove duplicate DecoderTable entries generated due to HwModes" ),
73
+ clEnumValN(
74
+ SUPPRESSION_LEVEL2, " O2" ,
75
+ " Extract HwModes-specific instructions into new DecoderTables, "
76
+ " significantly reducing Table Duplications" )),
77
+ cl::init(SUPPRESSION_DISABLE), cl::cat(DisassemblerEmitterCat));
61
78
62
79
namespace {
63
80
@@ -128,6 +145,7 @@ struct EncodingIDAndOpcode {
128
145
};
129
146
130
147
using EncodingIDsVec = std::vector<EncodingIDAndOpcode>;
148
+ using NamespacesHwModesMap = std::map<std::string, std::set<StringRef>>;
131
149
132
150
raw_ostream &operator <<(raw_ostream &OS, const EncodingAndInst &Value) {
133
151
if (Value.EncodingDef != Value.Inst ->TheDef )
@@ -2417,21 +2435,65 @@ static bool Check(DecodeStatus &Out, DecodeStatus In) {
2417
2435
2418
2436
// Collect all HwModes referenced by the target for encoding purposes,
2419
2437
// returning a vector of corresponding names.
2420
- static void
2421
- collectHwModesReferencedForEncodings ( const CodeGenHwModes &HWM,
2422
- std::vector<StringRef> &Names ) {
2438
+ static void collectHwModesReferencedForEncodings (
2439
+ const CodeGenHwModes &HWM, std::vector<StringRef> &Names ,
2440
+ NamespacesHwModesMap &NamespacesWithHwModes ) {
2423
2441
SmallBitVector BV (HWM.getNumModeIds ());
2424
2442
for (const auto &MS : HWM.getHwModeSelects ()) {
2425
2443
for (const HwModeSelect::PairType &P : MS.second .Items ) {
2426
- if (P.second ->isSubClassOf (" InstructionEncoding" ))
2444
+ if (P.second ->isSubClassOf (" InstructionEncoding" )) {
2445
+ std::string DecoderNamespace =
2446
+ std::string (P.second ->getValueAsString (" DecoderNamespace" ));
2447
+ if (P.first == DefaultMode) {
2448
+ NamespacesWithHwModes[DecoderNamespace].insert (" " );
2449
+ } else {
2450
+ NamespacesWithHwModes[DecoderNamespace].insert (
2451
+ HWM.getMode (P.first ).Name );
2452
+ }
2427
2453
BV.set (P.first );
2454
+ }
2428
2455
}
2429
2456
}
2430
2457
transform (BV.set_bits (), std::back_inserter (Names), [&HWM](const int &M) {
2458
+ if (M == DefaultMode)
2459
+ return StringRef (" " );
2431
2460
return HWM.getModeName (M, /* IncludeDefault=*/ true );
2432
2461
});
2433
2462
}
2434
2463
2464
+ static void
2465
+ handleHwModesUnrelatedEncodings (const CodeGenInstruction *Instr,
2466
+ const std::vector<StringRef> &HwModeNames,
2467
+ NamespacesHwModesMap &NamespacesWithHwModes,
2468
+ std::vector<EncodingAndInst> &GlobalEncodings) {
2469
+ const Record *InstDef = Instr->TheDef ;
2470
+
2471
+ switch (DecoderEmitterSuppressDuplicates) {
2472
+ case SUPPRESSION_DISABLE: {
2473
+ for (StringRef HwModeName : HwModeNames)
2474
+ GlobalEncodings.emplace_back (InstDef, Instr, HwModeName);
2475
+ break ;
2476
+ }
2477
+ case SUPPRESSION_LEVEL1: {
2478
+ std::string DecoderNamespace =
2479
+ std::string (InstDef->getValueAsString (" DecoderNamespace" ));
2480
+ auto It = NamespacesWithHwModes.find (DecoderNamespace);
2481
+ if (It != NamespacesWithHwModes.end ()) {
2482
+ for (StringRef HwModeName : It->second )
2483
+ GlobalEncodings.emplace_back (InstDef, Instr, HwModeName);
2484
+ } else {
2485
+ // Only emit the encoding once, as it's DecoderNamespace doesn't
2486
+ // contain any HwModes.
2487
+ GlobalEncodings.emplace_back (InstDef, Instr, " " );
2488
+ }
2489
+ break ;
2490
+ }
2491
+ case SUPPRESSION_LEVEL2:
2492
+ GlobalEncodings.emplace_back (InstDef, Instr, " " );
2493
+ break ;
2494
+ }
2495
+ }
2496
+
2435
2497
// Emits disassembler code for instruction decoding.
2436
2498
void DecoderEmitter::run (raw_ostream &o) {
2437
2499
formatted_raw_ostream OS (o);
@@ -2457,10 +2519,12 @@ namespace llvm {
2457
2519
// Parameterize the decoders based on namespace and instruction width.
2458
2520
2459
2521
// First, collect all encoding-related HwModes referenced by the target.
2522
+ // And establish a mapping table between DecoderNamespace and HwMode.
2460
2523
// If HwModeNames is empty, add the empty string so we always have one HwMode.
2461
2524
const CodeGenHwModes &HWM = Target.getHwModes ();
2462
2525
std::vector<StringRef> HwModeNames;
2463
- collectHwModesReferencedForEncodings (HWM, HwModeNames);
2526
+ NamespacesHwModesMap NamespacesWithHwModes;
2527
+ collectHwModesReferencedForEncodings (HWM, HwModeNames, NamespacesWithHwModes);
2464
2528
if (HwModeNames.empty ())
2465
2529
HwModeNames.push_back (" " );
2466
2530
@@ -2471,22 +2535,22 @@ namespace llvm {
2471
2535
if (const RecordVal *RV = InstDef->getValue (" EncodingInfos" )) {
2472
2536
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue ())) {
2473
2537
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 ));
2538
+ for (auto &[ModeId, Encoding] : EBM) {
2539
+ // DecoderTables with DefaultMode should not have any suffix.
2540
+ if (ModeId == DefaultMode) {
2541
+ NumberedEncodings.emplace_back (Encoding, NumberedInstruction, " " );
2542
+ } else {
2543
+ NumberedEncodings.emplace_back (Encoding, NumberedInstruction,
2544
+ HWM.getMode (ModeId).Name );
2545
+ }
2546
+ }
2478
2547
continue ;
2479
2548
}
2480
2549
}
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
- }
2550
+ // This instruction is encoded the same on all HwModes.
2551
+ // According to user needs, provide varying degrees of suppression.
2552
+ handleHwModesUnrelatedEncodings (NumberedInstruction, HwModeNames,
2553
+ NamespacesWithHwModes, NumberedEncodings);
2490
2554
}
2491
2555
for (const auto &NumberedAlias :
2492
2556
RK.getAllDerivedDefinitions (" AdditionalEncoding" ))
0 commit comments