//===----------------------------------------------------------------------===//
#include "AArch64.h"
-#include "AArch64InstrInfo.h"
-#include "AArch64Subtarget.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetInstrInfo.h"
using namespace llvm;
namespace {
class AArch64A53Fix835769 : public MachineFunctionPass {
- const AArch64InstrInfo *TII;
+ const TargetInstrInfo *TII;
public:
static char ID;
bool
AArch64A53Fix835769::runOnMachineFunction(MachineFunction &F) {
- const TargetMachine &TM = F.getTarget();
-
- bool Changed = false;
DEBUG(dbgs() << "***** AArch64A53Fix835769 *****\n");
-
- TII = TM.getSubtarget<AArch64Subtarget>().getInstrInfo();
+ bool Changed = false;
+ TII = F.getSubtarget().getInstrInfo();
for (auto &MBB : F) {
Changed |= runOnBasicBlock(MBB);
}
-
return Changed;
}
// Return the block that was fallen through to get to MBB, if any,
// otherwise nullptr.
-static MachineBasicBlock *getBBFallenThrough(MachineBasicBlock &MBB,
+static MachineBasicBlock *getBBFallenThrough(MachineBasicBlock *MBB,
const TargetInstrInfo *TII) {
// Get the previous machine basic block in the function.
- MachineFunction::iterator MBBI = MBB;
+ MachineFunction::iterator MBBI = *MBB;
// Can't go off top of function.
- if (MBBI == MBB.getParent()->begin())
+ if (MBBI == MBB->getParent()->begin())
return nullptr;
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
SmallVector<MachineOperand, 2> Cond;
MachineBasicBlock *PrevBB = std::prev(MBBI);
- for (MachineBasicBlock *S : MBB.predecessors())
+ for (MachineBasicBlock *S : MBB->predecessors())
if (S == PrevBB && !TII->AnalyzeBranch(*PrevBB, TBB, FBB, Cond) &&
!TBB && !FBB)
return S;
return nullptr;
}
-static MachineInstr *getLastNonPseudo(MachineBasicBlock *MBB) {
- for (auto I = MBB->rbegin(), E = MBB->rend(); I != E; ++I) {
- if (!I->isPseudo())
- return &*I;
+// Iterate through fallen through blocks trying to find a previous non-pseudo if
+// there is one, otherwise return nullptr. Only look for instructions in
+// previous blocks, not the current block, since we only use this to look at
+// previous blocks.
+static MachineInstr *getLastNonPseudo(MachineBasicBlock &MBB,
+ const TargetInstrInfo *TII) {
+ MachineBasicBlock *FMBB = &MBB;
+
+ // If there is no non-pseudo in the current block, loop back around and try
+ // the previous block (if there is one).
+ while ((FMBB = getBBFallenThrough(FMBB, TII))) {
+ for (auto I = FMBB->rbegin(), E = FMBB->rend(); I != E; ++I) {
+ if (!I->isPseudo())
+ return &*I;
+ }
}
- llvm_unreachable("Expected to find a non-pseudo instruction");
+ // There was no previous non-pseudo in the fallen through blocks
+ return nullptr;
}
static void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr* MI,
// If we are the first instruction of the block, put the NOP at the end of
// the previous fallthrough block
if (MI == &MBB.front()) {
- MachineBasicBlock *PMBB = getBBFallenThrough(MBB, TII);
- assert(PMBB && "Expected basic block");
- MachineInstr *I = getLastNonPseudo(PMBB);
+ MachineInstr *I = getLastNonPseudo(MBB, TII);
assert(I && "Expected instruction");
DebugLoc DL = I->getDebugLoc();
- BuildMI(PMBB, DL, TII->get(AArch64::HINT)).addImm(0);
+ BuildMI(I->getParent(), DL, TII->get(AArch64::HINT)).addImm(0);
}
else {
DebugLoc DL = MI->getDebugLoc();
unsigned Idx = 0;
MachineInstr *PrevInstr = nullptr;
- if (MachineBasicBlock *PMBB = getBBFallenThrough(MBB, TII))
- PrevInstr = getLastNonPseudo(PMBB);
+ // Try and find the last non-pseudo instruction in any fallen through blocks,
+ // if there isn't one, then we use nullptr to represent that.
+ PrevInstr = getLastNonPseudo(MBB, TII);
for (auto &MI : MBB) {
MachineInstr *CurrInstr = &MI;