bool Filler::tryCombineRestoreWithPrevInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) { // No previous instruction. if (MBBI == MBB.begin()) return false; // assert that MBBI is a "restore %g0, %g0, %g0". assert(MBBI->getOpcode() == SP::RESTORErr && MBBI->getOperand(0).getReg() == SP::G0 && MBBI->getOperand(1).getReg() == SP::G0 && MBBI->getOperand(2).getReg() == SP::G0); MachineBasicBlock::iterator PrevInst = std::prev(MBBI); // It cannot be combined with a bundled instruction. if (PrevInst->isBundledWithSucc()) return false; const TargetInstrInfo *TII = TM.getInstrInfo(); switch (PrevInst->getOpcode()) { default: break; case SP::ADDrr: case SP::ADDri: return combineRestoreADD(MBBI, PrevInst, TII); break; case SP::ORrr: case SP::ORri: return combineRestoreOR(MBBI, PrevInst, TII); break; case SP::SETHIi: return combineRestoreSETHIi(MBBI, PrevInst, TII); break; } // It cannot combine with the previous instruction. return false; }
MachineBasicBlock::iterator Filler::findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot) { SmallSet<unsigned, 32> RegDefs; SmallSet<unsigned, 32> RegUses; bool sawLoad = false; bool sawStore = false; if (slot == MBB.begin()) return MBB.end(); if (slot->getOpcode() == SP::RET || slot->getOpcode() == SP::TLS_CALL) return MBB.end(); if (slot->getOpcode() == SP::RETL) { MachineBasicBlock::iterator J = slot; --J; if (J->getOpcode() == SP::RESTORErr || J->getOpcode() == SP::RESTOREri) { // change retl to ret. slot->setDesc(TM.getInstrInfo()->get(SP::RET)); return J; } } // Call's delay filler can def some of call's uses. if (slot->isCall()) insertCallDefsUses(slot, RegDefs, RegUses); else insertDefsUses(slot, RegDefs, RegUses); bool done = false; MachineBasicBlock::iterator I = slot; while (!done) { done = (I == MBB.begin()); if (!done) --I; // skip debug value if (I->isDebugValue()) continue; if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() || I->hasDelaySlot() || I->isBundledWithSucc()) break; if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) { insertDefsUses(I, RegDefs, RegUses); continue; } return I; } return MBB.end(); }