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