#include "llvm/CodeGen/ModuloSchedule.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE …
usingnamespacellvm;
static cl::opt<bool> SwapBranchTargetsMVE(
"pipeliner-swap-branch-targets-mve", cl::Hidden, cl::init(false),
cl::desc("Swap target blocks of a conditional branch for MVE expander"));
void ModuloSchedule::print(raw_ostream &OS) { … }
static void getPhiRegs(MachineInstr &Phi, MachineBasicBlock *Loop,
unsigned &InitVal, unsigned &LoopVal) { … }
static unsigned getInitPhiReg(MachineInstr &Phi, MachineBasicBlock *LoopBB) { … }
static unsigned getLoopPhiReg(MachineInstr &Phi, MachineBasicBlock *LoopBB) { … }
void ModuloScheduleExpander::expand() { … }
void ModuloScheduleExpander::generatePipelinedLoop() { … }
void ModuloScheduleExpander::cleanup() { … }
void ModuloScheduleExpander::generateProlog(unsigned LastStage,
MachineBasicBlock *KernelBB,
ValueMapTy *VRMap,
MBBVectorTy &PrologBBs) { … }
void ModuloScheduleExpander::generateEpilog(
unsigned LastStage, MachineBasicBlock *KernelBB, MachineBasicBlock *OrigBB,
ValueMapTy *VRMap, ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
MBBVectorTy &PrologBBs) { … }
static void replaceRegUsesAfterLoop(unsigned FromReg, unsigned ToReg,
MachineBasicBlock *MBB,
MachineRegisterInfo &MRI,
LiveIntervals &LIS) { … }
static bool hasUseAfterLoop(unsigned Reg, MachineBasicBlock *BB,
MachineRegisterInfo &MRI) { … }
void ModuloScheduleExpander::generateExistingPhis(
MachineBasicBlock *NewBB, MachineBasicBlock *BB1, MachineBasicBlock *BB2,
MachineBasicBlock *KernelBB, ValueMapTy *VRMap, InstrMapTy &InstrMap,
unsigned LastStageNum, unsigned CurStageNum, bool IsLast) { … }
void ModuloScheduleExpander::generatePhis(
MachineBasicBlock *NewBB, MachineBasicBlock *BB1, MachineBasicBlock *BB2,
MachineBasicBlock *KernelBB, ValueMapTy *VRMap, ValueMapTy *VRMapPhi,
InstrMapTy &InstrMap, unsigned LastStageNum, unsigned CurStageNum,
bool IsLast) { … }
void ModuloScheduleExpander::removeDeadInstructions(MachineBasicBlock *KernelBB,
MBBVectorTy &EpilogBBs) { … }
void ModuloScheduleExpander::splitLifetimes(MachineBasicBlock *KernelBB,
MBBVectorTy &EpilogBBs) { … }
static void removePhis(MachineBasicBlock *BB, MachineBasicBlock *Incoming) { … }
void ModuloScheduleExpander::addBranches(MachineBasicBlock &PreheaderBB,
MBBVectorTy &PrologBBs,
MachineBasicBlock *KernelBB,
MBBVectorTy &EpilogBBs,
ValueMapTy *VRMap) { … }
bool ModuloScheduleExpander::computeDelta(MachineInstr &MI, unsigned &Delta) { … }
void ModuloScheduleExpander::updateMemOperands(MachineInstr &NewMI,
MachineInstr &OldMI,
unsigned Num) { … }
MachineInstr *ModuloScheduleExpander::cloneInstr(MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) { … }
MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
MachineInstr *OldMI, unsigned CurStageNum, unsigned InstStageNum) { … }
void ModuloScheduleExpander::updateInstruction(MachineInstr *NewMI,
bool LastDef,
unsigned CurStageNum,
unsigned InstrStageNum,
ValueMapTy *VRMap) { … }
MachineInstr *ModuloScheduleExpander::findDefInLoop(unsigned Reg) { … }
unsigned ModuloScheduleExpander::getPrevMapVal(
unsigned StageNum, unsigned PhiStage, unsigned LoopVal, unsigned LoopStage,
ValueMapTy *VRMap, MachineBasicBlock *BB) { … }
void ModuloScheduleExpander::rewritePhiValues(MachineBasicBlock *NewBB,
unsigned StageNum,
ValueMapTy *VRMap,
InstrMapTy &InstrMap) { … }
void ModuloScheduleExpander::rewriteScheduledInstr(
MachineBasicBlock *BB, InstrMapTy &InstrMap, unsigned CurStageNum,
unsigned PhiNum, MachineInstr *Phi, unsigned OldReg, unsigned NewReg,
unsigned PrevReg) { … }
bool ModuloScheduleExpander::isLoopCarried(MachineInstr &Phi) { … }
namespace {
void EliminateDeadPhis(MachineBasicBlock *MBB, MachineRegisterInfo &MRI,
LiveIntervals *LIS, bool KeepSingleSrcPhi = false) { … }
class KernelRewriter { … };
}
KernelRewriter::KernelRewriter(MachineLoop &L, ModuloSchedule &S,
MachineBasicBlock *LoopBB, LiveIntervals *LIS)
: … { … }
void KernelRewriter::rewrite() { … }
Register KernelRewriter::remapUse(Register Reg, MachineInstr &MI) { … }
Register KernelRewriter::phi(Register LoopReg, std::optional<Register> InitReg,
const TargetRegisterClass *RC) { … }
Register KernelRewriter::undef(const TargetRegisterClass *RC) { … }
namespace {
class KernelOperandInfo { … };
}
MachineBasicBlock *
PeelingModuloScheduleExpander::peelKernel(LoopPeelDirection LPD) { … }
void PeelingModuloScheduleExpander::filterInstructions(MachineBasicBlock *MB,
int MinStage) { … }
void PeelingModuloScheduleExpander::moveStageBetweenBlocks(
MachineBasicBlock *DestBB, MachineBasicBlock *SourceBB, unsigned Stage) { … }
Register
PeelingModuloScheduleExpander::getPhiCanonicalReg(MachineInstr *CanonicalPhi,
MachineInstr *Phi) { … }
void PeelingModuloScheduleExpander::peelPrologAndEpilogs() { … }
MachineBasicBlock *PeelingModuloScheduleExpander::CreateLCSSAExitingBlock() { … }
Register
PeelingModuloScheduleExpander::getEquivalentRegisterIn(Register Reg,
MachineBasicBlock *BB) { … }
void PeelingModuloScheduleExpander::rewriteUsesOf(MachineInstr *MI) { … }
void PeelingModuloScheduleExpander::fixupBranches() { … }
void PeelingModuloScheduleExpander::rewriteKernel() { … }
void PeelingModuloScheduleExpander::expand() { … }
void PeelingModuloScheduleExpander::validateAgainstModuloScheduleExpander() { … }
MachineInstr *ModuloScheduleExpanderMVE::cloneInstr(MachineInstr *OldMI) { … }
static MachineBasicBlock *createDedicatedExit(MachineBasicBlock *Loop,
MachineBasicBlock *Exit) { … }
void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &MBB,
int RequiredTC,
InstrMapTy &LastStage0Insts,
MachineBasicBlock &GreaterThan,
MachineBasicBlock &Otherwise) { … }
void ModuloScheduleExpanderMVE::generatePipelinedLoop() { … }
void ModuloScheduleExpanderMVE::updateInstrUse(
MachineInstr *MI, int StageNum, int PhaseNum,
SmallVectorImpl<ValueMapTy> &CurVRMap,
SmallVectorImpl<ValueMapTy> *PrevVRMap) { … }
static MachineInstr *getLoopPhiUser(Register Reg, MachineBasicBlock *Loop) { … }
void ModuloScheduleExpanderMVE::generatePhi(
MachineInstr *OrigMI, int UnrollNum,
SmallVectorImpl<ValueMapTy> &PrologVRMap,
SmallVectorImpl<ValueMapTy> &KernelVRMap,
SmallVectorImpl<ValueMapTy> &PhiVRMap) { … }
static void replacePhiSrc(MachineInstr &Phi, Register OrigReg, Register NewReg,
MachineBasicBlock *NewMBB) { … }
void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(Register OrigReg,
Register NewReg) { … }
void ModuloScheduleExpanderMVE::generateProlog(
SmallVectorImpl<ValueMapTy> &PrologVRMap) { … }
void ModuloScheduleExpanderMVE::generateKernel(
SmallVectorImpl<ValueMapTy> &PrologVRMap,
SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) { … }
void ModuloScheduleExpanderMVE::generateEpilog(
SmallVectorImpl<ValueMapTy> &KernelVRMap,
SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) { … }
void ModuloScheduleExpanderMVE::calcNumUnroll() { … }
void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
ValueMapTy &VRMap,
bool LastDef) { … }
void ModuloScheduleExpanderMVE::expand() { … }
bool ModuloScheduleExpanderMVE::canApply(MachineLoop &L) { … }
namespace {
class ModuloScheduleTest : public MachineFunctionPass { … };
}
char ModuloScheduleTest::ID = …;
INITIALIZE_PASS_BEGIN(ModuloScheduleTest, "modulo-schedule-test",
"Modulo Schedule test pass", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_END(ModuloScheduleTest, "modulo-schedule-test",
"Modulo Schedule test pass", false, false)
bool ModuloScheduleTest::runOnMachineFunction(MachineFunction &MF) { … }
static void parseSymbolString(StringRef S, int &Cycle, int &Stage) { … }
void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) { … }
void ModuloScheduleTestAnnotater::annotate() { … }