diff options
Diffstat (limited to 'lib/Target/Sparc/DelaySlotFiller.cpp')
| -rw-r--r-- | lib/Target/Sparc/DelaySlotFiller.cpp | 62 | 
1 files changed, 27 insertions, 35 deletions
diff --git a/lib/Target/Sparc/DelaySlotFiller.cpp b/lib/Target/Sparc/DelaySlotFiller.cpp index 9a0466aa692d..f3441ffcf6a6 100644 --- a/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/lib/Target/Sparc/DelaySlotFiller.cpp @@ -12,13 +12,13 @@  // NOP is placed.  //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "delay-slot-filler"  #include "Sparc.h"  #include "SparcSubtarget.h"  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/Statistic.h"  #include "llvm/CodeGen/MachineFunctionPass.h"  #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h"  #include "llvm/Support/CommandLine.h"  #include "llvm/Target/TargetInstrInfo.h"  #include "llvm/Target/TargetMachine.h" @@ -26,6 +26,8 @@  using namespace llvm; +#define DEBUG_TYPE "delay-slot-filler" +  STATISTIC(FilledSlots, "Number of delay slots filled");  static cl::opt<bool> DisableDelaySlotFiller( @@ -48,22 +50,24 @@ namespace {          Subtarget(&TM.getSubtarget<SparcSubtarget>()) {      } -    virtual const char *getPassName() const { +    const char *getPassName() const override {        return "SPARC Delay Slot Filler";      }      bool runOnMachineBasicBlock(MachineBasicBlock &MBB); -    bool runOnMachineFunction(MachineFunction &F) { +    bool runOnMachineFunction(MachineFunction &F) override {        bool Changed = false; + +      // This pass invalidates liveness information when it reorders +      // instructions to fill delay slot. +      F.getRegInfo().invalidateLiveness(); +        for (MachineFunction::iterator FI = F.begin(), FE = F.end();             FI != FE; ++FI)          Changed |= runOnMachineBasicBlock(*FI);        return Changed;      } -    bool isDelayFiller(MachineBasicBlock &MBB, -                       MachineBasicBlock::iterator candidate); -      void insertCallDefsUses(MachineBasicBlock::iterator MI,                              SmallSet<unsigned, 32>& RegDefs,                              SmallSet<unsigned, 32>& RegUses); @@ -152,6 +156,10 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {        assert (J != MBB.end() && "MI needs a delay instruction.");        BuildMI(MBB, ++J, MI->getDebugLoc(),                TII->get(SP::UNIMP)).addImm(structSize); +      // Bundle the delay filler and unimp with the instruction. +      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J); +    } else { +      MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);      }    }    return Changed; @@ -204,12 +212,8 @@ Filler::findDelayInstr(MachineBasicBlock &MBB,      if (I->isDebugValue())        continue; - -    if (I->hasUnmodeledSideEffects() -        || I->isInlineAsm() -        || I->isLabel() -        || I->hasDelaySlot() -        || isDelayFiller(MBB, I)) +    if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || +        I->hasDelaySlot() || I->isBundledWithSucc())        break;      if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) { @@ -278,19 +282,19 @@ void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,    switch(MI->getOpcode()) {    default: llvm_unreachable("Unknown opcode.");    case SP::CALL: break; -  case SP::JMPLrr: -  case SP::JMPLri: +  case SP::CALLrr: +  case SP::CALLri:      assert(MI->getNumOperands() >= 2);      const MachineOperand &Reg = MI->getOperand(0); -    assert(Reg.isReg() && "JMPL first operand is not a register."); -    assert(Reg.isUse() && "JMPL first operand is not a use."); +    assert(Reg.isReg() && "CALL first operand is not a register."); +    assert(Reg.isUse() && "CALL first operand is not a use.");      RegUses.insert(Reg.getReg());      const MachineOperand &RegOrImm = MI->getOperand(1);      if (RegOrImm.isImm())          break; -    assert(RegOrImm.isReg() && "JMPLrr second operand is not a register."); -    assert(RegOrImm.isUse() && "JMPLrr second operand is not a use."); +    assert(RegOrImm.isReg() && "CALLrr second operand is not a register."); +    assert(RegOrImm.isUse() && "CALLrr second operand is not a use.");      RegUses.insert(RegOrImm.getReg());      break;    } @@ -332,18 +336,6 @@ bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)    return false;  } -// return true if the candidate is a delay filler. -bool Filler::isDelayFiller(MachineBasicBlock &MBB, -                           MachineBasicBlock::iterator candidate) -{ -  if (candidate == MBB.begin()) -    return false; -  if (candidate->getOpcode() == SP::UNIMP) -    return true; -  --candidate; -  return candidate->hasDelaySlot(); -} -  bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)  {    if (!I->isCall()) @@ -353,8 +345,8 @@ bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)    switch (I->getOpcode()) {    default: llvm_unreachable("Unknown call opcode.");    case SP::CALL: structSizeOpNum = 1; break; -  case SP::JMPLrr: -  case SP::JMPLri: structSizeOpNum = 2; break; +  case SP::CALLrr: +  case SP::CALLri: structSizeOpNum = 2; break;    case SP::TLS_CALL: return false;    } @@ -484,10 +476,10 @@ bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,           && MBBI->getOperand(1).getReg() == SP::G0           && MBBI->getOperand(2).getReg() == SP::G0); -  MachineBasicBlock::iterator PrevInst = MBBI; --PrevInst; +  MachineBasicBlock::iterator PrevInst = std::prev(MBBI); -  // It cannot combine with a delay filler. -  if (isDelayFiller(MBB, PrevInst)) +  // It cannot be combined with a bundled instruction. +  if (PrevInst->isBundledWithSucc())      return false;    const TargetInstrInfo *TII = TM.getInstrInfo();  | 
