[llvm] [Sparc] Add errata workaround pass for GR712RC and UT700 (PR #103843)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 14 05:18:45 PDT 2024


================
@@ -19,6 +19,304 @@
 
 using namespace llvm;
 
+char ErrataWorkaround::ID = 0;
+
+ErrataWorkaround::ErrataWorkaround() : MachineFunctionPass(ID) {
+  initializeErrataWorkaroundPass(*PassRegistry::getPassRegistry());
+}
+
+INITIALIZE_PASS(ErrataWorkaround, "errata-workaround", "Errata workaround pass",
+                false, false)
+
+bool ErrataWorkaround::moveNext(MachineBasicBlock::iterator &I) {
+
+  MachineBasicBlock *MBB = I->getParent();
+
+  do {
+    I++;
+
+    while (I == MBB->end()) {
+      if (MBB->getFallThrough() == nullptr)
+        return false;
+      MBB = MBB->getFallThrough();
+      I = MBB->begin();
+    }
+  } while (I->isMetaInstruction() || I->isInlineAsm());
+
+  return true;
+}
+
+void ErrataWorkaround::insertNop(MachineBasicBlock::iterator I) {
+  BuildMI(*I->getParent(), I, I->getDebugLoc(), TII->get(SP::NOP));
+}
+
+bool ErrataWorkaround::isFloat(MachineBasicBlock::iterator I) {
+  if (I->getNumOperands() == 0)
+    return false;
+
+  if (!I->getOperand(0).isReg())
+    return false;
+
+  unsigned reg = I->getOperand(0).getReg();
+
+  if (!SP::FPRegsRegClass.contains(reg) && !SP::DFPRegsRegClass.contains(reg))
+    return false;
+
+  return true;
+}
+
+bool ErrataWorkaround::isDivSqrt(MachineBasicBlock::iterator I) {
+  switch (I->getOpcode()) {
+  case SP::FDIVS:
+  case SP::FDIVD:
+  case SP::FSQRTS:
+  case SP::FSQRTD:
+    return true;
+  }
+  return false;
+}
+
+// Prevents the following code sequence from being generated:
+// (stb/sth/st/stf) -> (single non-store/load instruction) -> (any store)
+// If the sequence is detected a NOP instruction is inserted after
+// the first store instruction.
+bool ErrataWorkaround::checkSeqTN0009A(MachineBasicBlock::iterator I) {
+  switch (I->getOpcode()) {
+  case SP::STrr:
+  case SP::STri:
+  case SP::STBrr:
+  case SP::STBri:
+  case SP::STHrr:
+  case SP::STHri:
+  case SP::STFrr:
+  case SP::STFri:
+    break;
+  default:
+    return false;
+  }
+
+  MachineBasicBlock::iterator MI = I;
+  if (!moveNext(MI))
+    return false;
+
+  if (MI->mayStore() || MI->mayLoad())
+    return false;
+
+  MachineBasicBlock::iterator PatchHere = MI;
+
+  if (!moveNext(MI))
+    return false;
+
+  if (!MI->mayStore())
+    return false;
+
+  insertNop(PatchHere);
+  return true;
+}
+
+// Prevents the following code sequence from being generated:
+// (std/stdf) -> (any store)
+// If the sequence is detected a NOP instruction is inserted after
+// the first store instruction.
+bool ErrataWorkaround::checkSeqTN0009B(MachineBasicBlock::iterator I) {
+
+  switch (I->getOpcode()) {
+  case SP::STDrr:
+  case SP::STDri:
+  case SP::STDFrr:
+  case SP::STDFri:
+    break;
+  default:
+    return false;
+  }
+
+  MachineBasicBlock::iterator MI = I;
+
+  if (!moveNext(MI))
+    return false;
+
+  if (!MI->mayStore())
+    return false;
+
+  insertNop(MI);
+  return true;
+}
+
+bool ErrataWorkaround::checkSeqTN0010(MachineBasicBlock::iterator I) {
----------------
koachan wrote:

Probably need a description for this too?

https://github.com/llvm/llvm-project/pull/103843


More information about the llvm-commits mailing list