24#define DEBUG_TYPE "delay-slot-filler"
26STATISTIC(FilledSlots,
"Number of delay slots filled");
30 cl::desc(
"Fill Lanai delay slots with NOPs."),
44 StringRef getPassName()
const override {
return "Lanai Delay Slot Filler"; }
46 bool runOnMachineBasicBlock(MachineBasicBlock &
MBB);
48 bool runOnMachineFunction(MachineFunction &MF)
override {
49 const LanaiSubtarget &Subtarget = MF.
getSubtarget<LanaiSubtarget>();
54 for (MachineBasicBlock &
MBB : MF)
59 MachineFunctionProperties getRequiredProperties()
const override {
60 return MachineFunctionProperties().setNoVRegs();
64 SmallSet<unsigned, 32> &RegDefs,
65 SmallSet<unsigned, 32> &RegUses);
67 bool isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg);
70 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
71 SmallSet<unsigned, 32> &RegUses);
73 bool findDelayInstr(MachineBasicBlock &
MBB,
91 LastFiller =
MBB.instr_end();
94 I !=
MBB.instr_end(); ++
I) {
95 if (
I->getDesc().hasDelaySlot()) {
101 if (
I->getOpcode() == Lanai::RET) {
106 assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() &&
107 RI->getOperand(0).getReg() == Lanai::FP &&
108 RI->getOperand(1).isReg() &&
109 RI->getOperand(1).getReg() == Lanai::FP &&
110 RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8);
112 assert(RI->getOpcode() == Lanai::ADD_I_LO &&
113 RI->getOperand(0).isReg() &&
114 RI->getOperand(0).getReg() == Lanai::SP &&
115 RI->getOperand(1).isReg() &&
116 RI->getOperand(1).getReg() == Lanai::FP);
118 MBB.splice(std::next(
I), &
MBB, FI,
I);
136 MIBundleBuilder(
MBB, InstrWithSlot, std::next(LastFiller));
142bool Filler::findDelayInstr(MachineBasicBlock &
MBB,
145 SmallSet<unsigned, 32> RegDefs;
146 SmallSet<unsigned, 32> RegUses;
148 insertDefsUses(Slot, RegDefs, RegUses);
150 bool SawLoad =
false;
151 bool SawStore =
false;
156 if (
I->isDebugInstr())
162 if (
I->hasUnmodeledSideEffects() ||
I->isInlineAsm() ||
I->isLabel() ||
163 FI == LastFiller ||
I->isPseudo())
166 if (delayHasHazard(FI, SawLoad, SawStore, RegDefs, RegUses)) {
167 insertDefsUses(FI, RegDefs, RegUses);
177 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
178 SmallSet<unsigned, 32> &RegUses) {
179 if (
MI->isImplicitDef() ||
MI->isKill())
190 if (
MI->mayStore()) {
199 "Cannot put calls or returns in delay slot.");
201 for (
const MachineOperand &MO :
MI->operands()) {
204 if (!MO.isReg() || !(
Reg = MO.getReg()))
209 if (isRegInSet(RegDefs,
Reg) || isRegInSet(RegUses,
Reg))
214 if (isRegInSet(RegDefs,
Reg))
223 SmallSet<unsigned, 32> &RegDefs,
224 SmallSet<unsigned, 32> &RegUses) {
226 const MCInstrDesc &MCID =
MI->getDesc();
228 :
MI->getNumOperands();
229 for (
unsigned I = 0;
I !=
E; ++
I) {
230 const MachineOperand &MO =
MI->getOperand(
I);
247 if (
MI->isCall() ||
MI->isReturn())
248 RegDefs.
insert(Lanai::SP);
252bool Filler::isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg) {
254 for (MCRegAliasIterator AI(
Reg,
TRI,
true); AI.isValid(); ++AI)
255 if (RegSet.
count(*AI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
static cl::opt< bool > NopDelaySlotFiller("lanai-nop-delay-filler", cl::init(false), cl::desc("Fill Lanai delay slots with NOPs."), cl::Hidden)
Register const TargetRegisterInfo * TRI
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.
const LanaiRegisterInfo * getRegisterInfo() const override
const LanaiInstrInfo * getInstrInfo() const override
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
reverse_instr_iterator instr_rend()
Instructions::iterator instr_iterator
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 '...
Instructions::reverse_iterator reverse_instr_iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
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.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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 * createLanaiDelaySlotFillerPass(const LanaiTargetMachine &TM)