23#define DEBUG_TYPE "pipeliner"
28 cl::desc(
"Swap target blocks of a conditional branch for MVE expander"));
43 assert(Phi.isPHI() &&
"Expecting a Phi.");
47 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
48 if (Phi.getOperand(i + 1).getMBB() !=
Loop)
49 InitVal = Phi.getOperand(i).getReg();
51 LoopVal = Phi.getOperand(i).getReg();
53 assert(InitVal && LoopVal &&
"Unexpected Phi structure.");
58 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
59 if (Phi.getOperand(i + 1).getMBB() != LoopBB)
60 return Phi.getOperand(i).getReg();
66 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
67 if (Phi.getOperand(i + 1).getMBB() == LoopBB)
68 return Phi.getOperand(i).getReg();
73 BB = Schedule.getLoop()->getTopBlock();
74 Preheader = *BB->pred_begin();
76 Preheader = *std::next(BB->pred_begin());
81 int DefStage = Schedule.getStage(
MI);
85 bool PhiIsSwapped =
false;
88 int UseStage = Schedule.getStage(
UseMI);
90 if (UseStage != -1 && UseStage >= DefStage)
91 Diff = UseStage - DefStage;
93 if (isLoopCarried(*
MI))
98 MaxDiff = std::max(Diff, MaxDiff);
100 RegToStageDiff[Reg] = std::make_pair(MaxDiff, PhiIsSwapped);
104 generatePipelinedLoop();
107void ModuloScheduleExpander::generatePipelinedLoop() {
120 ValueMapTy *VRMap =
new ValueMapTy[(MaxStageCount + 1) * 2];
125 ValueMapTy *VRMapPhi =
new ValueMapTy[(MaxStageCount + 1) * 2];
132 generateProlog(MaxStageCount, KernelBB, VRMap, PrologBBs);
141 unsigned StageNum = Schedule.
getStage(CI);
143 updateInstruction(NewMI,
false, MaxStageCount, StageNum, VRMap);
146 InstrMap[NewMI] = CI;
153 updateInstruction(NewMI,
false, MaxStageCount, 0, VRMap);
156 InstrMap[NewMI] = &
MI;
159 NewKernel = KernelBB;
163 generateExistingPhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap,
164 InstrMap, MaxStageCount, MaxStageCount,
false);
165 generatePhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap, VRMapPhi,
166 InstrMap, MaxStageCount, MaxStageCount,
false);
170 SmallVector<MachineBasicBlock *, 4> EpilogBBs;
172 generateEpilog(MaxStageCount, KernelBB, BB, VRMap, VRMapPhi, EpilogBBs,
177 splitLifetimes(KernelBB, EpilogBBs);
180 removeDeadInstructions(KernelBB, EpilogBBs);
183 addBranches(*Preheader, PrologBBs, KernelBB, EpilogBBs, VRMap);
192 LIS.RemoveMachineInstrFromMaps(
I);
194 BB->eraseFromParent();
198void ModuloScheduleExpander::generateProlog(
unsigned LastStage,
201 MBBVectorTy &PrologBBs) {
208 for (
unsigned i = 0; i < LastStage; ++i) {
221 for (
int StageNum = i; StageNum >= 0; --StageNum) {
225 if (Schedule.
getStage(&*BBI) == StageNum) {
229 cloneAndChangeInstr(&*BBI, i, (
unsigned)StageNum);
230 updateInstruction(NewMI,
false, i, (
unsigned)StageNum, VRMap);
233 InstrMap[NewMI] = &*BBI;
237 rewritePhiValues(NewBB, i, VRMap, InstrMap);
239 dbgs() <<
"prolog:\n";
248 unsigned numBranches = TII->removeBranch(*Preheader);
251 TII->insertBranch(*Preheader, PrologBBs[0],
nullptr,
Cond,
DebugLoc());
258void ModuloScheduleExpander::generateEpilog(
260 ValueMapTy *VRMap, ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
261 MBBVectorTy &PrologBBs) {
264 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
266 bool checkBranch = TII->analyzeBranch(*KernelBB,
TBB, FBB,
Cond);
267 assert(!checkBranch &&
"generateEpilog must be able to analyze the branch");
272 if (*LoopExitI == KernelBB)
274 assert(LoopExitI != KernelBB->
succ_end() &&
"Expecting a successor");
275 MachineBasicBlock *LoopExitBB = *LoopExitI;
277 MachineBasicBlock *PredBB = KernelBB;
278 MachineBasicBlock *EpilogStart = LoopExitBB;
284 int EpilogStage = LastStage + 1;
285 for (
unsigned i = LastStage; i >= 1; --i, ++EpilogStage) {
286 MachineBasicBlock *NewBB = MF.CreateMachineBasicBlock();
288 MF.insert(BB->getIterator(), NewBB);
292 LIS.insertMBBInMaps(NewBB);
294 if (EpilogStart == LoopExitBB)
299 for (
unsigned StageNum = i; StageNum <= LastStage; ++StageNum) {
300 for (
auto &BBI : *BB) {
303 MachineInstr *
In = &BBI;
304 if ((
unsigned)Schedule.getStage(In) == StageNum) {
307 MachineInstr *NewMI = cloneInstr(In, UINT_MAX, 0);
308 updateInstruction(NewMI, i == 1, EpilogStage, 0, VRMap);
310 LIS.InsertMachineInstrInMaps(*NewMI);
311 InstrMap[NewMI] =
In;
315 generateExistingPhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap,
316 InstrMap, LastStage, EpilogStage, i == 1);
317 generatePhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap, VRMapPhi,
318 InstrMap, LastStage, EpilogStage, i == 1);
322 dbgs() <<
"epilog:\n";
332 TII->removeBranch(*KernelBB);
333 assert((OrigBB ==
TBB || OrigBB == FBB) &&
334 "Unable to determine looping branch direction");
336 TII->insertBranch(*KernelBB, EpilogStart, KernelBB,
Cond,
DebugLoc());
338 TII->insertBranch(*KernelBB, KernelBB, EpilogStart,
Cond,
DebugLoc());
340 if (EpilogBBs.size() > 0) {
341 MachineBasicBlock *LastEpilogBB = EpilogBBs.back();
343 TII->insertBranch(*LastEpilogBB, LoopExitBB,
nullptr, Cond1,
DebugLoc());
354 if (O.getParent()->getParent() !=
MBB)
363 if (MO.getParent()->getParent() != BB)
371void ModuloScheduleExpander::generateExistingPhis(
374 unsigned LastStageNum,
unsigned CurStageNum,
bool IsLast) {
378 unsigned PrologStage = 0;
379 unsigned PrevStage = 0;
380 bool InKernel = (LastStageNum == CurStageNum);
382 PrologStage = LastStageNum - 1;
383 PrevStage = CurStageNum;
385 PrologStage = LastStageNum - (CurStageNum - LastStageNum);
386 PrevStage = LastStageNum + (CurStageNum - LastStageNum) - 1;
390 BBE = BB->getFirstNonPHI();
402 if (
auto It = VRMap[LastStageNum].
find(LoopVal);
403 It != VRMap[LastStageNum].end())
406 int StageScheduled = Schedule.getStage(&*BBI);
407 int LoopValStage = Schedule.getStage(MRI.getVRegDef(LoopVal));
408 unsigned NumStages = getStagesForReg(Def, CurStageNum);
409 if (NumStages == 0) {
412 Register NewReg = VRMap[PrevStage][LoopVal];
413 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, 0, &*BBI, Def,
415 auto It = VRMap[CurStageNum].find(LoopVal);
416 if (It != VRMap[CurStageNum].
end()) {
418 VRMap[CurStageNum][
Def] =
Reg;
425 unsigned MaxPhis = PrologStage + 2;
426 if (!InKernel && (
int)PrologStage <= LoopValStage)
427 MaxPhis = std::max((
int)MaxPhis - LoopValStage, 1);
428 unsigned NumPhis = std::min(NumStages, MaxPhis);
431 unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled;
438 if (!InKernel && StageScheduled >= LoopValStage && AccessStage == 0 &&
443 if (InKernel && LoopValStage != -1 && StageScheduled > LoopValStage)
444 StageDiff = StageScheduled - LoopValStage;
445 for (
unsigned np = 0; np < NumPhis; ++np) {
449 if (np > PrologStage || StageScheduled >= (
int)LastStageNum)
452 else if (PrologStage >= AccessStage + StageDiff + np &&
453 VRMap[PrologStage - StageDiff - np].
count(LoopVal) != 0)
454 PhiOp1 = VRMap[PrologStage - StageDiff - np][LoopVal];
457 else if (PrologStage >= AccessStage + StageDiff + np) {
461 MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1);
463 while (InstOp1 && InstOp1->
isPHI() && InstOp1->
getParent() == BB) {
464 int PhiStage = Schedule.getStage(InstOp1);
465 if ((
int)(PrologStage - StageDiff - np) < PhiStage + Indirects)
469 InstOp1 = MRI.getVRegDef(PhiOp1);
470 int PhiOpStage = Schedule.getStage(InstOp1);
471 int StageAdj = (PhiOpStage != -1 ? PhiStage - PhiOpStage : 0);
472 if (PhiOpStage != -1 && PrologStage - StageAdj >= Indirects + np) {
473 auto &
M = VRMap[PrologStage - StageAdj - Indirects - np];
474 if (
auto It =
M.find(PhiOp1); It !=
M.end()) {
485 if (MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1))
489 MachineInstr *PhiInst = MRI.getVRegDef(LoopVal);
490 bool LoopDefIsPhi = PhiInst && PhiInst->
isPHI();
495 int StageDiffAdj = 0;
496 if (LoopValStage != -1 && StageScheduled > LoopValStage)
497 StageDiffAdj = StageScheduled - LoopValStage;
500 if (np == 0 && PrevStage == LastStageNum &&
501 (StageScheduled != 0 || LoopValStage != 0) &&
502 VRMap[PrevStage - StageDiffAdj].
count(LoopVal))
503 PhiOp2 = VRMap[PrevStage - StageDiffAdj][LoopVal];
506 else if (np > 0 && PrevStage == LastStageNum &&
507 VRMap[PrevStage - np + 1].
count(Def))
508 PhiOp2 = VRMap[PrevStage - np + 1][
Def];
510 else if (
static_cast<unsigned>(LoopValStage) > PrologStage + 1 &&
511 VRMap[PrevStage - StageDiffAdj - np].
count(LoopVal))
512 PhiOp2 = VRMap[PrevStage - StageDiffAdj - np][LoopVal];
515 else if (VRMap[PrevStage - np].
count(Def) &&
516 (!LoopDefIsPhi || (PrevStage != LastStageNum) ||
517 (LoopValStage == StageScheduled)))
518 PhiOp2 = VRMap[PrevStage - np][
Def];
526 if (
static_cast<int>(PrologStage - np) >= StageScheduled) {
527 int LVNumStages = getStagesForPhi(LoopVal);
528 int StageDiff = (StageScheduled - LoopValStage);
529 LVNumStages -= StageDiff;
531 if (LVNumStages > (
int)np && VRMap[CurStageNum].
count(LoopVal)) {
533 unsigned ReuseStage = CurStageNum;
534 if (isLoopCarried(*PhiInst))
535 ReuseStage -= LVNumStages;
538 if (VRMap[ReuseStage - np].
count(LoopVal)) {
539 NewReg = VRMap[ReuseStage - np][LoopVal];
541 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI,
544 VRMap[CurStageNum - np][
Def] = NewReg;
546 if (VRMap[LastStageNum - np - 1].
count(LoopVal))
547 PhiOp2 = VRMap[LastStageNum - np - 1][LoopVal];
549 if (IsLast && np == NumPhis - 1)
555 if (InKernel && StageDiff > 0 &&
556 VRMap[CurStageNum - StageDiff - np].
count(LoopVal))
557 PhiOp2 = VRMap[CurStageNum - StageDiff - np][LoopVal];
560 const TargetRegisterClass *RC = MRI.getRegClass(Def);
561 NewReg = MRI.createVirtualRegister(RC);
563 MachineInstrBuilder NewPhi =
565 TII->get(TargetOpcode::PHI), NewReg);
568 LIS.InsertMachineInstrInMaps(*NewPhi);
570 InstrMap[NewPhi] = &*BBI;
576 if (InKernel && VRMap[PrevStage - np].
count(LoopVal))
577 PrevReg = VRMap[PrevStage - np][LoopVal];
578 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
581 if (VRMap[CurStageNum - np].
count(Def)) {
583 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, R,
590 if (IsLast && np == NumPhis - 1)
598 VRMap[CurStageNum - np][
Def] = NewReg;
601 while (NumPhis++ < NumStages) {
602 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, NumPhis, &*BBI, Def,
608 if (NumStages == 0 && IsLast) {
609 auto &CurStageMap = VRMap[CurStageNum];
610 auto It = CurStageMap.find(LoopVal);
611 if (It != CurStageMap.end())
620void ModuloScheduleExpander::generatePhis(
623 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
627 unsigned PrologStage = 0;
628 unsigned PrevStage = 0;
629 unsigned StageDiff = CurStageNum - LastStageNum;
630 bool InKernel = (StageDiff == 0);
632 PrologStage = LastStageNum - 1;
633 PrevStage = CurStageNum;
635 PrologStage = LastStageNum - StageDiff;
636 PrevStage = LastStageNum + StageDiff - 1;
640 BBE = BB->instr_end();
642 for (
unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) {
643 MachineOperand &MO = BBI->getOperand(i);
647 int StageScheduled = Schedule.getStage(&*BBI);
648 assert(StageScheduled != -1 &&
"Expecting scheduled instruction.");
650 unsigned NumPhis = getStagesForReg(Def, CurStageNum);
654 if (!InKernel && NumPhis == 0 && StageScheduled == 0 &&
657 if (!InKernel && (
unsigned)StageScheduled > PrologStage)
662 PhiOp2 = VRMap[PrevStage][
Def];
663 if (MachineInstr *InstOp2 = MRI.getVRegDef(PhiOp2))
664 if (InstOp2->isPHI() && InstOp2->getParent() == NewBB)
669 if (NumPhis > PrologStage + 1 - StageScheduled)
670 NumPhis = PrologStage + 1 - StageScheduled;
671 for (
unsigned np = 0; np < NumPhis; ++np) {
695 if (np <= PrologStage)
696 PhiOp1 = VRMap[PrologStage - np][
Def];
698 if (PrevStage == LastStageNum && np == 0)
699 PhiOp2 = VRMap[LastStageNum][
Def];
701 PhiOp2 = VRMapPhi[PrevStage - np][
Def];
704 const TargetRegisterClass *RC = MRI.getRegClass(Def);
705 Register NewReg = MRI.createVirtualRegister(RC);
707 MachineInstrBuilder NewPhi =
709 TII->get(TargetOpcode::PHI), NewReg);
712 LIS.InsertMachineInstrInMaps(*NewPhi);
714 InstrMap[NewPhi] = &*BBI;
719 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp1,
721 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp2,
725 VRMapPhi[PrevStage - np - 1][
Def] = NewReg;
727 VRMapPhi[CurStageNum - np][
Def] = NewReg;
728 if (np == NumPhis - 1)
729 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
732 if (IsLast && np == NumPhis - 1)
744 MBBVectorTy &EpilogBBs) {
752 if (
MI->isInlineAsm()) {
756 bool SawStore =
false;
759 if (!
MI->isSafeToMove(SawStore) && !
MI->isPHI()) {
764 for (
const MachineOperand &MO :
MI->all_defs()) {
773 unsigned realUses = 0;
774 for (
const MachineOperand &U : MRI.use_operands(reg)) {
777 if (
U.getParent()->getParent() != BB) {
788 LIS.RemoveMachineInstrFromMaps(*
MI);
789 MI++->eraseFromParent();
798 if (MRI.use_begin(reg) == MRI.use_end()) {
799 LIS.RemoveMachineInstrFromMaps(
MI);
800 MI.eraseFromParent();
816 MBBVectorTy &EpilogBBs) {
817 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
818 for (
auto &
PHI : KernelBB->
phis()) {
823 E = MRI.use_instr_end();
825 if (
I->isPHI() &&
I->getParent() == KernelBB) {
830 MachineInstr *
MI = MRI.getVRegDef(LCDef);
831 if (!
MI ||
MI->getParent() != KernelBB ||
MI->isPHI())
838 if (BBJ.readsRegister(Def,
nullptr)) {
841 SplitReg = MRI.createVirtualRegister(MRI.getRegClass(Def));
842 MachineInstr *newCopy =
844 TII->get(TargetOpcode::COPY), SplitReg)
846 LIS.InsertMachineInstrInMaps(*newCopy);
848 BBJ.substituteRegister(Def, SplitReg, 0, *
TRI);
853 for (
auto &
Epilog : EpilogBBs)
855 if (
I.readsRegister(Def,
nullptr))
856 I.substituteRegister(Def, SplitReg, 0, *
TRI);
867 MBBVectorTy &PrologBBs,
869 MBBVectorTy &EpilogBBs,
871 assert(PrologBBs.size() == EpilogBBs.size() &&
"Prolog/Epilog mismatch");
872 MachineBasicBlock *LastPro = KernelBB;
873 MachineBasicBlock *LastEpi = KernelBB;
877 unsigned MaxIter = PrologBBs.
size() - 1;
878 for (
unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --
j) {
881 MachineBasicBlock *
Prolog = PrologBBs[
j];
882 MachineBasicBlock *
Epilog = EpilogBBs[i];
885 std::optional<bool> StaticallyGreater =
886 LoopInfo->createTripCountGreaterCondition(j + 1, *
Prolog,
Cond);
887 unsigned numAdded = 0;
888 if (!StaticallyGreater) {
891 }
else if (*StaticallyGreater ==
false) {
893 Prolog->removeSuccessor(LastPro);
896 Epilog->removePHIsIncomingValuesForPredecessor(*LastEpi);
898 if (LastPro != LastEpi) {
899 for (
auto &
MI : *LastEpi)
900 LIS.RemoveMachineInstrFromMaps(
MI);
902 LastEpi->eraseFromParent();
904 if (LastPro == KernelBB) {
905 LoopInfo->disposed(&LIS);
908 for (
auto &
MI : *LastPro)
909 LIS.RemoveMachineInstrFromMaps(
MI);
911 LastPro->eraseFromParent();
914 Epilog->removePHIsIncomingValuesForPredecessor(*
Prolog);
920 I !=
E && numAdded > 0; ++
I, --numAdded)
921 updateInstruction(&*
I,
false, j, 0, VRMap);
925 LoopInfo->setPreheader(PrologBBs[MaxIter]);
926 LoopInfo->adjustTripCount(-(MaxIter + 1));
932bool ModuloScheduleExpander::computeDelta(
MachineInstr &
MI,
unsigned &Delta) {
933 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
934 const MachineOperand *BaseOp;
936 bool OffsetIsScalable;
937 if (!TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
941 if (OffsetIsScalable)
944 if (!BaseOp->
isReg())
949 MachineRegisterInfo &MRI = MF.getRegInfo();
951 MachineInstr *BaseDef = MRI.getVRegDef(BaseReg);
952 if (BaseDef && BaseDef->
isPHI()) {
954 BaseDef = MRI.getVRegDef(BaseReg);
960 if (!TII->getIncrementValue(*BaseDef,
D) &&
D >= 0)
970void ModuloScheduleExpander::updateMemOperands(
MachineInstr &NewMI,
980 for (MachineMemOperand *MMO : NewMI.
memoperands()) {
982 if (MMO->isVolatile() || MMO->isAtomic() ||
983 (MMO->isInvariant() && MMO->isDereferenceable()) ||
984 (!MMO->getValue())) {
989 if (Num != UINT_MAX && computeDelta(OldMI, Delta)) {
990 int64_t AdjOffset = Delta * Num;
992 MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()));
994 NewMMOs.
push_back(MF.getMachineMemOperand(
1004 unsigned CurStageNum,
1005 unsigned InstStageNum) {
1006 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1007 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1014MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
1015 MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) {
1016 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1017 auto It = InstrChanges.find(OldMI);
1018 if (It != InstrChanges.end()) {
1019 std::pair<Register, int64_t> RegAndOffset = It->second;
1020 unsigned BasePos, OffsetPos;
1021 if (!TII->getBaseAndOffsetPosition(*OldMI, BasePos, OffsetPos))
1024 MachineInstr *LoopDef = findDefInLoop(RegAndOffset.first);
1025 if (Schedule.getStage(LoopDef) > (
signed)InstStageNum)
1026 NewOffset += RegAndOffset.second * (CurStageNum - InstStageNum);
1029 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1035void ModuloScheduleExpander::updateInstruction(
MachineInstr *NewMI,
1037 unsigned CurStageNum,
1038 unsigned InstrStageNum,
1039 ValueMapTy *VRMap) {
1040 for (MachineOperand &MO : NewMI->
operands()) {
1046 const TargetRegisterClass *RC = MRI.getRegClass(reg);
1047 Register NewReg = MRI.createVirtualRegister(RC);
1049 VRMap[CurStageNum][reg] = NewReg;
1052 }
else if (MO.
isUse()) {
1053 MachineInstr *
Def = MRI.getVRegDef(reg);
1055 int DefStageNum = Schedule.getStage(Def);
1056 unsigned StageNum = CurStageNum;
1057 if (DefStageNum != -1 && (
int)InstrStageNum > DefStageNum) {
1059 unsigned StageDiff = (InstrStageNum - DefStageNum);
1061 StageNum -= StageDiff;
1063 if (
auto It = VRMap[StageNum].
find(reg); It != VRMap[StageNum].end())
1073 SmallPtrSet<MachineInstr *, 8> Visited;
1074 MachineInstr *
Def = MRI.getVRegDef(
Reg);
1075 while (
Def->isPHI()) {
1076 if (!Visited.
insert(Def).second)
1078 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2)
1079 if (
Def->getOperand(i + 1).getMBB() == BB) {
1080 Def = MRI.getVRegDef(
Def->getOperand(i).getReg());
1088Register ModuloScheduleExpander::getPrevMapVal(
1089 unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
unsigned LoopStage,
1092 if (StageNum > PhiStage) {
1093 MachineInstr *LoopInst = MRI.getVRegDef(LoopVal);
1094 if (PhiStage == LoopStage && VRMap[StageNum - 1].
count(LoopVal))
1096 PrevVal = VRMap[StageNum - 1][LoopVal];
1097 else if (VRMap[StageNum].
count(LoopVal))
1100 PrevVal = VRMap[StageNum][LoopVal];
1104 else if (StageNum == PhiStage + 1)
1107 else if (StageNum > PhiStage + 1 && LoopInst->
getParent() == BB)
1110 getPrevMapVal(StageNum - 1, PhiStage,
getLoopPhiReg(*LoopInst, BB),
1111 LoopStage, VRMap, BB);
1123 InstrMapTy &InstrMap) {
1124 for (
auto &
PHI : BB->phis()) {
1130 unsigned PhiStage = (unsigned)Schedule.getStage(MRI.getVRegDef(PhiDef));
1131 unsigned LoopStage = (unsigned)Schedule.getStage(MRI.getVRegDef(LoopVal));
1132 unsigned NumPhis = getStagesForPhi(PhiDef);
1133 if (NumPhis > StageNum)
1135 for (
unsigned np = 0; np <= NumPhis; ++np) {
1137 getPrevMapVal(StageNum - np, PhiStage, LoopVal, LoopStage, VRMap, BB);
1140 rewriteScheduledInstr(NewBB, InstrMap, StageNum - np, np, &
PHI, PhiDef,
1149void ModuloScheduleExpander::rewriteScheduledInstr(
1153 bool InProlog = (CurStageNum < (unsigned)Schedule.getNumStages() - 1);
1154 int StagePhi = Schedule.getStage(Phi) + PhiNum;
1157 for (MachineOperand &UseOp :
1159 MachineInstr *
UseMI = UseOp.getParent();
1169 assert(OrigInstr != InstrMap.end() &&
"Instruction not scheduled.");
1170 MachineInstr *OrigMI = OrigInstr->second;
1171 int StageSched = Schedule.getStage(OrigMI);
1172 int CycleSched = Schedule.getCycle(OrigMI);
1175 if (StagePhi == StageSched &&
Phi->isPHI()) {
1176 int CyclePhi = Schedule.getCycle(Phi);
1177 if (PrevReg && InProlog)
1178 ReplaceReg = PrevReg;
1179 else if (PrevReg && !isLoopCarried(*Phi) &&
1180 (CyclePhi <= CycleSched || OrigMI->isPHI()))
1181 ReplaceReg = PrevReg;
1183 ReplaceReg = NewReg;
1187 if (!InProlog && StagePhi + 1 == StageSched && !isLoopCarried(*Phi))
1188 ReplaceReg = NewReg;
1189 if (StagePhi > StageSched &&
Phi->isPHI())
1190 ReplaceReg = NewReg;
1191 if (!InProlog && !
Phi->isPHI() && StagePhi < StageSched)
1192 ReplaceReg = NewReg;
1194 const TargetRegisterClass *NRC =
1195 MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg));
1197 UseOp.setReg(ReplaceReg);
1199 Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
1201 TII->
get(TargetOpcode::COPY), SplitReg)
1203 UseOp.setReg(SplitReg);
1204 LIS.InsertMachineInstrInMaps(*newCopy);
1210bool ModuloScheduleExpander::isLoopCarried(
MachineInstr &Phi) {
1213 int DefCycle = Schedule.getCycle(&Phi);
1214 int DefStage = Schedule.getStage(&Phi);
1219 MachineInstr *
Use = MRI.getVRegDef(LoopVal);
1220 if (!Use ||
Use->isPHI())
1222 int LoopCycle = Schedule.getCycle(Use);
1223 int LoopStage = Schedule.getStage(Use);
1224 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
1244 if (
MRI.use_empty(
MI.getOperand(0).getReg())) {
1247 MI.eraseFromParent();
1249 }
else if (!KeepSingleSrcPhi &&
MI.getNumExplicitOperands() == 3) {
1251 MRI.constrainRegClass(
MI.getOperand(1).getReg(),
1252 MRI.getRegClass(
MI.getOperand(0).getReg()));
1253 assert(ConstrainRegClass &&
1254 "Expected a valid constrained register class!");
1255 (void)ConstrainRegClass;
1256 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
1257 MI.getOperand(1).getReg());
1260 MI.eraseFromParent();
1269class KernelRewriter {
1271 MachineBasicBlock *BB;
1272 MachineBasicBlock *PreheaderBB, *ExitBB;
1273 MachineRegisterInfo &
MRI;
1274 const TargetInstrInfo *
TII;
1278 DenseMap<const TargetRegisterClass *, Register> Undefs;
1281 DenseMap<std::pair<Register, Register>,
Register> Phis;
1283 DenseMap<Register, Register> UndefPhis;
1292 const TargetRegisterClass *RC =
nullptr);
1294 Register undef(
const TargetRegisterClass *RC);
1297 KernelRewriter(MachineLoop &L, ModuloSchedule &S, MachineBasicBlock *LoopBB,
1298 LiveIntervals *LIS =
nullptr);
1305 : S(S), BB(LoopBB), PreheaderBB(
L.getLoopPreheader()),
1306 ExitBB(
L.getExitBlock()),
MRI(BB->
getParent()->getRegInfo()),
1307 TII(BB->
getParent()->getSubtarget().getInstrInfo()), LIS(LIS) {
1309 if (PreheaderBB == BB)
1313void KernelRewriter::rewrite() {
1319 MachineInstr *FirstMI =
nullptr;
1323 if (
MI->getParent())
1324 MI->removeFromParent();
1329 assert(FirstMI &&
"Failed to find first MI in schedule");
1336 (
I++)->eraseFromParent();
1340 for (MachineInstr &
MI : *BB) {
1341 if (
MI.isPHI() ||
MI.isTerminator())
1343 for (MachineOperand &MO :
MI.uses()) {
1350 EliminateDeadPhis(BB,
MRI, LIS);
1356 for (
auto MI = BB->getFirstNonPHI();
MI != BB->end(); ++
MI) {
1363 for (MachineOperand &Def :
MI->defs()) {
1364 for (MachineInstr &
MI :
MRI.use_instructions(
Def.getReg())) {
1365 if (
MI.getParent() != BB) {
1386 int ProducerStage = S.
getStage(Producer);
1387 assert(ConsumerStage != -1 &&
1388 "In-loop consumer should always be scheduled!");
1389 assert(ConsumerStage >= ProducerStage);
1390 unsigned StageDiff = ConsumerStage - ProducerStage;
1392 for (
unsigned I = 0;
I < StageDiff; ++
I)
1402 while (LoopProducer->isPHI() && LoopProducer->getParent() == BB) {
1405 LoopProducer =
MRI.getUniqueVRegDef(LoopReg);
1408 int LoopProducerStage = S.
getStage(LoopProducer);
1410 std::optional<Register> IllegalPhiDefault;
1412 if (LoopProducerStage == -1) {
1414 }
else if (LoopProducerStage > ConsumerStage) {
1420 int LoopProducerCycle = S.
getCycle(LoopProducer);
1423 assert(LoopProducerCycle <= ConsumerCycle);
1424 assert(LoopProducerStage == ConsumerStage + 1);
1431 IllegalPhiDefault = Defaults.
front();
1434 assert(ConsumerStage >= LoopProducerStage);
1435 int StageDiff = ConsumerStage - LoopProducerStage;
1436 if (StageDiff > 0) {
1438 <<
" to " << (Defaults.
size() + StageDiff) <<
"\n");
1443 Defaults.
empty() ? std::optional<Register>()
1449 auto DefaultI = Defaults.
rbegin();
1450 while (DefaultI != Defaults.
rend())
1451 LoopReg =
phi(LoopReg, *DefaultI++,
MRI.getRegClass(
Reg));
1453 if (IllegalPhiDefault) {
1459 auto RC =
MRI.getRegClass(
Reg);
1461 MachineInstr *IllegalPhi =
1463 .
addReg(*IllegalPhiDefault)
1469 S.
setStage(IllegalPhi, LoopProducerStage);
1476Register KernelRewriter::phi(
Register LoopReg, std::optional<Register> InitReg,
1477 const TargetRegisterClass *RC) {
1480 auto I = Phis.find({LoopReg, *InitReg});
1481 if (
I != Phis.end())
1484 for (
auto &KV : Phis) {
1485 if (KV.first.first == LoopReg)
1492 auto I = UndefPhis.
find(LoopReg);
1493 if (
I != UndefPhis.
end()) {
1500 MachineInstr *
MI =
MRI.getVRegDef(R);
1501 MI->getOperand(1).setReg(*InitReg);
1502 Phis.insert({{LoopReg, *InitReg},
R});
1503 const TargetRegisterClass *ConstrainRegClass =
1504 MRI.constrainRegClass(R,
MRI.getRegClass(*InitReg));
1505 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1506 (void)ConstrainRegClass;
1513 RC =
MRI.getRegClass(LoopReg);
1516 const TargetRegisterClass *ConstrainRegClass =
1517 MRI.constrainRegClass(R,
MRI.getRegClass(*InitReg));
1518 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1519 (void)ConstrainRegClass;
1522 .
addReg(InitReg ? *InitReg : undef(RC))
1527 UndefPhis[LoopReg] =
R;
1529 Phis[{LoopReg, *InitReg}] =
R;
1533Register KernelRewriter::undef(
const TargetRegisterClass *RC) {
1539 R =
MRI.createVirtualRegister(RC);
1542 TII->get(TargetOpcode::IMPLICIT_DEF), R);
1551class KernelOperandInfo {
1552 MachineBasicBlock *BB;
1553 MachineRegisterInfo &
MRI;
1555 MachineOperand *Source;
1556 MachineOperand *Target;
1559 KernelOperandInfo(MachineOperand *MO, MachineRegisterInfo &
MRI,
1560 const SmallPtrSetImpl<MachineInstr *> &IllegalPhis)
1564 while (isRegInLoop(MO)) {
1566 if (
MI->isFullCopy()) {
1567 MO = &
MI->getOperand(1);
1574 MO = &
MI->getOperand(3);
1579 MO =
MI->getOperand(2).getMBB() == BB ? &
MI->getOperand(1)
1580 : &
MI->getOperand(3);
1587 return PhiDefaults.
size() ==
Other.PhiDefaults.size();
1590 void print(raw_ostream &OS)
const {
1591 OS <<
"use of " << *
Source <<
": distance(" << PhiDefaults.
size() <<
") in "
1596 bool isRegInLoop(MachineOperand *MO) {
1598 MRI.getVRegDef(MO->
getReg())->getParent() == BB;
1610 for (
auto I =
BB->begin(), NI = NewBB->
begin(); !
I->isTerminator();
1626 if (Stage == -1 || Stage >= MinStage)
1639 for (
auto &
Sub : Subs)
1640 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1641 *
MRI.getTargetRegisterInfo());
1644 LIS->RemoveMachineInstrFromMaps(*
MI);
1645 MI->eraseFromParent();
1662 auto RC =
MRI.getRegClass(PhiR);
1675 MI.removeFromParent();
1679 BlockMIs.erase({SourceBB, KernelMI});
1689 assert(Def->findRegisterDefOperandIdx(
MI.getOperand(1).getReg(),
1691 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
1692 MI.getOperand(0).setReg(PhiReg);
1696 for (
auto *
P : PhiToDelete)
1697 P->eraseFromParent();
1703 DestBB->
insert(InsertPt, NewMI);
1704 Register OrigR = Phi->getOperand(0).getReg();
1725 if (
Use &&
Use->isPHI() &&
Use->getParent() == SourceBB) {
1740 for (
unsigned I = 0;
I < distance; ++
I) {
1743 unsigned LoopRegIdx = 3, InitRegIdx = 1;
1747 CanonicalUse =
MRI.getVRegDef(CanonicalUseReg);
1749 return CanonicalUseReg;
1760 for (
int I = 0;
I <
Schedule.getNumStages() - 1; ++
I) {
1774 EliminateDeadPhis(ExitingBB,
MRI,
LIS,
true);
1791 for (
int I = 1;
I <=
Schedule.getNumStages() - 1; ++
I) {
1797 EliminateDeadPhis(
B,
MRI,
LIS,
true);
1801 for (
size_t I = 0;
I <
Epilogs.size();
I++) {
1803 for (
size_t J =
I; J <
Epilogs.size(); J++) {
1805 unsigned Stage =
Schedule.getNumStages() - 1 +
I - J;
1807 for (
size_t K = Iteration; K >
I; K--)
1821 for (; PI !=
Prologs.end(); ++PI, ++EI) {
1823 (*PI)->addSuccessor(*EI);
1827 if (
Use &&
Use->getParent() == Pred) {
1829 if (CanonicalUse->
isPHI()) {
1850 for (
auto I =
B->instr_rbegin();
1851 I != std::next(
B->getFirstNonPHI()->getReverseIterator());) {
1858 LIS->RemoveMachineInstrFromMaps(*
MI);
1859 MI->eraseFromParent();
1865 EliminateDeadPhis(
B,
MRI,
LIS);
1866 EliminateDeadPhis(ExitingBB,
MRI,
LIS);
1873 Exit = *std::next(
BB->succ_begin());
1876 MF.insert(std::next(
BB->getIterator()), NewBB);
1880 auto RC =
MRI.getRegClass(
MI.getOperand(0).getReg());
1885 if (
Use.getParent() !=
BB)
1888 Use->substituteRegister(OldR, R, 0,
1889 *
MRI.getTargetRegisterInfo());
1896 BB->replaceSuccessor(Exit, NewBB);
1897 Exit->replacePhiUsesWith(
BB, NewBB);
1902 bool CanAnalyzeBr = !
TII->analyzeBranch(*
BB,
TBB, FBB,
Cond);
1904 assert(CanAnalyzeBr &&
"Must be able to analyze the loop branch!");
1905 TII->removeBranch(*
BB);
1906 TII->insertBranch(*
BB,
TBB == Exit ? NewBB :
TBB, FBB == Exit ? NewBB : FBB,
1908 TII->insertUnconditionalBranch(*NewBB, Exit,
DebugLoc());
1916 unsigned OpIdx =
MI->findRegisterDefOperandIdx(Reg,
nullptr);
1928 R =
MI->getOperand(1).getReg();
1929 MRI.setRegClass(R,
MRI.getRegClass(PhiR));
1930 MRI.replaceRegWith(PhiR, R);
1933 MI->getOperand(0).setReg(PhiR);
1939 if (Stage == -1 ||
LiveStages.count(
MI->getParent()) == 0 ||
1954 for (
auto &
Sub : Subs)
1955 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1956 *
MRI.getTargetRegisterInfo());
1959 LIS->RemoveMachineInstrFromMaps(*
MI);
1960 MI->eraseFromParent();
1965 bool KernelDisposed =
false;
1966 int TC =
Schedule.getNumStages() - 1;
1974 std::optional<bool> StaticallyGreater =
1976 if (!StaticallyGreater) {
1980 }
else if (*StaticallyGreater ==
false) {
1984 Prolog->removeSuccessor(Fallthrough);
1990 KernelDisposed =
true;
2002 if (!KernelDisposed) {
2033 std::string ScheduleDump;
2040 assert(
LIS &&
"Requires LiveIntervals!");
2045 if (!ExpandedKernel) {
2061 for (
auto NI =
BB->getFirstNonPHI(); NI !=
BB->end(); ++NI) {
2063 IllegalPhis.
insert(&*NI);
2069 auto OI = ExpandedKernel->
begin();
2070 auto NI =
BB->begin();
2071 for (; !OI->isTerminator() && !NI->isTerminator(); ++OI, ++NI) {
2072 while (OI->isPHI() || OI->isFullCopy())
2074 while (NI->isPHI() || NI->isFullCopy())
2076 assert(OI->getOpcode() == NI->getOpcode() &&
"Opcodes don't match?!");
2078 for (
auto OOpI = OI->operands_begin(), NOpI = NI->operands_begin();
2079 OOpI != OI->operands_end(); ++OOpI, ++NOpI)
2081 KernelOperandInfo(&*NOpI,
MRI, IllegalPhis));
2085 for (
auto &OldAndNew : KOIs) {
2086 if (OldAndNew.first == OldAndNew.second)
2089 errs() <<
"Modulo kernel validation error: [\n";
2090 errs() <<
" [golden] ";
2091 OldAndNew.first.print(
errs());
2093 OldAndNew.second.print(
errs());
2098 errs() <<
"Golden reference kernel:\n";
2100 errs() <<
"New kernel:\n";
2102 errs() << ScheduleDump;
2104 "Modulo kernel validation (-pipeliner-experimental-cg) failed");
2128 if (Exit->pred_size() == 1)
2144 else if (FBB ==
Loop)
2150 Loop->replaceSuccessor(Exit, NewExit);
2151 TII->insertUnconditionalBranch(*NewExit, Exit,
DebugLoc());
2154 Exit->replacePhiUsesWith(
Loop, NewExit);
2162void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &
MBB,
2164 InstrMapTy &LastStage0Insts,
2165 MachineBasicBlock &GreaterThan,
2166 MachineBasicBlock &Otherwise) {
2168 LoopInfo->createRemainingIterationsGreaterCondition(RequiredTC,
MBB,
Cond,
2187void ModuloScheduleExpanderMVE::generatePipelinedLoop() {
2262 assert(LoopInfo &&
"Must be able to analyze loop!");
2266 Check = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2267 Prolog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2268 NewKernel = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2269 Epilog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2270 NewPreheader = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2272 MF.insert(OrigKernel->getIterator(),
Check);
2274 MF.insert(OrigKernel->getIterator(),
Prolog);
2276 MF.insert(OrigKernel->getIterator(), NewKernel);
2278 MF.insert(OrigKernel->getIterator(),
Epilog);
2280 MF.insert(OrigKernel->getIterator(), NewPreheader);
2285 NewPreheader->transferSuccessorsAndUpdatePHIs(OrigPreheader);
2286 TII->insertUnconditionalBranch(*NewPreheader, OrigKernel,
DebugLoc());
2288 OrigPreheader->addSuccessor(
Check);
2293 Check->addSuccessor(NewPreheader);
2295 Prolog->addSuccessor(NewKernel);
2297 NewKernel->addSuccessor(NewKernel);
2298 NewKernel->addSuccessor(
Epilog);
2300 Epilog->addSuccessor(NewPreheader);
2301 Epilog->addSuccessor(NewExit);
2303 InstrMapTy LastStage0Insts;
2304 insertCondBranch(*
Check, Schedule.getNumStages() + NumUnroll - 2,
2305 LastStage0Insts, *
Prolog, *NewPreheader);
2310 generateProlog(PrologVRMap);
2311 generateKernel(PrologVRMap, KernelVRMap, LastStage0Insts);
2312 generateEpilog(KernelVRMap, EpilogVRMap, LastStage0Insts);
2316void ModuloScheduleExpanderMVE::updateInstrUse(
2317 MachineInstr *
MI,
int StageNum,
int PhaseNum,
2318 SmallVectorImpl<ValueMapTy> &CurVRMap,
2319 SmallVectorImpl<ValueMapTy> *PrevVRMap) {
2326 for (MachineOperand &UseMO :
MI->uses()) {
2327 if (!UseMO.isReg() || !UseMO.getReg().isVirtual())
2331 MachineInstr *DefInst =
MRI.getVRegDef(OrigReg);
2332 if (!DefInst || DefInst->
getParent() != OrigKernel)
2336 if (DefInst->
isPHI()) {
2339 getPhiRegs(*DefInst, OrigKernel, InitReg, LoopReg);
2342 DefInst =
MRI.getVRegDef(LoopReg);
2344 unsigned DefStageNum = Schedule.getStage(DefInst);
2345 DiffStage += StageNum - DefStageNum;
2347 if (PhaseNum >= DiffStage && CurVRMap[PhaseNum - DiffStage].
count(DefReg))
2349 NewReg = CurVRMap[PhaseNum - DiffStage][DefReg];
2350 else if (!PrevVRMap)
2359 NewReg = (*PrevVRMap)[PrevVRMap->
size() - (DiffStage - PhaseNum)][DefReg];
2361 const TargetRegisterClass *NRC =
2362 MRI.constrainRegClass(NewReg,
MRI.getRegClass(OrigReg));
2364 UseMO.setReg(NewReg);
2366 Register SplitReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2367 MachineInstr *NewCopy =
BuildMI(*OrigKernel,
MI,
MI->getDebugLoc(),
2368 TII->get(TargetOpcode::COPY), SplitReg)
2371 UseMO.setReg(SplitReg);
2389void ModuloScheduleExpanderMVE::generatePhi(
2390 MachineInstr *OrigMI,
int UnrollNum,
2391 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2392 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2393 SmallVectorImpl<ValueMapTy> &PhiVRMap) {
2394 int StageNum = Schedule.getStage(OrigMI);
2396 if (Schedule.getNumStages() - NumUnroll + UnrollNum - 1 >= StageNum)
2397 UsePrologReg =
true;
2398 else if (Schedule.getNumStages() - NumUnroll + UnrollNum == StageNum)
2399 UsePrologReg =
false;
2434 for (MachineOperand &DefMO : OrigMI->
defs()) {
2435 if (!DefMO.isReg() || DefMO.isDead())
2438 auto NewReg = KernelVRMap[UnrollNum].find(OrigReg);
2439 if (NewReg == KernelVRMap[UnrollNum].
end())
2443 int PrologNum = Schedule.getNumStages() - NumUnroll + UnrollNum - 1;
2444 CorrespondReg = PrologVRMap[PrologNum][OrigReg];
2453 Register PhiReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2454 MachineInstr *NewPhi =
2456 TII->get(TargetOpcode::PHI), PhiReg)
2462 PhiVRMap[UnrollNum][OrigReg] = PhiReg;
2468 for (
unsigned Idx = 1; Idx < Phi.getNumOperands(); Idx += 2) {
2469 if (Phi.getOperand(Idx).getReg() == OrigReg) {
2470 Phi.getOperand(Idx).setReg(NewReg);
2471 Phi.getOperand(Idx + 1).setMBB(NewMBB);
2478void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(
Register OrigReg,
2485 MachineOperand &
O = *
I;
2486 if (
O.getParent()->getParent() != OrigKernel &&
2487 O.getParent()->getParent() !=
Prolog &&
2488 O.getParent()->getParent() != NewKernel &&
2489 O.getParent()->getParent() !=
Epilog)
2491 if (
O.getParent()->getParent() == OrigKernel &&
O.getParent()->isPHI())
2497 if (!UsesAfterLoop.
empty()) {
2498 Register PhiReg =
MRI.createVirtualRegister(
MRI.getRegClass(OrigReg));
2499 MachineInstr *NewPhi =
2501 TII->get(TargetOpcode::PHI), PhiReg)
2508 for (MachineOperand *MO : UsesAfterLoop)
2519 if (!LoopPhis.
empty()) {
2520 for (MachineInstr *Phi : LoopPhis) {
2522 getPhiRegs(*Phi, OrigKernel, InitReg, LoopReg);
2523 Register NewInit =
MRI.createVirtualRegister(
MRI.getRegClass(InitReg));
2524 MachineInstr *NewPhi =
2525 BuildMI(*NewPreheader, NewPreheader->getFirstNonPHI(),
2526 Phi->getDebugLoc(),
TII->get(TargetOpcode::PHI), NewInit)
2537void ModuloScheduleExpanderMVE::generateProlog(
2538 SmallVectorImpl<ValueMapTy> &PrologVRMap) {
2539 PrologVRMap.
clear();
2540 PrologVRMap.
resize(Schedule.getNumStages() - 1);
2541 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2542 for (
int PrologNum = 0; PrologNum < Schedule.getNumStages() - 1;
2544 for (MachineInstr *
MI : Schedule.getInstructions()) {
2547 int StageNum = Schedule.getStage(
MI);
2548 if (StageNum > PrologNum)
2551 updateInstrDef(NewMI, PrologVRMap[PrologNum],
false);
2552 NewMIMap[NewMI] = {PrologNum, StageNum};
2553 Prolog->push_back(NewMI);
2558 for (
auto I : NewMIMap) {
2559 MachineInstr *
MI =
I.first;
2560 int PrologNum =
I.second.first;
2561 int StageNum =
I.second.second;
2562 updateInstrUse(
MI, StageNum, PrologNum, PrologVRMap,
nullptr);
2566 dbgs() <<
"prolog:\n";
2571void ModuloScheduleExpanderMVE::generateKernel(
2572 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2573 SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) {
2574 KernelVRMap.
clear();
2575 KernelVRMap.
resize(NumUnroll);
2577 PhiVRMap.
resize(NumUnroll);
2578 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2579 for (
int UnrollNum = 0; UnrollNum < NumUnroll; ++UnrollNum) {
2580 for (MachineInstr *
MI : Schedule.getInstructions()) {
2583 int StageNum = Schedule.getStage(
MI);
2585 if (UnrollNum == NumUnroll - 1)
2586 LastStage0Insts[
MI] = NewMI;
2587 updateInstrDef(NewMI, KernelVRMap[UnrollNum],
2588 (UnrollNum == NumUnroll - 1 && StageNum == 0));
2589 generatePhi(
MI, UnrollNum, PrologVRMap, KernelVRMap, PhiVRMap);
2590 NewMIMap[NewMI] = {UnrollNum, StageNum};
2591 NewKernel->push_back(NewMI);
2596 for (
auto I : NewMIMap) {
2597 MachineInstr *
MI =
I.first;
2598 int UnrollNum =
I.second.first;
2599 int StageNum =
I.second.second;
2600 updateInstrUse(
MI, StageNum, UnrollNum, KernelVRMap, &PhiVRMap);
2604 insertCondBranch(*NewKernel, NumUnroll - 1, LastStage0Insts, *NewKernel,
2608 dbgs() <<
"kernel:\n";
2613void ModuloScheduleExpanderMVE::generateEpilog(
2614 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2615 SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) {
2616 EpilogVRMap.
clear();
2617 EpilogVRMap.
resize(Schedule.getNumStages() - 1);
2618 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2619 for (
int EpilogNum = 0; EpilogNum < Schedule.getNumStages() - 1;
2621 for (MachineInstr *
MI : Schedule.getInstructions()) {
2624 int StageNum = Schedule.getStage(
MI);
2625 if (StageNum <= EpilogNum)
2628 updateInstrDef(NewMI, EpilogVRMap[EpilogNum], StageNum - 1 == EpilogNum);
2629 NewMIMap[NewMI] = {EpilogNum, StageNum};
2630 Epilog->push_back(NewMI);
2635 for (
auto I : NewMIMap) {
2636 MachineInstr *
MI =
I.first;
2637 int EpilogNum =
I.second.first;
2638 int StageNum =
I.second.second;
2639 updateInstrUse(
MI, StageNum, EpilogNum, EpilogVRMap, &KernelVRMap);
2646 insertCondBranch(*
Epilog, 0, LastStage0Insts, *NewPreheader, *NewExit);
2649 dbgs() <<
"epilog:\n";
2655void ModuloScheduleExpanderMVE::calcNumUnroll() {
2656 DenseMap<MachineInstr *, unsigned> Inst2Idx;
2658 for (
unsigned I = 0;
I < Schedule.getInstructions().
size(); ++
I)
2659 Inst2Idx[Schedule.getInstructions()[
I]] =
I;
2661 for (MachineInstr *
MI : Schedule.getInstructions()) {
2664 int StageNum = Schedule.getStage(
MI);
2665 for (
const MachineOperand &MO :
MI->uses()) {
2672 int NumUnrollLocal = 1;
2679 NumUnrollLocal += StageNum - Schedule.getStage(
DefMI);
2680 if (Inst2Idx[
MI] <= Inst2Idx[
DefMI])
2682 NumUnroll = std::max(NumUnroll, NumUnrollLocal);
2691void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
2694 for (MachineOperand &MO : NewMI->
all_defs()) {
2698 const TargetRegisterClass *RC =
MRI.getRegClass(
Reg);
2701 VRMap[
Reg] = NewReg;
2703 mergeRegUsesAfterPipeline(
Reg, NewReg);
2708 OrigKernel = Schedule.getLoop()->getTopBlock();
2709 OrigPreheader = Schedule.getLoop()->getLoopPreheader();
2710 OrigExit = Schedule.getLoop()->getExitBlock();
2714 generatePipelinedLoop();
2719 if (!L.getExitBlock()) {
2720 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: No single exit block.\n");
2736 if (
Ref.getParent() != BB ||
Ref.isPHI()) {
2737 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A phi result is "
2738 "referenced outside of the loop or by phi.\n");
2747 if (!
Register(LoopVal).isVirtual() ||
2748 MRI.getVRegDef(LoopVal)->getParent() != BB) {
2750 dbgs() <<
"Can not apply MVE expander: A phi source value coming "
2751 "from the loop is not defined in the loop.\n");
2754 if (UsedByPhi.
count(LoopVal)) {
2755 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A value defined in the "
2756 "loop is referenced by two or more phis.\n");
2759 UsedByPhi.
insert(LoopVal);
2798char ModuloScheduleTest::ID = 0;
2801 "Modulo Schedule test pass",
false,
false)
2808 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
2809 for (
auto *L : MLI) {
2810 if (L->getTopBlock() != L->getBottomBlock())
2819 std::pair<StringRef, StringRef> StageAndCycle =
getToken(S,
"_");
2820 std::pair<StringRef, StringRef> StageTokenAndValue =
2821 getToken(StageAndCycle.first,
"-");
2822 std::pair<StringRef, StringRef> CycleTokenAndValue =
2823 getToken(StageAndCycle.second,
"-");
2824 if (StageTokenAndValue.first !=
"Stage" ||
2825 CycleTokenAndValue.first !=
"_Cycle") {
2827 "Bad post-instr symbol syntax: see comment in ModuloScheduleTest");
2831 StageTokenAndValue.second.drop_front().getAsInteger(10, Stage);
2832 CycleTokenAndValue.second.drop_front().getAsInteger(10,
Cycle);
2834 dbgs() <<
" Stage=" << Stage <<
", Cycle=" <<
Cycle <<
"\n";
2837void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) {
2838 LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
2839 MachineBasicBlock *BB =
L.getTopBlock();
2840 dbgs() <<
"--- ModuloScheduleTest running on BB#" << BB->
getNumber() <<
"\n";
2842 DenseMap<MachineInstr *, int>
Cycle, Stage;
2843 std::vector<MachineInstr *> Instrs;
2844 for (MachineInstr &
MI : *BB) {
2845 if (
MI.isTerminator())
2847 Instrs.push_back(&
MI);
2848 if (MCSymbol *Sym =
MI.getPostInstrSymbol()) {
2849 dbgs() <<
"Parsing post-instr symbol for " <<
MI;
2854 ModuloSchedule MS(MF, &L, std::move(Instrs), std::move(
Cycle),
2856 ModuloScheduleExpander MSE(
2870 OS <<
"Stage-" << S.getStage(
MI) <<
"_Cycle-" << S.getCycle(
MI);
2871 MCSymbol *Sym = MF.getContext().getOrCreateSymbol(OS.
str());
2872 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 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.