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 VRMapPhi, 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 VRMapPhi, 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 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
379 unsigned PrologStage = 0;
380 unsigned PrevStage = 0;
381 bool InKernel = (LastStageNum == CurStageNum);
383 PrologStage = LastStageNum - 1;
384 PrevStage = CurStageNum;
386 PrologStage = LastStageNum - (CurStageNum - LastStageNum);
387 PrevStage = LastStageNum + (CurStageNum - LastStageNum) - 1;
391 BBE = BB->getFirstNonPHI();
403 if (
auto It = VRMap[LastStageNum].
find(LoopVal);
404 It != VRMap[LastStageNum].end())
407 int StageScheduled = Schedule.getStage(&*BBI);
408 int LoopValStage = Schedule.getStage(MRI.getVRegDef(LoopVal));
409 unsigned NumStages = getStagesForReg(Def, CurStageNum);
410 if (NumStages == 0) {
413 Register NewReg = VRMap[PrevStage][LoopVal];
414 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, 0, &*BBI, Def,
416 auto It = VRMap[CurStageNum].find(LoopVal);
417 if (It != VRMap[CurStageNum].
end()) {
419 VRMap[CurStageNum][
Def] =
Reg;
426 unsigned MaxPhis = PrologStage + 2;
427 if (!InKernel && (
int)PrologStage <= LoopValStage)
428 MaxPhis = std::max((
int)MaxPhis - LoopValStage, 1);
429 unsigned NumPhis = std::min(NumStages, MaxPhis);
432 unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled;
439 if (!InKernel && StageScheduled >= LoopValStage && AccessStage == 0 &&
444 if (InKernel && LoopValStage != -1 && StageScheduled > LoopValStage)
445 StageDiff = StageScheduled - LoopValStage;
446 for (
unsigned np = 0; np < NumPhis; ++np) {
450 if (np > PrologStage || StageScheduled >= (
int)LastStageNum)
453 else if (PrologStage >= AccessStage + StageDiff + np &&
454 VRMap[PrologStage - StageDiff - np].
count(LoopVal) != 0)
455 PhiOp1 = VRMap[PrologStage - StageDiff - np][LoopVal];
458 else if (PrologStage >= AccessStage + StageDiff + np) {
462 MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1);
464 while (InstOp1 && InstOp1->
isPHI() && InstOp1->
getParent() == BB) {
465 int PhiStage = Schedule.getStage(InstOp1);
466 if ((
int)(PrologStage - StageDiff - np) < PhiStage + Indirects)
470 InstOp1 = MRI.getVRegDef(PhiOp1);
471 int PhiOpStage = Schedule.getStage(InstOp1);
472 int StageAdj = (PhiOpStage != -1 ? PhiStage - PhiOpStage : 0);
473 if (PhiOpStage != -1 && PrologStage - StageAdj >= Indirects + np) {
474 auto &
M = VRMap[PrologStage - StageAdj - Indirects - np];
475 if (
auto It =
M.find(PhiOp1); It !=
M.end()) {
486 if (MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1))
490 MachineInstr *PhiInst = MRI.getVRegDef(LoopVal);
491 bool LoopDefIsPhi = PhiInst && PhiInst->
isPHI();
496 int StageDiffAdj = 0;
497 if (LoopValStage != -1 && StageScheduled > LoopValStage)
498 StageDiffAdj = StageScheduled - LoopValStage;
501 if (np == 0 && PrevStage == LastStageNum &&
502 (StageScheduled != 0 || LoopValStage != 0) &&
503 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal))
505 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal);
508 else if (np > 0 && PrevStage == LastStageNum &&
509 getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def))
510 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def);
512 else if (
static_cast<unsigned>(LoopValStage) > PrologStage + 1 &&
513 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
515 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
519 else if (getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def) &&
520 (!LoopDefIsPhi || (PrevStage != LastStageNum) ||
521 (LoopValStage == StageScheduled)))
522 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def);
530 if (
static_cast<int>(PrologStage - np) >= StageScheduled) {
531 int LVNumStages = getStagesForPhi(LoopVal);
532 int StageDiff = (StageScheduled - LoopValStage);
533 LVNumStages -= StageDiff;
535 if (LVNumStages > (
int)np && VRMap[CurStageNum].
count(LoopVal)) {
537 unsigned ReuseStage = CurStageNum;
538 if (isLoopCarried(*PhiInst))
539 ReuseStage -= LVNumStages;
542 if (VRMap[ReuseStage - np].
count(LoopVal)) {
543 NewReg = VRMap[ReuseStage - np][LoopVal];
545 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI,
548 VRMap[CurStageNum - np][
Def] = NewReg;
550 if (VRMap[LastStageNum - np - 1].
count(LoopVal))
551 PhiOp2 = VRMap[LastStageNum - np - 1][LoopVal];
553 if (IsLast && np == NumPhis - 1)
559 if (InKernel && StageDiff > 0 &&
560 VRMap[CurStageNum - StageDiff - np].
count(LoopVal))
561 PhiOp2 = VRMap[CurStageNum - StageDiff - np][LoopVal];
565 NewReg = MRI.createVirtualRegister(RC);
567 MachineInstrBuilder NewPhi =
569 TII->get(TargetOpcode::PHI), NewReg);
572 LIS.InsertMachineInstrInMaps(*NewPhi);
574 InstrMap[NewPhi] = &*BBI;
580 if (InKernel && VRMap[PrevStage - np].
count(LoopVal))
581 PrevReg = VRMap[PrevStage - np][LoopVal];
582 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
585 if (VRMap[CurStageNum - np].
count(Def)) {
587 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, R,
594 if (IsLast && np == NumPhis - 1)
602 VRMap[CurStageNum - np][
Def] = NewReg;
605 while (NumPhis++ < NumStages) {
606 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, NumPhis, &*BBI, Def,
612 if (NumStages == 0 && IsLast) {
613 auto &CurStageMap = VRMap[CurStageNum];
614 auto It = CurStageMap.find(LoopVal);
615 if (It != CurStageMap.end())
624void ModuloScheduleExpander::generatePhis(
627 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
631 unsigned PrologStage = 0;
632 unsigned PrevStage = 0;
633 unsigned StageDiff = CurStageNum - LastStageNum;
634 bool InKernel = (StageDiff == 0);
636 PrologStage = LastStageNum - 1;
637 PrevStage = CurStageNum;
639 PrologStage = LastStageNum - StageDiff;
640 PrevStage = LastStageNum + StageDiff - 1;
644 BBE = BB->instr_end();
646 for (
unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) {
647 MachineOperand &MO = BBI->getOperand(i);
651 int StageScheduled = Schedule.getStage(&*BBI);
652 assert(StageScheduled != -1 &&
"Expecting scheduled instruction.");
654 unsigned NumPhis = getStagesForReg(Def, CurStageNum);
658 if (!InKernel && NumPhis == 0 && StageScheduled == 0 &&
661 if (!InKernel && (
unsigned)StageScheduled > PrologStage)
666 PhiOp2 = VRMap[PrevStage][
Def];
667 if (MachineInstr *InstOp2 = MRI.getVRegDef(PhiOp2))
668 if (InstOp2->isPHI() && InstOp2->getParent() == NewBB)
673 if (NumPhis > PrologStage + 1 - StageScheduled)
674 NumPhis = PrologStage + 1 - StageScheduled;
675 for (
unsigned np = 0; np < NumPhis; ++np) {
699 if (np <= PrologStage)
700 PhiOp1 = VRMap[PrologStage - np][
Def];
702 if (PrevStage == LastStageNum && np == 0)
703 PhiOp2 = VRMap[LastStageNum][
Def];
705 PhiOp2 = VRMapPhi[PrevStage - np][
Def];
709 Register NewReg = MRI.createVirtualRegister(RC);
711 MachineInstrBuilder NewPhi =
713 TII->get(TargetOpcode::PHI), NewReg);
716 LIS.InsertMachineInstrInMaps(*NewPhi);
718 InstrMap[NewPhi] = &*BBI;
723 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp1,
725 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp2,
729 VRMapPhi[PrevStage - np - 1][
Def] = NewReg;
731 VRMapPhi[CurStageNum - np][
Def] = NewReg;
732 if (np == NumPhis - 1)
733 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
736 if (IsLast && np == NumPhis - 1)
748 MBBVectorTy &EpilogBBs) {
756 if (
MI->isInlineAsm()) {
760 bool SawStore =
false;
763 if (!
MI->isSafeToMove(SawStore) && !
MI->isPHI()) {
768 for (
const MachineOperand &MO :
MI->all_defs()) {
777 unsigned realUses = 0;
778 for (
const MachineOperand &U : MRI.use_operands(reg)) {
781 if (
U.getParent()->getParent() != BB) {
792 LIS.RemoveMachineInstrFromMaps(*
MI);
793 MI++->eraseFromParent();
802 if (MRI.use_begin(reg) == MRI.use_end()) {
803 LIS.RemoveMachineInstrFromMaps(
MI);
804 MI.eraseFromParent();
820 MBBVectorTy &EpilogBBs) {
821 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
822 for (
auto &
PHI : KernelBB->
phis()) {
827 E = MRI.use_instr_end();
829 if (
I->isPHI() &&
I->getParent() == KernelBB) {
834 MachineInstr *
MI = MRI.getVRegDef(LCDef);
835 if (!
MI ||
MI->getParent() != KernelBB ||
MI->isPHI())
842 if (BBJ.readsRegister(Def,
nullptr)) {
845 SplitReg = MRI.createVirtualRegister(MRI.getRegClass(Def));
846 MachineInstr *newCopy =
848 TII->get(TargetOpcode::COPY), SplitReg)
850 LIS.InsertMachineInstrInMaps(*newCopy);
852 BBJ.substituteRegister(Def, SplitReg, 0, *
TRI);
857 for (
auto &
Epilog : EpilogBBs)
859 if (
I.readsRegister(Def,
nullptr))
860 I.substituteRegister(Def, SplitReg, 0, *
TRI);
871 MBBVectorTy &PrologBBs,
873 MBBVectorTy &EpilogBBs,
875 assert(PrologBBs.size() == EpilogBBs.size() &&
"Prolog/Epilog mismatch");
876 MachineBasicBlock *LastPro = KernelBB;
877 MachineBasicBlock *LastEpi = KernelBB;
881 unsigned MaxIter = PrologBBs.
size() - 1;
882 for (
unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --
j) {
885 MachineBasicBlock *
Prolog = PrologBBs[
j];
886 MachineBasicBlock *
Epilog = EpilogBBs[i];
889 std::optional<bool> StaticallyGreater =
890 LoopInfo->createTripCountGreaterCondition(j + 1, *
Prolog,
Cond);
891 unsigned numAdded = 0;
892 if (!StaticallyGreater) {
895 }
else if (*StaticallyGreater ==
false) {
897 Prolog->removeSuccessor(LastPro);
900 Epilog->removePHIsIncomingValuesForPredecessor(*LastEpi);
902 if (LastPro != LastEpi) {
903 for (
auto &
MI : *LastEpi)
904 LIS.RemoveMachineInstrFromMaps(
MI);
906 LastEpi->eraseFromParent();
908 if (LastPro == KernelBB) {
909 LoopInfo->disposed(&LIS);
912 for (
auto &
MI : *LastPro)
913 LIS.RemoveMachineInstrFromMaps(
MI);
915 LastPro->eraseFromParent();
918 Epilog->removePHIsIncomingValuesForPredecessor(*
Prolog);
924 I !=
E && numAdded > 0; ++
I, --numAdded)
925 updateInstruction(&*
I,
false, j, 0, VRMap);
929 LoopInfo->setPreheader(PrologBBs[MaxIter]);
930 LoopInfo->adjustTripCount(-(MaxIter + 1));
936bool ModuloScheduleExpander::computeDelta(
MachineInstr &
MI,
unsigned &Delta) {
937 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
938 const MachineOperand *BaseOp;
940 bool OffsetIsScalable;
941 if (!TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
945 if (OffsetIsScalable)
948 if (!BaseOp->
isReg())
953 MachineRegisterInfo &MRI = MF.getRegInfo();
955 MachineInstr *BaseDef = MRI.getVRegDef(BaseReg);
956 if (BaseDef && BaseDef->
isPHI()) {
958 BaseDef = MRI.getVRegDef(BaseReg);
964 if (!TII->getIncrementValue(*BaseDef,
D) &&
D >= 0)
974void ModuloScheduleExpander::updateMemOperands(
MachineInstr &NewMI,
984 for (MachineMemOperand *MMO : NewMI.
memoperands()) {
986 if (MMO->isVolatile() || MMO->isAtomic() ||
987 (MMO->isInvariant() && MMO->isDereferenceable()) ||
988 (!MMO->getValue())) {
993 if (Num != UINT_MAX && computeDelta(OldMI, Delta)) {
994 int64_t AdjOffset = Delta * Num;
996 MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()));
998 NewMMOs.
push_back(MF.getMachineMemOperand(
1008 unsigned CurStageNum,
1009 unsigned InstStageNum) {
1010 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1011 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1018MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
1019 MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) {
1020 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1021 auto It = InstrChanges.find(OldMI);
1022 if (It != InstrChanges.end()) {
1023 std::pair<Register, int64_t> RegAndOffset = It->second;
1024 unsigned BasePos, OffsetPos;
1025 if (!TII->getBaseAndOffsetPosition(*OldMI, BasePos, OffsetPos))
1028 MachineInstr *LoopDef = findDefInLoop(RegAndOffset.first);
1029 if (Schedule.getStage(LoopDef) > (
signed)InstStageNum)
1030 NewOffset += RegAndOffset.second * (CurStageNum - InstStageNum);
1033 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1039void ModuloScheduleExpander::updateInstruction(
MachineInstr *NewMI,
1041 unsigned CurStageNum,
1042 unsigned InstrStageNum,
1043 ValueMapTy *VRMap) {
1044 for (MachineOperand &MO : NewMI->
operands()) {
1051 Register NewReg = MRI.createVirtualRegister(RC);
1053 VRMap[CurStageNum][reg] = NewReg;
1056 }
else if (MO.
isUse()) {
1057 MachineInstr *
Def = MRI.getVRegDef(reg);
1059 int DefStageNum = Schedule.getStage(Def);
1060 unsigned StageNum = CurStageNum;
1061 if (DefStageNum != -1 && (
int)InstrStageNum > DefStageNum) {
1063 unsigned StageDiff = (InstrStageNum - DefStageNum);
1065 StageNum -= StageDiff;
1067 if (
auto It = VRMap[StageNum].
find(reg); It != VRMap[StageNum].end())
1077 SmallPtrSet<MachineInstr *, 8> Visited;
1078 MachineInstr *
Def = MRI.getVRegDef(
Reg);
1079 while (
Def->isPHI()) {
1080 if (!Visited.
insert(Def).second)
1082 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2)
1083 if (
Def->getOperand(i + 1).getMBB() == BB) {
1084 Def = MRI.getVRegDef(
Def->getOperand(i).getReg());
1092Register ModuloScheduleExpander::getPrevMapVal(
1093 unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
unsigned LoopStage,
1096 if (StageNum > PhiStage) {
1097 MachineInstr *LoopInst = MRI.getVRegDef(LoopVal);
1098 if (PhiStage == LoopStage && VRMap[StageNum - 1].
count(LoopVal))
1100 PrevVal = VRMap[StageNum - 1][LoopVal];
1101 else if (VRMap[StageNum].
count(LoopVal))
1104 PrevVal = VRMap[StageNum][LoopVal];
1108 else if (StageNum == PhiStage + 1)
1111 else if (StageNum > PhiStage + 1 && LoopInst->
getParent() == BB)
1114 getPrevMapVal(StageNum - 1, PhiStage,
getLoopPhiReg(*LoopInst, BB),
1115 LoopStage, VRMap, BB);
1127 InstrMapTy &InstrMap) {
1128 for (
auto &
PHI : BB->phis()) {
1134 unsigned PhiStage = (unsigned)Schedule.getStage(MRI.getVRegDef(PhiDef));
1135 unsigned LoopStage = (unsigned)Schedule.getStage(MRI.getVRegDef(LoopVal));
1136 unsigned NumPhis = getStagesForPhi(PhiDef);
1137 if (NumPhis > StageNum)
1139 for (
unsigned np = 0; np <= NumPhis; ++np) {
1141 getPrevMapVal(StageNum - np, PhiStage, LoopVal, LoopStage, VRMap, BB);
1144 rewriteScheduledInstr(NewBB, InstrMap, StageNum - np, np, &
PHI, PhiDef,
1153void ModuloScheduleExpander::rewriteScheduledInstr(
1157 bool InProlog = (CurStageNum < (unsigned)Schedule.getNumStages() - 1);
1158 int StagePhi = Schedule.getStage(Phi) + PhiNum;
1161 for (MachineOperand &UseOp :
1163 MachineInstr *
UseMI = UseOp.getParent();
1173 assert(OrigInstr != InstrMap.end() &&
"Instruction not scheduled.");
1174 MachineInstr *OrigMI = OrigInstr->second;
1175 int StageSched = Schedule.getStage(OrigMI);
1176 int CycleSched = Schedule.getCycle(OrigMI);
1179 if (StagePhi == StageSched &&
Phi->isPHI()) {
1180 int CyclePhi = Schedule.getCycle(Phi);
1181 if (PrevReg && InProlog)
1182 ReplaceReg = PrevReg;
1183 else if (PrevReg && !isLoopCarried(*Phi) &&
1184 (CyclePhi <= CycleSched || OrigMI->isPHI()))
1185 ReplaceReg = PrevReg;
1187 ReplaceReg = NewReg;
1191 if (!InProlog && StagePhi + 1 == StageSched && !isLoopCarried(*Phi))
1192 ReplaceReg = NewReg;
1193 if (StagePhi > StageSched &&
Phi->isPHI())
1194 ReplaceReg = NewReg;
1195 if (!InProlog && !
Phi->isPHI() && StagePhi < StageSched)
1196 ReplaceReg = NewReg;
1199 MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg));
1201 UseOp.setReg(ReplaceReg);
1203 Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
1205 TII->
get(TargetOpcode::COPY), SplitReg)
1207 UseOp.setReg(SplitReg);
1208 LIS.InsertMachineInstrInMaps(*newCopy);
1214bool ModuloScheduleExpander::isLoopCarried(
MachineInstr &Phi) {
1217 int DefCycle = Schedule.getCycle(&Phi);
1218 int DefStage = Schedule.getStage(&Phi);
1223 MachineInstr *
Use = MRI.getVRegDef(LoopVal);
1224 if (!Use ||
Use->isPHI())
1226 int LoopCycle = Schedule.getCycle(Use);
1227 int LoopStage = Schedule.getStage(Use);
1228 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
1251 MI.eraseFromParent();
1253 }
else if (!KeepSingleSrcPhi &&
MI.getNumExplicitOperands() == 3) {
1257 assert(ConstrainRegClass &&
1258 "Expected a valid constrained register class!");
1259 (void)ConstrainRegClass;
1261 MI.getOperand(1).getReg());
1264 MI.eraseFromParent();
1273class KernelRewriter {
1275 MachineBasicBlock *BB;
1276 MachineBasicBlock *PreheaderBB, *ExitBB;
1277 MachineRegisterInfo &MRI;
1278 const TargetInstrInfo *
TII;
1282 DenseMap<const TargetRegisterClass *, Register> Undefs;
1285 DenseMap<std::pair<Register, Register>,
Register> Phis;
1287 DenseMap<Register, Register> UndefPhis;
1301 KernelRewriter(MachineLoop &L, ModuloSchedule &S, MachineBasicBlock *LoopBB,
1302 LiveIntervals *LIS =
nullptr);
1309 : S(S), BB(LoopBB), PreheaderBB(
L.getLoopPreheader()),
1310 ExitBB(
L.getExitBlock()), MRI(BB->
getParent()->getRegInfo()),
1311 TII(BB->
getParent()->getSubtarget().getInstrInfo()), LIS(LIS) {
1313 if (PreheaderBB == BB)
1317void KernelRewriter::rewrite() {
1323 MachineInstr *FirstMI =
nullptr;
1327 if (
MI->getParent())
1328 MI->removeFromParent();
1333 assert(FirstMI &&
"Failed to find first MI in schedule");
1340 (
I++)->eraseFromParent();
1344 for (MachineInstr &
MI : *BB) {
1345 if (
MI.isPHI() ||
MI.isTerminator())
1347 for (MachineOperand &MO :
MI.uses()) {
1354 EliminateDeadPhis(BB, MRI, LIS);
1360 for (
auto MI = BB->getFirstNonPHI();
MI != BB->end(); ++
MI) {
1367 for (MachineOperand &Def :
MI->defs()) {
1369 if (
MI.getParent() != BB) {
1390 int ProducerStage = S.
getStage(Producer);
1391 assert(ConsumerStage != -1 &&
1392 "In-loop consumer should always be scheduled!");
1393 assert(ConsumerStage >= ProducerStage);
1394 unsigned StageDiff = ConsumerStage - ProducerStage;
1396 for (
unsigned I = 0;
I < StageDiff; ++
I)
1406 while (LoopProducer->isPHI() && LoopProducer->getParent() == BB) {
1412 int LoopProducerStage = S.
getStage(LoopProducer);
1414 std::optional<Register> IllegalPhiDefault;
1416 if (LoopProducerStage == -1) {
1418 }
else if (LoopProducerStage > ConsumerStage) {
1424 int LoopProducerCycle = S.
getCycle(LoopProducer);
1427 assert(LoopProducerCycle <= ConsumerCycle);
1428 assert(LoopProducerStage == ConsumerStage + 1);
1435 IllegalPhiDefault = Defaults.
front();
1438 assert(ConsumerStage >= LoopProducerStage);
1439 int StageDiff = ConsumerStage - LoopProducerStage;
1440 if (StageDiff > 0) {
1442 <<
" to " << (Defaults.
size() + StageDiff) <<
"\n");
1447 Defaults.
empty() ? std::optional<Register>()
1453 auto DefaultI = Defaults.
rbegin();
1454 while (DefaultI != Defaults.
rend())
1457 if (IllegalPhiDefault) {
1465 MachineInstr *IllegalPhi =
1467 .
addReg(*IllegalPhiDefault)
1473 S.
setStage(IllegalPhi, LoopProducerStage);
1480Register KernelRewriter::phi(
Register LoopReg, std::optional<Register> InitReg,
1484 auto I = Phis.find({LoopReg, *InitReg});
1485 if (
I != Phis.end())
1488 for (
auto &KV : Phis) {
1489 if (KV.first.first == LoopReg)
1496 auto I = UndefPhis.
find(LoopReg);
1497 if (
I != UndefPhis.
end()) {
1505 MI->getOperand(1).setReg(*InitReg);
1506 Phis.insert({{LoopReg, *InitReg},
R});
1509 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1510 (void)ConstrainRegClass;
1522 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1523 (void)ConstrainRegClass;
1526 .
addReg(InitReg ? *InitReg : undef(RC))
1531 UndefPhis[LoopReg] =
R;
1533 Phis[{LoopReg, *InitReg}] =
R;
1546 TII->get(TargetOpcode::IMPLICIT_DEF), R);
1555class KernelOperandInfo {
1556 MachineBasicBlock *BB;
1557 MachineRegisterInfo &MRI;
1559 MachineOperand *Source;
1560 MachineOperand *Target;
1563 KernelOperandInfo(MachineOperand *MO, MachineRegisterInfo &MRI,
1564 const SmallPtrSetImpl<MachineInstr *> &IllegalPhis)
1568 while (isRegInLoop(MO)) {
1570 if (
MI->isFullCopy()) {
1571 MO = &
MI->getOperand(1);
1578 MO = &
MI->getOperand(3);
1583 MO =
MI->getOperand(2).getMBB() == BB ? &
MI->getOperand(1)
1584 : &
MI->getOperand(3);
1591 return PhiDefaults.
size() ==
Other.PhiDefaults.size();
1594 void print(raw_ostream &OS)
const {
1595 OS <<
"use of " << *
Source <<
": distance(" << PhiDefaults.
size() <<
") in "
1600 bool isRegInLoop(MachineOperand *MO) {
1614 for (
auto I =
BB->begin(), NI = NewBB->
begin(); !
I->isTerminator();
1630 if (Stage == -1 || Stage >= MinStage)
1643 for (
auto &
Sub : Subs)
1644 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1645 *
MRI.getTargetRegisterInfo());
1648 LIS->RemoveMachineInstrFromMaps(*
MI);
1649 MI->eraseFromParent();
1666 auto RC =
MRI.getRegClass(PhiR);
1679 MI.removeFromParent();
1683 BlockMIs.erase({SourceBB, KernelMI});
1693 assert(Def->findRegisterDefOperandIdx(
MI.getOperand(1).getReg(),
1695 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
1696 MI.getOperand(0).setReg(PhiReg);
1700 for (
auto *
P : PhiToDelete)
1701 P->eraseFromParent();
1707 DestBB->
insert(InsertPt, NewMI);
1708 Register OrigR = Phi->getOperand(0).getReg();
1729 if (
Use &&
Use->isPHI() &&
Use->getParent() == SourceBB) {
1744 for (
unsigned I = 0;
I < distance; ++
I) {
1747 unsigned LoopRegIdx = 3, InitRegIdx = 1;
1751 CanonicalUse =
MRI.getVRegDef(CanonicalUseReg);
1753 return CanonicalUseReg;
1764 for (
int I = 0;
I <
Schedule.getNumStages() - 1; ++
I) {
1778 EliminateDeadPhis(ExitingBB,
MRI,
LIS,
true);
1795 for (
int I = 1;
I <=
Schedule.getNumStages() - 1; ++
I) {
1801 EliminateDeadPhis(
B,
MRI,
LIS,
true);
1805 for (
size_t I = 0;
I <
Epilogs.size();
I++) {
1807 for (
size_t J =
I; J <
Epilogs.size(); J++) {
1809 unsigned Stage =
Schedule.getNumStages() - 1 +
I - J;
1811 for (
size_t K = Iteration; K >
I; K--)
1825 for (; PI !=
Prologs.end(); ++PI, ++EI) {
1827 (*PI)->addSuccessor(*EI);
1831 if (
Use &&
Use->getParent() == Pred) {
1833 if (CanonicalUse->
isPHI()) {
1854 for (
auto I =
B->instr_rbegin();
1855 I != std::next(
B->getFirstNonPHI()->getReverseIterator());) {
1862 LIS->RemoveMachineInstrFromMaps(*
MI);
1863 MI->eraseFromParent();
1869 EliminateDeadPhis(
B,
MRI,
LIS);
1870 EliminateDeadPhis(ExitingBB,
MRI,
LIS);
1877 Exit = *std::next(
BB->succ_begin());
1880 MF.insert(std::next(
BB->getIterator()), NewBB);
1884 auto RC =
MRI.getRegClass(
MI.getOperand(0).getReg());
1889 if (
Use.getParent() !=
BB)
1892 Use->substituteRegister(OldR, R, 0,
1893 *
MRI.getTargetRegisterInfo());
1900 BB->replaceSuccessor(Exit, NewBB);
1901 Exit->replacePhiUsesWith(
BB, NewBB);
1906 bool CanAnalyzeBr = !
TII->analyzeBranch(*
BB,
TBB, FBB,
Cond);
1908 assert(CanAnalyzeBr &&
"Must be able to analyze the loop branch!");
1909 TII->removeBranch(*
BB);
1910 TII->insertBranch(*
BB,
TBB == Exit ? NewBB :
TBB, FBB == Exit ? NewBB : FBB,
1912 TII->insertUnconditionalBranch(*NewBB, Exit,
DebugLoc());
1920 unsigned OpIdx =
MI->findRegisterDefOperandIdx(Reg,
nullptr);
1932 R =
MI->getOperand(1).getReg();
1933 MRI.setRegClass(R,
MRI.getRegClass(PhiR));
1934 MRI.replaceRegWith(PhiR, R);
1937 MI->getOperand(0).setReg(PhiR);
1943 if (Stage == -1 ||
LiveStages.count(
MI->getParent()) == 0 ||
1958 for (
auto &
Sub : Subs)
1959 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1960 *
MRI.getTargetRegisterInfo());
1963 LIS->RemoveMachineInstrFromMaps(*
MI);
1964 MI->eraseFromParent();
1969 bool KernelDisposed =
false;
1970 int TC =
Schedule.getNumStages() - 1;
1978 std::optional<bool> StaticallyGreater =
1980 if (!StaticallyGreater) {
1984 }
else if (*StaticallyGreater ==
false) {
1988 Prolog->removeSuccessor(Fallthrough);
1994 KernelDisposed =
true;
2006 if (!KernelDisposed) {
2037 std::string ScheduleDump;
2043 assert(
LIS &&
"Requires LiveIntervals!");
2048 if (!ExpandedKernel) {
2064 for (
auto NI =
BB->getFirstNonPHI(); NI !=
BB->end(); ++NI) {
2066 IllegalPhis.
insert(&*NI);
2072 auto OI = ExpandedKernel->
begin();
2073 auto NI =
BB->begin();
2074 for (; !OI->isTerminator() && !NI->isTerminator(); ++OI, ++NI) {
2075 while (OI->isPHI() || OI->isFullCopy())
2077 while (NI->isPHI() || NI->isFullCopy())
2079 assert(OI->getOpcode() == NI->getOpcode() &&
"Opcodes don't match?!");
2081 for (
auto OOpI = OI->operands_begin(), NOpI = NI->operands_begin();
2082 OOpI != OI->operands_end(); ++OOpI, ++NOpI)
2084 KernelOperandInfo(&*NOpI,
MRI, IllegalPhis));
2088 for (
auto &OldAndNew : KOIs) {
2089 if (OldAndNew.first == OldAndNew.second)
2092 errs() <<
"Modulo kernel validation error: [\n";
2093 errs() <<
" [golden] ";
2094 OldAndNew.first.print(
errs());
2096 OldAndNew.second.print(
errs());
2101 errs() <<
"Golden reference kernel:\n";
2103 errs() <<
"New kernel:\n";
2105 errs() << ScheduleDump;
2107 "Modulo kernel validation (-pipeliner-experimental-cg) failed");
2131 if (Exit->pred_size() == 1)
2147 else if (FBB ==
Loop)
2153 Loop->replaceSuccessor(Exit, NewExit);
2154 TII->insertUnconditionalBranch(*NewExit, Exit,
DebugLoc());
2157 Exit->replacePhiUsesWith(
Loop, NewExit);
2165void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &
MBB,
2167 InstrMapTy &LastStage0Insts,
2168 MachineBasicBlock &GreaterThan,
2169 MachineBasicBlock &Otherwise) {
2171 LoopInfo->createRemainingIterationsGreaterCondition(RequiredTC,
MBB,
Cond,
2190void ModuloScheduleExpanderMVE::generatePipelinedLoop() {
2265 assert(LoopInfo &&
"Must be able to analyze loop!");
2269 Check = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2270 Prolog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2271 NewKernel = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2272 Epilog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2273 NewPreheader = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2275 MF.insert(OrigKernel->getIterator(),
Check);
2277 MF.insert(OrigKernel->getIterator(),
Prolog);
2279 MF.insert(OrigKernel->getIterator(), NewKernel);
2281 MF.insert(OrigKernel->getIterator(),
Epilog);
2283 MF.insert(OrigKernel->getIterator(), NewPreheader);
2288 NewPreheader->transferSuccessorsAndUpdatePHIs(OrigPreheader);
2289 TII->insertUnconditionalBranch(*NewPreheader, OrigKernel,
DebugLoc());
2291 OrigPreheader->addSuccessor(
Check);
2296 Check->addSuccessor(NewPreheader);
2298 Prolog->addSuccessor(NewKernel);
2300 NewKernel->addSuccessor(NewKernel);
2301 NewKernel->addSuccessor(
Epilog);
2303 Epilog->addSuccessor(NewPreheader);
2304 Epilog->addSuccessor(NewExit);
2306 InstrMapTy LastStage0Insts;
2307 insertCondBranch(*
Check, Schedule.getNumStages() + NumUnroll - 2,
2308 LastStage0Insts, *
Prolog, *NewPreheader);
2313 generateProlog(PrologVRMap);
2314 generateKernel(PrologVRMap, KernelVRMap, LastStage0Insts);
2315 generateEpilog(KernelVRMap, EpilogVRMap, LastStage0Insts);
2319void ModuloScheduleExpanderMVE::updateInstrUse(
2320 MachineInstr *
MI,
int StageNum,
int PhaseNum,
2321 SmallVectorImpl<ValueMapTy> &CurVRMap,
2322 SmallVectorImpl<ValueMapTy> *PrevVRMap) {
2329 for (MachineOperand &UseMO :
MI->uses()) {
2330 if (!UseMO.isReg() || !UseMO.getReg().isVirtual())
2334 MachineInstr *DefInst = MRI.
getVRegDef(OrigReg);
2335 if (!DefInst || DefInst->
getParent() != OrigKernel)
2339 if (DefInst->
isPHI()) {
2342 getPhiRegs(*DefInst, OrigKernel, InitReg, LoopReg);
2347 unsigned DefStageNum = Schedule.getStage(DefInst);
2348 DiffStage += StageNum - DefStageNum;
2350 if (PhaseNum >= DiffStage && CurVRMap[PhaseNum - DiffStage].
count(DefReg))
2352 NewReg = CurVRMap[PhaseNum - DiffStage][DefReg];
2353 else if (!PrevVRMap)
2362 NewReg = (*PrevVRMap)[PrevVRMap->
size() - (DiffStage - PhaseNum)][DefReg];
2367 UseMO.setReg(NewReg);
2370 MachineInstr *NewCopy =
BuildMI(*OrigKernel,
MI,
MI->getDebugLoc(),
2371 TII->get(TargetOpcode::COPY), SplitReg)
2374 UseMO.setReg(SplitReg);
2392void ModuloScheduleExpanderMVE::generatePhi(
2393 MachineInstr *OrigMI,
int UnrollNum,
2394 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2395 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2396 SmallVectorImpl<ValueMapTy> &PhiVRMap) {
2397 int StageNum = Schedule.getStage(OrigMI);
2399 if (Schedule.getNumStages() - NumUnroll + UnrollNum - 1 >= StageNum)
2400 UsePrologReg =
true;
2401 else if (Schedule.getNumStages() - NumUnroll + UnrollNum == StageNum)
2402 UsePrologReg =
false;
2437 for (MachineOperand &DefMO : OrigMI->
defs()) {
2438 if (!DefMO.isReg() || DefMO.isDead())
2441 auto NewReg = KernelVRMap[UnrollNum].find(OrigReg);
2442 if (NewReg == KernelVRMap[UnrollNum].
end())
2446 int PrologNum = Schedule.getNumStages() - NumUnroll + UnrollNum - 1;
2447 CorrespondReg = PrologVRMap[PrologNum][OrigReg];
2457 MachineInstr *NewPhi =
2459 TII->get(TargetOpcode::PHI), PhiReg)
2465 PhiVRMap[UnrollNum][OrigReg] = PhiReg;
2471 for (
unsigned Idx = 1; Idx < Phi.getNumOperands(); Idx += 2) {
2472 if (Phi.getOperand(Idx).getReg() == OrigReg) {
2473 Phi.getOperand(Idx).setReg(NewReg);
2474 Phi.getOperand(Idx + 1).setMBB(NewMBB);
2481void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(
Register OrigReg,
2488 MachineOperand &
O = *
I;
2489 if (
O.getParent()->getParent() != OrigKernel &&
2490 O.getParent()->getParent() !=
Prolog &&
2491 O.getParent()->getParent() != NewKernel &&
2492 O.getParent()->getParent() !=
Epilog)
2494 if (
O.getParent()->getParent() == OrigKernel &&
O.getParent()->isPHI())
2500 if (!UsesAfterLoop.
empty()) {
2502 MachineInstr *NewPhi =
2504 TII->get(TargetOpcode::PHI), PhiReg)
2511 for (MachineOperand *MO : UsesAfterLoop)
2522 if (!LoopPhis.
empty()) {
2523 for (MachineInstr *Phi : LoopPhis) {
2525 getPhiRegs(*Phi, OrigKernel, InitReg, LoopReg);
2527 MachineInstr *NewPhi =
2528 BuildMI(*NewPreheader, NewPreheader->getFirstNonPHI(),
2529 Phi->getDebugLoc(),
TII->get(TargetOpcode::PHI), NewInit)
2540void ModuloScheduleExpanderMVE::generateProlog(
2541 SmallVectorImpl<ValueMapTy> &PrologVRMap) {
2542 PrologVRMap.
clear();
2543 PrologVRMap.
resize(Schedule.getNumStages() - 1);
2544 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2545 for (
int PrologNum = 0; PrologNum < Schedule.getNumStages() - 1;
2547 for (MachineInstr *
MI : Schedule.getInstructions()) {
2550 int StageNum = Schedule.getStage(
MI);
2551 if (StageNum > PrologNum)
2554 updateInstrDef(NewMI, PrologVRMap[PrologNum],
false);
2555 NewMIMap[NewMI] = {PrologNum, StageNum};
2556 Prolog->push_back(NewMI);
2561 for (
auto I : NewMIMap) {
2562 MachineInstr *
MI =
I.first;
2563 int PrologNum =
I.second.first;
2564 int StageNum =
I.second.second;
2565 updateInstrUse(
MI, StageNum, PrologNum, PrologVRMap,
nullptr);
2569 dbgs() <<
"prolog:\n";
2574void ModuloScheduleExpanderMVE::generateKernel(
2575 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2576 SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) {
2577 KernelVRMap.
clear();
2578 KernelVRMap.
resize(NumUnroll);
2580 PhiVRMap.
resize(NumUnroll);
2581 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2582 for (
int UnrollNum = 0; UnrollNum < NumUnroll; ++UnrollNum) {
2583 for (MachineInstr *
MI : Schedule.getInstructions()) {
2586 int StageNum = Schedule.getStage(
MI);
2588 if (UnrollNum == NumUnroll - 1)
2589 LastStage0Insts[
MI] = NewMI;
2590 updateInstrDef(NewMI, KernelVRMap[UnrollNum],
2591 (UnrollNum == NumUnroll - 1 && StageNum == 0));
2592 generatePhi(
MI, UnrollNum, PrologVRMap, KernelVRMap, PhiVRMap);
2593 NewMIMap[NewMI] = {UnrollNum, StageNum};
2594 NewKernel->push_back(NewMI);
2599 for (
auto I : NewMIMap) {
2600 MachineInstr *
MI =
I.first;
2601 int UnrollNum =
I.second.first;
2602 int StageNum =
I.second.second;
2603 updateInstrUse(
MI, StageNum, UnrollNum, KernelVRMap, &PhiVRMap);
2607 insertCondBranch(*NewKernel, NumUnroll - 1, LastStage0Insts, *NewKernel,
2611 dbgs() <<
"kernel:\n";
2616void ModuloScheduleExpanderMVE::generateEpilog(
2617 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2618 SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) {
2619 EpilogVRMap.
clear();
2620 EpilogVRMap.
resize(Schedule.getNumStages() - 1);
2621 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2622 for (
int EpilogNum = 0; EpilogNum < Schedule.getNumStages() - 1;
2624 for (MachineInstr *
MI : Schedule.getInstructions()) {
2627 int StageNum = Schedule.getStage(
MI);
2628 if (StageNum <= EpilogNum)
2631 updateInstrDef(NewMI, EpilogVRMap[EpilogNum], StageNum - 1 == EpilogNum);
2632 NewMIMap[NewMI] = {EpilogNum, StageNum};
2633 Epilog->push_back(NewMI);
2638 for (
auto I : NewMIMap) {
2639 MachineInstr *
MI =
I.first;
2640 int EpilogNum =
I.second.first;
2641 int StageNum =
I.second.second;
2642 updateInstrUse(
MI, StageNum, EpilogNum, EpilogVRMap, &KernelVRMap);
2649 insertCondBranch(*
Epilog, 0, LastStage0Insts, *NewPreheader, *NewExit);
2652 dbgs() <<
"epilog:\n";
2658void ModuloScheduleExpanderMVE::calcNumUnroll() {
2659 DenseMap<MachineInstr *, unsigned> Inst2Idx;
2661 for (
unsigned I = 0;
I < Schedule.getInstructions().
size(); ++
I)
2662 Inst2Idx[Schedule.getInstructions()[
I]] =
I;
2664 for (MachineInstr *
MI : Schedule.getInstructions()) {
2667 int StageNum = Schedule.getStage(
MI);
2668 for (
const MachineOperand &MO :
MI->uses()) {
2675 int NumUnrollLocal = 1;
2682 NumUnrollLocal += StageNum - Schedule.getStage(
DefMI);
2683 if (Inst2Idx[
MI] <= Inst2Idx[
DefMI])
2685 NumUnroll = std::max(NumUnroll, NumUnrollLocal);
2694void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
2697 for (MachineOperand &MO : NewMI->
all_defs()) {
2704 VRMap[
Reg] = NewReg;
2706 mergeRegUsesAfterPipeline(
Reg, NewReg);
2711 OrigKernel = Schedule.getLoop()->getTopBlock();
2712 OrigPreheader = Schedule.getLoop()->getLoopPreheader();
2713 OrigExit = Schedule.getLoop()->getExitBlock();
2717 generatePipelinedLoop();
2722 if (!L.getExitBlock()) {
2723 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: No single exit block.\n");
2739 if (
Ref.getParent() != BB ||
Ref.isPHI()) {
2740 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A phi result is "
2741 "referenced outside of the loop or by phi.\n");
2750 if (!
Register(LoopVal).isVirtual() ||
2751 MRI.getVRegDef(LoopVal)->getParent() != BB) {
2753 dbgs() <<
"Can not apply MVE expander: A phi source value coming "
2754 "from the loop is not defined in the loop.\n");
2757 if (UsedByPhi.
count(LoopVal)) {
2758 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A value defined in the "
2759 "loop is referenced by two or more phis.\n");
2762 UsedByPhi.
insert(LoopVal);
2799char ModuloScheduleTest::ID = 0;
2802 "Modulo Schedule test pass",
false,
false)
2809 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
2810 for (
auto *L : MLI) {
2811 if (L->getTopBlock() != L->getBottomBlock())
2820 std::pair<StringRef, StringRef> StageAndCycle =
getToken(S,
"_");
2821 std::pair<StringRef, StringRef> StageTokenAndValue =
2822 getToken(StageAndCycle.first,
"-");
2823 std::pair<StringRef, StringRef> CycleTokenAndValue =
2824 getToken(StageAndCycle.second,
"-");
2825 if (StageTokenAndValue.first !=
"Stage" ||
2826 CycleTokenAndValue.first !=
"_Cycle") {
2828 "Bad post-instr symbol syntax: see comment in ModuloScheduleTest");
2832 StageTokenAndValue.second.drop_front().getAsInteger(10, Stage);
2833 CycleTokenAndValue.second.drop_front().getAsInteger(10, Cycle);
2835 dbgs() <<
" Stage=" << Stage <<
", Cycle=" << Cycle <<
"\n";
2838void ModuloScheduleTest::runOnLoop(MachineFunction &MF, MachineLoop &L) {
2839 LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
2840 MachineBasicBlock *BB =
L.getTopBlock();
2841 dbgs() <<
"--- ModuloScheduleTest running on BB#" << BB->
getNumber() <<
"\n";
2843 DenseMap<MachineInstr *, int> Cycle, Stage;
2844 std::vector<MachineInstr *> Instrs;
2845 for (MachineInstr &
MI : *BB) {
2846 if (
MI.isTerminator())
2848 Instrs.push_back(&
MI);
2849 if (MCSymbol *Sym =
MI.getPostInstrSymbol()) {
2850 dbgs() <<
"Parsing post-instr symbol for " <<
MI;
2855 ModuloSchedule MS(MF, &L, std::move(Instrs), std::move(Cycle),
2857 ModuloScheduleExpander MSE(
2871 OS <<
"Stage-" << S.getStage(
MI) <<
"_Cycle-" << S.getCycle(
MI);
2872 MCSymbol *Sym = MF.getContext().getOrCreateSymbol(OS.
str());
2873 MI->setPostInstrSymbol(MF, Sym);
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, RegState Flags={}, 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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
use_iterator use_begin(Register RegNo) const
static use_iterator use_end()
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
iterator_range< use_iterator > use_operands(Register Reg) const
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static LLVM_ABI 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.
LLVM_ABI void cleanup()
Performs final cleanup after expansion.
LLVM_ABI void expand()
Performs the actual expansion.
DenseMap< MachineInstr *, std::pair< Register, int64_t > > InstrChangesTy
LLVM_ABI 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.
LLVM_ABI 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.
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.
LLVM_ABI 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.
LLVM_ABI 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
LLVM_ABI 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.
LLVM_ABI 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
LLVM_ABI void filterInstructions(MachineBasicBlock *MB, int MinStage)
LLVM_ABI 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.
LLVM_ABI void fixupBranches()
Insert branches between prologs, kernel and epilogs.
LLVM_ABI MachineBasicBlock * CreateLCSSAExitingBlock()
Create a poor-man's LCSSA by cloning only the PHIs from the kernel block to a block dominated by all ...
LLVM_ABI void validateAgainstModuloScheduleExpander()
Runs ModuloScheduleExpander and treats it as a golden input to validate aspects of the code generated...
LLVM_ABI 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
LLVM_ABI 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.
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)
bool used(const UsedT *U, size_t I)
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.
LLVM_ABI 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)
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.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.