15 #define DEBUG_TYPE "delay-slot-filler"
29 STATISTIC(FilledSlots,
"Number of delay slots filled");
32 "disable-sparc-delay-filler",
34 cl::desc(
"Disable the Sparc delay slot filler."),
51 virtual const char *getPassName()
const {
52 return "SPARC Delay Slot Filler";
60 Changed |= runOnMachineBasicBlock(*FI);
79 bool &sawLoad,
bool &sawStore,
99 return new Filler(tm);
107 bool Changed =
false;
117 (MI->getOpcode() == SP::RESTORErr
118 || MI->getOpcode() == SP::RESTOREri)) {
119 Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
123 if (!Subtarget->isV9() &&
124 (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD
125 || MI->getOpcode() == SP::FCMPQ)) {
126 BuildMI(MBB,
I, MI->getDebugLoc(), TII->
get(SP::NOP));
132 if (!MI->hasDelaySlot())
138 D = findDelayInstr(MBB, MI);
144 BuildMI(MBB,
I, MI->getDebugLoc(), TII->
get(SP::NOP));
148 unsigned structSize = 0;
149 if (needsUnimp(MI, structSize)) {
152 assert (J != MBB.
end() &&
"MI needs a delay instruction.");
153 BuildMI(MBB, ++J, MI->getDebugLoc(),
154 TII->
get(SP::UNIMP)).addImm(structSize);
166 bool sawLoad =
false;
167 bool sawStore =
false;
169 if (slot == MBB.
begin())
172 if (slot->getOpcode() == SP::RET || slot->getOpcode() ==
SP::TLS_CALL)
175 if (slot->getOpcode() == SP::RETL) {
179 if (J->getOpcode() == SP::RESTORErr
180 || J->getOpcode() == SP::RESTOREri) {
182 slot->setDesc(
TM.getInstrInfo()->get(SP::RET));
189 insertCallDefsUses(slot, RegDefs, RegUses);
191 insertDefsUses(slot, RegDefs, RegUses);
198 done = (I == MBB.
begin());
204 if (I->isDebugValue())
208 if (I->hasUnmodeledSideEffects()
212 || isDelayFiller(MBB, I))
215 if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
216 insertDefsUses(I, RegDefs, RegUses);
232 if (candidate->isImplicitDef() || candidate->isKill())
235 if (candidate->mayLoad()) {
241 if (candidate->mayStore()) {
249 for (
unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
258 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
263 if (IsRegInSet(RegDefs, Reg))
278 switch(MI->getOpcode()) {
283 assert(MI->getNumOperands() >= 2);
285 assert(Reg.isReg() &&
"JMPL first operand is not a register.");
286 assert(Reg.isUse() &&
"JMPL first operand is not a use.");
287 RegUses.
insert(Reg.getReg());
290 if (RegOrImm.
isImm())
292 assert(RegOrImm.
isReg() &&
"JMPLrr second operand is not a register.");
293 assert(RegOrImm.
isUse() &&
"JMPLrr second operand is not a use.");
304 for (
unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
309 unsigned Reg = MO.
getReg();
317 if (MO.
isImplicit() && MI->getOpcode() == SP::RETL)
330 if (RegSet.
count(*AI))
339 if (candidate == MBB.
begin())
341 if (candidate->getOpcode() == SP::UNIMP)
344 return candidate->hasDelaySlot();
352 unsigned structSizeOpNum = 0;
353 switch (I->getOpcode()) {
355 case SP::CALL: structSizeOpNum = 1;
break;
357 case SP::JMPLri: structSizeOpNum = 2;
break;
377 unsigned reg = AddMI->getOperand(0).getReg();
378 if (reg < SP::I0 || reg > SP::I7)
382 RestoreMI->eraseFromParent();
385 AddMI->setDesc(TII->
get((AddMI->getOpcode() == SP::ADDrr)
390 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
405 unsigned reg = OrMI->getOperand(0).getReg();
406 if (reg < SP::I0 || reg > SP::I7)
410 if (OrMI->getOpcode() == SP::ORrr
411 && OrMI->getOperand(1).getReg() != SP::G0
412 && OrMI->getOperand(2).getReg() != SP::G0)
415 if (OrMI->getOpcode() == SP::ORri
416 && OrMI->getOperand(1).getReg() != SP::G0
417 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
421 RestoreMI->eraseFromParent();
424 OrMI->setDesc(TII->
get((OrMI->getOpcode() == SP::ORrr)
429 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
443 unsigned reg = SetHiMI->getOperand(0).getReg();
444 if (reg < SP::I0 || reg > SP::I7)
447 if (!SetHiMI->getOperand(1).isImm())
450 int64_t imm = SetHiMI->getOperand(1).getImm();
457 imm = (imm << 10) & 0x1FFF;
459 assert(RestoreMI->getOpcode() == SP::RESTORErr);
461 RestoreMI->setDesc(TII->
get(SP::RESTOREri));
463 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
464 RestoreMI->getOperand(1).setReg(SP::G0);
465 RestoreMI->getOperand(2).ChangeToImmediate(imm);
469 SetHiMI->eraseFromParent();
478 if (MBBI == MBB.
begin())
482 assert(MBBI->getOpcode() == SP::RESTORErr
483 && MBBI->getOperand(0).getReg() == SP::G0
484 && MBBI->getOperand(1).getReg() == SP::G0
485 && MBBI->getOperand(2).getReg() == SP::G0);
490 if (isDelayFiller(MBB, PrevInst))
495 switch (PrevInst->getOpcode()) {
FunctionPass * createSparcDelaySlotFillerPass(TargetMachine &TM)
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator OrMI, const TargetInstrInfo *TII)
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
ID
LLVM Calling Convention Representation.
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator SetHiMI, const TargetInstrInfo *TII)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
const MCInstrDesc & get(unsigned Opcode) const
static cl::opt< bool > DisableDelaySlotFiller("disable-sparc-delay-filler", cl::init(false), cl::desc("Disable the Sparc delay slot filler."), cl::Hidden)
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator AddMI, const TargetInstrInfo *TII)
STATISTIC(FilledSlots,"Number of delay slots filled")
bool count(const T &V) const
count - Return true if the element is in the set.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
unsigned getReg() const
getReg - Returns the register number.
BasicBlockListType::iterator iterator