27#define DEBUG_TYPE "delay-slot-filler"
29STATISTIC(FilledSlots,
"Number of delay slots filled");
32 "disable-sparc-delay-filler",
34 cl::desc(
"Disable the Sparc delay slot filler."),
53 F.getRegInfo().invalidateLiveness();
56 Changed |= runOnMachineBasicBlock(
MBB);
76 bool &sawLoad,
bool &sawStore,
104 bool Changed =
false;
114 (
MI->getOpcode() == SP::RESTORErr
115 ||
MI->getOpcode() == SP::RESTOREri)) {
116 Changed |= tryCombineRestoreWithPrevInst(
MBB,
MI);
122 if (!Subtarget->isV9() &&
123 (
MI->getOpcode() == SP::FCMPS ||
MI->getOpcode() == SP::FCMPD
124 ||
MI->getOpcode() == SP::FCMPQ)) {
131 if (!
MI->hasDelaySlot())
137 D = findDelayInstr(
MBB,
MI);
147 unsigned structSize = 0;
148 if (needsUnimp(
MI, structSize)) {
151 assert (J !=
MBB.
end() &&
"MI needs a delay instruction.");
169 bool sawLoad =
false;
170 bool sawStore =
false;
175 unsigned Opc = slot->getOpcode();
177 if (
Opc == SP::RET ||
Opc == SP::TLS_CALL)
180 if (
Opc == SP::RETL ||
Opc == SP::TAIL_CALL ||
Opc == SP::TAIL_CALLri) {
184 if (J->getOpcode() == SP::RESTORErr
185 || J->getOpcode() == SP::RESTOREri) {
195 insertCallDefsUses(slot, RegDefs, RegUses);
197 insertDefsUses(slot, RegDefs, RegUses);
210 if (
I->isDebugInstr())
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()) {
259 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
264 if (IsRegInSet(RegDefs, Reg))
269 unsigned Opcode = candidate->getOpcode();
272 if (Subtarget->insertNOPLoad()
274 Opcode >= SP::LDDArr && Opcode <= SP::LDrr)
278 if (Subtarget->fixAllFDIVSQRT()
280 Opcode >= SP::FDIVD && Opcode <= SP::FSQRTD)
283 if (Subtarget->fixTN0009() && candidate->mayStore())
286 if (Subtarget->fixTN0013()) {
309 switch(
MI->getOpcode()) {
317 assert(
Reg.isReg() &&
"CALL first operand is not a register.");
318 assert(
Reg.isUse() &&
"CALL first operand is not a use.");
324 assert(Operand1.
isReg() &&
"CALLrr second operand is not a register.");
325 assert(Operand1.
isUse() &&
"CALLrr second operand is not a use.");
348 if (MO.isImplicit() &&
MI->getOpcode() == SP::RETL)
361 if (RegSet.
count(*AI))
371 unsigned structSizeOpNum = 0;
372 switch (
I->getOpcode()) {
381 case SP::TLS_CALL:
return false;
382 case SP::TAIL_CALLri:
383 case SP::TAIL_CALL:
return false;
402 Register reg = AddMI->getOperand(0).getReg();
403 if (reg < SP::I0 || reg > SP::I7)
407 RestoreMI->eraseFromParent();
410 AddMI->setDesc(
TII->get((AddMI->getOpcode() == SP::ADDrr)
415 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
430 Register reg = OrMI->getOperand(0).getReg();
431 if (reg < SP::I0 || reg > SP::I7)
435 if (OrMI->getOpcode() == SP::ORrr
436 && OrMI->getOperand(1).getReg() != SP::G0
437 && OrMI->getOperand(2).getReg() != SP::G0)
440 if (OrMI->getOpcode() == SP::ORri
441 && OrMI->getOperand(1).getReg() != SP::G0
442 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
446 RestoreMI->eraseFromParent();
449 OrMI->setDesc(
TII->get((OrMI->getOpcode() == SP::ORrr)
454 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
468 Register reg = SetHiMI->getOperand(0).getReg();
469 if (reg < SP::I0 || reg > SP::I7)
472 if (!SetHiMI->getOperand(1).isImm())
475 int64_t imm = SetHiMI->getOperand(1).getImm();
482 imm = (imm << 10) & 0x1FFF;
484 assert(RestoreMI->getOpcode() == SP::RESTORErr);
486 RestoreMI->setDesc(
TII->get(SP::RESTOREri));
488 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
489 RestoreMI->getOperand(1).setReg(SP::G0);
490 RestoreMI->getOperand(2).ChangeToImmediate(imm);
494 SetHiMI->eraseFromParent();
508 &&
MBBI->getOperand(0).getReg() == SP::G0
509 &&
MBBI->getOperand(1).getReg() == SP::G0
510 &&
MBBI->getOperand(2).getReg() == SP::G0);
515 if (PrevInst->isBundledWithSucc())
520 switch (PrevInst->getOpcode()) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static bool combineRestoreSETHIi(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator SetHiMI, const TargetInstrInfo *TII)
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator OrMI, const TargetInstrInfo *TII)
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)
const HexagonInstrInfo * TII
This file defines the SmallSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
FunctionPass class - This class is used to implement most global optimizations.
MCRegAliasIterator enumerates all registers aliasing Reg.
Helper class for constructing bundles of MachineInstrs.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const SparcRegisterInfo * getRegisterInfo() const override
const SparcInstrInfo * getInstrInfo() const override
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createSparcDelaySlotFillerPass()
createSparcDelaySlotFillerPass - Returns a pass that fills in delay slots in Sparc MachineFunctions