26#define DEBUG_TYPE "delay-slot-filler"
28STATISTIC(FilledSlots,
"Number of delay slots filled");
32 const LanaiOptions *CLOpts;
54 SmallSet<unsigned, 32> &RegDefs,
55 SmallSet<unsigned, 32> &RegUses);
57 bool isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg);
60 bool &SawStore, SmallSet<unsigned, 32> &RegDefs,
61 SmallSet<unsigned, 32> &RegUses);
72 explicit LanaiDelaySlotFillerLegacy() : MachineFunctionPass(ID) {}
74 StringRef getPassName()
const override {
return "Lanai Delay Slot Filler"; }
76 MachineFunctionProperties getRequiredProperties()
const override {
77 return MachineFunctionProperties().setNoVRegs();
82char LanaiDelaySlotFillerLegacy::ID = 0;
89 return new LanaiDelaySlotFillerLegacy();
96 LastFiller =
MBB.instr_end();
99 I !=
MBB.instr_end(); ++
I) {
100 if (
I->getDesc().hasDelaySlot()) {
106 if (
I->getOpcode() == Lanai::RET) {
111 assert(RI->getOpcode() == Lanai::LDW_RI && RI->getOperand(0).isReg() &&
112 RI->getOperand(0).getReg() == Lanai::FP &&
113 RI->getOperand(1).isReg() &&
114 RI->getOperand(1).getReg() == Lanai::FP &&
115 RI->getOperand(2).isImm() && RI->getOperand(2).getImm() == -8);
117 assert(RI->getOpcode() == Lanai::ADD_I_LO &&
118 RI->getOperand(0).isReg() &&
119 RI->getOperand(0).getReg() == Lanai::SP &&
120 RI->getOperand(1).isReg() &&
121 RI->getOperand(1).getReg() == Lanai::FP);
123 MBB.splice(std::next(
I), &
MBB, FI,
I);
140 if (InstrWithSlot->getOpcode() == Lanai::RET)
145 MIBundleBuilder(
MBB, InstrWithSlot, std::next(LastFiller));
151bool FillerImpl::findDelayInstr(MachineBasicBlock &
MBB,
154 SmallSet<unsigned, 32> RegDefs;
155 SmallSet<unsigned, 32> RegUses;
159 bool SawLoad =
false;
160 bool SawStore =
false;
165 if (
I->isDebugInstr())
171 if (
I->hasUnmodeledSideEffects() ||
I->isInlineAsm() ||
I->isLabel() ||
172 FI == LastFiller ||
I->isPseudo())
186 bool &SawLoad,
bool &SawStore,
187 SmallSet<unsigned, 32> &RegDefs,
188 SmallSet<unsigned, 32> &RegUses) {
189 if (
MI->isImplicitDef() ||
MI->isKill())
200 if (
MI->mayStore()) {
209 "Cannot put calls or returns in delay slot.");
211 for (
const MachineOperand &MO :
MI->operands()) {
214 if (!MO.isReg() || !(
Reg = MO.getReg()))
219 if (isRegInSet(RegDefs,
Reg) || isRegInSet(RegUses,
Reg))
224 if (isRegInSet(RegDefs,
Reg))
233 SmallSet<unsigned, 32> &RegDefs,
234 SmallSet<unsigned, 32> &RegUses) {
235 for (
const MachineOperand &MO :
MI->operands()) {
236 if (MO.isRegMask()) {
248 if (
Reg != MO.getReg())
258 }
else if (MO.isUse()) {
267 if (
MI->isCall() ||
MI->isReturn())
268 RegDefs.
insert(Lanai::SP);
272bool FillerImpl::isRegInSet(SmallSet<unsigned, 32> &RegSet,
unsigned Reg) {
274 for (MCRegAliasIterator AI(
Reg,
TRI,
true); AI.isValid(); ++AI)
275 if (RegSet.
count(*AI))
280bool LanaiDelaySlotFillerLegacy::runOnMachineFunction(
MachineFunction &MF) {
282 return Impl.runOnMachineFunction(MF);
289 return Impl.runOnMachineFunction(MF)
const AArch64Subtarget & Subtarget
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void insertDefsUses(MachineBasicBlock::iterator MI, SmallSet< unsigned, 32 > &RegDefs, SmallSet< unsigned, 32 > &RegUses, const SparcSubtarget *Subtarget)
static MachineBasicBlock::iterator findDelayInstr(MachineBasicBlock &MBB, MachineBasicBlock::iterator slot, const SparcSubtarget *Subtarget)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool runOnMachineBasicBlock(MachineBasicBlock &MBB, MachineInstr *FirstNextMBBInstr, function_ref< MachineBranchProbabilityInfo &()> GetMBPI)
runOnMachineBasicBlock - Fill in delay slots for the given basic block.
static bool delayHasHazard(const MipsSubtarget &STI, const MachineInstr &Candidate, const BranchInformation &BranchInfo, RegDefsUses &RegDU, InspectMemInstr &IM)
This function checks if it is valid to move Candidate to the delay slot and returns true if it isn't.
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)
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.
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)