60#ifndef LLVM_CODEGEN_MODULOSCHEDULE_H
61#define LLVM_CODEGEN_MODULOSCHEDULE_H
88 std::vector<MachineInstr *> ScheduledInstrs;
108 std::vector<MachineInstr *> ScheduledInstrs,
111 : Loop(Loop), ScheduledInstrs(ScheduledInstrs), Cycle(
std::
move(Cycle)),
114 for (
auto &KV : this->Stage)
115 NumStages = std::max(NumStages, KV.second);
136 auto I = Stage.find(
MI);
137 return I == Stage.end() ? -1 :
I->second;
142 auto I = Cycle.find(
MI);
143 return I == Cycle.end() ? -1 :
I->second;
180 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
186 std::map<Register, std::pair<unsigned, bool>> RegToStageDiff;
191 void generatePipelinedLoop();
193 ValueMapTy *VRMap, MBBVectorTy &PrologBBs);
196 ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
197 MBBVectorTy &PrologBBs);
200 ValueMapTy *VRMap, InstrMapTy &InstrMap,
201 unsigned LastStageNum,
unsigned CurStageNum,
205 ValueMapTy *VRMap, ValueMapTy *VRMapPhi,
206 InstrMapTy &InstrMap,
unsigned LastStageNum,
207 unsigned CurStageNum,
bool IsLast);
209 MBBVectorTy &EpilogBBs);
218 unsigned InstStageNum);
220 unsigned InstStageNum);
221 void updateInstruction(
MachineInstr *NewMI,
bool LastDef,
222 unsigned CurStageNum,
unsigned InstrStageNum,
225 Register getPrevMapVal(
unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
226 unsigned LoopStage, ValueMapTy *VRMap,
229 ValueMapTy *VRMap, InstrMapTy &InstrMap);
231 unsigned CurStageNum,
unsigned PhiNum,
238 unsigned getStagesForReg(
Register Reg,
unsigned CurStage) {
239 std::pair<unsigned, bool> Stages = RegToStageDiff[
Reg];
240 if ((
int)CurStage > Schedule.getNumStages() - 1 && Stages.first == 0 &&
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)) {}
373 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
LoopInfo;
400 std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
406 void calcNumUnroll();
407 void generatePipelinedLoop();
415 InstrMapTy &LastStage0Insts);
418 InstrMapTy &LastStage0Insts);
423 void updateInstrDef(
MachineInstr *NewMI, ValueMapTy &VRMap,
bool LastDef);
434 InstrMapTy &LastStage0Insts,
441 : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
442 TII(ST.getInstrInfo()), LIS(LIS) {}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Promote Memory to Register
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI bool canApply(MachineLoop &L)
Check if ModuloScheduleExpanderMVE can be applied to L.
ModuloScheduleExpanderMVE(MachineFunction &MF, ModuloSchedule &S, LiveIntervals &LIS)
MachineBasicBlock * getRewrittenKernel()
Returns the newly rewritten kernel block, or nullptr if this was optimized away.
LLVM_ABI void cleanup()
Performs final cleanup after expansion.
LLVM_ABI void expand()
Performs the actual expansion.
DenseMap< MachineInstr *, std::pair< Register, int64_t > > InstrChangesTy
ModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S, LiveIntervals &LIS, InstrChangesTy InstrChanges)
Create a new ModuloScheduleExpander.
LLVM_ABI 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.
LLVM_ABI 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.
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.
LLVM_ABI 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.
LLVM_ABI 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
LLVM_ABI 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)
LLVM_ABI 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
LLVM_ABI void filterInstructions(MachineBasicBlock *MB, int MinStage)
LLVM_ABI 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.
LLVM_ABI void fixupBranches()
Insert branches between prologs, kernel and epilogs.
LLVM_ABI MachineBasicBlock * CreateLCSSAExitingBlock()
Create a poor-man's LCSSA by cloning only the PHIs from the kernel block to a block dominated by all ...
LLVM_ABI void validateAgainstModuloScheduleExpander()
Runs ModuloScheduleExpander and treats it as a golden input to validate aspects of the code generated...
LLVM_ABI 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
LLVM_ABI void moveStageBetweenBlocks(MachineBasicBlock *DestBB, MachineBasicBlock *SourceBB, unsigned Stage)
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
LLVM_ABI 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.