28#define DEBUG_TYPE "delay-slot-filler"
30STATISTIC(FilledSlots,
"Number of delay slots filled");
33 "disable-sparc-delay-filler",
35 cl::desc(
"Disable the Sparc delay slot filler."),
54 F.getRegInfo().invalidateLiveness();
57 Changed |= runOnMachineBasicBlock(
MBB);
63 MachineFunctionProperties::Property::NoVRegs);
78 bool &sawLoad,
bool &sawStore,
106 bool Changed =
false;
116 (
MI->getOpcode() == SP::RESTORErr
117 ||
MI->getOpcode() == SP::RESTOREri)) {
118 Changed |= tryCombineRestoreWithPrevInst(
MBB,
MI);
124 if (!Subtarget->
isV9() &&
125 (
MI->getOpcode() == SP::FCMPS ||
MI->getOpcode() == SP::FCMPD
126 ||
MI->getOpcode() == SP::FCMPQ)) {
133 if (!
MI->hasDelaySlot())
139 D = findDelayInstr(
MBB,
MI);
149 unsigned structSize = 0;
150 if (needsUnimp(
MI, structSize)) {
153 assert (J !=
MBB.
end() &&
"MI needs a delay instruction.");
171 bool sawLoad =
false;
172 bool sawStore =
false;
177 unsigned Opc = slot->getOpcode();
179 if (Opc == SP::RET || Opc == SP::TLS_CALL)
182 if (Opc == SP::RETL || Opc == SP::TAIL_CALL || Opc == SP::TAIL_CALLri) {
186 if (J->getOpcode() == SP::RESTORErr
187 || J->getOpcode() == SP::RESTOREri) {
197 insertCallDefsUses(slot, RegDefs, RegUses);
199 insertDefsUses(slot, RegDefs, RegUses);
212 if (
I->isDebugInstr())
215 if (
I->hasUnmodeledSideEffects() ||
I->isInlineAsm() ||
I->isPosition() ||
216 I->hasDelaySlot() ||
I->isBundledWithSucc())
219 if (delayHasHazard(
I, sawLoad, sawStore, RegDefs, RegUses)) {
220 insertDefsUses(
I, RegDefs, RegUses);
236 if (candidate->isImplicitDef() || candidate->isKill())
239 if (candidate->mayLoad()) {
245 if (candidate->mayStore()) {
253 for (
unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
262 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
267 if (IsRegInSet(RegDefs, Reg))
272 unsigned Opcode = candidate->getOpcode();
277 Opcode >= SP::LDDArr && Opcode <= SP::LDrr)
283 Opcode >= SP::FDIVD && Opcode <= SP::FSQRTD)
298 switch(
MI->getOpcode()) {
300 case SP::CALL:
break;
305 assert(
Reg.isReg() &&
"CALL first operand is not a register.");
306 assert(
Reg.isUse() &&
"CALL first operand is not a use.");
312 assert(Operand1.
isReg() &&
"CALLrr second operand is not a register.");
313 assert(Operand1.
isUse() &&
"CALLrr second operand is not a use.");
349 if (RegSet.
count(*AI))
359 unsigned structSizeOpNum = 0;
360 switch (
I->getOpcode()) {
362 case SP::CALL: structSizeOpNum = 1;
break;
364 case SP::CALLri: structSizeOpNum = 2;
break;
365 case SP::TLS_CALL:
return false;
366 case SP::TAIL_CALLri:
367 case SP::TAIL_CALL:
return false;
386 Register reg = AddMI->getOperand(0).getReg();
387 if (reg < SP::I0 || reg > SP::I7)
391 RestoreMI->eraseFromParent();
394 AddMI->setDesc(
TII->get((AddMI->getOpcode() == SP::ADDrr)
399 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
414 Register reg = OrMI->getOperand(0).getReg();
415 if (reg < SP::I0 || reg > SP::I7)
419 if (OrMI->getOpcode() == SP::ORrr
420 && OrMI->getOperand(1).getReg() != SP::G0
421 && OrMI->getOperand(2).getReg() != SP::G0)
424 if (OrMI->getOpcode() == SP::ORri
425 && OrMI->getOperand(1).getReg() != SP::G0
426 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
430 RestoreMI->eraseFromParent();
433 OrMI->setDesc(
TII->get((OrMI->getOpcode() == SP::ORrr)
438 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
452 Register reg = SetHiMI->getOperand(0).getReg();
453 if (reg < SP::I0 || reg > SP::I7)
456 if (!SetHiMI->getOperand(1).isImm())
459 int64_t imm = SetHiMI->getOperand(1).getImm();
466 imm = (imm << 10) & 0x1FFF;
468 assert(RestoreMI->getOpcode() == SP::RESTORErr);
470 RestoreMI->setDesc(
TII->get(SP::RESTOREri));
472 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
473 RestoreMI->getOperand(1).setReg(SP::G0);
474 RestoreMI->getOperand(2).ChangeToImmediate(imm);
478 SetHiMI->eraseFromParent();
492 &&
MBBI->getOperand(0).getReg() == SP::G0
493 &&
MBBI->getOperand(1).getReg() == SP::G0
494 &&
MBBI->getOperand(2).getReg() == SP::G0);
499 if (PrevInst->isBundledWithSucc())
504 switch (PrevInst->getOpcode()) {
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
MachineFunctionProperties & set(Property P)
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
bool insertNOPLoad() const
bool fixAllFDIVSQRT() const
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