//===- ModuloSchedule.h - Software pipeline schedule expansion ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Software pipelining (SWP) is an instruction scheduling technique for loops // that overlaps loop iterations and exploits ILP via compiler transformations. // // There are multiple methods for analyzing a loop and creating a schedule. // An example algorithm is Swing Modulo Scheduling (implemented by the // MachinePipeliner). The details of how a schedule is arrived at are irrelevant // for the task of actually rewriting a loop to adhere to the schedule, which // is what this file does. // // A schedule is, for every instruction in a block, a Cycle and a Stage. Note // that we only support single-block loops, so "block" and "loop" can be used // interchangably. // // The Cycle of an instruction defines a partial order of the instructions in // the remapped loop. Instructions within a cycle must not consume the output // of any instruction in the same cycle. Cycle information is assumed to have // been calculated such that the processor will execute instructions in // lock-step (for example in a VLIW ISA). // // The Stage of an instruction defines the mapping between logical loop // iterations and pipelined loop iterations. An example (unrolled) pipeline // may look something like: // // I0[0] Execute instruction I0 of iteration 0 // I1[0], I0[1] Execute I0 of iteration 1 and I1 of iteration 1 // I1[1], I0[2] // I1[2], I0[3] // // In the schedule for this unrolled sequence we would say that I0 was scheduled // in stage 0 and I1 in stage 1: // // loop: // [stage 0] x = I0 // [stage 1] I1 x (from stage 0) // // And to actually generate valid code we must insert a phi: // // loop: // x' = phi(x) // x = I0 // I1 x' // // This is a simple example; the rules for how to generate correct code given // an arbitrary schedule containing loop-carried values are complex. // // Note that these examples only mention the steady-state kernel of the // generated loop; prologs and epilogs must be generated also that prime and // flush the pipeline. Doing so is nontrivial. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_MODULOSCHEDULE_H #define LLVM_CODEGEN_MODULOSCHEDULE_H #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineLoopUtils.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include <deque> #include <map> #include <vector> namespace llvm { class MachineBasicBlock; class MachineLoop; class MachineRegisterInfo; class MachineInstr; class LiveIntervals; /// Represents a schedule for a single-block loop. For every instruction we /// maintain a Cycle and Stage. class ModuloSchedule { … }; /// The ModuloScheduleExpander takes a ModuloSchedule and expands it in-place, /// rewriting the old loop and inserting prologs and epilogs as required. class ModuloScheduleExpander { … }; /// A reimplementation of ModuloScheduleExpander. It works by generating a /// standalone kernel loop and peeling out the prologs and epilogs. class PeelingModuloScheduleExpander { … }; /// Expand the kernel using modulo variable expansion algorithm (MVE). /// It unrolls the kernel enough to avoid overlap of register lifetime. class ModuloScheduleExpanderMVE { … }; /// Expander that simply annotates each scheduled instruction with a post-instr /// symbol that can be consumed by the ModuloScheduleTest pass. /// /// The post-instr symbol is a way of annotating an instruction that can be /// roundtripped in MIR. The syntax is: /// MYINST %0, post-instr-symbol <mcsymbol Stage-1_Cycle-5> class ModuloScheduleTestAnnotater { … }; } // end namespace llvm #endif // LLVM_CODEGEN_MODULOSCHEDULE_H