17c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner//===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//                     The LLVM Compiler Infrastructure
420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//===----------------------------------------------------------------------===//
920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
1071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju// This is a simple local pass that attempts to fill delay slots with useful
1171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju// instructions. If no instructions can be moved into the delay slot, then a
1271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju// NOP is placed.
1320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//===----------------------------------------------------------------------===//
1420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
1571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#define DEBUG_TYPE "delay-slot-filler"
167c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "Sparc.h"
1720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineFunctionPass.h"
1820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineInstrBuilder.h"
1971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#include "llvm/Support/CommandLine.h"
20870248b16491c9a9a604494b4e7aa94035af2158Brian Gaeke#include "llvm/Target/TargetMachine.h"
21870248b16491c9a9a604494b4e7aa94035af2158Brian Gaeke#include "llvm/Target/TargetInstrInfo.h"
2271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#include "llvm/Target/TargetRegisterInfo.h"
2371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#include "llvm/ADT/SmallSet.h"
2474dfcf12000fcec60e1854f7bb78d481347a0a4bBrian Gaeke#include "llvm/ADT/Statistic.h"
2571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
2620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekeusing namespace llvm;
2720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
2895b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(FilledSlots, "Number of delay slots filled");
2920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
3071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajustatic cl::opt<bool> DisableDelaySlotFiller(
3171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  "disable-sparc-delay-filler",
3271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  cl::init(false),
3371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  cl::desc("Disable the Sparc delay slot filler."),
3471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  cl::Hidden);
3571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
3695b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
3720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  struct Filler : public MachineFunctionPass {
3820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    /// Target machine description which we query for reg. names, data
3920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    /// layout, etc.
4020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    ///
4120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    TargetMachine &TM;
42870248b16491c9a9a604494b4e7aa94035af2158Brian Gaeke    const TargetInstrInfo *TII;
4320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
441997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel    static char ID;
45794fd75c67a2cdc128d67342c6d88a504d186896Devang Patel    Filler(TargetMachine &tm)
4690c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson      : MachineFunctionPass(ID), TM(tm), TII(tm.getInstrInfo()) { }
4720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
487c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner    virtual const char *getPassName() const {
497c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      return "SPARC Delay Slot Filler";
5020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
5120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
527c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner    bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
537c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner    bool runOnMachineFunction(MachineFunction &F) {
5420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      bool Changed = false;
557c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      for (MachineFunction::iterator FI = F.begin(), FE = F.end();
5620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke           FI != FE; ++FI)
577c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner        Changed |= runOnMachineBasicBlock(*FI);
5820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      return Changed;
5920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
6020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
6171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    bool isDelayFiller(MachineBasicBlock &MBB,
6271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                       MachineBasicBlock::iterator candidate);
6371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
6471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    void insertCallUses(MachineBasicBlock::iterator MI,
6571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        SmallSet<unsigned, 32>& RegUses);
6671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
6771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    void insertDefsUses(MachineBasicBlock::iterator MI,
6871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        SmallSet<unsigned, 32>& RegDefs,
6971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        SmallSet<unsigned, 32>& RegUses);
7071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
7171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
7271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                    unsigned Reg);
7371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
7471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    bool delayHasHazard(MachineBasicBlock::iterator candidate,
7571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        bool &sawLoad, bool &sawStore,
7671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        SmallSet<unsigned, 32> &RegDefs,
7771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                        SmallSet<unsigned, 32> &RegUses);
7871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
7971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    MachineBasicBlock::iterator
8071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot);
8171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
8258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize);
8371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
8420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  };
851997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel  char Filler::ID = 0;
8620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke} // end of anonymous namespace
8720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
887c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner/// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
897c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner/// slots in Sparc MachineFunctions
9020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke///
917c90f73a1b06040d971a3dd95a491031ae6238d5Chris LattnerFunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) {
927c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner  return new Filler(tm);
9320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke}
9420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
9558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
9620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
9771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju/// We assume there is only one delay slot per delayed instruction.
9820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke///
997c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattnerbool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
1000f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke  bool Changed = false;
10171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
1027c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner  for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
1035a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (I->hasDelaySlot()) {
10471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      MachineBasicBlock::iterator D = MBB.end();
10520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      MachineBasicBlock::iterator J = I;
10671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
10771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      if (!DisableDelaySlotFiller)
10871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        D = findDelayInstr(MBB, I);
10971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
11020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      ++FilledSlots;
1110f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke      Changed = true;
11271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
11371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      if (D == MBB.end())
11471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        BuildMI(MBB, ++J, I->getDebugLoc(), TII->get(SP::NOP));
11571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      else
11671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        MBB.splice(++J, &MBB, D);
11758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju      unsigned structSize = 0;
11858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju      if (needsUnimp(I, structSize)) {
11958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju        MachineBasicBlock::iterator J = I;
12058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju        ++J; //skip the delay filler.
12158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju        BuildMI(MBB, ++J, I->getDebugLoc(),
12258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju                TII->get(SP::UNIMP)).addImm(structSize);
12358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju      }
12420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
1250f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke  return Changed;
12620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke}
12771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
12871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman GovindarajuMachineBasicBlock::iterator
12971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman GovindarajuFiller::findDelayInstr(MachineBasicBlock &MBB,
13071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                       MachineBasicBlock::iterator slot)
13171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
13271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  SmallSet<unsigned, 32> RegDefs;
13371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  SmallSet<unsigned, 32> RegUses;
13471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  bool sawLoad = false;
13571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  bool sawStore = false;
13671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
13771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  MachineBasicBlock::iterator I = slot;
13871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
13971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  if (slot->getOpcode() == SP::RET)
14071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    return MBB.end();
14171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
14271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  if (slot->getOpcode() == SP::RETL) {
14371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    --I;
14471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (I->getOpcode() != SP::RESTORErr)
14571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      return MBB.end();
14671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    //change retl to ret
14771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    slot->setDesc(TII->get(SP::RET));
14871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    return I;
14971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
15071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
15171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  //Call's delay filler can def some of call's uses.
1525a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (slot->isCall())
15371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    insertCallUses(slot, RegUses);
15471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  else
15571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    insertDefsUses(slot, RegDefs, RegUses);
15671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
15771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  bool done = false;
15871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
15971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  while (!done) {
16071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    done = (I == MBB.begin());
16171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
16271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (!done)
16371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      --I;
16471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
16571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    // skip debug value
16671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (I->isDebugValue())
16771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      continue;
16871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
16971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
17071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (I->hasUnmodeledSideEffects()
17171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        || I->isInlineAsm()
17271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        || I->isLabel()
1735a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng        || I->hasDelaySlot()
17471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        || isDelayFiller(MBB, I))
17571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      break;
17671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
17771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
17871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      insertDefsUses(I, RegDefs, RegUses);
17971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      continue;
18071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    }
18171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
18271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    return I;
18371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
18471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  return MBB.end();
18571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
18671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
18771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajubool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
18871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            bool &sawLoad,
18971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            bool &sawStore,
19071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            SmallSet<unsigned, 32> &RegDefs,
19171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            SmallSet<unsigned, 32> &RegUses)
19271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
19371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
194cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju  if (candidate->isImplicitDef() || candidate->isKill())
195cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju    return true;
196cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju
1975a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (candidate->mayLoad()) {
19871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    sawLoad = true;
19971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (sawStore)
20071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      return true;
20171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
20271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
2035a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (candidate->mayStore()) {
20471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (sawStore)
20571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      return true;
20671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    sawStore = true;
20771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (sawLoad)
20871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      return true;
20971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
21071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
21171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
21271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    const MachineOperand &MO = candidate->getOperand(i);
21371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (!MO.isReg())
21471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      continue; // skip
21571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
21671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    unsigned Reg = MO.getReg();
21771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
21871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (MO.isDef()) {
21971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      //check whether Reg is defined or used before delay slot.
22071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
22171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        return true;
22271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    }
22371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (MO.isUse()) {
22471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      //check whether Reg is defined before delay slot.
22571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      if (IsRegInSet(RegDefs, Reg))
22671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        return true;
22771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    }
22871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
22971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  return false;
23071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
23171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
23271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
23371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajuvoid Filler::insertCallUses(MachineBasicBlock::iterator MI,
23471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            SmallSet<unsigned, 32>& RegUses)
23571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
23671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
23771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  switch(MI->getOpcode()) {
23871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  default: llvm_unreachable("Unknown opcode.");
23971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  case SP::CALL: break;
24071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  case SP::JMPLrr:
24171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  case SP::JMPLri:
24271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    assert(MI->getNumOperands() >= 2);
24371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    const MachineOperand &Reg = MI->getOperand(0);
24471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    assert(Reg.isReg() && "JMPL first operand is not a register.");
24571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    assert(Reg.isUse() && "JMPL first operand is not a use.");
24671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    RegUses.insert(Reg.getReg());
24771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
24871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    const MachineOperand &RegOrImm = MI->getOperand(1);
24971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (RegOrImm.isImm())
25071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju        break;
25171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    assert(RegOrImm.isReg() && "JMPLrr second operand is not a register.");
25271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    assert(RegOrImm.isUse() && "JMPLrr second operand is not a use.");
25371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    RegUses.insert(RegOrImm.getReg());
25471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    break;
25571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
25671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
25771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
25871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju//Insert Defs and Uses of MI into the sets RegDefs and RegUses.
25971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajuvoid Filler::insertDefsUses(MachineBasicBlock::iterator MI,
26071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            SmallSet<unsigned, 32>& RegDefs,
26171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                            SmallSet<unsigned, 32>& RegUses)
26271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
26371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
26471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    const MachineOperand &MO = MI->getOperand(i);
26571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (!MO.isReg())
26671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      continue;
26771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
26871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    unsigned Reg = MO.getReg();
26971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (Reg == 0)
27071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      continue;
27171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (MO.isDef())
27271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      RegDefs.insert(Reg);
27371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    if (MO.isUse())
27471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      RegUses.insert(Reg);
27571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
27671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  }
27771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
27871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
27971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju//returns true if the Reg or its alias is in the RegSet.
28071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajubool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)
28171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
282f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen  // Check Reg and all aliased Registers.
283f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen  for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true);
284f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen       AI.isValid(); ++AI)
285f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen    if (RegSet.count(*AI))
28671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju      return true;
28771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  return false;
28871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
28971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju
29071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju// return true if the candidate is a delay filler.
29171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajubool Filler::isDelayFiller(MachineBasicBlock &MBB,
29271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju                           MachineBasicBlock::iterator candidate)
29371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{
29471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju  if (candidate == MBB.begin())
29571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju    return false;
29658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  if (candidate->getOpcode() == SP::UNIMP)
29758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    return true;
2985a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  --candidate;
2995a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  return candidate->hasDelaySlot();
30071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju}
30158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
30258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindarajubool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
30358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju{
3045a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  if (!I->isCall())
30558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    return false;
30658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
30758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  unsigned structSizeOpNum = 0;
30858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  switch (I->getOpcode()) {
30958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  default: llvm_unreachable("Unknown call opcode.");
31058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  case SP::CALL: structSizeOpNum = 1; break;
31158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  case SP::JMPLrr:
31258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  case SP::JMPLri: structSizeOpNum = 2; break;
31358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  }
31458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju
31558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  const MachineOperand &MO = I->getOperand(structSizeOpNum);
31658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  if (!MO.isImm())
31758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju    return false;
31858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  StructSize = MO.getImm();
31958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju  return true;
32058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju}
321