27#define DEBUG_TYPE "delay-slot-filler"
29STATISTIC(FilledSlots,
"Number of delay slots filled");
33 cl::desc(
"Fill Lanai delay slots with NOPs."),
58 SmallSet<unsigned, 32> &RegDefs,
59 SmallSet<unsigned, 32> &RegUses);
61 bool isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg);
64 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
65 SmallSet<unsigned, 32> &RegUses);
67 bool findDelayInstr(MachineBasicBlock &
MBB,
76 explicit LanaiDelaySlotFillerLegacy() : MachineFunctionPass(ID) {}
78 StringRef getPassName()
const override {
return "Lanai Delay Slot Filler"; }
80 MachineFunctionProperties getRequiredProperties()
const override {
81 return MachineFunctionProperties().setNoVRegs();
84 bool runOnMachineFunction(MachineFunction &MF)
override;
86char LanaiDelaySlotFillerLegacy::ID = 0;
93 return new LanaiDelaySlotFillerLegacy();
100 LastFiller =
MBB.instr_end();
103 I !=
MBB.instr_end(); ++
I) {
104 if (
I->getDesc().hasDelaySlot()) {
110 if (
I->getOpcode() == Lanai::RET) {
115 assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() &&
116 RI->getOperand(0).getReg() == Lanai::FP &&
117 RI->getOperand(1).isReg() &&
118 RI->getOperand(1).getReg() == Lanai::FP &&
119 RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8);
121 assert(RI->getOpcode() == Lanai::ADD_I_LO &&
122 RI->getOperand(0).isReg() &&
123 RI->getOperand(0).getReg() == Lanai::SP &&
124 RI->getOperand(1).isReg() &&
125 RI->getOperand(1).getReg() == Lanai::FP);
127 MBB.splice(std::next(
I), &
MBB, FI,
I);
144 if (InstrWithSlot->getOpcode() == Lanai::RET)
149 MIBundleBuilder(
MBB, InstrWithSlot, std::next(LastFiller));
155bool FillerImpl::findDelayInstr(MachineBasicBlock &
MBB,
158 SmallSet<unsigned, 32> RegDefs;
159 SmallSet<unsigned, 32> RegUses;
161 insertDefsUses(Slot, RegDefs, RegUses);
163 bool SawLoad =
false;
164 bool SawStore =
false;
169 if (
I->isDebugInstr())
175 if (
I->hasUnmodeledSideEffects() ||
I->isInlineAsm() ||
I->isLabel() ||
176 FI == LastFiller ||
I->isPseudo())
179 if (delayHasHazard(FI, SawLoad, SawStore, RegDefs, RegUses)) {
180 insertDefsUses(FI, RegDefs, RegUses);
190 bool &SawLoad,
bool &SawStore,
191 SmallSet<unsigned, 32> &RegDefs,
192 SmallSet<unsigned, 32> &RegUses) {
193 if (
MI->isImplicitDef() ||
MI->isKill())
204 if (
MI->mayStore()) {
213 "Cannot put calls or returns in delay slot.");
215 for (
const MachineOperand &MO :
MI->operands()) {
218 if (!MO.isReg() || !(
Reg = MO.getReg()))
223 if (isRegInSet(RegDefs,
Reg) || isRegInSet(RegUses,
Reg))
228 if (isRegInSet(RegDefs,
Reg))
237 SmallSet<unsigned, 32> &RegDefs,
238 SmallSet<unsigned, 32> &RegUses) {
239 for (
const MachineOperand &MO :
MI->operands()) {
240 if (MO.isRegMask()) {
252 if (
Reg != MO.getReg())
262 }
else if (MO.isUse()) {
271 if (
MI->isCall() ||
MI->isReturn())
272 RegDefs.
insert(Lanai::SP);
276bool FillerImpl::isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg) {
278 for (MCRegAliasIterator AI(
Reg,
TRI,
true); AI.isValid(); ++AI)
279 if (RegSet.
count(*AI))
284bool LanaiDelaySlotFillerLegacy::runOnMachineFunction(MachineFunction &MF) {
286 return Impl.runOnMachineFunction(MF);
293 return Impl.runOnMachineFunction(MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
Promote Memory to Register
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)
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
const LanaiRegisterInfo * getRegisterInfo() const override
const LanaiInstrInfo * getInstrInfo() const override
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
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...
Pass manager infrastructure for declaring and invalidating analyses.
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.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
FunctionPass * createLanaiDelaySlotFillerLegacyPass(const LanaiTargetMachine &TM)