DelaySlotFiller.cpp revision 74dfcf12000fcec60e1854f7bb78d481347a0a4b
120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===//
220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//                     The LLVM Compiler Infrastructure
420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke// This file was developed by the LLVM research group and is distributed under
620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke// the University of Illinois Open Source License. See LICENSE.TXT for details.
720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//===----------------------------------------------------------------------===//
920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
1020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke// Simple local delay slot filler for SparcV8 machine code
1120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//
1220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke//===----------------------------------------------------------------------===//
1320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
1420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "SparcV8.h"
1520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineFunctionPass.h"
1620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineInstrBuilder.h"
1774dfcf12000fcec60e1854f7bb78d481347a0a4bBrian Gaeke#include "llvm/ADT/Statistic.h"
18ff8282604a6a872536c188e5daff9a9b37b7d105Brian Gaeke
1920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekeusing namespace llvm;
2020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
2120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekenamespace {
2220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  Statistic<> FilledSlots ("delayslotfiller", "Num. of delay slots filled");
2320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
2420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  struct Filler : public MachineFunctionPass {
2520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    /// Target machine description which we query for reg. names, data
2620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    /// layout, etc.
2720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    ///
2820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    TargetMachine &TM;
2920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
3020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    Filler (TargetMachine &tm) : TM (tm) { }
3120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
3220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    virtual const char *getPassName () const {
3320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      return "SparcV8 Delay Slot Filler";
3420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
3520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
3620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    bool runOnMachineBasicBlock (MachineBasicBlock &MBB);
3720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    bool runOnMachineFunction (MachineFunction &F) {
3820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      bool Changed = false;
3920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      for (MachineFunction::iterator FI = F.begin (), FE = F.end ();
4020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke           FI != FE; ++FI)
4120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke        Changed |= runOnMachineBasicBlock (*FI);
4220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      return Changed;
4320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
4420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
4520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  };
4620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke} // end of anonymous namespace
4720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
4820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// createSparcV8DelaySlotFillerPass - Returns a pass that fills in delay
4920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// slots in SparcV8 MachineFunctions
5020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke///
5120117102c2e10fa2c0fa74965894e28751a3df34Brian GaekeFunctionPass *llvm::createSparcV8DelaySlotFillerPass (TargetMachine &tm) {
5220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  return new Filler (tm);
5320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke}
5420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
5520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekestatic bool hasDelaySlot (unsigned Opcode) {
5620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  switch (Opcode) {
57fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BA:
58fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BCC:
59fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BCS:
60fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BE:
61fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BG:
62fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BGE:
63fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BGU:
64fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BL:
65fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BLE:
66fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BLEU:
67fc7fa3121162e2b50b308fbc2945c1082450b107Brian Gaeke    case V8::BNE:
6820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    case V8::CALL:
69fbaae01269b580ca12d7b5ae131986dd001041feBrian Gaeke    case V8::JMPLrr:
7020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    case V8::RETL:
714185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBA:
724185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBN:
734185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBU:
744185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBG:
754185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBUG:
764185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBL:
774185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBUL:
784185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBLG:
794185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBNE:
804185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBE:
814185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBUE:
824185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBGE:
834185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBUGE:
844185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBLE:
854185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBULE:
864185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FBO:
874185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FCMPS:
884185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FCMPD:
894185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FCMPES:
904185d03dc5290550f0bad33764f3971ec9a74132Brian Gaeke    case V8::FCMPED:
9120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      return true;
9220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    default:
9320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      return false;
9420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  }
9520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke}
9620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke
9720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
980f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke/// Currently, we fill delay slots with NOPs. We assume there is only one
990f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke/// delay slot per delayed instruction.
10020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke///
10120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekebool Filler::runOnMachineBasicBlock (MachineBasicBlock &MBB) {
1020f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke  bool Changed = false;
10320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke  for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I)
10420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    if (hasDelaySlot (I->getOpcode ())) {
10520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      MachineBasicBlock::iterator J = I;
10620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      ++J;
1070f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke      BuildMI (MBB, J, V8::NOP, 0);
10820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke      ++FilledSlots;
1090f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke      Changed = true;
11020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke    }
1110f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke  return Changed;
11220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke}
113