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