LLVM API Documentation

DelaySlotFiller.cpp
Go to the documentation of this file.
00001 //===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This is a simple local pass that attempts to fill delay slots with useful
00011 // instructions. If no instructions can be moved into the delay slot, then a
00012 // NOP is placed.
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "Sparc.h"
00016 #include "SparcSubtarget.h"
00017 #include "llvm/ADT/SmallSet.h"
00018 #include "llvm/ADT/Statistic.h"
00019 #include "llvm/CodeGen/MachineFunctionPass.h"
00020 #include "llvm/CodeGen/MachineInstrBuilder.h"
00021 #include "llvm/CodeGen/MachineRegisterInfo.h"
00022 #include "llvm/Support/CommandLine.h"
00023 #include "llvm/Target/TargetInstrInfo.h"
00024 #include "llvm/Target/TargetMachine.h"
00025 #include "llvm/Target/TargetRegisterInfo.h"
00026 
00027 using namespace llvm;
00028 
00029 #define DEBUG_TYPE "delay-slot-filler"
00030 
00031 STATISTIC(FilledSlots, "Number of delay slots filled");
00032 
00033 static cl::opt<bool> DisableDelaySlotFiller(
00034   "disable-sparc-delay-filler",
00035   cl::init(false),
00036   cl::desc("Disable the Sparc delay slot filler."),
00037   cl::Hidden);
00038 
00039 namespace {
00040   struct Filler : public MachineFunctionPass {
00041     /// Target machine description which we query for reg. names, data
00042     /// layout, etc.
00043     ///
00044     TargetMachine &TM;
00045     const SparcSubtarget *Subtarget;
00046 
00047     static char ID;
00048     Filler(TargetMachine &tm)
00049       : MachineFunctionPass(ID), TM(tm),
00050         Subtarget(&TM.getSubtarget<SparcSubtarget>()) {
00051     }
00052 
00053     const char *getPassName() const override {
00054       return "SPARC Delay Slot Filler";
00055     }
00056 
00057     bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
00058     bool runOnMachineFunction(MachineFunction &F) override {
00059       bool Changed = false;
00060 
00061       // This pass invalidates liveness information when it reorders
00062       // instructions to fill delay slot.
00063       F.getRegInfo().invalidateLiveness();
00064 
00065       for (MachineFunction::iterator FI = F.begin(), FE = F.end();
00066            FI != FE; ++FI)
00067         Changed |= runOnMachineBasicBlock(*FI);
00068       return Changed;
00069     }
00070 
00071     void insertCallDefsUses(MachineBasicBlock::iterator MI,
00072                             SmallSet<unsigned, 32>& RegDefs,
00073                             SmallSet<unsigned, 32>& RegUses);
00074 
00075     void insertDefsUses(MachineBasicBlock::iterator MI,
00076                         SmallSet<unsigned, 32>& RegDefs,
00077                         SmallSet<unsigned, 32>& RegUses);
00078 
00079     bool IsRegInSet(SmallSet<unsigned, 32>& RegSet,
00080                     unsigned Reg);
00081 
00082     bool delayHasHazard(MachineBasicBlock::iterator candidate,
00083                         bool &sawLoad, bool &sawStore,
00084                         SmallSet<unsigned, 32> &RegDefs,
00085                         SmallSet<unsigned, 32> &RegUses);
00086 
00087     MachineBasicBlock::iterator
00088     findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot);
00089 
00090     bool needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize);
00091 
00092     bool tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
00093                                        MachineBasicBlock::iterator MBBI);
00094 
00095   };
00096   char Filler::ID = 0;
00097 } // end of anonymous namespace
00098 
00099 /// createSparcDelaySlotFillerPass - Returns a pass that fills in delay
00100 /// slots in Sparc MachineFunctions
00101 ///
00102 FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) {
00103   return new Filler(tm);
00104 }
00105 
00106 
00107 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
00108 /// We assume there is only one delay slot per delayed instruction.
00109 ///
00110 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
00111   bool Changed = false;
00112 
00113   const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo();
00114 
00115   for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
00116     MachineBasicBlock::iterator MI = I;
00117     ++I;
00118 
00119     // If MI is restore, try combining it with previous inst.
00120     if (!DisableDelaySlotFiller &&
00121         (MI->getOpcode() == SP::RESTORErr
00122          || MI->getOpcode() == SP::RESTOREri)) {
00123       Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
00124       continue;
00125     }
00126 
00127     if (!Subtarget->isV9() &&
00128         (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD
00129          || MI->getOpcode() == SP::FCMPQ)) {
00130       BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP));
00131       Changed = true;
00132       continue;
00133     }
00134 
00135     // If MI has no delay slot, skip.
00136     if (!MI->hasDelaySlot())
00137       continue;
00138 
00139     MachineBasicBlock::iterator D = MBB.end();
00140 
00141     if (!DisableDelaySlotFiller)
00142       D = findDelayInstr(MBB, MI);
00143 
00144     ++FilledSlots;
00145     Changed = true;
00146 
00147     if (D == MBB.end())
00148       BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP));
00149     else
00150       MBB.splice(I, &MBB, D);
00151 
00152     unsigned structSize = 0;
00153     if (needsUnimp(MI, structSize)) {
00154       MachineBasicBlock::iterator J = MI;
00155       ++J; // skip the delay filler.
00156       assert (J != MBB.end() && "MI needs a delay instruction.");
00157       BuildMI(MBB, ++J, MI->getDebugLoc(),
00158               TII->get(SP::UNIMP)).addImm(structSize);
00159       // Bundle the delay filler and unimp with the instruction.
00160       MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), J);
00161     } else {
00162       MIBundleBuilder(MBB, MachineBasicBlock::iterator(MI), I);
00163     }
00164   }
00165   return Changed;
00166 }
00167 
00168 MachineBasicBlock::iterator
00169 Filler::findDelayInstr(MachineBasicBlock &MBB,
00170                        MachineBasicBlock::iterator slot)
00171 {
00172   SmallSet<unsigned, 32> RegDefs;
00173   SmallSet<unsigned, 32> RegUses;
00174   bool sawLoad = false;
00175   bool sawStore = false;
00176 
00177   if (slot == MBB.begin())
00178     return MBB.end();
00179 
00180   if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL)
00181     return MBB.end();
00182 
00183   if (slot->getOpcode() == SP::RETL) {
00184     MachineBasicBlock::iterator J = slot;
00185     --J;
00186 
00187     if (J->getOpcode() == SP::RESTORErr
00188         || J->getOpcode() == SP::RESTOREri) {
00189       // change retl to ret.
00190       slot->setDesc(TM.getSubtargetImpl()->getInstrInfo()->get(SP::RET));
00191       return J;
00192     }
00193   }
00194 
00195   // Call's delay filler can def some of call's uses.
00196   if (slot->isCall())
00197     insertCallDefsUses(slot, RegDefs, RegUses);
00198   else
00199     insertDefsUses(slot, RegDefs, RegUses);
00200 
00201   bool done = false;
00202 
00203   MachineBasicBlock::iterator I = slot;
00204 
00205   while (!done) {
00206     done = (I == MBB.begin());
00207 
00208     if (!done)
00209       --I;
00210 
00211     // skip debug value
00212     if (I->isDebugValue())
00213       continue;
00214 
00215     if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() ||
00216         I->hasDelaySlot() || I->isBundledWithSucc())
00217       break;
00218 
00219     if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
00220       insertDefsUses(I, RegDefs, RegUses);
00221       continue;
00222     }
00223 
00224     return I;
00225   }
00226   return MBB.end();
00227 }
00228 
00229 bool Filler::delayHasHazard(MachineBasicBlock::iterator candidate,
00230                             bool &sawLoad,
00231                             bool &sawStore,
00232                             SmallSet<unsigned, 32> &RegDefs,
00233                             SmallSet<unsigned, 32> &RegUses)
00234 {
00235 
00236   if (candidate->isImplicitDef() || candidate->isKill())
00237     return true;
00238 
00239   if (candidate->mayLoad()) {
00240     sawLoad = true;
00241     if (sawStore)
00242       return true;
00243   }
00244 
00245   if (candidate->mayStore()) {
00246     if (sawStore)
00247       return true;
00248     sawStore = true;
00249     if (sawLoad)
00250       return true;
00251   }
00252 
00253   for (unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
00254     const MachineOperand &MO = candidate->getOperand(i);
00255     if (!MO.isReg())
00256       continue; // skip
00257 
00258     unsigned Reg = MO.getReg();
00259 
00260     if (MO.isDef()) {
00261       // check whether Reg is defined or used before delay slot.
00262       if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
00263         return true;
00264     }
00265     if (MO.isUse()) {
00266       // check whether Reg is defined before delay slot.
00267       if (IsRegInSet(RegDefs, Reg))
00268         return true;
00269     }
00270   }
00271   return false;
00272 }
00273 
00274 
00275 void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,
00276                                 SmallSet<unsigned, 32>& RegDefs,
00277                                 SmallSet<unsigned, 32>& RegUses)
00278 {
00279   // Call defines o7, which is visible to the instruction in delay slot.
00280   RegDefs.insert(SP::O7);
00281 
00282   switch(MI->getOpcode()) {
00283   default: llvm_unreachable("Unknown opcode.");
00284   case SP::CALL: break;
00285   case SP::CALLrr:
00286   case SP::CALLri:
00287     assert(MI->getNumOperands() >= 2);
00288     const MachineOperand &Reg = MI->getOperand(0);
00289     assert(Reg.isReg() && "CALL first operand is not a register.");
00290     assert(Reg.isUse() && "CALL first operand is not a use.");
00291     RegUses.insert(Reg.getReg());
00292 
00293     const MachineOperand &RegOrImm = MI->getOperand(1);
00294     if (RegOrImm.isImm())
00295         break;
00296     assert(RegOrImm.isReg() && "CALLrr second operand is not a register.");
00297     assert(RegOrImm.isUse() && "CALLrr second operand is not a use.");
00298     RegUses.insert(RegOrImm.getReg());
00299     break;
00300   }
00301 }
00302 
00303 // Insert Defs and Uses of MI into the sets RegDefs and RegUses.
00304 void Filler::insertDefsUses(MachineBasicBlock::iterator MI,
00305                             SmallSet<unsigned, 32>& RegDefs,
00306                             SmallSet<unsigned, 32>& RegUses)
00307 {
00308   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
00309     const MachineOperand &MO = MI->getOperand(i);
00310     if (!MO.isReg())
00311       continue;
00312 
00313     unsigned Reg = MO.getReg();
00314     if (Reg == 0)
00315       continue;
00316     if (MO.isDef())
00317       RegDefs.insert(Reg);
00318     if (MO.isUse()) {
00319       // Implicit register uses of retl are return values and
00320       // retl does not use them.
00321       if (MO.isImplicit() && MI->getOpcode() == SP::RETL)
00322         continue;
00323       RegUses.insert(Reg);
00324     }
00325   }
00326 }
00327 
00328 // returns true if the Reg or its alias is in the RegSet.
00329 bool Filler::IsRegInSet(SmallSet<unsigned, 32>& RegSet, unsigned Reg)
00330 {
00331   // Check Reg and all aliased Registers.
00332   for (MCRegAliasIterator AI(Reg, TM.getSubtargetImpl()->getRegisterInfo(),
00333                              true);
00334        AI.isValid(); ++AI)
00335     if (RegSet.count(*AI))
00336       return true;
00337   return false;
00338 }
00339 
00340 bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
00341 {
00342   if (!I->isCall())
00343     return false;
00344 
00345   unsigned structSizeOpNum = 0;
00346   switch (I->getOpcode()) {
00347   default: llvm_unreachable("Unknown call opcode.");
00348   case SP::CALL: structSizeOpNum = 1; break;
00349   case SP::CALLrr:
00350   case SP::CALLri: structSizeOpNum = 2; break;
00351   case SP::TLS_CALL: return false;
00352   }
00353 
00354   const MachineOperand &MO = I->getOperand(structSizeOpNum);
00355   if (!MO.isImm())
00356     return false;
00357   StructSize = MO.getImm();
00358   return true;
00359 }
00360 
00361 static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI,
00362                               MachineBasicBlock::iterator AddMI,
00363                               const TargetInstrInfo *TII)
00364 {
00365   // Before:  add  <op0>, <op1>, %i[0-7]
00366   //          restore %g0, %g0, %i[0-7]
00367   //
00368   // After :  restore <op0>, <op1>, %o[0-7]
00369 
00370   unsigned reg = AddMI->getOperand(0).getReg();
00371   if (reg < SP::I0 || reg > SP::I7)
00372     return false;
00373 
00374   // Erase RESTORE.
00375   RestoreMI->eraseFromParent();
00376 
00377   // Change ADD to RESTORE.
00378   AddMI->setDesc(TII->get((AddMI->getOpcode() == SP::ADDrr)
00379                           ? SP::RESTORErr
00380                           : SP::RESTOREri));
00381 
00382   // Map the destination register.
00383   AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
00384 
00385   return true;
00386 }
00387 
00388 static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI,
00389                              MachineBasicBlock::iterator OrMI,
00390                              const TargetInstrInfo *TII)
00391 {
00392   // Before:  or  <op0>, <op1>, %i[0-7]
00393   //          restore %g0, %g0, %i[0-7]
00394   //    and <op0> or <op1> is zero,
00395   //
00396   // After :  restore <op0>, <op1>, %o[0-7]
00397 
00398   unsigned reg = OrMI->getOperand(0).getReg();
00399   if (reg < SP::I0 || reg > SP::I7)
00400     return false;
00401 
00402   // check whether it is a copy.
00403   if (OrMI->getOpcode() == SP::ORrr
00404       && OrMI->getOperand(1).getReg() != SP::G0
00405       && OrMI->getOperand(2).getReg() != SP::G0)
00406     return false;
00407 
00408   if (OrMI->getOpcode() == SP::ORri
00409       && OrMI->getOperand(1).getReg() != SP::G0
00410       && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
00411     return false;
00412 
00413   // Erase RESTORE.
00414   RestoreMI->eraseFromParent();
00415 
00416   // Change OR to RESTORE.
00417   OrMI->setDesc(TII->get((OrMI->getOpcode() == SP::ORrr)
00418                          ? SP::RESTORErr
00419                          : SP::RESTOREri));
00420 
00421   // Map the destination register.
00422   OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
00423 
00424   return true;
00425 }
00426 
00427 static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI,
00428                                  MachineBasicBlock::iterator SetHiMI,
00429                                  const TargetInstrInfo *TII)
00430 {
00431   // Before:  sethi imm3, %i[0-7]
00432   //          restore %g0, %g0, %g0
00433   //
00434   // After :  restore %g0, (imm3<<10), %o[0-7]
00435 
00436   unsigned reg = SetHiMI->getOperand(0).getReg();
00437   if (reg < SP::I0 || reg > SP::I7)
00438     return false;
00439 
00440   if (!SetHiMI->getOperand(1).isImm())
00441     return false;
00442 
00443   int64_t imm = SetHiMI->getOperand(1).getImm();
00444 
00445   // Is it a 3 bit immediate?
00446   if (!isInt<3>(imm))
00447     return false;
00448 
00449   // Make it a 13 bit immediate.
00450   imm = (imm << 10) & 0x1FFF;
00451 
00452   assert(RestoreMI->getOpcode() == SP::RESTORErr);
00453 
00454   RestoreMI->setDesc(TII->get(SP::RESTOREri));
00455 
00456   RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
00457   RestoreMI->getOperand(1).setReg(SP::G0);
00458   RestoreMI->getOperand(2).ChangeToImmediate(imm);
00459 
00460 
00461   // Erase the original SETHI.
00462   SetHiMI->eraseFromParent();
00463 
00464   return true;
00465 }
00466 
00467 bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB,
00468                                         MachineBasicBlock::iterator MBBI)
00469 {
00470   // No previous instruction.
00471   if (MBBI == MBB.begin())
00472     return false;
00473 
00474   // assert that MBBI is a "restore %g0, %g0, %g0".
00475   assert(MBBI->getOpcode() == SP::RESTORErr
00476          && MBBI->getOperand(0).getReg() == SP::G0
00477          && MBBI->getOperand(1).getReg() == SP::G0
00478          && MBBI->getOperand(2).getReg() == SP::G0);
00479 
00480   MachineBasicBlock::iterator PrevInst = std::prev(MBBI);
00481 
00482   // It cannot be combined with a bundled instruction.
00483   if (PrevInst->isBundledWithSucc())
00484     return false;
00485 
00486   const TargetInstrInfo *TII = TM.getSubtargetImpl()->getInstrInfo();
00487 
00488   switch (PrevInst->getOpcode()) {
00489   default: break;
00490   case SP::ADDrr:
00491   case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); break;
00492   case SP::ORrr:
00493   case SP::ORri:  return combineRestoreOR(MBBI, PrevInst, TII); break;
00494   case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break;
00495   }
00496   // It cannot combine with the previous instruction.
00497   return false;
00498 }