diff options
| author | Simon Dardis <simon.dardis@imgtec.com> | 2016-12-13 11:07:51 +0000 | 
|---|---|---|
| committer | Simon Dardis <simon.dardis@imgtec.com> | 2016-12-13 11:07:51 +0000 | 
| commit | 43b5ce492d4480c6bca08351e36f47da8413776c (patch) | |
| tree | bb367c86f15aebffca94018cece1a7a40c575bf9 /llvm/lib/Target/Mips | |
| parent | 2d9adbf5244292537b30946570ac73ff8b2219b8 (diff) | |
| download | bcm5719-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')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsHazardSchedule.cpp | 64 | 
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++;        }      } | 

