14
14
#include " llvm/MCA/InstrBuilder.h"
15
15
#include " llvm/ADT/APInt.h"
16
16
#include " llvm/ADT/DenseMap.h"
17
+ #include " llvm/ADT/Hashing.h"
17
18
#include " llvm/ADT/Statistic.h"
18
19
#include " llvm/MC/MCInst.h"
19
20
#include " llvm/Support/Debug.h"
@@ -504,6 +505,24 @@ void InstrBuilder::populateReads(InstrDesc &ID, const MCInst &MCI,
504
505
ID.Reads .resize (CurrentUse);
505
506
}
506
507
508
+ hash_code hashMCOperand (const MCOperand &MCO) {
509
+ hash_code TypeHash = hash_combine (MCO.isReg (), MCO.isImm (), MCO.isSFPImm (),
510
+ MCO.isDFPImm (), MCO.isExpr (), MCO.isInst ());
511
+ if (MCO.isReg ())
512
+ return hash_combine (TypeHash, MCO.getReg ());
513
+
514
+ return TypeHash;
515
+ }
516
+
517
+ hash_code hashMCInst (const MCInst &MCI) {
518
+ hash_code InstructionHash = hash_combine (MCI.getOpcode (), MCI.getFlags ());
519
+ for (unsigned I = 0 ; I < MCI.getNumOperands (); ++I) {
520
+ InstructionHash =
521
+ hash_combine (InstructionHash, hashMCOperand (MCI.getOperand (I)));
522
+ }
523
+ return InstructionHash;
524
+ }
525
+
507
526
Error InstrBuilder::verifyInstrDesc (const InstrDesc &ID,
508
527
const MCInst &MCI) const {
509
528
if (ID.NumMicroOps != 0 )
@@ -521,6 +540,22 @@ Error InstrBuilder::verifyInstrDesc(const InstrDesc &ID,
521
540
return make_error<InstructionError<MCInst>>(std::string (Message), MCI);
522
541
}
523
542
543
+ Expected<unsigned > InstrBuilder::getVariantSchedClassID (const MCInst &MCI,
544
+ unsigned SchedClassID) {
545
+ const MCSchedModel &SM = STI.getSchedModel ();
546
+ unsigned CPUID = SM.getProcessorID ();
547
+ while (SchedClassID && SM.getSchedClassDesc (SchedClassID)->isVariant ())
548
+ SchedClassID =
549
+ STI.resolveVariantSchedClass (SchedClassID, &MCI, &MCII, CPUID);
550
+
551
+ if (!SchedClassID) {
552
+ return make_error<InstructionError<MCInst>>(
553
+ " unable to resolve scheduling class for write variant." , MCI);
554
+ }
555
+
556
+ return SchedClassID;
557
+ }
558
+
524
559
Expected<const InstrDesc &>
525
560
InstrBuilder::createInstrDescImpl (const MCInst &MCI,
526
561
const SmallVector<Instrument *> &IVec) {
@@ -539,15 +574,13 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
539
574
540
575
// Try to solve variant scheduling classes.
541
576
if (IsVariant) {
542
- unsigned CPUID = SM.getProcessorID ();
543
- while (SchedClassID && SM.getSchedClassDesc (SchedClassID)->isVariant ())
544
- SchedClassID =
545
- STI.resolveVariantSchedClass (SchedClassID, &MCI, &MCII, CPUID);
546
-
547
- if (!SchedClassID) {
548
- return make_error<InstructionError<MCInst>>(
549
- " unable to resolve scheduling class for write variant." , MCI);
577
+ Expected<unsigned > VariantSchedClassIDOrErr =
578
+ getVariantSchedClassID (MCI, SchedClassID);
579
+ if (!VariantSchedClassIDOrErr) {
580
+ return VariantSchedClassIDOrErr.takeError ();
550
581
}
582
+
583
+ SchedClassID = *VariantSchedClassIDOrErr;
551
584
}
552
585
553
586
// Check if this instruction is supported. Otherwise, report an error.
@@ -605,7 +638,10 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
605
638
return *Descriptors[DKey];
606
639
}
607
640
608
- auto VDKey = std::make_pair (&MCI, SchedClassID);
641
+ auto VDKey = std::make_pair (hashMCInst (MCI), SchedClassID);
642
+ assert (
643
+ !VariantDescriptors.contains (VDKey) &&
644
+ " Expected VariantDescriptors to not already have a value for this key." );
609
645
VariantDescriptors[VDKey] = std::move (ID);
610
646
return *VariantDescriptors[VDKey];
611
647
}
@@ -620,9 +656,15 @@ InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI,
620
656
if (Descriptors.find_as (DKey) != Descriptors.end ())
621
657
return *Descriptors[DKey];
622
658
623
- unsigned CPUID = STI.getSchedModel ().getProcessorID ();
624
- SchedClassID = STI.resolveVariantSchedClass (SchedClassID, &MCI, &MCII, CPUID);
625
- auto VDKey = std::make_pair (&MCI, SchedClassID);
659
+ Expected<unsigned > VariantSchedClassIDOrErr =
660
+ getVariantSchedClassID (MCI, SchedClassID);
661
+ if (!VariantSchedClassIDOrErr) {
662
+ return VariantSchedClassIDOrErr.takeError ();
663
+ }
664
+
665
+ SchedClassID = *VariantSchedClassIDOrErr;
666
+
667
+ auto VDKey = std::make_pair (hashMCInst (MCI), SchedClassID);
626
668
if (VariantDescriptors.contains (VDKey))
627
669
return *VariantDescriptors[VDKey];
628
670
0 commit comments