122c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===-- AArch64A53Fix835769.cpp -------------------------------------------===//
222c310d78ce9630af15b0de94c18a409705b7496Tim Murray//
322c310d78ce9630af15b0de94c18a409705b7496Tim Murray//                     The LLVM Compiler Infrastructure
422c310d78ce9630af15b0de94c18a409705b7496Tim Murray//
522c310d78ce9630af15b0de94c18a409705b7496Tim Murray// This file is distributed under the University of Illinois Open Source
622c310d78ce9630af15b0de94c18a409705b7496Tim Murray// License. See LICENSE.TXT for details.
722c310d78ce9630af15b0de94c18a409705b7496Tim Murray//
822c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===----------------------------------------------------------------------===//
922c310d78ce9630af15b0de94c18a409705b7496Tim Murray// This pass changes code to work around Cortex-A53 erratum 835769.
1022c310d78ce9630af15b0de94c18a409705b7496Tim Murray// It works around it by inserting a nop instruction in code sequences that
1122c310d78ce9630af15b0de94c18a409705b7496Tim Murray// in some circumstances may trigger the erratum.
1222c310d78ce9630af15b0de94c18a409705b7496Tim Murray// It inserts a nop instruction between a sequence of the following 2 classes
1322c310d78ce9630af15b0de94c18a409705b7496Tim Murray// of instructions:
1422c310d78ce9630af15b0de94c18a409705b7496Tim Murray// instr 1: mem-instr (including loads, stores and prefetches).
1522c310d78ce9630af15b0de94c18a409705b7496Tim Murray// instr 2: non-SIMD integer multiply-accumulate writing 64-bit X registers.
1622c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===----------------------------------------------------------------------===//
1722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
1822c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "AArch64.h"
1922c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "AArch64InstrInfo.h"
2022c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "AArch64Subtarget.h"
2122c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/ADT/Statistic.h"
2222c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/CodeGen/MachineFunction.h"
2322c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/CodeGen/MachineFunctionPass.h"
2422c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/CodeGen/MachineInstr.h"
2522c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/CodeGen/MachineInstrBuilder.h"
2622c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/CodeGen/MachineRegisterInfo.h"
2722c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/Support/CommandLine.h"
2822c310d78ce9630af15b0de94c18a409705b7496Tim Murray#include "llvm/Support/Debug.h"
2922c310d78ce9630af15b0de94c18a409705b7496Tim Murray
3022c310d78ce9630af15b0de94c18a409705b7496Tim Murrayusing namespace llvm;
3122c310d78ce9630af15b0de94c18a409705b7496Tim Murray
3222c310d78ce9630af15b0de94c18a409705b7496Tim Murray#define DEBUG_TYPE "aarch64-fix-cortex-a53-835769"
3322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
3422c310d78ce9630af15b0de94c18a409705b7496Tim MurraySTATISTIC(NumNopsAdded, "Number of Nops added to work around erratum 835769");
3522c310d78ce9630af15b0de94c18a409705b7496Tim Murray
3622c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===----------------------------------------------------------------------===//
3722c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Helper functions
3822c310d78ce9630af15b0de94c18a409705b7496Tim Murray
3922c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Is the instruction a match for the instruction that comes first in the
4022c310d78ce9630af15b0de94c18a409705b7496Tim Murray// sequence of instructions that can trigger the erratum?
4122c310d78ce9630af15b0de94c18a409705b7496Tim Murraystatic bool isFirstInstructionInSequence(MachineInstr *MI) {
4222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Must return true if this instruction is a load, a store or a prefetch.
4322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  switch (MI->getOpcode()) {
4422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::PRFMl:
4522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::PRFMroW:
4622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::PRFMroX:
4722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::PRFMui:
4822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::PRFUMi:
4922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return true;
5022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  default:
5122c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return (MI->mayLoad() || MI->mayStore());
5222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
5322c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
5422c310d78ce9630af15b0de94c18a409705b7496Tim Murray
5522c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Is the instruction a match for the instruction that comes second in the
5622c310d78ce9630af15b0de94c18a409705b7496Tim Murray// sequence that can trigger the erratum?
5722c310d78ce9630af15b0de94c18a409705b7496Tim Murraystatic bool isSecondInstructionInSequence(MachineInstr *MI) {
5822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Must return true for non-SIMD integer multiply-accumulates, writing
5922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // to a 64-bit register.
6022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  switch (MI->getOpcode()) {
6122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Erratum cannot be triggered when the destination register is 32 bits,
6222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // therefore only include the following.
6322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::MSUBXrrr:
6422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::MADDXrrr:
6522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::SMADDLrrr:
6622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::SMSUBLrrr:
6722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::UMADDLrrr:
6822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  case AArch64::UMSUBLrrr:
6922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    // Erratum can only be triggered by multiply-adds, not by regular
7022c310d78ce9630af15b0de94c18a409705b7496Tim Murray    // non-accumulating multiplies, i.e. when Ra=XZR='11111'
7122c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return MI->getOperand(3).getReg() != AArch64::XZR;
7222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  default:
7322c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return false;
7422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
7522c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
7622c310d78ce9630af15b0de94c18a409705b7496Tim Murray
7722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
7822c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===----------------------------------------------------------------------===//
7922c310d78ce9630af15b0de94c18a409705b7496Tim Murray
8022c310d78ce9630af15b0de94c18a409705b7496Tim Murraynamespace {
8122c310d78ce9630af15b0de94c18a409705b7496Tim Murrayclass AArch64A53Fix835769 : public MachineFunctionPass {
8222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  const AArch64InstrInfo *TII;
8322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
8422c310d78ce9630af15b0de94c18a409705b7496Tim Murraypublic:
8522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  static char ID;
8622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  explicit AArch64A53Fix835769() : MachineFunctionPass(ID) {}
8722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
8822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  bool runOnMachineFunction(MachineFunction &F) override;
8922c310d78ce9630af15b0de94c18a409705b7496Tim Murray
9022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  const char *getPassName() const override {
9122c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return "Workaround A53 erratum 835769 pass";
9222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
9322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
9422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  void getAnalysisUsage(AnalysisUsage &AU) const override {
9522c310d78ce9630af15b0de94c18a409705b7496Tim Murray    AU.setPreservesCFG();
9622c310d78ce9630af15b0de94c18a409705b7496Tim Murray    MachineFunctionPass::getAnalysisUsage(AU);
9722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
9822c310d78ce9630af15b0de94c18a409705b7496Tim Murray
9922c310d78ce9630af15b0de94c18a409705b7496Tim Murrayprivate:
10022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  bool runOnBasicBlock(MachineBasicBlock &MBB);
10122c310d78ce9630af15b0de94c18a409705b7496Tim Murray};
10222c310d78ce9630af15b0de94c18a409705b7496Tim Murraychar AArch64A53Fix835769::ID = 0;
10322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
10422c310d78ce9630af15b0de94c18a409705b7496Tim Murray} // end anonymous namespace
10522c310d78ce9630af15b0de94c18a409705b7496Tim Murray
10622c310d78ce9630af15b0de94c18a409705b7496Tim Murray//===----------------------------------------------------------------------===//
10722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
10822c310d78ce9630af15b0de94c18a409705b7496Tim Murraybool
10922c310d78ce9630af15b0de94c18a409705b7496Tim MurrayAArch64A53Fix835769::runOnMachineFunction(MachineFunction &F) {
11022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  const TargetMachine &TM = F.getTarget();
11122c310d78ce9630af15b0de94c18a409705b7496Tim Murray
11222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  bool Changed = false;
11322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  DEBUG(dbgs() << "***** AArch64A53Fix835769 *****\n");
11422c310d78ce9630af15b0de94c18a409705b7496Tim Murray
11522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  TII = TM.getSubtarget<AArch64Subtarget>().getInstrInfo();
11622c310d78ce9630af15b0de94c18a409705b7496Tim Murray
11722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  for (auto &MBB : F) {
11822c310d78ce9630af15b0de94c18a409705b7496Tim Murray    Changed |= runOnBasicBlock(MBB);
11922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
12022c310d78ce9630af15b0de94c18a409705b7496Tim Murray
12122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  return Changed;
12222c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
12322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
12422c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Return the block that was fallen through to get to MBB, if any,
12522c310d78ce9630af15b0de94c18a409705b7496Tim Murray// otherwise nullptr.
12622c310d78ce9630af15b0de94c18a409705b7496Tim Murraystatic MachineBasicBlock *getBBFallenThrough(MachineBasicBlock *MBB,
12722c310d78ce9630af15b0de94c18a409705b7496Tim Murray                                             const TargetInstrInfo *TII) {
12822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Get the previous machine basic block in the function.
12922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  MachineFunction::iterator MBBI = *MBB;
13022c310d78ce9630af15b0de94c18a409705b7496Tim Murray
13122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Can't go off top of function.
13222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  if (MBBI == MBB->getParent()->begin())
13322c310d78ce9630af15b0de94c18a409705b7496Tim Murray    return nullptr;
13422c310d78ce9630af15b0de94c18a409705b7496Tim Murray
13522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
13622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  SmallVector<MachineOperand, 2> Cond;
13722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
13822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  MachineBasicBlock *PrevBB = std::prev(MBBI);
13922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  for (MachineBasicBlock *S : MBB->predecessors())
14022c310d78ce9630af15b0de94c18a409705b7496Tim Murray    if (S == PrevBB && !TII->AnalyzeBranch(*PrevBB, TBB, FBB, Cond) &&
14122c310d78ce9630af15b0de94c18a409705b7496Tim Murray        !TBB && !FBB)
14222c310d78ce9630af15b0de94c18a409705b7496Tim Murray      return S;
14322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
14422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  return nullptr;
14522c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
14622c310d78ce9630af15b0de94c18a409705b7496Tim Murray
14722c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Iterate through fallen through blocks trying to find a previous non-pseudo if
14822c310d78ce9630af15b0de94c18a409705b7496Tim Murray// there is one, otherwise return nullptr. Only look for instructions in
14922c310d78ce9630af15b0de94c18a409705b7496Tim Murray// previous blocks, not the current block, since we only use this to look at
15022c310d78ce9630af15b0de94c18a409705b7496Tim Murray// previous blocks.
15122c310d78ce9630af15b0de94c18a409705b7496Tim Murraystatic MachineInstr *getLastNonPseudo(MachineBasicBlock &MBB,
15222c310d78ce9630af15b0de94c18a409705b7496Tim Murray                                      const TargetInstrInfo *TII) {
15322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  MachineBasicBlock *FMBB = &MBB;
15422c310d78ce9630af15b0de94c18a409705b7496Tim Murray
15522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // If there is no non-pseudo in the current block, loop back around and try
15622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // the previous block (if there is one).
15722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  while ((FMBB = getBBFallenThrough(FMBB, TII))) {
15822c310d78ce9630af15b0de94c18a409705b7496Tim Murray    for (auto I = FMBB->rbegin(), E = FMBB->rend(); I != E; ++I) {
15922c310d78ce9630af15b0de94c18a409705b7496Tim Murray      if (!I->isPseudo())
16022c310d78ce9630af15b0de94c18a409705b7496Tim Murray        return &*I;
16122c310d78ce9630af15b0de94c18a409705b7496Tim Murray    }
16222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
16322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
16422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // There was no previous non-pseudo in the fallen through blocks
16522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  return nullptr;
16622c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
16722c310d78ce9630af15b0de94c18a409705b7496Tim Murray
16822c310d78ce9630af15b0de94c18a409705b7496Tim Murraystatic void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr* MI,
16922c310d78ce9630af15b0de94c18a409705b7496Tim Murray                                       const TargetInstrInfo *TII) {
17022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // If we are the first instruction of the block, put the NOP at the end of
17122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // the previous fallthrough block
17222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  if (MI == &MBB.front()) {
17322c310d78ce9630af15b0de94c18a409705b7496Tim Murray    MachineInstr *I = getLastNonPseudo(MBB, TII);
17422c310d78ce9630af15b0de94c18a409705b7496Tim Murray    assert(I && "Expected instruction");
17522c310d78ce9630af15b0de94c18a409705b7496Tim Murray    DebugLoc DL = I->getDebugLoc();
17622c310d78ce9630af15b0de94c18a409705b7496Tim Murray    BuildMI(I->getParent(), DL, TII->get(AArch64::HINT)).addImm(0);
17722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
17822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  else {
17922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    DebugLoc DL = MI->getDebugLoc();
18022c310d78ce9630af15b0de94c18a409705b7496Tim Murray    BuildMI(MBB, MI, DL, TII->get(AArch64::HINT)).addImm(0);
18122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
18222c310d78ce9630af15b0de94c18a409705b7496Tim Murray
18322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  ++NumNopsAdded;
18422c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
18522c310d78ce9630af15b0de94c18a409705b7496Tim Murray
18622c310d78ce9630af15b0de94c18a409705b7496Tim Murraybool
18722c310d78ce9630af15b0de94c18a409705b7496Tim MurrayAArch64A53Fix835769::runOnBasicBlock(MachineBasicBlock &MBB) {
18822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  bool Changed = false;
18922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  DEBUG(dbgs() << "Running on MBB: " << MBB << " - scanning instructions...\n");
19022c310d78ce9630af15b0de94c18a409705b7496Tim Murray
19122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // First, scan the basic block, looking for a sequence of 2 instructions
19222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // that match the conditions under which the erratum may trigger.
19322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
19422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // List of terminating instructions in matching sequences
19522c310d78ce9630af15b0de94c18a409705b7496Tim Murray  std::vector<MachineInstr*> Sequences;
19622c310d78ce9630af15b0de94c18a409705b7496Tim Murray  unsigned Idx = 0;
19722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  MachineInstr *PrevInstr = nullptr;
19822c310d78ce9630af15b0de94c18a409705b7496Tim Murray
19922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Try and find the last non-pseudo instruction in any fallen through blocks,
20022c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // if there isn't one, then we use nullptr to represent that.
20122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  PrevInstr = getLastNonPseudo(MBB, TII);
20222c310d78ce9630af15b0de94c18a409705b7496Tim Murray
20322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  for (auto &MI : MBB) {
20422c310d78ce9630af15b0de94c18a409705b7496Tim Murray    MachineInstr *CurrInstr = &MI;
20522c310d78ce9630af15b0de94c18a409705b7496Tim Murray    DEBUG(dbgs() << "  Examining: " << MI);
20622c310d78ce9630af15b0de94c18a409705b7496Tim Murray    if (PrevInstr) {
20722c310d78ce9630af15b0de94c18a409705b7496Tim Murray      DEBUG(dbgs() << "    PrevInstr: " << *PrevInstr
20822c310d78ce9630af15b0de94c18a409705b7496Tim Murray                   << "    CurrInstr: " << *CurrInstr
20922c310d78ce9630af15b0de94c18a409705b7496Tim Murray                   << "    isFirstInstructionInSequence(PrevInstr): "
21022c310d78ce9630af15b0de94c18a409705b7496Tim Murray                   << isFirstInstructionInSequence(PrevInstr) << "\n"
21122c310d78ce9630af15b0de94c18a409705b7496Tim Murray                   << "    isSecondInstructionInSequence(CurrInstr): "
21222c310d78ce9630af15b0de94c18a409705b7496Tim Murray                   << isSecondInstructionInSequence(CurrInstr) << "\n");
21322c310d78ce9630af15b0de94c18a409705b7496Tim Murray      if (isFirstInstructionInSequence(PrevInstr) &&
21422c310d78ce9630af15b0de94c18a409705b7496Tim Murray          isSecondInstructionInSequence(CurrInstr)) {
21522c310d78ce9630af15b0de94c18a409705b7496Tim Murray        DEBUG(dbgs() << "   ** pattern found at Idx " << Idx << "!\n");
21622c310d78ce9630af15b0de94c18a409705b7496Tim Murray        Sequences.push_back(CurrInstr);
21722c310d78ce9630af15b0de94c18a409705b7496Tim Murray      }
21822c310d78ce9630af15b0de94c18a409705b7496Tim Murray    }
21922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    if (!CurrInstr->isPseudo())
22022c310d78ce9630af15b0de94c18a409705b7496Tim Murray      PrevInstr = CurrInstr;
22122c310d78ce9630af15b0de94c18a409705b7496Tim Murray    ++Idx;
22222c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
22322c310d78ce9630af15b0de94c18a409705b7496Tim Murray
22422c310d78ce9630af15b0de94c18a409705b7496Tim Murray  DEBUG(dbgs() << "Scan complete, "<< Sequences.size()
22522c310d78ce9630af15b0de94c18a409705b7496Tim Murray               << " occurences of pattern found.\n");
22622c310d78ce9630af15b0de94c18a409705b7496Tim Murray
22722c310d78ce9630af15b0de94c18a409705b7496Tim Murray  // Then update the basic block, inserting nops between the detected sequences.
22822c310d78ce9630af15b0de94c18a409705b7496Tim Murray  for (auto &MI : Sequences) {
22922c310d78ce9630af15b0de94c18a409705b7496Tim Murray    Changed = true;
23022c310d78ce9630af15b0de94c18a409705b7496Tim Murray    insertNopBeforeInstruction(MBB, MI, TII);
23122c310d78ce9630af15b0de94c18a409705b7496Tim Murray  }
23222c310d78ce9630af15b0de94c18a409705b7496Tim Murray
23322c310d78ce9630af15b0de94c18a409705b7496Tim Murray  return Changed;
23422c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
23522c310d78ce9630af15b0de94c18a409705b7496Tim Murray
23622c310d78ce9630af15b0de94c18a409705b7496Tim Murray// Factory function used by AArch64TargetMachine to add the pass to
23722c310d78ce9630af15b0de94c18a409705b7496Tim Murray// the passmanager.
23822c310d78ce9630af15b0de94c18a409705b7496Tim MurrayFunctionPass *llvm::createAArch64A53Fix835769() {
23922c310d78ce9630af15b0de94c18a409705b7496Tim Murray  return new AArch64A53Fix835769();
24022c310d78ce9630af15b0de94c18a409705b7496Tim Murray}
241