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 157c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "Sparc.h" 1679c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju#include "SparcSubtarget.h" 17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallSet.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 1920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineFunctionPass.h" 2020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke#include "llvm/CodeGen/MachineInstrBuilder.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineRegisterInfo.h" 2271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#include "llvm/Support/CommandLine.h" 23870248b16491c9a9a604494b4e7aa94035af2158Brian Gaeke#include "llvm/Target/TargetInstrInfo.h" 24d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 2571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju#include "llvm/Target/TargetRegisterInfo.h" 2671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 2720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaekeusing namespace llvm; 2820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "delay-slot-filler" 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3195b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(FilledSlots, "Number of delay slots filled"); 3220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 3371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajustatic cl::opt<bool> DisableDelaySlotFiller( 3471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju "disable-sparc-delay-filler", 3571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju cl::init(false), 3671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju cl::desc("Disable the Sparc delay slot filler."), 3771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju cl::Hidden); 3871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 3995b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace { 4020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke struct Filler : public MachineFunctionPass { 4120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke /// Target machine description which we query for reg. names, data 4220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke /// layout, etc. 4320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke /// 4420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke TargetMachine &TM; 4579c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju const SparcSubtarget *Subtarget; 4620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 471997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel static char ID; 481e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju Filler(TargetMachine &tm) 4979c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju : MachineFunctionPass(ID), TM(tm), 5079c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju Subtarget(&TM.getSubtarget<SparcSubtarget>()) { 5179c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju } 5220117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *getPassName() const override { 547c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner return "SPARC Delay Slot Filler"; 5520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke } 5620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 577c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner bool runOnMachineBasicBlock(MachineBasicBlock &MBB); 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnMachineFunction(MachineFunction &F) override { 5920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke bool Changed = false; 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This pass invalidates liveness information when it reorders 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // instructions to fill delay slot. 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines F.getRegInfo().invalidateLiveness(); 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 657c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner for (MachineFunction::iterator FI = F.begin(), FE = F.end(); 6620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke FI != FE; ++FI) 677c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner Changed |= runOnMachineBasicBlock(*FI); 6820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke return Changed; 6920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke } 7020117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 71d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju void insertCallDefsUses(MachineBasicBlock::iterator MI, 72d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju SmallSet<unsigned, 32>& RegDefs, 73d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju SmallSet<unsigned, 32>& RegUses); 7471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 7571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju void insertDefsUses(MachineBasicBlock::iterator MI, 7671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32>& RegDefs, 7771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32>& RegUses); 7871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 7971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool IsRegInSet(SmallSet<unsigned, 32>& RegSet, 8071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju unsigned Reg); 8171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 8271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool delayHasHazard(MachineBasicBlock::iterator candidate, 8371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool &sawLoad, bool &sawStore, 8471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> &RegDefs, 8571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> &RegUses); 8671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 8771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju MachineBasicBlock::iterator 8871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot); 8971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 9058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize); 9171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 9265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju bool tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, 9365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator MBBI); 9465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 9520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke }; 961997473cf72957d0e70322e2fe6fe2ab141c58a6Devang Patel char Filler::ID = 0; 9720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke} // end of anonymous namespace 9820117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 997c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner/// createSparcDelaySlotFillerPass - Returns a pass that fills in delay 1007c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner/// slots in Sparc MachineFunctions 10120117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// 1027c90f73a1b06040d971a3dd95a491031ae6238d5Chris LattnerFunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) { 1037c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner return new Filler(tm); 10420117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke} 10520117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke 10658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 10720117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// runOnMachineBasicBlock - Fill in delay slots for the given basic block. 10871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju/// We assume there is only one delay slot per delayed instruction. 10920117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke/// 1107c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattnerbool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { 1110f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke bool Changed = false; 11271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 11379c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju const TargetInstrInfo *TII = TM.getInstrInfo(); 11479c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju 11565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { 11665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator MI = I; 11765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju ++I; 11865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 1191e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // If MI is restore, try combining it with previous inst. 12065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (!DisableDelaySlotFiller && 12165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju (MI->getOpcode() == SP::RESTORErr 12265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju || MI->getOpcode() == SP::RESTOREri)) { 12365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju Changed |= tryCombineRestoreWithPrevInst(MBB, MI); 12465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju continue; 12565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju } 12665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 12779c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju if (!Subtarget->isV9() && 12879c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD 12979c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju || MI->getOpcode() == SP::FCMPQ)) { 13079c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); 13179c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju Changed = true; 13279c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju continue; 13379c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju } 13479c5e0c5ca85454da568dfafc0bedb84af6c2a68Venkatraman Govindaraju 1351e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // If MI has no delay slot, skip. 13665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (!MI->hasDelaySlot()) 13765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju continue; 13865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 13965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator D = MBB.end(); 14065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 14165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (!DisableDelaySlotFiller) 14265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju D = findDelayInstr(MBB, MI); 14365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 14465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju ++FilledSlots; 14565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju Changed = true; 14665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 14765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (D == MBB.end()) 14865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); 14965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju else 15065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MBB.splice(I, &MBB, D); 15165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 15265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju unsigned structSize = 0; 15365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (needsUnimp(MI, structSize)) { 15465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator J = MI; 1551e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju ++J; // skip the delay filler. 15665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju assert (J != MBB.end() && "MI needs a delay instruction."); 15780cdaf35abc528ee00bd49486d455436ec049581Venkatraman Govindaraju BuildMI(MBB, ++J, MI->getDebugLoc(), 15865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju TII->get(SP::UNIMP)).addImm(structSize); 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Bundle the delay filler and unimp with the instruction. 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J); 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I); 16320117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke } 16465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju } 1650f51cc1759e2162485b5f9ee57b3b5bc8f5c6759Brian Gaeke return Changed; 16620117102c2e10fa2c0fa74965894e28751a3df34Brian Gaeke} 16771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 16871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman GovindarajuMachineBasicBlock::iterator 16971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman GovindarajuFiller::findDelayInstr(MachineBasicBlock &MBB, 17071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju MachineBasicBlock::iterator slot) 17171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{ 17271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> RegDefs; 17371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> RegUses; 17471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool sawLoad = false; 17571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool sawStore = false; 17671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 177530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju if (slot == MBB.begin()) 178530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju return MBB.end(); 17971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 1803bd3419e86867ba88e7ece12c9184a01759ed917Venkatraman Govindaraju if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL) 18171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return MBB.end(); 18271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 18371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (slot->getOpcode() == SP::RETL) { 184530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju MachineBasicBlock::iterator J = slot; 185530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju --J; 186530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju 187530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju if (J->getOpcode() == SP::RESTORErr 188530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju || J->getOpcode() == SP::RESTOREri) { 1891e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // change retl to ret. 190c1dcb8d654d4468d63224269ee3c92480bf2385bBill Wendling slot->setDesc(TM.getInstrInfo()->get(SP::RET)); 191530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju return J; 192530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju } 19371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 19471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 1951e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Call's delay filler can def some of call's uses. 1965a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (slot->isCall()) 197d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju insertCallDefsUses(slot, RegDefs, RegUses); 19871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju else 19971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju insertDefsUses(slot, RegDefs, RegUses); 20071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 20171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool done = false; 20271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 203530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju MachineBasicBlock::iterator I = slot; 204530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju 20571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju while (!done) { 20671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju done = (I == MBB.begin()); 20771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 20871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (!done) 20971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju --I; 21071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 21171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju // skip debug value 21271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (I->isDebugValue()) 21371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju continue; 21471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I->hasDelaySlot() || I->isBundledWithSucc()) 21771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju break; 21871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 21971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) { 22071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju insertDefsUses(I, RegDefs, RegUses); 22171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju continue; 22271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 22371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 22471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return I; 22571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 22671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return MBB.end(); 22771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju} 22871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 22971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajubool Filler::delayHasHazard(MachineBasicBlock::iterator candidate, 23071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool &sawLoad, 23171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju bool &sawStore, 23271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> &RegDefs, 23371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32> &RegUses) 23471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{ 23571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 236cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju if (candidate->isImplicitDef() || candidate->isKill()) 237cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju return true; 238cc5bd4a56140f8c7381afa686f28b361fd540436Venkatraman Govindaraju 2395a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (candidate->mayLoad()) { 24071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju sawLoad = true; 24171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (sawStore) 24271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 24371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 24471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 2455a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (candidate->mayStore()) { 24671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (sawStore) 24771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 24871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju sawStore = true; 24971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (sawLoad) 25071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 25171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 25271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 25371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) { 25471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju const MachineOperand &MO = candidate->getOperand(i); 25571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (!MO.isReg()) 25671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju continue; // skip 25771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 25871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju unsigned Reg = MO.getReg(); 25971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 26071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (MO.isDef()) { 2611e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // check whether Reg is defined or used before delay slot. 26271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg)) 26371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 26471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 26571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (MO.isUse()) { 2661e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // check whether Reg is defined before delay slot. 26771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (IsRegInSet(RegDefs, Reg)) 26871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 26971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 27071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 27171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return false; 27271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju} 27371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 27471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 275d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindarajuvoid Filler::insertCallDefsUses(MachineBasicBlock::iterator MI, 276d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju SmallSet<unsigned, 32>& RegDefs, 277d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju SmallSet<unsigned, 32>& RegUses) 27871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{ 2791e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Call defines o7, which is visible to the instruction in delay slot. 280d6b4caf291aa8c3cd4bcb5f3b55b72621b506278Venkatraman Govindaraju RegDefs.insert(SP::O7); 28171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 28271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju switch(MI->getOpcode()) { 28371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju default: llvm_unreachable("Unknown opcode."); 28471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju case SP::CALL: break; 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::CALLrr: 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::CALLri: 28771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju assert(MI->getNumOperands() >= 2); 28871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju const MachineOperand &Reg = MI->getOperand(0); 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Reg.isReg() && "CALL first operand is not a register."); 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Reg.isUse() && "CALL first operand is not a use."); 29171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju RegUses.insert(Reg.getReg()); 29271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 29371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju const MachineOperand &RegOrImm = MI->getOperand(1); 29471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (RegOrImm.isImm()) 29571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju break; 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(RegOrImm.isReg() && "CALLrr second operand is not a register."); 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(RegOrImm.isUse() && "CALLrr second operand is not a use."); 29871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju RegUses.insert(RegOrImm.getReg()); 29971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju break; 30071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 30171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju} 30271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 3031e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju// Insert Defs and Uses of MI into the sets RegDefs and RegUses. 30471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajuvoid Filler::insertDefsUses(MachineBasicBlock::iterator MI, 30571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32>& RegDefs, 30671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju SmallSet<unsigned, 32>& RegUses) 30771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{ 30871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 30971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju const MachineOperand &MO = MI->getOperand(i); 31071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (!MO.isReg()) 31171e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju continue; 31271e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 31371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju unsigned Reg = MO.getReg(); 31471e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (Reg == 0) 31571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju continue; 31671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju if (MO.isDef()) 31771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju RegDefs.insert(Reg); 318530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju if (MO.isUse()) { 3191e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Implicit register uses of retl are return values and 3201e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // retl does not use them. 321530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju if (MO.isImplicit() && MI->getOpcode() == SP::RETL) 322530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju continue; 32371e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju RegUses.insert(Reg); 324530086925695f074b0e1e38a0d88ee6a4c91c54cVenkatraman Govindaraju } 32571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju } 32671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju} 32771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 3281e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju// returns true if the Reg or its alias is in the RegSet. 32971e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindarajubool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg) 33071e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju{ 331f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen // Check Reg and all aliased Registers. 332f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen for (MCRegAliasIterator AI(Reg, TM.getRegisterInfo(), true); 333f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen AI.isValid(); ++AI) 334f152fe8d487c46873bbdd4abab43200f783e978bJakob Stoklund Olesen if (RegSet.count(*AI)) 33571e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return true; 33671e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju return false; 33771e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju} 33871e39dac0ce9676dd3d0a92164167e18499d40faVenkatraman Govindaraju 33958269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindarajubool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize) 34058269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju{ 3415a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (!I->isCall()) 34258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju return false; 34358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 34458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju unsigned structSizeOpNum = 0; 34558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju switch (I->getOpcode()) { 34658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju default: llvm_unreachable("Unknown call opcode."); 34758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju case SP::CALL: structSizeOpNum = 1; break; 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::CALLrr: 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case SP::CALLri: structSizeOpNum = 2; break; 3503bd3419e86867ba88e7ece12c9184a01759ed917Venkatraman Govindaraju case SP::TLS_CALL: return false; 35158269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju } 35258269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju 35358269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju const MachineOperand &MO = I->getOperand(structSizeOpNum); 35458269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju if (!MO.isImm()) 35558269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju return false; 35658269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju StructSize = MO.getImm(); 35758269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju return true; 35858269b973256bf2436cac0f047aa277fe4bc01ddVenkatraman Govindaraju} 35965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 36065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindarajustatic bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, 36165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator AddMI, 36265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju const TargetInstrInfo *TII) 36365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju{ 3641e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Before: add <op0>, <op1>, %i[0-7] 3651e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // restore %g0, %g0, %i[0-7] 36665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju // 3671e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // After : restore <op0>, <op1>, %o[0-7] 36865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 36965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju unsigned reg = AddMI->getOperand(0).getReg(); 37065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (reg < SP::I0 || reg > SP::I7) 37165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 37265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 3731e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Erase RESTORE. 37465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->eraseFromParent(); 37565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 3761e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Change ADD to RESTORE. 37765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr) 37865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju ? SP::RESTORErr 37965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju : SP::RESTOREri)); 38065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 3811e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Map the destination register. 38265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 38365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 38465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return true; 38565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju} 38665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 38765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindarajustatic bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, 38865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator OrMI, 38965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju const TargetInstrInfo *TII) 39065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju{ 3911e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Before: or <op0>, <op1>, %i[0-7] 3921e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // restore %g0, %g0, %i[0-7] 3931e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // and <op0> or <op1> is zero, 39465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju // 3951e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // After : restore <op0>, <op1>, %o[0-7] 39665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 39765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju unsigned reg = OrMI->getOperand(0).getReg(); 39865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (reg < SP::I0 || reg > SP::I7) 39965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 40065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4011e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // check whether it is a copy. 40265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (OrMI->getOpcode() == SP::ORrr 40365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && OrMI->getOperand(1).getReg() != SP::G0 40465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && OrMI->getOperand(2).getReg() != SP::G0) 40565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 40665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 40765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (OrMI->getOpcode() == SP::ORri 40865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && OrMI->getOperand(1).getReg() != SP::G0 40965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0)) 41065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 41165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4121e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Erase RESTORE. 41365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->eraseFromParent(); 41465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4151e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Change OR to RESTORE. 41665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr) 41765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju ? SP::RESTORErr 41865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju : SP::RESTOREri)); 41965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4201e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Map the destination register. 42165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 42265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 42365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return true; 42465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju} 42565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 42665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindarajustatic bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, 42765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator SetHiMI, 42865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju const TargetInstrInfo *TII) 42965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju{ 4301e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Before: sethi imm3, %i[0-7] 4311e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // restore %g0, %g0, %g0 43265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju // 4331e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // After : restore %g0, (imm3<<10), %o[0-7] 43465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 43565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju unsigned reg = SetHiMI->getOperand(0).getReg(); 43665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (reg < SP::I0 || reg > SP::I7) 43765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 43865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 43965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (!SetHiMI->getOperand(1).isImm()) 44065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 44165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 44265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju int64_t imm = SetHiMI->getOperand(1).getImm(); 44365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4441e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Is it a 3 bit immediate? 44565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (!isInt<3>(imm)) 44665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 44765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4481e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Make it a 13 bit immediate. 44965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju imm = (imm << 10) & 0x1FFF; 45065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 45165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju assert(RestoreMI->getOpcode() == SP::RESTORErr); 45265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 45365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->setDesc(TII->get(SP::RESTOREri)); 45465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 45565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0); 45665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->getOperand(1).setReg(SP::G0); 45765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju RestoreMI->getOperand(2).ChangeToImmediate(imm); 45865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 45965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4601e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // Erase the original SETHI. 46165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju SetHiMI->eraseFromParent(); 46265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 46365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return true; 46465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju} 46565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 46665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindarajubool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, 46765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju MachineBasicBlock::iterator MBBI) 46865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju{ 4691e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // No previous instruction. 47065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju if (MBBI == MBB.begin()) 47165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 47265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 4731e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // assert that MBBI is a "restore %g0, %g0, %g0". 47465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju assert(MBBI->getOpcode() == SP::RESTORErr 47565ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && MBBI->getOperand(0).getReg() == SP::G0 47665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && MBBI->getOperand(1).getReg() == SP::G0 47765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju && MBBI->getOperand(2).getReg() == SP::G0); 47865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PrevInst = std::prev(MBBI); 48065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It cannot be combined with a bundled instruction. 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (PrevInst->isBundledWithSucc()) 48365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 48465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju 485c1dcb8d654d4468d63224269ee3c92480bf2385bBill Wendling const TargetInstrInfo *TII = TM.getInstrInfo(); 486c1dcb8d654d4468d63224269ee3c92480bf2385bBill Wendling 48765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju switch (PrevInst->getOpcode()) { 48865ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju default: break; 48965ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju case SP::ADDrr: 49065ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); break; 49165ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju case SP::ORrr: 49265ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju case SP::ORri: return combineRestoreOR(MBBI, PrevInst, TII); break; 49365ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break; 49465ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju } 4951e06bcbd633175d75d13aaa5695ca0633ba86068Venkatraman Govindaraju // It cannot combine with the previous instruction. 49665ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju return false; 49765ca7aa57d5e9b391f02a5686e7622deaac146f9Venkatraman Govindaraju} 498