22#define DEBUG_TYPE "pipeliner"
27 cl::desc(
"Swap target blocks of a conditional branch for MVE expander"));
42 assert(Phi.isPHI() &&
"Expecting a Phi.");
46 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
47 if (Phi.getOperand(i + 1).getMBB() !=
Loop)
48 InitVal = Phi.getOperand(i).getReg();
50 LoopVal = Phi.getOperand(i).getReg();
52 assert(InitVal && LoopVal &&
"Unexpected Phi structure.");
57 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
58 if (Phi.getOperand(i + 1).getMBB() != LoopBB)
59 return Phi.getOperand(i).getReg();
65 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
66 if (Phi.getOperand(i + 1).getMBB() == LoopBB)
67 return Phi.getOperand(i).getReg();
72 BB = Schedule.getLoop()->getTopBlock();
73 Preheader = *BB->pred_begin();
75 Preheader = *std::next(BB->pred_begin());
80 int DefStage = Schedule.getStage(
MI);
84 bool PhiIsSwapped =
false;
87 int UseStage = Schedule.getStage(
UseMI);
89 if (UseStage != -1 && UseStage >= DefStage)
90 Diff = UseStage - DefStage;
92 if (isLoopCarried(*
MI))
97 MaxDiff = std::max(Diff, MaxDiff);
99 RegToStageDiff[Reg] = std::make_pair(MaxDiff, PhiIsSwapped);
103 generatePipelinedLoop();
106void ModuloScheduleExpander::generatePipelinedLoop() {
119 ValueMapTy *VRMap =
new ValueMapTy[(MaxStageCount + 1) * 2];
124 ValueMapTy *VRMapPhi =
new ValueMapTy[(MaxStageCount + 1) * 2];
131 generateProlog(MaxStageCount, KernelBB, VRMap, PrologBBs);
140 unsigned StageNum = Schedule.
getStage(CI);
142 updateInstruction(NewMI,
false, MaxStageCount, StageNum, VRMap);
145 InstrMap[NewMI] = CI;
152 updateInstruction(NewMI,
false, MaxStageCount, 0, VRMap);
155 InstrMap[NewMI] = &
MI;
158 NewKernel = KernelBB;
162 generateExistingPhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap,
163 InstrMap, MaxStageCount, MaxStageCount,
false);
164 generatePhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap, VRMapPhi,
165 InstrMap, MaxStageCount, MaxStageCount,
false);
169 SmallVector<MachineBasicBlock *, 4> EpilogBBs;
171 generateEpilog(MaxStageCount, KernelBB, BB, VRMap, VRMapPhi, EpilogBBs,
176 splitLifetimes(KernelBB, EpilogBBs);
179 removeDeadInstructions(KernelBB, EpilogBBs);
182 addBranches(*Preheader, PrologBBs, KernelBB, EpilogBBs, VRMap);
191 LIS.RemoveMachineInstrFromMaps(
I);
193 BB->eraseFromParent();
197void ModuloScheduleExpander::generateProlog(
unsigned LastStage,
200 MBBVectorTy &PrologBBs) {
207 for (
unsigned i = 0; i < LastStage; ++i) {
220 for (
int StageNum = i; StageNum >= 0; --StageNum) {
224 if (Schedule.
getStage(&*BBI) == StageNum) {
228 cloneAndChangeInstr(&*BBI, i, (
unsigned)StageNum);
229 updateInstruction(NewMI,
false, i, (
unsigned)StageNum, VRMap);
232 InstrMap[NewMI] = &*BBI;
236 rewritePhiValues(NewBB, i, VRMap, InstrMap);
238 dbgs() <<
"prolog:\n";
247 unsigned numBranches = TII->removeBranch(*Preheader);
250 TII->insertBranch(*Preheader, PrologBBs[0],
nullptr,
Cond,
DebugLoc());
257void ModuloScheduleExpander::generateEpilog(
259 ValueMapTy *VRMap, ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
260 MBBVectorTy &PrologBBs) {
263 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
265 bool checkBranch = TII->analyzeBranch(*KernelBB,
TBB, FBB,
Cond);
266 assert(!checkBranch &&
"generateEpilog must be able to analyze the branch");
271 if (*LoopExitI == KernelBB)
273 assert(LoopExitI != KernelBB->
succ_end() &&
"Expecting a successor");
274 MachineBasicBlock *LoopExitBB = *LoopExitI;
276 MachineBasicBlock *PredBB = KernelBB;
277 MachineBasicBlock *EpilogStart = LoopExitBB;
283 int EpilogStage = LastStage + 1;
284 for (
unsigned i = LastStage; i >= 1; --i, ++EpilogStage) {
285 MachineBasicBlock *NewBB = MF.CreateMachineBasicBlock();
287 MF.insert(BB->getIterator(), NewBB);
291 LIS.insertMBBInMaps(NewBB);
293 if (EpilogStart == LoopExitBB)
298 for (
unsigned StageNum = i; StageNum <= LastStage; ++StageNum) {
299 for (
auto &BBI : *BB) {
302 MachineInstr *
In = &BBI;
303 if ((
unsigned)Schedule.getStage(In) == StageNum) {
306 MachineInstr *NewMI = cloneInstr(In, UINT_MAX, 0);
307 updateInstruction(NewMI, i == 1, EpilogStage, 0, VRMap);
309 LIS.InsertMachineInstrInMaps(*NewMI);
310 InstrMap[NewMI] =
In;
314 generateExistingPhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap,
315 InstrMap, LastStage, EpilogStage, i == 1);
316 generatePhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap, VRMapPhi,
317 InstrMap, LastStage, EpilogStage, i == 1);
321 dbgs() <<
"epilog:\n";
331 TII->removeBranch(*KernelBB);
332 assert((OrigBB ==
TBB || OrigBB == FBB) &&
333 "Unable to determine looping branch direction");
335 TII->insertBranch(*KernelBB, EpilogStart, KernelBB,
Cond,
DebugLoc());
337 TII->insertBranch(*KernelBB, KernelBB, EpilogStart,
Cond,
DebugLoc());
339 if (EpilogBBs.size() > 0) {
340 MachineBasicBlock *LastEpilogBB = EpilogBBs.back();
342 TII->insertBranch(*LastEpilogBB, LoopExitBB,
nullptr, Cond1,
DebugLoc());
353 if (O.getParent()->getParent() !=
MBB)
362 if (MO.getParent()->getParent() != BB)
370void ModuloScheduleExpander::generateExistingPhis(
373 unsigned LastStageNum,
unsigned CurStageNum,
bool IsLast) {
377 unsigned PrologStage = 0;
378 unsigned PrevStage = 0;
379 bool InKernel = (LastStageNum == CurStageNum);
381 PrologStage = LastStageNum - 1;
382 PrevStage = CurStageNum;
384 PrologStage = LastStageNum - (CurStageNum - LastStageNum);
385 PrevStage = LastStageNum + (CurStageNum - LastStageNum) - 1;
389 BBE = BB->getFirstNonPHI();
401 if (
auto It = VRMap[LastStageNum].
find(LoopVal);
402 It != VRMap[LastStageNum].end())
405 int StageScheduled = Schedule.getStage(&*BBI);
406 int LoopValStage = Schedule.getStage(MRI.getVRegDef(LoopVal));
407 unsigned NumStages = getStagesForReg(Def, CurStageNum);
408 if (NumStages == 0) {
411 Register NewReg = VRMap[PrevStage][LoopVal];
412 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, 0, &*BBI, Def,
414 auto It = VRMap[CurStageNum].find(LoopVal);
415 if (It != VRMap[CurStageNum].
end()) {
417 VRMap[CurStageNum][
Def] =
Reg;
424 unsigned MaxPhis = PrologStage + 2;
425 if (!InKernel && (
int)PrologStage <= LoopValStage)
426 MaxPhis = std::max((
int)MaxPhis - LoopValStage, 1);
427 unsigned NumPhis = std::min(NumStages, MaxPhis);
430 unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled;
437 if (!InKernel && StageScheduled >= LoopValStage && AccessStage == 0 &&
442 if (InKernel && LoopValStage != -1 && StageScheduled > LoopValStage)
443 StageDiff = StageScheduled - LoopValStage;
444 for (
unsigned np = 0; np < NumPhis; ++np) {
448 if (np > PrologStage || StageScheduled >= (
int)LastStageNum)
451 else if (PrologStage >= AccessStage + StageDiff + np &&
452 VRMap[PrologStage - StageDiff - np].
count(LoopVal) != 0)
453 PhiOp1 = VRMap[PrologStage - StageDiff - np][LoopVal];
456 else if (PrologStage >= AccessStage + StageDiff + np) {
460 MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1);
462 while (InstOp1 && InstOp1->
isPHI() && InstOp1->
getParent() == BB) {
463 int PhiStage = Schedule.getStage(InstOp1);
464 if ((
int)(PrologStage - StageDiff - np) < PhiStage + Indirects)
468 InstOp1 = MRI.getVRegDef(PhiOp1);
469 int PhiOpStage = Schedule.getStage(InstOp1);
470 int StageAdj = (PhiOpStage != -1 ? PhiStage - PhiOpStage : 0);
471 if (PhiOpStage != -1 && PrologStage - StageAdj >= Indirects + np) {
472 auto &
M = VRMap[PrologStage - StageAdj - Indirects - np];
473 if (
auto It =
M.find(PhiOp1); It !=
M.end()) {
484 if (MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1))
488 MachineInstr *PhiInst = MRI.getVRegDef(LoopVal);
489 bool LoopDefIsPhi = PhiInst && PhiInst->
isPHI();
494 int StageDiffAdj = 0;
495 if (LoopValStage != -1 && StageScheduled > LoopValStage)
496 StageDiffAdj = StageScheduled - LoopValStage;
499 if (np == 0 && PrevStage == LastStageNum &&
500 (StageScheduled != 0 || LoopValStage != 0) &&
501 VRMap[PrevStage - StageDiffAdj].
count(LoopVal))
502 PhiOp2 = VRMap[PrevStage - StageDiffAdj][LoopVal];
505 else if (np > 0 && PrevStage == LastStageNum &&
506 VRMap[PrevStage - np + 1].
count(Def))
507 PhiOp2 = VRMap[PrevStage - np + 1][
Def];
509 else if (
static_cast<unsigned>(LoopValStage) > PrologStage + 1 &&
510 VRMap[PrevStage - StageDiffAdj - np].
count(LoopVal))
511 PhiOp2 = VRMap[PrevStage - StageDiffAdj - np][LoopVal];
514 else if (VRMap[PrevStage - np].
count(Def) &&
515 (!LoopDefIsPhi || (PrevStage != LastStageNum) ||
516 (LoopValStage == StageScheduled)))
517 PhiOp2 = VRMap[PrevStage - np][
Def];
525 if (
static_cast<int>(PrologStage - np) >= StageScheduled) {
526 int LVNumStages = getStagesForPhi(LoopVal);
527 int StageDiff = (StageScheduled - LoopValStage);
528 LVNumStages -= StageDiff;
530 if (LVNumStages > (
int)np && VRMap[CurStageNum].
count(LoopVal)) {
532 unsigned ReuseStage = CurStageNum;
533 if (isLoopCarried(*PhiInst))
534 ReuseStage -= LVNumStages;
537 if (VRMap[ReuseStage - np].
count(LoopVal)) {
538 NewReg = VRMap[ReuseStage - np][LoopVal];
540 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI,
543 VRMap[CurStageNum - np][
Def] = NewReg;
545 if (VRMap[LastStageNum - np - 1].
count(LoopVal))
546 PhiOp2 = VRMap[LastStageNum - np - 1][LoopVal];
548 if (IsLast && np == NumPhis - 1)
554 if (InKernel && StageDiff > 0 &&
555 VRMap[CurStageNum - StageDiff - np].
count(LoopVal))
556 PhiOp2 = VRMap[CurStageNum - StageDiff - np][LoopVal];
559 const TargetRegisterClass *RC = MRI.getRegClass(Def);
560 NewReg = MRI.createVirtualRegister(RC);
562 MachineInstrBuilder NewPhi =
564 TII->get(TargetOpcode::PHI), NewReg);
567 LIS.InsertMachineInstrInMaps(*NewPhi);
569 InstrMap[NewPhi] = &*BBI;
575 if (InKernel && VRMap[PrevStage - np].
count(LoopVal))
576 PrevReg = VRMap[PrevStage - np][LoopVal];
577 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
580 if (VRMap[CurStageNum - np].
count(Def)) {
582 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, R,
589 if (IsLast && np == NumPhis - 1)
597 VRMap[CurStageNum - np][
Def] = NewReg;
600 while (NumPhis++ < NumStages) {
601 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, NumPhis, &*BBI, Def,
607 if (NumStages == 0 && IsLast) {
608 auto &CurStageMap = VRMap[CurStageNum];
609 auto It = CurStageMap.find(LoopVal);
610 if (It != CurStageMap.end())
619void ModuloScheduleExpander::generatePhis(
622 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
626 unsigned PrologStage = 0;
627 unsigned PrevStage = 0;
628 unsigned StageDiff = CurStageNum - LastStageNum;
629 bool InKernel = (StageDiff == 0);
631 PrologStage = LastStageNum - 1;
632 PrevStage = CurStageNum;
634 PrologStage = LastStageNum - StageDiff;
635 PrevStage = LastStageNum + StageDiff - 1;
639 BBE = BB->instr_end();
641 for (
unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) {
642 MachineOperand &MO = BBI->getOperand(i);
646 int StageScheduled = Schedule.getStage(&*BBI);
647 assert(StageScheduled != -1 &&
"Expecting scheduled instruction.");
649 unsigned NumPhis = getStagesForReg(Def, CurStageNum);
653 if (!InKernel && NumPhis == 0 && StageScheduled == 0 &&
656 if (!InKernel && (
unsigned)StageScheduled > PrologStage)
661 PhiOp2 = VRMap[PrevStage][
Def];
662 if (MachineInstr *InstOp2 = MRI.getVRegDef(PhiOp2))
663 if (InstOp2->isPHI() && InstOp2->getParent() == NewBB)
668 if (NumPhis > PrologStage + 1 - StageScheduled)
669 NumPhis = PrologStage + 1 - StageScheduled;
670 for (
unsigned np = 0; np < NumPhis; ++np) {
694 if (np <= PrologStage)
695 PhiOp1 = VRMap[PrologStage - np][
Def];
697 if (PrevStage == LastStageNum && np == 0)
698 PhiOp2 = VRMap[LastStageNum][
Def];
700 PhiOp2 = VRMapPhi[PrevStage - np][
Def];
703 const TargetRegisterClass *RC = MRI.getRegClass(Def);
704 Register NewReg = MRI.createVirtualRegister(RC);
706 MachineInstrBuilder NewPhi =
708 TII->get(TargetOpcode::PHI), NewReg);
711 LIS.InsertMachineInstrInMaps(*NewPhi);
713 InstrMap[NewPhi] = &*BBI;
718 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp1,
720 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp2,
724 VRMapPhi[PrevStage - np - 1][
Def] = NewReg;
726 VRMapPhi[CurStageNum - np][
Def] = NewReg;
727 if (np == NumPhis - 1)
728 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
731 if (IsLast && np == NumPhis - 1)
743 MBBVectorTy &EpilogBBs) {
751 if (
MI->isInlineAsm()) {
755 bool SawStore =
false;
758 if (!
MI->isSafeToMove(SawStore) && !
MI->isPHI()) {
763 for (
const MachineOperand &MO :
MI->all_defs()) {
772 unsigned realUses = 0;
773 for (
const MachineOperand &U : MRI.use_operands(reg)) {
776 if (
U.getParent()->getParent() != BB) {
787 LIS.RemoveMachineInstrFromMaps(*
MI);
788 MI++->eraseFromParent();
797 if (MRI.use_begin(reg) == MRI.use_end()) {
798 LIS.RemoveMachineInstrFromMaps(
MI);
799 MI.eraseFromParent();
815 MBBVectorTy &EpilogBBs) {
816 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
817 for (
auto &
PHI : KernelBB->
phis()) {
822 E = MRI.use_instr_end();
824 if (
I->isPHI() &&
I->getParent() == KernelBB) {
829 MachineInstr *
MI = MRI.getVRegDef(LCDef);
830 if (!
MI ||
MI->getParent() != KernelBB ||
MI->isPHI())
837 if (BBJ.readsRegister(Def,
nullptr)) {
840 SplitReg = MRI.createVirtualRegister(MRI.getRegClass(Def));
841 MachineInstr *newCopy =
843 TII->get(TargetOpcode::COPY), SplitReg)
845 LIS.InsertMachineInstrInMaps(*newCopy);
847 BBJ.substituteRegister(Def, SplitReg, 0, *
TRI);
852 for (
auto &
Epilog : EpilogBBs)
854 if (
I.readsRegister(Def,
nullptr))
855 I.substituteRegister(Def, SplitReg, 0, *
TRI);
867 for (
unsigned i = 1, e =
MI.getNumOperands(); i != e; i += 2)
868 if (
MI.getOperand(i + 1).getMBB() ==
Incoming) {
869 MI.removeOperand(i + 1);
880 MBBVectorTy &PrologBBs,
882 MBBVectorTy &EpilogBBs,
884 assert(PrologBBs.size() == EpilogBBs.size() &&
"Prolog/Epilog mismatch");
885 MachineBasicBlock *LastPro = KernelBB;
886 MachineBasicBlock *LastEpi = KernelBB;
890 unsigned MaxIter = PrologBBs.
size() - 1;
891 for (
unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --
j) {
894 MachineBasicBlock *
Prolog = PrologBBs[
j];
895 MachineBasicBlock *
Epilog = EpilogBBs[i];
898 std::optional<bool> StaticallyGreater =
899 LoopInfo->createTripCountGreaterCondition(j + 1, *
Prolog,
Cond);
900 unsigned numAdded = 0;
901 if (!StaticallyGreater) {
904 }
else if (*StaticallyGreater ==
false) {
906 Prolog->removeSuccessor(LastPro);
911 if (LastPro != LastEpi) {
912 for (
auto &
MI : *LastEpi)
913 LIS.RemoveMachineInstrFromMaps(
MI);
915 LastEpi->eraseFromParent();
917 if (LastPro == KernelBB) {
918 LoopInfo->disposed(&LIS);
921 for (
auto &
MI : *LastPro)
922 LIS.RemoveMachineInstrFromMaps(
MI);
924 LastPro->eraseFromParent();
933 I !=
E && numAdded > 0; ++
I, --numAdded)
934 updateInstruction(&*
I,
false, j, 0, VRMap);
938 LoopInfo->setPreheader(PrologBBs[MaxIter]);
939 LoopInfo->adjustTripCount(-(MaxIter + 1));
945bool ModuloScheduleExpander::computeDelta(
MachineInstr &
MI,
unsigned &Delta) {
946 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
947 const MachineOperand *BaseOp;
949 bool OffsetIsScalable;
950 if (!TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
954 if (OffsetIsScalable)
957 if (!BaseOp->
isReg())
962 MachineRegisterInfo &MRI = MF.getRegInfo();
964 MachineInstr *BaseDef = MRI.getVRegDef(BaseReg);
965 if (BaseDef && BaseDef->
isPHI()) {
967 BaseDef = MRI.getVRegDef(BaseReg);
973 if (!TII->getIncrementValue(*BaseDef,
D) &&
D >= 0)
983void ModuloScheduleExpander::updateMemOperands(
MachineInstr &NewMI,
993 for (MachineMemOperand *MMO : NewMI.
memoperands()) {
995 if (MMO->isVolatile() || MMO->isAtomic() ||
996 (MMO->isInvariant() && MMO->isDereferenceable()) ||
997 (!MMO->getValue())) {
1002 if (Num != UINT_MAX && computeDelta(OldMI, Delta)) {
1003 int64_t AdjOffset = Delta * Num;
1005 MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()));
1007 NewMMOs.
push_back(MF.getMachineMemOperand(
1017 unsigned CurStageNum,
1018 unsigned InstStageNum) {
1019 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1020 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1027MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
1028 MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) {
1029 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1030 auto It = InstrChanges.find(OldMI);
1031 if (It != InstrChanges.end()) {
1032 std::pair<Register, int64_t> RegAndOffset = It->second;
1033 unsigned BasePos, OffsetPos;
1034 if (!TII->getBaseAndOffsetPosition(*OldMI, BasePos, OffsetPos))
1037 MachineInstr *LoopDef = findDefInLoop(RegAndOffset.first);
1038 if (Schedule.getStage(LoopDef) > (
signed)InstStageNum)
1039 NewOffset += RegAndOffset.second * (CurStageNum - InstStageNum);
1042 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1048void ModuloScheduleExpander::updateInstruction(
MachineInstr *NewMI,
1050 unsigned CurStageNum,
1051 unsigned InstrStageNum,
1052 ValueMapTy *VRMap) {
1053 for (MachineOperand &MO : NewMI->
operands()) {
1059 const TargetRegisterClass *RC = MRI.getRegClass(reg);
1060 Register NewReg = MRI.createVirtualRegister(RC);
1062 VRMap[CurStageNum][reg] = NewReg;
1065 }
else if (MO.
isUse()) {
1066 MachineInstr *
Def = MRI.getVRegDef(reg);
1068 int DefStageNum = Schedule.getStage(Def);
1069 unsigned StageNum = CurStageNum;
1070 if (DefStageNum != -1 && (
int)InstrStageNum > DefStageNum) {
1072 unsigned StageDiff = (InstrStageNum - DefStageNum);
1074 StageNum -= StageDiff;
1076 if (
auto It = VRMap[StageNum].
find(reg); It != VRMap[StageNum].end())
1086 SmallPtrSet<MachineInstr *, 8> Visited;
1087 MachineInstr *
Def = MRI.getVRegDef(
Reg);
1088 while (
Def->isPHI()) {
1089 if (!Visited.
insert(Def).second)
1091 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2)
1092 if (
Def->getOperand(i + 1).getMBB() == BB) {
1093 Def = MRI.getVRegDef(
Def->getOperand(i).getReg());
1101Register ModuloScheduleExpander::getPrevMapVal(
1102 unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
unsigned LoopStage,
1105 if (StageNum > PhiStage) {
1106 MachineInstr *LoopInst = MRI.getVRegDef(LoopVal);
1107 if (PhiStage == LoopStage && VRMap[StageNum - 1].
count(LoopVal))
1109 PrevVal = VRMap[StageNum - 1][LoopVal];
1110 else if (VRMap[StageNum].
count(LoopVal))
1113 PrevVal = VRMap[StageNum][LoopVal];
1117 else if (StageNum == PhiStage + 1)
1120 else if (StageNum > PhiStage + 1 && LoopInst->
getParent() == BB)
1123 getPrevMapVal(StageNum - 1, PhiStage,
getLoopPhiReg(*LoopInst, BB),
1124 LoopStage, VRMap, BB);
1136 InstrMapTy &InstrMap) {
1137 for (
auto &
PHI : BB->phis()) {
1143 unsigned PhiStage = (unsigned)Schedule.getStage(MRI.getVRegDef(PhiDef));
1144 unsigned LoopStage = (unsigned)Schedule.getStage(MRI.getVRegDef(LoopVal));
1145 unsigned NumPhis = getStagesForPhi(PhiDef);
1146 if (NumPhis > StageNum)
1148 for (
unsigned np = 0; np <= NumPhis; ++np) {
1150 getPrevMapVal(StageNum - np, PhiStage, LoopVal, LoopStage, VRMap, BB);
1153 rewriteScheduledInstr(NewBB, InstrMap, StageNum - np, np, &
PHI, PhiDef,
1162void ModuloScheduleExpander::rewriteScheduledInstr(
1166 bool InProlog = (CurStageNum < (unsigned)Schedule.getNumStages() - 1);
1167 int StagePhi = Schedule.getStage(Phi) + PhiNum;
1170 for (MachineOperand &UseOp :
1172 MachineInstr *
UseMI = UseOp.getParent();
1182 assert(OrigInstr != InstrMap.end() &&
"Instruction not scheduled.");
1183 MachineInstr *OrigMI = OrigInstr->second;
1184 int StageSched = Schedule.getStage(OrigMI);
1185 int CycleSched = Schedule.getCycle(OrigMI);
1188 if (StagePhi == StageSched &&
Phi->isPHI()) {
1189 int CyclePhi = Schedule.getCycle(Phi);
1190 if (PrevReg && InProlog)
1191 ReplaceReg = PrevReg;
1192 else if (PrevReg && !isLoopCarried(*Phi) &&
1193 (CyclePhi <= CycleSched || OrigMI->isPHI()))
1194 ReplaceReg = PrevReg;
1196 ReplaceReg = NewReg;
1200 if (!InProlog && StagePhi + 1 == StageSched && !isLoopCarried(*Phi))
1201 ReplaceReg = NewReg;
1202 if (StagePhi > StageSched &&
Phi->isPHI())
1203 ReplaceReg = NewReg;
1204 if (!InProlog && !
Phi->isPHI() && StagePhi < StageSched)
1205 ReplaceReg = NewReg;
1207 const TargetRegisterClass *NRC =
1208 MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg));
1210 UseOp.setReg(ReplaceReg);
1212 Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
1214 TII->
get(TargetOpcode::COPY), SplitReg)
1216 UseOp.setReg(SplitReg);
1217 LIS.InsertMachineInstrInMaps(*newCopy);
1223bool ModuloScheduleExpander::isLoopCarried(
MachineInstr &Phi) {
1226 int DefCycle = Schedule.getCycle(&Phi);
1227 int DefStage = Schedule.getStage(&Phi);
1232 MachineInstr *
Use = MRI.getVRegDef(LoopVal);
1233 if (!Use ||
Use->isPHI())
1235 int LoopCycle = Schedule.getCycle(Use);
1236 int LoopStage = Schedule.getStage(Use);
1237 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
1257 if (
MRI.use_empty(
MI.getOperand(0).getReg())) {
1260 MI.eraseFromParent();
1262 }
else if (!KeepSingleSrcPhi &&
MI.getNumExplicitOperands() == 3) {
1264 MRI.constrainRegClass(
MI.getOperand(1).getReg(),
1265 MRI.getRegClass(
MI.getOperand(0).getReg()));
1266 assert(ConstrainRegClass &&
1267 "Expected a valid constrained register class!");
1268 (void)ConstrainRegClass;
1269 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
1270 MI.getOperand(1).getReg());
1273 MI.eraseFromParent();
1282class KernelRewriter {
1284 MachineBasicBlock *BB;
1285 MachineBasicBlock *PreheaderBB, *ExitBB;
1286 MachineRegisterInfo &
MRI;
1287 const TargetInstrInfo *
TII;
1291 DenseMap<const TargetRegisterClass *, Register> Undefs;
1294 DenseMap<std::pair<Register, Register>,
Register> Phis;
1296 DenseMap<Register, Register> UndefPhis;
1305 const TargetRegisterClass *RC =
nullptr);
1307 Register undef(
const TargetRegisterClass *RC);
1310 KernelRewriter(MachineLoop &L, ModuloSchedule &S, MachineBasicBlock *LoopBB,
1311 LiveIntervals *LIS =
nullptr);
1318 : S(S), BB(LoopBB), PreheaderBB(
L.getLoopPreheader()),
1319 ExitBB(
L.getExitBlock()),
MRI(BB->
getParent()->getRegInfo()),
1320 TII(BB->
getParent()->getSubtarget().getInstrInfo()), LIS(LIS) {
1322 if (PreheaderBB == BB)
1326void KernelRewriter::rewrite() {
1332 MachineInstr *FirstMI =
nullptr;
1336 if (
MI->getParent())
1337 MI->removeFromParent();
1342 assert(FirstMI &&
"Failed to find first MI in schedule");
1349 (
I++)->eraseFromParent();
1353 for (MachineInstr &
MI : *BB) {
1354 if (
MI.isPHI() ||
MI.isTerminator())
1356 for (MachineOperand &MO :
MI.uses()) {
1363 EliminateDeadPhis(BB,
MRI, LIS);
1369 for (
auto MI = BB->getFirstNonPHI();
MI != BB->end(); ++
MI) {
1376 for (MachineOperand &Def :
MI->defs()) {
1377 for (MachineInstr &
MI :
MRI.use_instructions(
Def.getReg())) {
1378 if (
MI.getParent() != BB) {
1399 int ProducerStage = S.
getStage(Producer);
1400 assert(ConsumerStage != -1 &&
1401 "In-loop consumer should always be scheduled!");
1402 assert(ConsumerStage >= ProducerStage);
1403 unsigned StageDiff = ConsumerStage - ProducerStage;
1405 for (
unsigned I = 0;
I < StageDiff; ++
I)
1415 while (LoopProducer->isPHI() && LoopProducer->getParent() == BB) {
1418 LoopProducer =
MRI.getUniqueVRegDef(LoopReg);
1421 int LoopProducerStage = S.
getStage(LoopProducer);
1423 std::optional<Register> IllegalPhiDefault;
1425 if (LoopProducerStage == -1) {
1427 }
else if (LoopProducerStage > ConsumerStage) {
1433 int LoopProducerCycle = S.
getCycle(LoopProducer);
1436 assert(LoopProducerCycle <= ConsumerCycle);
1437 assert(LoopProducerStage == ConsumerStage + 1);
1444 IllegalPhiDefault = Defaults.
front();
1447 assert(ConsumerStage >= LoopProducerStage);
1448 int StageDiff = ConsumerStage - LoopProducerStage;
1449 if (StageDiff > 0) {
1451 <<
" to " << (Defaults.
size() + StageDiff) <<
"\n");
1456 Defaults.
empty() ? std::optional<Register>()
1462 auto DefaultI = Defaults.
rbegin();
1463 while (DefaultI != Defaults.
rend())
1464 LoopReg =
phi(LoopReg, *DefaultI++,
MRI.getRegClass(
Reg));
1466 if (IllegalPhiDefault) {
1472 auto RC =
MRI.getRegClass(
Reg);
1474 MachineInstr *IllegalPhi =
1476 .
addReg(*IllegalPhiDefault)
1482 S.
setStage(IllegalPhi, LoopProducerStage);
1489Register KernelRewriter::phi(
Register LoopReg, std::optional<Register> InitReg,
1490 const TargetRegisterClass *RC) {
1493 auto I = Phis.find({LoopReg, *InitReg});
1494 if (
I != Phis.end())
1497 for (
auto &KV : Phis) {
1498 if (KV.first.first == LoopReg)
1505 auto I = UndefPhis.
find(LoopReg);
1506 if (
I != UndefPhis.
end()) {
1513 MachineInstr *
MI =
MRI.getVRegDef(R);
1514 MI->getOperand(1).setReg(*InitReg);
1515 Phis.insert({{LoopReg, *InitReg},
R});
1516 const TargetRegisterClass *ConstrainRegClass =
1517 MRI.constrainRegClass(R,
MRI.getRegClass(*InitReg));
1518 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1519 (void)ConstrainRegClass;
1526 RC =
MRI.getRegClass(LoopReg);
1529 const TargetRegisterClass *ConstrainRegClass =
1530 MRI.constrainRegClass(R,
MRI.getRegClass(*InitReg));
1531 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1532 (void)ConstrainRegClass;
1535 .
addReg(InitReg ? *InitReg : undef(RC))
1540 UndefPhis[LoopReg] =
R;
1542 Phis[{LoopReg, *InitReg}] =
R;
1546Register KernelRewriter::undef(
const TargetRegisterClass *RC) {
1552 R =
MRI.createVirtualRegister(RC);
1555 TII->get(TargetOpcode::IMPLICIT_DEF), R);
1564class KernelOperandInfo {
1565 MachineBasicBlock *BB;
1566 MachineRegisterInfo &
MRI;
1568 MachineOperand *Source;
1569 MachineOperand *Target;
1572 KernelOperandInfo(MachineOperand *MO, MachineRegisterInfo &
MRI,
1573 const SmallPtrSetImpl<MachineInstr *> &IllegalPhis)
1577 while (isRegInLoop(MO)) {
1579 if (
MI->isFullCopy()) {
1580 MO = &
MI->getOperand(1);
1587 MO = &
MI->getOperand(3);
1592 MO =
MI->getOperand(2).getMBB() == BB ? &
MI->getOperand(1)
1593 : &
MI->getOperand(3);
1600 return PhiDefaults.
size() ==
Other.PhiDefaults.size();
1603 void print(raw_ostream &OS)
const {
1604 OS <<
"use of " << *
Source <<
": distance(" << PhiDefaults.
size() <<
") in "
1609 bool isRegInLoop(MachineOperand *MO) {
1611 MRI.getVRegDef(MO->
getReg())->getParent() == BB;
1623 for (
auto I =
BB->begin(), NI = NewBB->
begin(); !
I->isTerminator();
1639 if (Stage == -1 || Stage >= MinStage)
1652 for (
auto &
Sub : Subs)
1653 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1654 *
MRI.getTargetRegisterInfo());
1657 LIS->RemoveMachineInstrFromMaps(*
MI);
1658 MI->eraseFromParent();
1675 auto RC =
MRI.getRegClass(PhiR);
1688 MI.removeFromParent();
1692 BlockMIs.erase({SourceBB, KernelMI});
1702 assert(Def->findRegisterDefOperandIdx(
MI.getOperand(1).getReg(),
1704 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
1705 MI.getOperand(0).setReg(PhiReg);
1709 for (
auto *
P : PhiToDelete)
1710 P->eraseFromParent();
1716 DestBB->
insert(InsertPt, NewMI);
1717 Register OrigR = Phi->getOperand(0).getReg();
1738 if (
Use &&
Use->isPHI() &&
Use->getParent() == SourceBB) {
1753 for (
unsigned I = 0;
I < distance; ++
I) {
1756 unsigned LoopRegIdx = 3, InitRegIdx = 1;
1760 CanonicalUse =
MRI.getVRegDef(CanonicalUseReg);
1762 return CanonicalUseReg;
1773 for (
int I = 0;
I <
Schedule.getNumStages() - 1; ++
I) {
1787 EliminateDeadPhis(ExitingBB,
MRI,
LIS,
true);
1804 for (
int I = 1;
I <=
Schedule.getNumStages() - 1; ++
I) {
1810 EliminateDeadPhis(
B,
MRI,
LIS,
true);
1814 for (
size_t I = 0;
I <
Epilogs.size();
I++) {
1816 for (
size_t J =
I; J <
Epilogs.size(); J++) {
1818 unsigned Stage =
Schedule.getNumStages() - 1 +
I - J;
1820 for (
size_t K = Iteration; K >
I; K--)
1834 for (; PI !=
Prologs.end(); ++PI, ++EI) {
1836 (*PI)->addSuccessor(*EI);
1840 if (
Use &&
Use->getParent() == Pred) {
1842 if (CanonicalUse->
isPHI()) {
1863 for (
auto I =
B->instr_rbegin();
1864 I != std::next(
B->getFirstNonPHI()->getReverseIterator());) {
1871 LIS->RemoveMachineInstrFromMaps(*
MI);
1872 MI->eraseFromParent();
1878 EliminateDeadPhis(
B,
MRI,
LIS);
1879 EliminateDeadPhis(ExitingBB,
MRI,
LIS);
1886 Exit = *std::next(
BB->succ_begin());
1889 MF.insert(std::next(
BB->getIterator()), NewBB);
1893 auto RC =
MRI.getRegClass(
MI.getOperand(0).getReg());
1898 if (
Use.getParent() !=
BB)
1901 Use->substituteRegister(OldR, R, 0,
1902 *
MRI.getTargetRegisterInfo());
1909 BB->replaceSuccessor(Exit, NewBB);
1910 Exit->replacePhiUsesWith(
BB, NewBB);
1915 bool CanAnalyzeBr = !
TII->analyzeBranch(*
BB,
TBB, FBB,
Cond);
1917 assert(CanAnalyzeBr &&
"Must be able to analyze the loop branch!");
1918 TII->removeBranch(*
BB);
1919 TII->insertBranch(*
BB,
TBB == Exit ? NewBB :
TBB, FBB == Exit ? NewBB : FBB,
1921 TII->insertUnconditionalBranch(*NewBB, Exit,
DebugLoc());
1929 unsigned OpIdx =
MI->findRegisterDefOperandIdx(Reg,
nullptr);
1941 R =
MI->getOperand(1).getReg();
1942 MRI.setRegClass(R,
MRI.getRegClass(PhiR));
1943 MRI.replaceRegWith(PhiR, R);
1946 MI->getOperand(0).setReg(PhiR);
1952 if (Stage == -1 ||
LiveStages.count(
MI->getParent()) == 0 ||
1967 for (
auto &
Sub : Subs)
1968 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1969 *
MRI.getTargetRegisterInfo());
1972 LIS->RemoveMachineInstrFromMaps(*
MI);
1973 MI->eraseFromParent();
1978 bool KernelDisposed =
false;
1979 int TC =
Schedule.getNumStages() - 1;
1987 std::optional<bool> StaticallyGreater =
1989 if (!StaticallyGreater) {
1993 }
else if (*StaticallyGreater ==
false) {
1997 Prolog->removeSuccessor(Fallthrough);
2003 KernelDisposed =
true;
2015 if (!KernelDisposed) {
2046 std::string ScheduleDump;
2053 assert(
LIS &&
"Requires LiveIntervals!");
2058 if (!ExpandedKernel) {
2074 for (
auto NI =
BB->getFirstNonPHI(); NI !=
BB->end(); ++NI) {
2076 IllegalPhis.
insert(&*NI);
2082 auto OI = ExpandedKernel->
begin();
2083 auto NI =
BB->begin();
2084 for (; !OI->isTerminator() && !NI->isTerminator(); ++OI, ++NI) {
2085 while (OI->isPHI() || OI->isFullCopy())
2087 while (NI->isPHI() || NI->isFullCopy())
2089 assert(OI->getOpcode() == NI->getOpcode() &&
"Opcodes don't match?!");
2091 for (
auto OOpI = OI->operands_begin(), NOpI = NI->operands_begin();
2092 OOpI != OI->operands_end(); ++OOpI, ++NOpI)
2094 KernelOperandInfo(&*NOpI,
MRI, IllegalPhis));
2098 for (
auto &OldAndNew : KOIs) {
2099 if (OldAndNew.first == OldAndNew.second)
2102 errs() <<
"Modulo kernel validation error: [\n";
2103 errs() <<
" [golden] ";
2104 OldAndNew.first.print(
errs());
2106 OldAndNew.second.print(
errs());
2111 errs() <<
"Golden reference kernel:\n";
2113 errs() <<
"New kernel:\n";
2115 errs() << ScheduleDump;
2117 "Modulo kernel validation (-pipeliner-experimental-cg) failed");
2141 if (Exit->pred_size() == 1)
2157 else if (FBB ==
Loop)
2163 Loop->replaceSuccessor(Exit, NewExit);
2164 TII->insertUnconditionalBranch(*NewExit, Exit,
DebugLoc());
2167 Exit->replacePhiUsesWith(
Loop, NewExit);
2175void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &
MBB,
2177 InstrMapTy &LastStage0Insts,
2178 MachineBasicBlock &GreaterThan,
2179 MachineBasicBlock &Otherwise) {
2181 LoopInfo->createRemainingIterationsGreaterCondition(RequiredTC,
MBB,
Cond,
2200void ModuloScheduleExpanderMVE::generatePipelinedLoop() {
2275 assert(LoopInfo &&
"Must be able to analyze loop!");
2279 Check = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2280 Prolog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2281 NewKernel = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2282 Epilog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2283 NewPreheader = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2285 MF.insert(OrigKernel->getIterator(),
Check);
2287 MF.insert(OrigKernel->getIterator(),
Prolog);
2289 MF.insert(OrigKernel->getIterator(), NewKernel);
2291 MF.insert(OrigKernel->getIterator(),
Epilog);
2293 MF.insert(OrigKernel->getIterator(), NewPreheader);
2298 NewPreheader->transferSuccessorsAndUpdatePHIs(OrigPreheader);
2299 TII->insertUnconditionalBranch(*NewPreheader, OrigKernel,
DebugLoc());
2301 OrigPreheader->addSuccessor(
Check);
2306 Check->addSuccessor(NewPreheader);
2308 Prolog->addSuccessor(NewKernel);
2310 NewKernel->addSuccessor(NewKernel);
2311 NewKernel->addSuccessor(
Epilog);
2313 Epilog->addSuccessor(NewPreheader);
2314 Epilog->addSuccessor(NewExit);
2316 InstrMapTy LastStage0Insts;
2317 insertCondBranch(*
Check, Schedule.getNumStages() + NumUnroll - 2,
2318 LastStage0Insts, *
Prolog, *NewPreheader);
2323 generateProlog(PrologVRMap);
2324 generateKernel(PrologVRMap, KernelVRMap, LastStage0Insts);
2325 generateEpilog(KernelVRMap, EpilogVRMap, LastStage0Insts);
2329void ModuloScheduleExpanderMVE::updateInstrUse(
2330 MachineInstr *
MI,
int StageNum,
int PhaseNum,
2331 SmallVectorImpl<ValueMapTy> &CurVRMap,
2332 SmallVectorImpl<ValueMapTy> *PrevVRMap) {
2339 for (MachineOperand &UseMO :
MI->uses()) {
2340 if (!UseMO.isReg() || !UseMO.getReg().isVirtual())
2344 MachineInstr *DefInst =
MRI.getVRegDef(OrigReg);
2345 if (!DefInst || DefInst->
getParent() != OrigKernel)
2349 if (DefInst->
isPHI()) {
2352 getPhiRegs(*DefInst, OrigKernel, InitReg, LoopReg);
2355 DefInst =
MRI.getVRegDef(LoopReg);
2357 unsigned DefStageNum = Schedule.getStage(DefInst);
2358 DiffStage += StageNum - DefStageNum;
2360 if (PhaseNum >= DiffStage && CurVRMap[PhaseNum - DiffStage].
count(DefReg))
2362 NewReg = CurVRMap[PhaseNum - DiffStage][DefReg];
2363 else if (!PrevVRMap)
2372 NewReg = (*PrevVRMap)[PrevVRMap->
size() - (DiffStage - PhaseNum)][DefReg];
2374 const TargetRegisterClass *NRC =
2375 MRI.constrainRegClass(NewReg,
MRI.getRegClass(OrigReg));
2377 UseMO.setReg(NewReg);
2379 Register SplitReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2380 MachineInstr *NewCopy =
BuildMI(*OrigKernel,
MI,
MI->getDebugLoc(),
2381 TII->get(TargetOpcode::COPY), SplitReg)
2384 UseMO.setReg(SplitReg);
2402void ModuloScheduleExpanderMVE::generatePhi(
2403 MachineInstr *OrigMI,
int UnrollNum,
2404 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2405 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2406 SmallVectorImpl<ValueMapTy> &PhiVRMap) {
2407 int StageNum = Schedule.getStage(OrigMI);
2409 if (Schedule.getNumStages() - NumUnroll + UnrollNum - 1 >= StageNum)
2410 UsePrologReg =
true;
2411 else if (Schedule.getNumStages() - NumUnroll + UnrollNum == StageNum)
2412 UsePrologReg =
false;
2447 for (MachineOperand &DefMO : OrigMI->
defs()) {
2448 if (!DefMO.isReg() || DefMO.isDead())
2451 auto NewReg = KernelVRMap[UnrollNum].find(OrigReg);
2452 if (NewReg == KernelVRMap[UnrollNum].
end())
2456 int PrologNum = Schedule.getNumStages() - NumUnroll + UnrollNum - 1;
2457 CorrespondReg = PrologVRMap[PrologNum][OrigReg];
2466 Register PhiReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2467 MachineInstr *NewPhi =
2469 TII->get(TargetOpcode::PHI), PhiReg)
2475 PhiVRMap[UnrollNum][OrigReg] = PhiReg;
2481 for (
unsigned Idx = 1; Idx < Phi.getNumOperands(); Idx += 2) {
2482 if (Phi.getOperand(Idx).getReg() == OrigReg) {
2483 Phi.getOperand(Idx).setReg(NewReg);
2484 Phi.getOperand(Idx + 1).setMBB(NewMBB);
2491void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(
Register OrigReg,
2498 MachineOperand &
O = *
I;
2499 if (
O.getParent()->getParent() != OrigKernel &&
2500 O.getParent()->getParent() !=
Prolog &&
2501 O.getParent()->getParent() != NewKernel &&
2502 O.getParent()->getParent() !=
Epilog)
2504 if (
O.getParent()->getParent() == OrigKernel &&
O.getParent()->isPHI())
2510 if (!UsesAfterLoop.
empty()) {
2511 Register PhiReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2512 MachineInstr *NewPhi =
2514 TII->get(TargetOpcode::PHI), PhiReg)
2521 for (MachineOperand *MO : UsesAfterLoop)
2532 if (!LoopPhis.
empty()) {
2533 for (MachineInstr *Phi : LoopPhis) {
2535 getPhiRegs(*Phi, OrigKernel, InitReg, LoopReg);
2536 Register NewInit =
MRI.createVirtualRegister(
MRI.getRegClass(InitReg));
2537 MachineInstr *NewPhi =
2538 BuildMI(*NewPreheader, NewPreheader->getFirstNonPHI(),
2539 Phi->getDebugLoc(),
TII->get(TargetOpcode::PHI), NewInit)
2550void ModuloScheduleExpanderMVE::generateProlog(
2551 SmallVectorImpl<ValueMapTy> &PrologVRMap) {
2552 PrologVRMap.
clear();
2553 PrologVRMap.
resize(Schedule.getNumStages() - 1);
2554 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2555 for (
int PrologNum = 0; PrologNum < Schedule.getNumStages() - 1;
2557 for (MachineInstr *
MI : Schedule.getInstructions()) {
2560 int StageNum = Schedule.getStage(
MI);
2561 if (StageNum > PrologNum)
2564 updateInstrDef(NewMI, PrologVRMap[PrologNum],
false);
2565 NewMIMap[NewMI] = {PrologNum, StageNum};
2566 Prolog->push_back(NewMI);
2571 for (
auto I : NewMIMap) {
2572 MachineInstr *
MI =
I.first;
2573 int PrologNum =
I.second.first;
2574 int StageNum =
I.second.second;
2575 updateInstrUse(
MI, StageNum, PrologNum, PrologVRMap,
nullptr);
2579 dbgs() <<
"prolog:\n";
2584void ModuloScheduleExpanderMVE::generateKernel(
2585 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2586 SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) {
2587 KernelVRMap.
clear();
2588 KernelVRMap.
resize(NumUnroll);
2590 PhiVRMap.
resize(NumUnroll);
2591 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2592 for (
int UnrollNum = 0; UnrollNum < NumUnroll; ++UnrollNum) {
2593 for (MachineInstr *
MI : Schedule.getInstructions()) {
2596 int StageNum = Schedule.getStage(
MI);
2598 if (UnrollNum == NumUnroll - 1)
2599 LastStage0Insts[
MI] = NewMI;
2600 updateInstrDef(NewMI, KernelVRMap[UnrollNum],
2601 (UnrollNum == NumUnroll - 1 && StageNum == 0));
2602 generatePhi(
MI, UnrollNum, PrologVRMap, KernelVRMap, PhiVRMap);
2603 NewMIMap[NewMI] = {UnrollNum, StageNum};
2604 NewKernel->push_back(NewMI);
2609 for (
auto I : NewMIMap) {
2610 MachineInstr *
MI =
I.first;
2611 int UnrollNum =
I.second.first;
2612 int StageNum =
I.second.second;
2613 updateInstrUse(
MI, StageNum, UnrollNum, KernelVRMap, &PhiVRMap);
2617 insertCondBranch(*NewKernel, NumUnroll - 1, LastStage0Insts, *NewKernel,
2621 dbgs() <<
"kernel:\n";
2626void ModuloScheduleExpanderMVE::generateEpilog(
2627 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2628 SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) {
2629 EpilogVRMap.
clear();
2630 EpilogVRMap.
resize(Schedule.getNumStages() - 1);
2631 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2632 for (
int EpilogNum = 0; EpilogNum < Schedule.getNumStages() - 1;
2634 for (MachineInstr *
MI : Schedule.getInstructions()) {
2637 int StageNum = Schedule.getStage(
MI);
2638 if (StageNum <= EpilogNum)
2641 updateInstrDef(NewMI, EpilogVRMap[EpilogNum], StageNum - 1 == EpilogNum);
2642 NewMIMap[NewMI] = {EpilogNum, StageNum};
2643 Epilog->push_back(NewMI);
2648 for (
auto I : NewMIMap) {
2649 MachineInstr *
MI =
I.first;
2650 int EpilogNum =
I.second.first;
2651 int StageNum =
I.second.second;
2652 updateInstrUse(
MI, StageNum, EpilogNum, EpilogVRMap, &KernelVRMap);
2659 insertCondBranch(*
Epilog, 0, LastStage0Insts, *NewPreheader, *NewExit);
2662 dbgs() <<
"epilog:\n";
2668void ModuloScheduleExpanderMVE::calcNumUnroll() {
2669 DenseMap<MachineInstr *, unsigned> Inst2Idx;
2671 for (
unsigned I = 0;
I < Schedule.getInstructions().
size(); ++
I)
2672 Inst2Idx[Schedule.getInstructions()[
I]] =
I;
2674 for (MachineInstr *
MI : Schedule.getInstructions()) {
2677 int StageNum = Schedule.getStage(
MI);
2678 for (
const MachineOperand &MO :
MI->uses()) {
2685 int NumUnrollLocal = 1;
2692 NumUnrollLocal += StageNum - Schedule.getStage(
DefMI);
2693 if (Inst2Idx[
MI] <= Inst2Idx[
DefMI])
2695 NumUnroll = std::max(NumUnroll, NumUnrollLocal);
2704void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
2707 for (MachineOperand &MO : NewMI->
all_defs()) {
2711 const TargetRegisterClass *RC =
MRI.getRegClass(
Reg);
2714 VRMap[
Reg] = NewReg;
2716 mergeRegUsesAfterPipeline(
Reg, NewReg);
2721 OrigKernel = Schedule.getLoop()->getTopBlock();
2722 OrigPreheader = Schedule.getLoop()->getLoopPreheader();
2723 OrigExit = Schedule.getLoop()->getExitBlock();
2727 generatePipelinedLoop();
2732 if (!L.getExitBlock()) {
2733 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: No single exit block.\n");
2749 if (
Ref.getParent() != BB ||
Ref.isPHI()) {
2750 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A phi result is "
2751 "referenced outside of the loop or by phi.\n");
2760 if (!
Register(LoopVal).isVirtual() ||
2761 MRI.getVRegDef(LoopVal)->getParent() != BB) {
2763 dbgs() <<
"Can not apply MVE expander: A phi source value coming "
2764 "from the loop is not defined in the loop.\n");
2767 if (UsedByPhi.
count(LoopVal)) {
2768 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A value defined in the "
2769 "loop is referenced by two or more phis.\n");
2772 UsedByPhi.
insert(LoopVal);
2811char ModuloScheduleTest::ID = 0;
2814 "Modulo Schedule test pass",
false,
false)
2821 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
2822 for (
auto *L : MLI) {
2823 if (L->getTopBlock() != L->getBottomBlock())
2832 std::pair<StringRef, StringRef> StageAndCycle =
getToken(S,
"_");
2833 std::pair<StringRef, StringRef> StageTokenAndValue =
2834 getToken(StageAndCycle.first,
"-");
2835 std::pair<StringRef, StringRef> CycleTokenAndValue =
2836 getToken(StageAndCycle.second,
"-");
2837 if (StageTokenAndValue.first !=
"Stage" ||
2838 CycleTokenAndValue.first !=
"_Cycle") {
2840 "Bad post-instr symbol syntax: see comment in ModuloScheduleTest");
2844 StageTokenAndValue.second.drop_front().getAsInteger(10, Stage);
2845 CycleTokenAndValue.second.drop_front().getAsInteger(10,
Cycle);
2847 dbgs() <<
" Stage=" << Stage <<
", Cycle=" <<
Cycle <<
"\n";
2850void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) {
2851 LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
2852 MachineBasicBlock *BB =
L.getTopBlock();
2853 dbgs() <<
"--- ModuloScheduleTest running on BB#" << BB->
getNumber() <<
"\n";
2855 DenseMap<MachineInstr *, int>
Cycle, Stage;
2856 std::vector<MachineInstr *> Instrs;
2857 for (MachineInstr &
MI : *BB) {
2858 if (
MI.isTerminator())
2860 Instrs.push_back(&
MI);
2861 if (MCSymbol *Sym =
MI.getPostInstrSymbol()) {
2862 dbgs() <<
"Parsing post-instr symbol for " <<
MI;
2867 ModuloSchedule MS(MF, &L, std::move(Instrs), std::move(
Cycle),
2869 ModuloScheduleExpander MSE(
2883 OS <<
"Stage-" << S.getStage(
MI) <<
"_Cycle-" << S.getCycle(
MI);
2884 MCSymbol *Sym = MF.getContext().getOrCreateSymbol(OS.
str());
2885 MI->setPostInstrSymbol(MF, Sym);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static Register cloneInstr(const MachineInstr *MI, unsigned ReplaceOprNum, Register ReplaceReg, MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertTo)
Clone an instruction from MI.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static const Function * getParent(const Value *V)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
static void getPhiRegs(MachineInstr &Phi, MachineBasicBlock *Loop, Register &InitVal, Register &LoopVal)
Return the register values for the operands of a Phi instruction.
static Register getLoopPhiReg(const MachineInstr &Phi, const MachineBasicBlock *LoopBB)
Return the Phi register value that comes the loop block.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file provides utility analysis objects describing memory locations.
static bool hasUseAfterLoop(Register Reg, MachineBasicBlock *BB, MachineRegisterInfo &MRI)
Return true if the register has a use that occurs outside the specified loop.
static void removePhis(MachineBasicBlock *BB, MachineBasicBlock *Incoming)
Remove the incoming block from the Phis in a basic block.
static void replaceRegUsesAfterLoop(Register FromReg, Register ToReg, MachineBasicBlock *MBB, MachineRegisterInfo &MRI)
Replace all uses of FromReg that appear outside the specified basic block with ToReg.
static void replacePhiSrc(MachineInstr &Phi, Register OrigReg, Register NewReg, MachineBasicBlock *NewMBB)
static MachineInstr * getLoopPhiUser(Register Reg, MachineBasicBlock *Loop)
Return a phi if Reg is referenced by the phi.
static MachineBasicBlock * createDedicatedExit(MachineBasicBlock *Loop, MachineBasicBlock *Exit, LiveIntervals &LIS)
Create a dedicated exit for Loop.
static void parseSymbolString(StringRef S, int &Cycle, int &Stage)
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"))
static Register getInitPhiReg(MachineInstr &Phi, MachineBasicBlock *LoopBB)
Return the Phi register value that comes from the incoming block.
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Implements a dense probed hash-table based set.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
std::unique_ptr< PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
bool hasInterval(Register Reg) const
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
void insertMBBInMaps(MachineBasicBlock *MBB)
void RemoveMachineInstrFromMaps(MachineInstr &MI)
void removeInterval(Register Reg)
Interval removal.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
Represents a single loop in the control flow graph.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
LLVM_ABI void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
instr_iterator instr_begin()
LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator_range< iterator > phis()
Returns a range that iterates over the phis in the basic block.
reverse_instr_iterator instr_rbegin()
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
succ_iterator succ_begin()
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void dump() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI void print(raw_ostream &OS, const SlotIndexes *=nullptr, bool IsStandalone=true) const
reverse_instr_iterator instr_rend()
Instructions::iterator instr_iterator
pred_iterator pred_begin()
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
LLVM_ABI instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
MachineInstrBundleIterator< MachineInstr > iterator
Instructions::reverse_iterator reverse_instr_iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
mop_range defs()
Returns all explicit operands that are register definitions.
const MachineBasicBlock * getParent() const
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
unsigned getNumOperands() const
Retuns the total number of operands.
bool memoperands_empty() const
Return true if we don't have any memory operands which described the memory access done by this instr...
LLVM_ABI void setMemRefs(MachineFunction &MF, ArrayRef< MachineMemOperand * > MemRefs)
Assign this MachineInstr's memory reference descriptor list.
LLVM_ABI void dropMemRefs(MachineFunction &MF)
Clear this MachineInstr's memory reference descriptor list.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setMBB(MachineBasicBlock *MBB)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
static bool canApply(MachineLoop &L)
Check if ModuloScheduleExpanderMVE can be applied to L.
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.
DenseMap< MachineInstr *, std::pair< Register, int64_t > > InstrChangesTy
void annotate()
Performs the annotation.
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.
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.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
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.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
reverse_iterator rbegin()
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
virtual const TargetInstrInfo * getInstrInfo() const
A Use represents the edge between a Value definition and its users.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
MachineBasicBlock * PeelSingleBlockLoop(LoopPeelDirection Direction, MachineBasicBlock *Loop, MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Peels a single block loop.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI void initializeModuloScheduleTestPass(PassRegistry &)
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
@ Sub
Subtraction of integers.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
@ LPD_Back
Peel the last iteration of the loop.
@ LPD_Front
Peel the first iteration of the loop.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...