summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2016-12-13 11:07:51 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2016-12-13 11:07:51 +0000
commit43b5ce492d4480c6bca08351e36f47da8413776c (patch)
treebb367c86f15aebffca94018cece1a7a40c575bf9 /llvm/lib/Target/Mips/MipsHazardSchedule.cpp
parent2d9adbf5244292537b30946570ac73ff8b2219b8 (diff)
downloadbcm5719-llvm-43b5ce492d4480c6bca08351e36f47da8413776c.tar.gz
bcm5719-llvm-43b5ce492d4480c6bca08351e36f47da8413776c.zip
[mips] Fix compact branch hazard detection
In certain cases it is possible that transient instructions such as %reg = IMPLICIT_DEF as a single instruction in a basic block to reach the MipsHazardSchedule pass. This patch teaches MipsHazardSchedule to properly look through such cases. Reviewers: vkalintiris, zoran.jovanovic Differential Revision: https://reviews.llvm.org/D27209 llvm-svn: 289529
Diffstat (limited to 'llvm/lib/Target/Mips/MipsHazardSchedule.cpp')
-rw-r--r--llvm/lib/Target/Mips/MipsHazardSchedule.cpp64
1 files changed, 42 insertions, 22 deletions
diff --git a/llvm/lib/Target/Mips/MipsHazardSchedule.cpp b/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
index 7ff7b15113c..430b5fdf7c4 100644
--- a/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
+++ b/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
@@ -91,20 +91,44 @@ FunctionPass *llvm::createMipsHazardSchedule() {
return new MipsHazardSchedule();
}
-// Find the next real instruction from the current position.
-static Iter getNextMachineInstr(Iter Position) {
+// Find the next real instruction from the current position in current basic
+// block.
+static Iter getNextMachineInstrInBB(Iter Position) {
Iter I = Position, E = Position->getParent()->end();
- I = std::find_if_not(I, E, [](const Iter &Insn) { return Insn->isTransient(); });
- assert(I != E);
+ I = std::find_if_not(I, E,
+ [](const Iter &Insn) { return Insn->isTransient(); });
+
return I;
}
+// Find the next real instruction from the current position, looking through
+// basic block boundaries.
+static Iter getNextMachineInstr(Iter Position) {
+ if (std::next(Position) == Position->getParent()->end()) {
+ const MachineBasicBlock * MBB = (&*Position)->getParent();
+ for (auto *Succ : MBB->successors()) {
+ if (MBB->isLayoutSuccessor(Succ)) {
+ Iter I = Succ->begin();
+ Iter Next = getNextMachineInstrInBB(I);
+ if (Next == Succ->end()) {
+ return getNextMachineInstr(I);
+ } else {
+ return I;
+ }
+ }
+ }
+ llvm_unreachable("Should have identified the end of the function earlier!");
+ }
+
+ return getNextMachineInstrInBB(Position);
+}
+
bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) {
const MipsSubtarget *STI =
&static_cast<const MipsSubtarget &>(MF.getSubtarget());
- // Forbidden slot hazards are only defined for MIPSR6.
+ // Forbidden slot hazards are only defined for MIPSR6 but not microMIPSR6.
if (!STI->hasMips32r6() || STI->inMicroMipsMode())
return false;
@@ -118,27 +142,23 @@ bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) {
if (!TII->HasForbiddenSlot(*I))
continue;
- bool InsertNop = false;
- // Next instruction in the basic block.
- if (std::next(I) != FI->end() &&
- !TII->SafeInForbiddenSlot(*getNextMachineInstr(std::next(I)))) {
- InsertNop = true;
- } else {
- // Next instruction in the physical successor basic block.
- for (auto *Succ : FI->successors()) {
- if (FI->isLayoutSuccessor(Succ) &&
- getNextMachineInstr(Succ->begin()) != Succ->end() &&
- !TII->SafeInForbiddenSlot(*getNextMachineInstr(Succ->begin()))) {
- InsertNop = true;
- break;
- }
+ Iter Inst;
+ bool LastInstInFunction =
+ std::next(I) == FI->end() && std::next(FI) == MF.end();
+ if (!LastInstInFunction) {
+ if (std::next(I) != FI->end()) {
+ // Start looking from the next instruction in the basic block.
+ Inst = getNextMachineInstr(std::next(I));
+ } else {
+ // Next instruction in the physical successor basic block.
+ Inst = getNextMachineInstr(I);
}
}
- if (InsertNop) {
+ if (LastInstInFunction || !TII->SafeInForbiddenSlot(*Inst)) {
Changed = true;
- MIBundleBuilder(&*I).append(
- BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP)));
+ MIBundleBuilder(&*I)
+ .append(BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP)));
NumInsertedNops++;
}
}
OpenPOWER on IntegriCloud