60#ifndef LLVM_CODEGEN_MODULOSCHEDULE_H
61#define LLVM_CODEGEN_MODULOSCHEDULE_H
72class MachineBasicBlock;
74class MachineRegisterInfo;
88 std::vector<MachineInstr *> ScheduledInstrs;
108 std::vector<MachineInstr *> ScheduledInstrs,
114 for (
auto &KV : this->Stage)
115 NumStages = std::max(NumStages, KV.second);
137 return I == Stage.
end() ? -1 :
I->second;
143 return I ==
Cycle.end() ? -1 :
I->second;
180 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
LoopInfo;
186 std::map<unsigned, std::pair<unsigned, bool>> RegToStageDiff;
191 void generatePipelinedLoop();
201 unsigned LastStageNum,
unsigned CurStageNum,
207 unsigned CurStageNum,
bool IsLast);
218 unsigned InstStageNum);
220 unsigned InstStageNum);
221 void updateInstruction(
MachineInstr *NewMI,
bool LastDef,
222 unsigned CurStageNum,
unsigned InstrStageNum,
225 unsigned getPrevMapVal(
unsigned StageNum,
unsigned PhiStage,
unsigned LoopVal,
231 unsigned CurStageNum,
unsigned PhiNum,
233 unsigned NewReg,
unsigned PrevReg = 0);
238 unsigned getStagesForReg(
int Reg,
unsigned CurStage) {
239 std::pair<unsigned, bool> Stages = RegToStageDiff[
Reg];
240 if ((
int)CurStage > Schedule.
getNumStages() - 1 && Stages.first == 0 &&
252 unsigned getStagesForPhi(
int Reg) {
253 std::pair<unsigned, bool> Stages = RegToStageDiff[
Reg];
256 return Stages.first - 1;
267 : Schedule(S), MF(MF), ST(MF.getSubtarget()),
MRI(MF.getRegInfo()),
268 TII(ST.getInstrInfo()), LIS(LIS),
269 InstrChanges(
std::
move(InstrChanges)) {}
370 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
LoopInfo;
397 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
LoopInfo;
403 void calcNumUnroll();
404 void generatePipelinedLoop();
438 : Schedule(S), MF(MF), ST(MF.getSubtarget()),
MRI(MF.getRegInfo()),
439 TII(ST.getInstrInfo()), LIS(LIS) {}
unsigned const MachineRegisterInfo * MRI
const HexagonInstrInfo * TII
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
A possibly irreducible generalization of a Loop.
Represents a single loop in the control flow graph.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Expand the kernel using modulo variable expansion algorithm (MVE).
static bool canApply(MachineLoop &L)
Check if ModuloScheduleExpanderMVE can be applied to L.
ModuloScheduleExpanderMVE(MachineFunction &MF, ModuloSchedule &S, LiveIntervals &LIS)
The ModuloScheduleExpander takes a ModuloSchedule and expands it in-place, rewriting the old loop and...
MachineBasicBlock * getRewrittenKernel()
Returns the newly rewritten kernel block, or nullptr if this was optimized away.
void cleanup()
Performs final cleanup after expansion.
void expand()
Performs the actual expansion.
ModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S, LiveIntervals &LIS, InstrChangesTy InstrChanges)
Create a new ModuloScheduleExpander.
Expander that simply annotates each scheduled instruction with a post-instr symbol that can be consum...
void annotate()
Performs the annotation.
ModuloScheduleTestAnnotater(MachineFunction &MF, ModuloSchedule &S)
Represents a schedule for a single-block loop.
int getNumStages() const
Return the number of stages contained in this schedule, which is the largest stage index + 1.
MachineLoop * getLoop() const
Return the single-block loop being scheduled.
ArrayRef< MachineInstr * > getInstructions()
Return the rescheduled instructions in order.
void print(raw_ostream &OS)
int getCycle(MachineInstr *MI)
Return the cycle that MI is scheduled at, or -1.
void setStage(MachineInstr *MI, int MIStage)
Set the stage of a newly created instruction.
int getStage(MachineInstr *MI)
Return the stage that MI is scheduled in, or -1.
ModuloSchedule(MachineFunction &MF, MachineLoop *Loop, std::vector< MachineInstr * > ScheduledInstrs, DenseMap< MachineInstr *, int > Cycle, DenseMap< MachineInstr *, int > Stage)
Create a new ModuloSchedule.
int getFirstCycle()
Return the first cycle in the schedule, which is the cycle index of the first instruction.
int getFinalCycle()
Return the final cycle in the schedule, which is the cycle index of the last instruction.
A reimplementation of ModuloScheduleExpander.
const TargetSubtargetInfo & ST
std::deque< MachineBasicBlock * > PeeledBack
SmallVector< MachineInstr *, 4 > IllegalPhisToDelete
Illegal phis that need to be deleted once we re-link stages.
DenseMap< MachineInstr *, MachineInstr * > CanonicalMIs
CanonicalMIs and BlockMIs form a bidirectional map between any of the loop kernel clones.
SmallVector< MachineBasicBlock *, 4 > Prologs
All prolog and epilog blocks.
MachineBasicBlock * peelKernel(LoopPeelDirection LPD)
Peels one iteration of the rewritten kernel (BB) in the specified direction.
ModuloSchedule & Schedule
std::deque< MachineBasicBlock * > PeeledFront
State passed from peelKernel to peelPrologAndEpilogs().
unsigned getStage(MachineInstr *MI)
Helper to get the stage of an instruction in the schedule.
void rewriteUsesOf(MachineInstr *MI)
Change all users of MI, if MI is predicated out (LiveStages[MI->getParent()] == false).
SmallVector< MachineBasicBlock *, 4 > Epilogs
DenseMap< MachineBasicBlock *, BitVector > AvailableStages
For every block, the stages that are available.
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > LoopInfo
Target loop info before kernel peeling.
DenseMap< std::pair< MachineBasicBlock *, MachineInstr * >, MachineInstr * > BlockMIs
Register getEquivalentRegisterIn(Register Reg, MachineBasicBlock *BB)
All prolog and epilog blocks are clones of the kernel, so any produced register in one block has an c...
MachineBasicBlock * Preheader
The original loop preheader.
PeelingModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S, LiveIntervals *LIS)
void rewriteKernel()
Converts BB from the original loop body to the rewritten, pipelined steady-state.
DenseMap< MachineInstr *, unsigned > PhiNodeLoopIteration
When peeling the epilogue keep track of the distance between the phi nodes and the kernel.
DenseMap< MachineBasicBlock *, BitVector > LiveStages
For every block, the stages that are produced.
const TargetInstrInfo * TII
void filterInstructions(MachineBasicBlock *MB, int MinStage)
void peelPrologAndEpilogs()
Peel the kernel forwards and backwards to produce prologs and epilogs, and stitch them together.
MachineBasicBlock * BB
The original loop block that gets rewritten in-place.
void fixupBranches()
Insert branches between prologs, kernel and epilogs.
MachineBasicBlock * CreateLCSSAExitingBlock()
Create a poor-man's LCSSA by cloning only the PHIs from the kernel block to a block dominated by all ...
void validateAgainstModuloScheduleExpander()
Runs ModuloScheduleExpander and treats it as a golden input to validate aspects of the code generated...
Register getPhiCanonicalReg(MachineInstr *CanonicalPhi, MachineInstr *Phi)
Helper function to find the right canonical register for a phi instruction coming from a peeled out p...
MachineRegisterInfo & MRI
void moveStageBetweenBlocks(MachineBasicBlock *DestBB, MachineBasicBlock *SourceBB, unsigned Stage)
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetSubtargetInfo - Generic base class for all target subtargets.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Implement std::hash so that hash_code can be used in STL containers.