6262
6363#include " llvm/CodeGen/MachineFunction.h"
6464#include " llvm/CodeGen/MachineLoopInfo.h"
65+ #include " llvm/CodeGen/MachineLoopUtils.h"
6566#include " llvm/CodeGen/TargetInstrInfo.h"
6667#include " llvm/CodeGen/TargetSubtargetInfo.h"
68+ #include < deque>
6769#include < vector>
6870
6971namespace llvm {
@@ -142,9 +144,7 @@ class ModuloSchedule {
142144 // / Return the rescheduled instructions in order.
143145 ArrayRef<MachineInstr *> getInstructions () { return ScheduledInstrs; }
144146
145- void dump () {
146- print (dbgs ());
147- }
147+ void dump () { print (dbgs ()); }
148148 void print (raw_ostream &OS);
149149};
150150
@@ -270,9 +270,6 @@ class ModuloScheduleExpander {
270270
271271// / A reimplementation of ModuloScheduleExpander. It works by generating a
272272// / standalone kernel loop and peeling out the prologs and epilogs.
273- // /
274- // / FIXME: This implementation cannot yet generate valid code. It can generate
275- // / a correct kernel but cannot peel out prologs and epilogs.
276273class PeelingModuloScheduleExpander {
277274 ModuloSchedule &Schedule;
278275 MachineFunction &MF;
@@ -281,17 +278,70 @@ class PeelingModuloScheduleExpander {
281278 const TargetInstrInfo *TII;
282279 LiveIntervals *LIS;
283280
281+ // / The original loop block that gets rewritten in-place.
284282 MachineBasicBlock *BB;
283+ // / The original loop preheader.
285284 MachineBasicBlock *Preheader;
285+ // / All prolog and epilog blocks.
286+ SmallVector<MachineBasicBlock *, 4 > Prologs, Epilogs;
287+ // / For every block, the stages that are produced.
288+ DenseMap<MachineBasicBlock *, BitVector> LiveStages;
289+ // / For every block, the stages that are available. A stage can be available
290+ // / but not produced (in the epilog) or produced but not available (in the
291+ // / prolog).
292+ DenseMap<MachineBasicBlock *, BitVector> AvailableStages;
293+
294+ // / CanonicalMIs and BlockMIs form a bidirectional map between any of the
295+ // / loop kernel clones.
296+ DenseMap<MachineInstr *, MachineInstr *> CanonicalMIs;
297+ DenseMap<std::pair<MachineBasicBlock *, MachineInstr *>, MachineInstr *>
298+ BlockMIs;
299+
300+ // / State passed from peelKernel to peelPrologAndEpilogs().
301+ std::deque<MachineBasicBlock *> PeeledFront, PeeledBack;
302+
286303public:
287304 PeelingModuloScheduleExpander (MachineFunction &MF, ModuloSchedule &S,
288305 LiveIntervals *LIS)
289306 : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
290307 TII (ST.getInstrInfo()), LIS(LIS) {}
291308
309+ void expand ();
310+
292311 // / Runs ModuloScheduleExpander and treats it as a golden input to validate
293312 // / aspects of the code generated by PeelingModuloScheduleExpander.
294313 void validateAgainstModuloScheduleExpander ();
314+
315+ protected:
316+ // / Converts BB from the original loop body to the rewritten, pipelined
317+ // / steady-state.
318+ void rewriteKernel ();
319+
320+ private:
321+ // / Peels one iteration of the rewritten kernel (BB) in the specified
322+ // / direction.
323+ MachineBasicBlock *peelKernel (LoopPeelDirection LPD);
324+ // / Peel the kernel forwards and backwards to produce prologs and epilogs,
325+ // / and stitch them together.
326+ void peelPrologAndEpilogs ();
327+ // / All prolog and epilog blocks are clones of the kernel, so any produced
328+ // / register in one block has an corollary in all other blocks.
329+ Register getEquivalentRegisterIn (Register Reg, MachineBasicBlock *BB);
330+ // / Change all users of MI, if MI is predicated out
331+ // / (LiveStages[MI->getParent()] == false).
332+ void rewriteUsesOf (MachineInstr *MI);
333+ // / Insert branches between prologs, kernel and epilogs.
334+ void fixupBranches ();
335+ // / Create a poor-man's LCSSA by cloning only the PHIs from the kernel block
336+ // / to a block dominated by all prologs and epilogs. This allows us to treat
337+ // / the loop exiting block as any other kernel clone.
338+ MachineBasicBlock *CreateLCSSAExitingBlock ();
339+ // / Helper to get the stage of an instruction in the schedule.
340+ unsigned getStage (MachineInstr *MI) {
341+ if (CanonicalMIs.count (MI))
342+ MI = CanonicalMIs[MI];
343+ return Schedule.getStage (MI);
344+ }
295345};
296346
297347// / Expander that simply annotates each scheduled instruction with a post-instr
0 commit comments