29 #define DEBUG_TYPE "delay-slot-filler"
31 STATISTIC(FilledSlots,
"Number of delay slots filled");
34 "disable-sparc-delay-filler",
36 cl::desc(
"Disable the Sparc delay slot filler."),
50 const char *getPassName()
const override {
51 return "SPARC Delay Slot Filler";
65 Changed |= runOnMachineBasicBlock(*FI);
81 bool &sawLoad,
bool &sawStore,
101 return new Filler(tm);
109 bool Changed =
false;
119 (MI->getOpcode() == SP::RESTORErr
120 || MI->getOpcode() == SP::RESTOREri)) {
121 Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
125 if (!Subtarget->isV9() &&
126 (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD
127 || MI->getOpcode() == SP::FCMPQ)) {
128 BuildMI(MBB,
I, MI->getDebugLoc(), TII->get(SP::NOP));
134 if (!MI->hasDelaySlot())
140 D = findDelayInstr(MBB, MI);
146 BuildMI(MBB,
I, MI->getDebugLoc(), TII->get(SP::NOP));
150 unsigned structSize = 0;
151 if (needsUnimp(MI, structSize)) {
154 assert (J != MBB.
end() &&
"MI needs a delay instruction.");
155 BuildMI(MBB, ++J, MI->getDebugLoc(),
156 TII->get(SP::UNIMP)).addImm(structSize);
172 bool sawLoad =
false;
173 bool sawStore =
false;
175 if (slot == MBB.
begin())
178 if (slot->getOpcode() == SP::RET || slot->getOpcode() ==
SP::TLS_CALL)
181 if (slot->getOpcode() == SP::RETL) {
185 if (J->getOpcode() == SP::RESTORErr
186 || J->getOpcode() == SP::RESTOREri) {
188 slot->setDesc(Subtarget->getInstrInfo()->get(SP::RET));
195 insertCallDefsUses(slot, RegDefs, RegUses);
197 insertDefsUses(slot, RegDefs, RegUses);
204 done = (I == MBB.
begin());
210 if (I->isDebugValue())
213 if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() ||
214 I->hasDelaySlot() || I->isBundledWithSucc())
217 if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
218 insertDefsUses(I, RegDefs, RegUses);
234 if (candidate->isImplicitDef() || candidate->isKill())
237 if (candidate->mayLoad()) {
243 if (candidate->mayStore()) {
251 for (
unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
260 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
265 if (IsRegInSet(RegDefs, Reg))
280 switch(MI->getOpcode()) {
285 assert(MI->getNumOperands() >= 2);
287 assert(Reg.isReg() &&
"CALL first operand is not a register.");
288 assert(Reg.isUse() &&
"CALL first operand is not a use.");
289 RegUses.
insert(Reg.getReg());
292 if (RegOrImm.
isImm())
294 assert(RegOrImm.
isReg() &&
"CALLrr second operand is not a register.");
295 assert(RegOrImm.
isUse() &&
"CALLrr second operand is not a use.");
306 for (
unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
311 unsigned Reg = MO.
getReg();
319 if (MO.
isImplicit() && MI->getOpcode() == SP::RETL)
332 if (RegSet.
count(*AI))
342 unsigned structSizeOpNum = 0;
343 switch (I->getOpcode()) {
345 case SP::CALL: structSizeOpNum = 1;
break;
347 case SP::CALLri: structSizeOpNum = 2;
break;
367 unsigned reg = AddMI->getOperand(0).getReg();
368 if (reg < SP::I0 || reg > SP::I7)
372 RestoreMI->eraseFromParent();
375 AddMI->setDesc(TII->
get((AddMI->getOpcode() == SP::ADDrr)
380 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
395 unsigned reg = OrMI->getOperand(0).getReg();
396 if (reg < SP::I0 || reg > SP::I7)
400 if (OrMI->getOpcode() == SP::ORrr
401 && OrMI->getOperand(1).getReg() != SP::G0
402 && OrMI->getOperand(2).getReg() != SP::G0)
405 if (OrMI->getOpcode() == SP::ORri
406 && OrMI->getOperand(1).getReg() != SP::G0
407 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
411 RestoreMI->eraseFromParent();
414 OrMI->setDesc(TII->
get((OrMI->getOpcode() == SP::ORrr)
419 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
433 unsigned reg = SetHiMI->getOperand(0).getReg();
434 if (reg < SP::I0 || reg > SP::I7)
437 if (!SetHiMI->getOperand(1).isImm())
440 int64_t imm = SetHiMI->getOperand(1).getImm();
447 imm = (imm << 10) & 0x1FFF;
449 assert(RestoreMI->getOpcode() == SP::RESTORErr);
451 RestoreMI->setDesc(TII->
get(SP::RESTOREri));
453 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
454 RestoreMI->getOperand(1).setReg(SP::G0);
455 RestoreMI->getOperand(2).ChangeToImmediate(imm);
459 SetHiMI->eraseFromParent();
468 if (MBBI == MBB.
begin())
472 assert(MBBI->getOpcode() == SP::RESTORErr
473 && MBBI->getOperand(0).getReg() == SP::G0
474 && MBBI->getOperand(1).getReg() == SP::G0
475 && MBBI->getOperand(2).getReg() == SP::G0);
480 if (PrevInst->isBundledWithSucc())
485 switch (PrevInst->getOpcode()) {
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
STATISTIC(NumFunctions,"Total number of functions")
FunctionPass * createSparcDelaySlotFillerPass(TargetMachine &TM)
createSparcDelaySlotFillerPass - Returns a pass that fills in delay slots in Sparc MachineFunctions ...
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator OrMI, const TargetInstrInfo *TII)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
TargetInstrInfo - Interface to description of machine instruction set.
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator SetHiMI, const TargetInstrInfo *TII)
MCRegAliasIterator enumerates all registers aliasing Reg.
FunctionPass class - This class is used to implement most global optimizations.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static cl::opt< bool > DisableDelaySlotFiller("disable-sparc-delay-filler", cl::init(false), cl::desc("Disable the Sparc delay slot filler."), cl::Hidden)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
MachineOperand class - Representation of each machine instruction operand.
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator AddMI, const TargetInstrInfo *TII)
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
unsigned getReg() const
getReg - Returns the register number.
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.
Helper class for constructing bundles of MachineInstrs.