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."),
46 StringRef getPassName()
const override {
return "SPARC Delay Slot Filler"; }
59 Changed |= runOnMachineBasicBlock(*FI);
80 bool &sawLoad,
bool &sawStore,
108 bool Changed =
false;
118 (MI->getOpcode() == SP::RESTORErr
119 || MI->getOpcode() == SP::RESTOREri)) {
120 Changed |= tryCombineRestoreWithPrevInst(MBB, MI);
126 if (!Subtarget->
isV9() &&
127 (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD
128 || MI->getOpcode() == SP::FCMPQ)) {
129 BuildMI(MBB,
I, MI->getDebugLoc(), TII->get(SP::NOP));
135 if (!MI->hasDelaySlot())
141 D = findDelayInstr(MBB, MI);
147 BuildMI(MBB,
I, MI->getDebugLoc(), TII->get(SP::NOP));
151 unsigned structSize = 0;
152 if (needsUnimp(MI, structSize)) {
155 assert (J != MBB.
end() &&
"MI needs a delay instruction.");
156 BuildMI(MBB, ++J, MI->getDebugLoc(),
157 TII->get(SP::UNIMP)).addImm(structSize);
173 bool sawLoad =
false;
174 bool sawStore =
false;
176 if (slot == MBB.
begin())
182 if (slot->getOpcode() == SP::RETL) {
186 if (J->getOpcode() == SP::RESTORErr
187 || J->getOpcode() == SP::RESTOREri) {
196 insertCallDefsUses(slot, RegDefs, RegUses);
198 insertDefsUses(slot, RegDefs, RegUses);
205 done = (I == MBB.
begin());
211 if (I->isDebugInstr())
214 if (I->hasUnmodeledSideEffects() || I->isInlineAsm() || I->isPosition() ||
215 I->hasDelaySlot() || I->isBundledWithSucc())
218 if (delayHasHazard(I, sawLoad, sawStore, RegDefs, RegUses)) {
219 insertDefsUses(I, RegDefs, RegUses);
235 if (candidate->isImplicitDef() || candidate->isKill())
238 if (candidate->mayLoad()) {
244 if (candidate->mayStore()) {
252 for (
unsigned i = 0, e = candidate->getNumOperands(); i!= e; ++i) {
261 if (IsRegInSet(RegDefs, Reg) || IsRegInSet(RegUses, Reg))
266 if (IsRegInSet(RegDefs, Reg))
271 unsigned Opcode = candidate->getOpcode();
276 Opcode >= SP::LDDArr && Opcode <= SP::LDrr)
282 Opcode >= SP::FDIVD && Opcode <= SP::FSQRTD)
297 switch(MI->getOpcode()) {
302 assert(MI->getNumOperands() >= 2);
304 assert(Reg.isReg() &&
"CALL first operand is not a register.");
305 assert(Reg.isUse() &&
"CALL first operand is not a use.");
306 RegUses.
insert(Reg.getReg());
311 assert(Operand1.
isReg() &&
"CALLrr second operand is not a register.");
312 assert(Operand1.
isUse() &&
"CALLrr second operand is not a use.");
323 for (
unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
336 if (MO.
isImplicit() && MI->getOpcode() == SP::RETL)
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;
384 unsigned reg = AddMI->getOperand(0).getReg();
385 if (reg < SP::I0 || reg > SP::I7)
389 RestoreMI->eraseFromParent();
392 AddMI->setDesc(TII->
get((AddMI->getOpcode() == SP::ADDrr)
397 AddMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
412 unsigned reg = OrMI->getOperand(0).getReg();
413 if (reg < SP::I0 || reg > SP::I7)
417 if (OrMI->getOpcode() == SP::ORrr
418 && OrMI->getOperand(1).getReg() != SP::G0
419 && OrMI->getOperand(2).getReg() != SP::G0)
422 if (OrMI->getOpcode() == SP::ORri
423 && OrMI->getOperand(1).getReg() != SP::G0
424 && (!OrMI->getOperand(2).isImm() || OrMI->getOperand(2).getImm() != 0))
428 RestoreMI->eraseFromParent();
431 OrMI->setDesc(TII->
get((OrMI->getOpcode() == SP::ORrr)
436 OrMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
450 unsigned reg = SetHiMI->getOperand(0).getReg();
451 if (reg < SP::I0 || reg > SP::I7)
454 if (!SetHiMI->getOperand(1).isImm())
457 int64_t imm = SetHiMI->getOperand(1).getImm();
464 imm = (imm << 10) & 0x1FFF;
466 assert(RestoreMI->getOpcode() == SP::RESTORErr);
468 RestoreMI->setDesc(TII->
get(SP::RESTOREri));
470 RestoreMI->getOperand(0).setReg(reg - SP::I0 + SP::O0);
471 RestoreMI->getOperand(1).setReg(SP::G0);
472 RestoreMI->getOperand(2).ChangeToImmediate(imm);
476 SetHiMI->eraseFromParent();
485 if (MBBI == MBB.
begin())
489 assert(MBBI->getOpcode() == SP::RESTORErr
490 && MBBI->getOperand(0).getReg() == SP::G0
491 && MBBI->getOperand(1).getReg() == SP::G0
492 && MBBI->getOperand(2).getReg() == SP::G0);
497 if (PrevInst->isBundledWithSucc())
502 switch (PrevInst->getOpcode()) {
This class represents lattice values for constants.
FunctionPass * createSparcDelaySlotFillerPass()
createSparcDelaySlotFillerPass - Returns a pass that fills in delay slots in Sparc MachineFunctions ...
unsigned getReg() const
getReg - Returns the register number.
STATISTIC(NumFunctions, "Total number of functions")
const SparcInstrInfo * getInstrInfo() const override
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static bool combineRestoreOR(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator OrMI, const TargetInstrInfo *TII)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool insertNOPLoad() const
bool fixAllFDIVSQRT() const
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SparcRegisterInfo * getRegisterInfo() const override
static cl::opt< bool > DisableDelaySlotFiller("disable-sparc-delay-filler", cl::init(false), cl::desc("Disable the Sparc delay slot filler."), cl::Hidden)
Iterator for intrusive lists based on ilist_node.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperand class - Representation of each machine instruction operand.
static bool combineRestoreADD(MachineBasicBlock::iterator RestoreMI, MachineBasicBlock::iterator AddMI, const TargetInstrInfo *TII)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
MachineFunctionProperties & set(Property P)
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 '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
Properties which a MachineFunction may have at a given point in time.
Helper class for constructing bundles of MachineInstrs.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.