23#define DEBUG_TYPE "pipeliner"
28 cl::desc(
"Swap target blocks of a conditional branch for MVE expander"));
37 while (!
MBB->succ_empty()) {
39 MBB->removeSuccessor(
MBB->succ_begin());
59 assert(Phi.isPHI() &&
"Expecting a Phi.");
63 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
64 if (Phi.getOperand(i + 1).getMBB() !=
Loop)
65 InitVal = Phi.getOperand(i).getReg();
67 LoopVal = Phi.getOperand(i).getReg();
69 assert(InitVal && LoopVal &&
"Unexpected Phi structure.");
74 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
75 if (Phi.getOperand(i + 1).getMBB() != LoopBB)
76 return Phi.getOperand(i).getReg();
82 for (
unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
83 if (Phi.getOperand(i + 1).getMBB() == LoopBB)
84 return Phi.getOperand(i).getReg();
89 BB = Schedule.getLoop()->getTopBlock();
90 Preheader = *BB->pred_begin();
92 Preheader = *std::next(BB->pred_begin());
97 int DefStage = Schedule.getStage(
MI);
100 unsigned MaxDiff = 0;
101 bool PhiIsSwapped =
false;
103 int UseStage = Schedule.getStage(&
UseMI);
105 if (UseStage != -1 && UseStage >= DefStage)
106 Diff = UseStage - DefStage;
108 if (isLoopCarried(*
MI))
113 MaxDiff = std::max(Diff, MaxDiff);
115 RegToStageDiff[Reg] = std::make_pair(MaxDiff, PhiIsSwapped);
119 generatePipelinedLoop();
122void ModuloScheduleExpander::generatePipelinedLoop() {
135 ValueMapTy *VRMap =
new ValueMapTy[(MaxStageCount + 1) * 2];
140 ValueMapTy *VRMapPhi =
new ValueMapTy[(MaxStageCount + 1) * 2];
147 generateProlog(MaxStageCount, KernelBB, VRMap, PrologBBs);
156 unsigned StageNum = Schedule.
getStage(CI);
158 updateInstruction(NewMI,
false, MaxStageCount, StageNum, VRMap);
161 InstrMap[NewMI] = CI;
168 updateInstruction(NewMI,
false, MaxStageCount, 0, VRMap);
171 InstrMap[NewMI] = &
MI;
174 NewKernel = KernelBB;
180 for (MachineBasicBlock *Succ : KernelBB->
successors())
185 for (MachineBasicBlock *Succ : KernelBB->
successors()) {
190 MDTU.applyUpdates(Updates);
192 generateExistingPhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap,
193 VRMapPhi, InstrMap, MaxStageCount, MaxStageCount,
false);
194 generatePhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap, VRMapPhi,
195 InstrMap, MaxStageCount, MaxStageCount,
false);
199 SmallVector<MachineBasicBlock *, 4> EpilogBBs;
201 generateEpilog(MaxStageCount, KernelBB, BB, VRMap, VRMapPhi, EpilogBBs,
206 splitLifetimes(KernelBB, EpilogBBs);
209 removeDeadInstructions(KernelBB, EpilogBBs);
212 addBranches(*Preheader, PrologBBs, KernelBB, EpilogBBs, VRMap);
224void ModuloScheduleExpander::generateProlog(
unsigned LastStage,
227 MBBVectorTy &PrologBBs) {
234 for (
unsigned i = 0; i < LastStage; ++i) {
248 for (
int StageNum = i; StageNum >= 0; --StageNum) {
252 if (Schedule.
getStage(&*BBI) == StageNum) {
256 cloneAndChangeInstr(&*BBI, i, (
unsigned)StageNum);
257 updateInstruction(NewMI,
false, i, (
unsigned)StageNum, VRMap);
260 InstrMap[NewMI] = &*BBI;
264 rewritePhiValues(NewBB, i, VRMap, InstrMap);
266 dbgs() <<
"prolog:\n";
275 unsigned numBranches = TII->removeBranch(*Preheader);
278 TII->insertBranch(*Preheader, PrologBBs[0],
nullptr,
Cond,
DebugLoc());
285void ModuloScheduleExpander::generateEpilog(
287 ValueMapTy *VRMap, ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
288 MBBVectorTy &PrologBBs) {
291 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
292 SmallVector<MachineOperand, 4>
Cond;
293 bool checkBranch = TII->analyzeBranch(*KernelBB,
TBB, FBB,
Cond);
294 assert(!checkBranch &&
"generateEpilog must be able to analyze the branch");
299 if (*LoopExitI == KernelBB)
301 assert(LoopExitI != KernelBB->
succ_end() &&
"Expecting a successor");
302 MachineBasicBlock *LoopExitBB = *LoopExitI;
304 MachineBasicBlock *PredBB = KernelBB;
305 MachineBasicBlock *EpilogStart = LoopExitBB;
311 int EpilogStage = LastStage + 1;
312 for (
unsigned i = LastStage; i >= 1; --i, ++EpilogStage) {
313 MachineBasicBlock *NewBB = MF.CreateMachineBasicBlock();
315 MF.insert(BB->getIterator(), NewBB);
319 MDTU.splitCriticalEdge(PredBB, LoopExitBB, NewBB);
320 LIS.insertMBBInMaps(NewBB);
322 if (EpilogStart == LoopExitBB)
327 for (
unsigned StageNum = i; StageNum <= LastStage; ++StageNum) {
328 for (
auto &BBI : *BB) {
331 MachineInstr *
In = &BBI;
332 if ((
unsigned)Schedule.getStage(In) == StageNum) {
335 MachineInstr *NewMI = cloneInstr(In, UINT_MAX, 0);
336 updateInstruction(NewMI, i == 1, EpilogStage, 0, VRMap);
338 LIS.InsertMachineInstrInMaps(*NewMI);
339 InstrMap[NewMI] =
In;
343 generateExistingPhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap,
344 VRMapPhi, InstrMap, LastStage, EpilogStage, i == 1);
345 generatePhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap, VRMapPhi,
346 InstrMap, LastStage, EpilogStage, i == 1);
350 dbgs() <<
"epilog:\n";
360 TII->removeBranch(*KernelBB);
361 assert((OrigBB ==
TBB || OrigBB == FBB) &&
362 "Unable to determine looping branch direction");
364 TII->insertBranch(*KernelBB, EpilogStart, KernelBB,
Cond,
DebugLoc());
366 TII->insertBranch(*KernelBB, KernelBB, EpilogStart,
Cond,
DebugLoc());
368 if (EpilogBBs.size() > 0) {
369 MachineBasicBlock *LastEpilogBB = EpilogBBs.back();
370 SmallVector<MachineOperand, 4> Cond1;
371 TII->insertBranch(*LastEpilogBB, LoopExitBB,
nullptr, Cond1,
DebugLoc());
382 if (O.getParent()->getParent() !=
MBB)
391 if (
UseMI.getParent() != BB)
399void ModuloScheduleExpander::generateExistingPhis(
402 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
407 unsigned PrologStage = 0;
408 unsigned PrevStage = 0;
409 bool InKernel = (LastStageNum == CurStageNum);
411 PrologStage = LastStageNum - 1;
412 PrevStage = CurStageNum;
414 PrologStage = LastStageNum - (CurStageNum - LastStageNum);
415 PrevStage = LastStageNum + (CurStageNum - LastStageNum) - 1;
419 BBE = BB->getFirstNonPHI();
431 if (
auto It = VRMap[LastStageNum].
find(LoopVal);
432 It != VRMap[LastStageNum].end())
435 int StageScheduled = Schedule.getStage(&*BBI);
436 int LoopValStage = Schedule.getStage(MRI.getVRegDef(LoopVal));
437 unsigned NumStages = getStagesForReg(Def, CurStageNum);
438 if (NumStages == 0) {
441 Register NewReg = VRMap[PrevStage][LoopVal];
442 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, 0, &*BBI, Def,
444 auto It = VRMap[CurStageNum].find(LoopVal);
445 if (It != VRMap[CurStageNum].
end()) {
447 VRMap[CurStageNum][
Def] =
Reg;
454 unsigned MaxPhis = PrologStage + 2;
455 if (!InKernel && (
int)PrologStage <= LoopValStage)
456 MaxPhis = std::max((
int)MaxPhis - LoopValStage, 1);
457 unsigned NumPhis = std::min(NumStages, MaxPhis);
460 unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled;
467 if (!InKernel && StageScheduled >= LoopValStage && AccessStage == 0 &&
472 if (InKernel && LoopValStage != -1 && StageScheduled > LoopValStage)
473 StageDiff = StageScheduled - LoopValStage;
474 for (
unsigned np = 0; np < NumPhis; ++np) {
478 if (np > PrologStage || StageScheduled >= (
int)LastStageNum)
481 else if (PrologStage >= AccessStage + StageDiff + np &&
482 VRMap[PrologStage - StageDiff - np].
count(LoopVal) != 0)
483 PhiOp1 = VRMap[PrologStage - StageDiff - np][LoopVal];
486 else if (PrologStage >= AccessStage + StageDiff + np) {
490 MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1);
492 while (InstOp1 && InstOp1->
isPHI() && InstOp1->
getParent() == BB) {
493 int PhiStage = Schedule.getStage(InstOp1);
494 if ((
int)(PrologStage - StageDiff - np) < PhiStage + Indirects)
498 InstOp1 = MRI.getVRegDef(PhiOp1);
499 int PhiOpStage = Schedule.getStage(InstOp1);
500 int StageAdj = (PhiOpStage != -1 ? PhiStage - PhiOpStage : 0);
501 if (PhiOpStage != -1 && PrologStage - StageAdj >= Indirects + np) {
502 auto &
M = VRMap[PrologStage - StageAdj - Indirects - np];
503 if (
auto It =
M.find(PhiOp1); It !=
M.end()) {
514 if (MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1))
518 MachineInstr *PhiInst = MRI.getVRegDef(LoopVal);
519 bool LoopDefIsPhi = PhiInst && PhiInst->
isPHI();
524 int StageDiffAdj = 0;
525 if (LoopValStage != -1 && StageScheduled > LoopValStage)
526 StageDiffAdj = StageScheduled - LoopValStage;
529 if (np == 0 && PrevStage == LastStageNum &&
530 (StageScheduled != 0 || LoopValStage != 0) &&
531 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal))
533 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal);
536 else if (np > 0 && PrevStage == LastStageNum &&
537 getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def))
538 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def);
540 else if (
static_cast<unsigned>(LoopValStage) > PrologStage + 1 &&
541 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
543 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
547 else if (getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def) &&
548 (!LoopDefIsPhi || (PrevStage != LastStageNum) ||
549 (LoopValStage == StageScheduled)))
550 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def);
558 if (
static_cast<int>(PrologStage - np) >= StageScheduled) {
559 int LVNumStages = getStagesForPhi(LoopVal);
560 int StageDiff = (StageScheduled - LoopValStage);
561 LVNumStages -= StageDiff;
563 if (LVNumStages > (
int)np && VRMap[CurStageNum].
count(LoopVal)) {
565 unsigned ReuseStage = CurStageNum;
566 if (isLoopCarried(*PhiInst))
567 ReuseStage -= LVNumStages;
570 if (VRMap[ReuseStage - np].
count(LoopVal)) {
571 NewReg = VRMap[ReuseStage - np][LoopVal];
573 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI,
576 VRMap[CurStageNum - np][
Def] = NewReg;
578 if (VRMap[LastStageNum - np - 1].
count(LoopVal))
579 PhiOp2 = VRMap[LastStageNum - np - 1][LoopVal];
581 if (IsLast && np == NumPhis - 1)
587 if (InKernel && StageDiff > 0 &&
588 VRMap[CurStageNum - StageDiff - np].
count(LoopVal))
589 PhiOp2 = VRMap[CurStageNum - StageDiff - np][LoopVal];
593 NewReg = MRI.createVirtualRegister(RC);
595 MachineInstrBuilder NewPhi =
597 TII->get(TargetOpcode::PHI), NewReg);
600 LIS.InsertMachineInstrInMaps(*NewPhi);
602 InstrMap[NewPhi] = &*BBI;
608 if (InKernel && VRMap[PrevStage - np].
count(LoopVal))
609 PrevReg = VRMap[PrevStage - np][LoopVal];
610 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
613 if (VRMap[CurStageNum - np].
count(Def)) {
615 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, R,
622 if (IsLast && np == NumPhis - 1)
630 VRMap[CurStageNum - np][
Def] = NewReg;
633 while (NumPhis++ < NumStages) {
634 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, NumPhis, &*BBI, Def,
640 if (NumStages == 0 && IsLast) {
641 auto &CurStageMap = VRMap[CurStageNum];
642 auto It = CurStageMap.find(LoopVal);
643 if (It != CurStageMap.end())
652void ModuloScheduleExpander::generatePhis(
655 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
659 unsigned PrologStage = 0;
660 unsigned PrevStage = 0;
661 unsigned StageDiff = CurStageNum - LastStageNum;
662 bool InKernel = (StageDiff == 0);
664 PrologStage = LastStageNum - 1;
665 PrevStage = CurStageNum;
667 PrologStage = LastStageNum - StageDiff;
668 PrevStage = LastStageNum + StageDiff - 1;
672 BBE = BB->instr_end();
674 for (
unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) {
675 MachineOperand &MO = BBI->getOperand(i);
679 int StageScheduled = Schedule.getStage(&*BBI);
680 assert(StageScheduled != -1 &&
"Expecting scheduled instruction.");
682 unsigned NumPhis = getStagesForReg(Def, CurStageNum);
686 if (!InKernel && NumPhis == 0 && StageScheduled == 0 &&
689 if (!InKernel && (
unsigned)StageScheduled > PrologStage)
694 PhiOp2 = VRMap[PrevStage][
Def];
695 if (MachineInstr *InstOp2 = MRI.getVRegDef(PhiOp2))
696 if (InstOp2->isPHI() && InstOp2->getParent() == NewBB)
701 if (NumPhis > PrologStage + 1 - StageScheduled)
702 NumPhis = PrologStage + 1 - StageScheduled;
703 for (
unsigned np = 0; np < NumPhis; ++np) {
727 if (np <= PrologStage)
728 PhiOp1 = VRMap[PrologStage - np][
Def];
730 if (PrevStage == LastStageNum && np == 0)
731 PhiOp2 = VRMap[LastStageNum][
Def];
733 PhiOp2 = VRMapPhi[PrevStage - np][
Def];
737 Register NewReg = MRI.createVirtualRegister(RC);
739 MachineInstrBuilder NewPhi =
741 TII->get(TargetOpcode::PHI), NewReg);
744 LIS.InsertMachineInstrInMaps(*NewPhi);
746 InstrMap[NewPhi] = &*BBI;
751 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp1,
753 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp2,
757 VRMapPhi[PrevStage - np - 1][
Def] = NewReg;
759 VRMapPhi[CurStageNum - np][
Def] = NewReg;
760 if (np == NumPhis - 1)
761 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
764 if (IsLast && np == NumPhis - 1)
776 MBBVectorTy &EpilogBBs) {
784 if (
MI->isInlineAsm()) {
788 bool SawStore =
false;
791 if (!
MI->isSafeToMove(SawStore) && !
MI->isPHI()) {
796 for (
const MachineOperand &MO :
MI->all_defs()) {
805 unsigned realUses = 0;
806 for (
const MachineInstr &
UseMI : MRI.use_instructions(reg)) {
809 if (
UseMI.getParent() != BB) {
820 LIS.RemoveMachineInstrFromMaps(*
MI);
821 MI++->eraseFromParent();
830 if (MRI.use_begin(reg) == MRI.use_end()) {
831 LIS.RemoveMachineInstrFromMaps(
MI);
832 MI.eraseFromParent();
848 MBBVectorTy &EpilogBBs) {
849 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
850 for (
auto &
PHI : KernelBB->
phis()) {
855 E = MRI.use_instr_end();
857 if (
I->isPHI() &&
I->getParent() == KernelBB) {
862 MachineInstr *
MI = MRI.getVRegDef(LCDef);
863 if (!
MI ||
MI->getParent() != KernelBB ||
MI->isPHI())
870 if (BBJ.readsRegister(Def,
nullptr)) {
873 SplitReg = MRI.createVirtualRegister(MRI.getRegClass(Def));
874 MachineInstr *newCopy =
876 TII->get(TargetOpcode::COPY), SplitReg)
878 LIS.InsertMachineInstrInMaps(*newCopy);
880 BBJ.substituteRegister(Def, SplitReg, 0, *
TRI);
885 for (
auto &
Epilog : EpilogBBs)
887 if (
I.readsRegister(Def,
nullptr))
888 I.substituteRegister(Def, SplitReg, 0, *
TRI);
899 MBBVectorTy &PrologBBs,
901 MBBVectorTy &EpilogBBs,
903 assert(PrologBBs.size() == EpilogBBs.size() &&
"Prolog/Epilog mismatch");
904 MachineBasicBlock *LastPro = KernelBB;
905 MachineBasicBlock *LastEpi = KernelBB;
909 unsigned MaxIter = PrologBBs.
size() - 1;
910 for (
unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --
j) {
913 MachineBasicBlock *
Prolog = PrologBBs[
j];
914 MachineBasicBlock *
Epilog = EpilogBBs[i];
916 SmallVector<MachineOperand, 4>
Cond;
917 std::optional<bool> StaticallyGreater =
918 LoopInfo->createTripCountGreaterCondition(j + 1, *
Prolog,
Cond);
919 unsigned numAdded = 0;
920 if (!StaticallyGreater) {
924 }
else if (*StaticallyGreater ==
false) {
926 Prolog->removeSuccessor(LastPro);
932 Epilog->removePHIsIncomingValuesForPredecessor(*LastEpi);
934 if (LastPro == KernelBB) {
935 LoopInfo->disposed(&LIS);
939 if (LastPro != LastEpi)
943 Epilog->removePHIsIncomingValuesForPredecessor(*
Prolog);
949 I !=
E && numAdded > 0; ++
I, --numAdded)
950 updateInstruction(&*
I,
false, j, 0, VRMap);
954 LoopInfo->setPreheader(PrologBBs[MaxIter]);
955 LoopInfo->adjustTripCount(-(MaxIter + 1));
961bool ModuloScheduleExpander::computeDelta(
MachineInstr &
MI,
unsigned &Delta) {
962 const MachineOperand *BaseOp;
964 bool OffsetIsScalable;
965 if (!TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable))
969 if (OffsetIsScalable)
972 if (!BaseOp->
isReg())
979 MachineRegisterInfo &MRI = MF.getRegInfo();
981 MachineInstr *BaseDef = MRI.getVRegDef(BaseReg);
982 if (BaseDef && BaseDef->
isPHI()) {
984 BaseDef = MRI.getVRegDef(BaseReg);
990 if (!TII->getIncrementValue(*BaseDef,
D) &&
D >= 0)
1000void ModuloScheduleExpander::updateMemOperands(
MachineInstr &NewMI,
1010 for (MachineMemOperand *MMO : NewMI.
memoperands()) {
1012 if (MMO->isVolatile() || MMO->isAtomic() ||
1013 (MMO->isInvariant() && MMO->isDereferenceable()) ||
1014 (!MMO->getValue())) {
1019 if (Num != UINT_MAX && computeDelta(OldMI, Delta)) {
1020 int64_t AdjOffset =
static_cast<int64_t
>(Delta) * Num;
1022 MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()));
1024 NewMMOs.
push_back(MF.getMachineMemOperand(
1034 unsigned CurStageNum,
1035 unsigned InstStageNum) {
1036 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1037 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1044MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
1045 MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) {
1046 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1047 auto It = InstrChanges.find(OldMI);
1048 if (It != InstrChanges.end()) {
1049 std::pair<Register, int64_t> RegAndOffset = It->second;
1050 unsigned BasePos, OffsetPos;
1051 if (!TII->getBaseAndOffsetPosition(*OldMI, BasePos, OffsetPos))
1054 MachineInstr *LoopDef = findDefInLoop(RegAndOffset.first);
1055 if (Schedule.getStage(LoopDef) > (
signed)InstStageNum)
1056 NewOffset += RegAndOffset.second * (CurStageNum - InstStageNum);
1059 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1065void ModuloScheduleExpander::updateInstruction(
MachineInstr *NewMI,
1067 unsigned CurStageNum,
1068 unsigned InstrStageNum,
1069 ValueMapTy *VRMap) {
1070 for (MachineOperand &MO : NewMI->
operands()) {
1077 Register NewReg = MRI.createVirtualRegister(RC);
1079 VRMap[CurStageNum][reg] = NewReg;
1082 }
else if (MO.
isUse()) {
1083 MachineInstr *
Def = MRI.getVRegDef(reg);
1085 int DefStageNum = Schedule.getStage(Def);
1086 unsigned StageNum = CurStageNum;
1087 if (DefStageNum != -1 && (
int)InstrStageNum > DefStageNum) {
1089 unsigned StageDiff = (InstrStageNum - DefStageNum);
1091 StageNum -= StageDiff;
1093 if (
auto It = VRMap[StageNum].
find(reg); It != VRMap[StageNum].end())
1103 SmallPtrSet<MachineInstr *, 8> Visited;
1104 MachineInstr *
Def = MRI.getVRegDef(
Reg);
1105 while (
Def->isPHI()) {
1106 if (!Visited.
insert(Def).second)
1108 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2)
1109 if (
Def->getOperand(i + 1).getMBB() == BB) {
1110 Def = MRI.getVRegDef(
Def->getOperand(i).getReg());
1118Register ModuloScheduleExpander::getPrevMapVal(
1119 unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
unsigned LoopStage,
1122 if (StageNum > PhiStage) {
1123 MachineInstr *LoopInst = MRI.getVRegDef(LoopVal);
1124 if (PhiStage == LoopStage && VRMap[StageNum - 1].
count(LoopVal))
1126 PrevVal = VRMap[StageNum - 1][LoopVal];
1127 else if (VRMap[StageNum].
count(LoopVal))
1130 PrevVal = VRMap[StageNum][LoopVal];
1134 else if (StageNum == PhiStage + 1)
1137 else if (StageNum > PhiStage + 1 && LoopInst->
getParent() == BB)
1140 getPrevMapVal(StageNum - 1, PhiStage,
getLoopPhiReg(*LoopInst, BB),
1141 LoopStage, VRMap, BB);
1153 InstrMapTy &InstrMap) {
1154 for (
auto &
PHI : BB->phis()) {
1160 unsigned PhiStage = (unsigned)Schedule.getStage(MRI.getVRegDef(PhiDef));
1161 unsigned LoopStage = (unsigned)Schedule.getStage(MRI.getVRegDef(LoopVal));
1162 unsigned NumPhis = getStagesForPhi(PhiDef);
1163 if (NumPhis > StageNum)
1165 for (
unsigned np = 0; np <= NumPhis; ++np) {
1167 getPrevMapVal(StageNum - np, PhiStage, LoopVal, LoopStage, VRMap, BB);
1170 rewriteScheduledInstr(NewBB, InstrMap, StageNum - np, np, &
PHI, PhiDef,
1179void ModuloScheduleExpander::rewriteScheduledInstr(
1183 bool InProlog = (CurStageNum < (unsigned)Schedule.getNumStages() - 1);
1184 int StagePhi = Schedule.getStage(Phi) + PhiNum;
1187 for (MachineOperand &UseOp :
1189 MachineInstr *
UseMI = UseOp.getParent();
1199 assert(OrigInstr != InstrMap.end() &&
"Instruction not scheduled.");
1200 MachineInstr *OrigMI = OrigInstr->second;
1201 int StageSched = Schedule.getStage(OrigMI);
1202 int CycleSched = Schedule.getCycle(OrigMI);
1205 if (StagePhi == StageSched &&
Phi->isPHI()) {
1206 int CyclePhi = Schedule.getCycle(Phi);
1207 if (PrevReg && InProlog)
1208 ReplaceReg = PrevReg;
1209 else if (PrevReg && !isLoopCarried(*Phi) &&
1210 (CyclePhi <= CycleSched || OrigMI->isPHI()))
1211 ReplaceReg = PrevReg;
1213 ReplaceReg = NewReg;
1217 if (!InProlog && StagePhi + 1 == StageSched && !isLoopCarried(*Phi))
1218 ReplaceReg = NewReg;
1219 if (StagePhi > StageSched &&
Phi->isPHI())
1220 ReplaceReg = NewReg;
1221 if (!InProlog && !
Phi->isPHI() && StagePhi < StageSched)
1222 ReplaceReg = NewReg;
1225 MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg));
1227 UseOp.setReg(ReplaceReg);
1229 Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
1231 TII->
get(TargetOpcode::COPY), SplitReg)
1233 UseOp.setReg(SplitReg);
1234 LIS.InsertMachineInstrInMaps(*newCopy);
1240bool ModuloScheduleExpander::isLoopCarried(
MachineInstr &Phi) {
1243 int DefCycle = Schedule.getCycle(&Phi);
1244 int DefStage = Schedule.getStage(&Phi);
1249 MachineInstr *
Use = MRI.getVRegDef(LoopVal);
1250 if (!Use ||
Use->isPHI())
1252 int LoopCycle = Schedule.getCycle(Use);
1253 int LoopStage = Schedule.getStage(Use);
1254 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
1277 MI.eraseFromParent();
1279 }
else if (!KeepSingleSrcPhi &&
MI.getNumExplicitOperands() == 3) {
1283 assert(ConstrainRegClass &&
1284 "Expected a valid constrained register class!");
1285 (void)ConstrainRegClass;
1287 MI.getOperand(1).getReg());
1290 MI.eraseFromParent();
1299class KernelRewriter {
1301 MachineBasicBlock *BB;
1302 MachineBasicBlock *PreheaderBB, *ExitBB;
1303 MachineRegisterInfo &
MRI;
1304 const TargetInstrInfo *
TII;
1308 DenseMap<const TargetRegisterClass *, Register> Undefs;
1311 DenseMap<std::pair<Register, Register>,
Register> Phis;
1313 DenseMap<Register, Register> UndefPhis;
1327 KernelRewriter(MachineLoop &L, ModuloSchedule &S, MachineBasicBlock *LoopBB,
1328 LiveIntervals *LIS =
nullptr);
1335 : S(S), BB(LoopBB), PreheaderBB(
L.getLoopPreheader()),
1336 ExitBB(
L.getExitBlock()),
MRI(BB->
getParent()->getRegInfo()),
1337 TII(BB->
getParent()->getSubtarget().getInstrInfo()), LIS(LIS) {
1339 if (PreheaderBB == BB)
1343void KernelRewriter::rewrite() {
1349 MachineInstr *FirstMI =
nullptr;
1353 if (
MI->getParent())
1354 MI->removeFromParent();
1359 assert(FirstMI &&
"Failed to find first MI in schedule");
1366 (
I++)->eraseFromParent();
1370 for (MachineInstr &
MI : *BB) {
1371 if (
MI.isPHI() ||
MI.isTerminator())
1373 for (MachineOperand &MO :
MI.uses()) {
1380 EliminateDeadPhis(BB,
MRI, LIS);
1386 for (
auto MI = BB->getFirstNonPHI();
MI != BB->end(); ++
MI) {
1393 for (MachineOperand &Def :
MI->defs()) {
1395 if (
MI.getParent() != BB) {
1416 int ProducerStage = S.
getStage(Producer);
1417 assert(ConsumerStage != -1 &&
1418 "In-loop consumer should always be scheduled!");
1419 assert(ConsumerStage >= ProducerStage);
1420 unsigned StageDiff = ConsumerStage - ProducerStage;
1422 for (
unsigned I = 0;
I < StageDiff; ++
I)
1432 while (LoopProducer->isPHI() && LoopProducer->getParent() == BB) {
1438 int LoopProducerStage = S.
getStage(LoopProducer);
1440 std::optional<Register> IllegalPhiDefault;
1442 if (LoopProducerStage == -1) {
1444 }
else if (LoopProducerStage > ConsumerStage) {
1450 int LoopProducerCycle = S.
getCycle(LoopProducer);
1453 assert(LoopProducerCycle <= ConsumerCycle);
1454 assert(LoopProducerStage == ConsumerStage + 1);
1461 IllegalPhiDefault = Defaults.
front();
1464 assert(ConsumerStage >= LoopProducerStage);
1465 int StageDiff = ConsumerStage - LoopProducerStage;
1466 if (StageDiff > 0) {
1468 <<
" to " << (Defaults.
size() + StageDiff) <<
"\n");
1473 Defaults.
empty() ? std::optional<Register>()
1479 auto DefaultI = Defaults.
rbegin();
1480 while (DefaultI != Defaults.
rend())
1483 if (IllegalPhiDefault) {
1491 MachineInstr *IllegalPhi =
1493 .
addReg(*IllegalPhiDefault)
1499 S.
setStage(IllegalPhi, LoopProducerStage);
1506Register KernelRewriter::phi(
Register LoopReg, std::optional<Register> InitReg,
1510 auto I = Phis.find({LoopReg, *InitReg});
1511 if (
I != Phis.end())
1514 for (
auto &KV : Phis) {
1515 if (KV.first.first == LoopReg)
1522 auto I = UndefPhis.
find(LoopReg);
1523 if (
I != UndefPhis.
end()) {
1532 Phis.insert({{LoopReg, *InitReg},
R});
1535 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1536 (void)ConstrainRegClass;
1548 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1549 (void)ConstrainRegClass;
1552 .
addReg(InitReg ? *InitReg : undef(RC))
1557 UndefPhis[LoopReg] =
R;
1559 Phis[{LoopReg, *InitReg}] =
R;
1572 TII->get(TargetOpcode::IMPLICIT_DEF), R);
1581class KernelOperandInfo {
1582 MachineBasicBlock *BB;
1583 MachineRegisterInfo &
MRI;
1585 MachineOperand *Source;
1586 MachineOperand *Target;
1589 KernelOperandInfo(MachineOperand *MO, MachineRegisterInfo &
MRI,
1590 const SmallPtrSetImpl<MachineInstr *> &IllegalPhis)
1594 while (isRegInLoop(MO)) {
1596 if (
MI->isFullCopy()) {
1597 MO = &
MI->getOperand(1);
1604 MO = &
MI->getOperand(3);
1609 MO =
MI->getOperand(2).
getMBB() == BB ? &
MI->getOperand(1)
1610 : &
MI->getOperand(3);
1617 return PhiDefaults.
size() ==
Other.PhiDefaults.size();
1620 void print(raw_ostream &OS)
const {
1621 OS <<
"use of " << *
Source <<
": distance(" << PhiDefaults.
size() <<
") in "
1626 bool isRegInLoop(MachineOperand *MO) {
1640 for (
auto I =
BB->begin(), NI = NewBB->
begin(); !
I->isTerminator();
1656 if (Stage == -1 || Stage >= MinStage)
1669 for (
auto &
Sub : Subs)
1670 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1671 *
MRI.getTargetRegisterInfo());
1674 LIS->RemoveMachineInstrFromMaps(*
MI);
1675 MI->eraseFromParent();
1692 auto RC =
MRI.getRegClass(PhiR);
1705 MI.removeFromParent();
1709 BlockMIs.erase({SourceBB, KernelMI});
1719 assert(Def->findRegisterDefOperandIdx(
MI.getOperand(1).getReg(),
1721 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
1722 MI.getOperand(0).setReg(PhiReg);
1726 for (
auto *
P : PhiToDelete)
1727 P->eraseFromParent();
1733 DestBB->
insert(InsertPt, NewMI);
1734 Register OrigR = Phi->getOperand(0).getReg();
1755 if (
Use &&
Use->isPHI() &&
Use->getParent() == SourceBB) {
1770 for (
unsigned I = 0;
I < distance; ++
I) {
1773 unsigned LoopRegIdx = 3, InitRegIdx = 1;
1777 CanonicalUse =
MRI.getVRegDef(CanonicalUseReg);
1779 return CanonicalUseReg;
1790 for (
int I = 0;
I <
Schedule.getNumStages() - 1; ++
I) {
1804 EliminateDeadPhis(ExitingBB,
MRI,
LIS,
true);
1821 for (
int I = 1;
I <=
Schedule.getNumStages() - 1; ++
I) {
1827 EliminateDeadPhis(
B,
MRI,
LIS,
true);
1831 for (
size_t I = 0;
I <
Epilogs.size();
I++) {
1833 for (
size_t J =
I; J <
Epilogs.size(); J++) {
1835 unsigned Stage =
Schedule.getNumStages() - 1 +
I - J;
1837 for (
size_t K = Iteration;
K >
I;
K--)
1851 for (; PI !=
Prologs.end(); ++PI, ++EI) {
1853 (*PI)->addSuccessor(*EI);
1858 if (
Use &&
Use->getParent() == Pred) {
1860 if (CanonicalUse->
isPHI()) {
1881 for (
auto I =
B->instr_rbegin();
1882 I != std::next(
B->getFirstNonPHI()->getReverseIterator());) {
1889 LIS->RemoveMachineInstrFromMaps(*
MI);
1890 MI->eraseFromParent();
1896 EliminateDeadPhis(
B,
MRI,
LIS);
1897 EliminateDeadPhis(ExitingBB,
MRI,
LIS);
1904 Exit = *std::next(
BB->succ_begin());
1907 MF.insert(std::next(
BB->getIterator()), NewBB);
1911 auto RC =
MRI.getRegClass(
MI.getOperand(0).getReg());
1916 if (
Use.getParent() !=
BB)
1919 Use->substituteRegister(OldR, R, 0,
1920 *
MRI.getTargetRegisterInfo());
1927 BB->replaceSuccessor(Exit, NewBB);
1928 Exit->replacePhiUsesWith(
BB, NewBB);
1930 MDTU.splitCriticalEdge(
BB, Exit, NewBB);
1934 bool CanAnalyzeBr = !
TII->analyzeBranch(*
BB,
TBB, FBB,
Cond);
1936 assert(CanAnalyzeBr &&
"Must be able to analyze the loop branch!");
1937 TII->removeBranch(*
BB);
1938 TII->insertBranch(*
BB,
TBB == Exit ? NewBB :
TBB, FBB == Exit ? NewBB : FBB,
1940 TII->insertUnconditionalBranch(*NewBB, Exit,
DebugLoc());
1948 unsigned OpIdx =
MI->findRegisterDefOperandIdx(Reg,
nullptr);
1960 R =
MI->getOperand(1).getReg();
1961 MRI.setRegClass(R,
MRI.getRegClass(PhiR));
1962 MRI.replaceRegWith(PhiR, R);
1965 MI->getOperand(0).setReg(PhiR);
1971 if (Stage == -1 ||
LiveStages.count(
MI->getParent()) == 0 ||
1986 for (
auto &
Sub : Subs)
1987 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1988 *
MRI.getTargetRegisterInfo());
1991 LIS->RemoveMachineInstrFromMaps(*
MI);
1992 MI->eraseFromParent();
1997 bool KernelDisposed =
false;
1998 int TC =
Schedule.getNumStages() - 1;
2006 std::optional<bool> StaticallyGreater =
2008 if (!StaticallyGreater) {
2012 }
else if (*StaticallyGreater ==
false) {
2016 Prolog->removeSuccessor(Fallthrough);
2023 KernelDisposed =
true;
2036 if (!KernelDisposed) {
2067 std::string ScheduleDump;
2073 assert(
LIS &&
"Requires LiveIntervals!");
2076 MDTU.hasDomTree() ? &
MDTU.getDomTree() :
nullptr);
2079 if (!ExpandedKernel) {
2096 for (
auto NI =
BB->getFirstNonPHI(); NI !=
BB->end(); ++NI) {
2098 IllegalPhis.
insert(&*NI);
2104 auto OI = ExpandedKernel->
begin();
2105 auto NI =
BB->begin();
2106 for (; !OI->isTerminator() && !NI->isTerminator(); ++OI, ++NI) {
2107 while (OI->isPHI() || OI->isFullCopy())
2109 while (NI->isPHI() || NI->isFullCopy())
2111 assert(OI->getOpcode() == NI->getOpcode() &&
"Opcodes don't match?!");
2113 for (
auto OOpI = OI->operands_begin(), NOpI = NI->operands_begin();
2114 OOpI != OI->operands_end(); ++OOpI, ++NOpI)
2116 KernelOperandInfo(&*NOpI,
MRI, IllegalPhis));
2120 for (
auto &OldAndNew : KOIs) {
2121 if (OldAndNew.first == OldAndNew.second)
2124 errs() <<
"Modulo kernel validation error: [\n";
2125 errs() <<
" [golden] ";
2126 OldAndNew.first.print(
errs());
2128 OldAndNew.second.print(
errs());
2133 errs() <<
"Golden reference kernel:\n";
2135 errs() <<
"New kernel:\n";
2137 errs() << ScheduleDump;
2139 "Modulo kernel validation (-pipeliner-experimental-cg) failed");
2165 if (Exit->pred_size() == 1)
2181 else if (FBB ==
Loop)
2187 Loop->replaceSuccessor(Exit, NewExit);
2188 TII->insertUnconditionalBranch(*NewExit, Exit,
DebugLoc());
2192 Exit->replacePhiUsesWith(
Loop, NewExit);
2200void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &
MBB,
2202 InstrMapTy &LastStage0Insts,
2203 MachineBasicBlock &GreaterThan,
2204 MachineBasicBlock &Otherwise) {
2205 SmallVector<MachineOperand, 4>
Cond;
2206 LoopInfo->createRemainingIterationsGreaterCondition(RequiredTC,
MBB,
Cond,
2225void ModuloScheduleExpanderMVE::generatePipelinedLoop() {
2300 assert(LoopInfo &&
"Must be able to analyze loop!");
2304 Check = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2305 Prolog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2306 NewKernel = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2307 Epilog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2308 NewPreheader = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2310 MF.insert(OrigKernel->getIterator(),
Check);
2312 MF.insert(OrigKernel->getIterator(),
Prolog);
2314 MF.insert(OrigKernel->getIterator(), NewKernel);
2316 MF.insert(OrigKernel->getIterator(),
Epilog);
2318 MF.insert(OrigKernel->getIterator(), NewPreheader);
2323 NewPreheader->transferSuccessorsAndUpdatePHIs(OrigPreheader);
2324 TII->insertUnconditionalBranch(*NewPreheader, OrigKernel,
DebugLoc());
2326 OrigPreheader->addSuccessor(
Check);
2331 Check->addSuccessor(NewPreheader);
2333 Prolog->addSuccessor(NewKernel);
2335 NewKernel->addSuccessor(NewKernel);
2336 NewKernel->addSuccessor(
Epilog);
2338 Epilog->addSuccessor(NewPreheader);
2339 Epilog->addSuccessor(NewExit);
2342 {{MachineDominatorTree::Insert, NewPreheader, OrigKernel},
2343 {MachineDominatorTree::Insert, OrigPreheader,
Check},
2345 {MachineDominatorTree::Insert,
Check, NewPreheader},
2346 {MachineDominatorTree::Insert,
Prolog, NewKernel},
2347 {MachineDominatorTree::Insert, NewKernel, NewKernel},
2348 {MachineDominatorTree::Insert, NewKernel,
Epilog},
2349 {MachineDominatorTree::Insert,
Epilog, NewPreheader},
2350 {MachineDominatorTree::Insert,
Epilog, NewExit},
2351 {MachineDominatorTree::Delete, OrigPreheader, OrigKernel}});
2353 InstrMapTy LastStage0Insts;
2354 insertCondBranch(*
Check, Schedule.getNumStages() + NumUnroll - 2,
2355 LastStage0Insts, *
Prolog, *NewPreheader);
2360 generateProlog(PrologVRMap);
2361 generateKernel(PrologVRMap, KernelVRMap, LastStage0Insts);
2362 generateEpilog(KernelVRMap, EpilogVRMap, LastStage0Insts);
2366void ModuloScheduleExpanderMVE::updateInstrUse(
2367 MachineInstr *
MI,
int StageNum,
int PhaseNum,
2368 SmallVectorImpl<ValueMapTy> &CurVRMap,
2369 SmallVectorImpl<ValueMapTy> *PrevVRMap) {
2376 for (MachineOperand &UseMO :
MI->uses()) {
2377 if (!UseMO.isReg() || !UseMO.getReg().isVirtual())
2382 if (!DefInst || DefInst->
getParent() != OrigKernel)
2386 if (DefInst->
isPHI()) {
2389 getPhiRegs(*DefInst, OrigKernel, InitReg, LoopReg);
2394 unsigned DefStageNum = Schedule.getStage(DefInst);
2395 DiffStage += StageNum - DefStageNum;
2397 if (PhaseNum >= DiffStage && CurVRMap[PhaseNum - DiffStage].
count(DefReg))
2399 NewReg = CurVRMap[PhaseNum - DiffStage][DefReg];
2400 else if (!PrevVRMap)
2409 NewReg = (*PrevVRMap)[PrevVRMap->
size() - (DiffStage - PhaseNum)][DefReg];
2414 UseMO.setReg(NewReg);
2417 MachineInstr *NewCopy =
BuildMI(*OrigKernel,
MI,
MI->getDebugLoc(),
2418 TII->get(TargetOpcode::COPY), SplitReg)
2421 UseMO.setReg(SplitReg);
2439void ModuloScheduleExpanderMVE::generatePhi(
2440 MachineInstr *OrigMI,
int UnrollNum,
2441 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2442 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2443 SmallVectorImpl<ValueMapTy> &PhiVRMap) {
2444 int StageNum = Schedule.getStage(OrigMI);
2446 if (Schedule.getNumStages() - NumUnroll + UnrollNum - 1 >= StageNum)
2447 UsePrologReg =
true;
2448 else if (Schedule.getNumStages() - NumUnroll + UnrollNum == StageNum)
2449 UsePrologReg =
false;
2484 for (MachineOperand &DefMO : OrigMI->
defs()) {
2485 if (!DefMO.isReg() || DefMO.isDead())
2488 auto NewReg = KernelVRMap[UnrollNum].find(OrigReg);
2489 if (NewReg == KernelVRMap[UnrollNum].
end())
2493 int PrologNum = Schedule.getNumStages() - NumUnroll + UnrollNum - 1;
2494 CorrespondReg = PrologVRMap[PrologNum][OrigReg];
2504 MachineInstr *NewPhi =
2506 TII->get(TargetOpcode::PHI), PhiReg)
2512 PhiVRMap[UnrollNum][OrigReg] = PhiReg;
2518 for (
unsigned Idx = 1; Idx < Phi.getNumOperands(); Idx += 2) {
2519 if (Phi.getOperand(Idx).getReg() == OrigReg) {
2520 Phi.getOperand(Idx).setReg(NewReg);
2521 Phi.getOperand(Idx + 1).setMBB(NewMBB);
2528void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(
Register OrigReg,
2535 MachineOperand &
O = *
I;
2536 if (
O.getParent()->getParent() != OrigKernel &&
2537 O.getParent()->getParent() !=
Prolog &&
2538 O.getParent()->getParent() != NewKernel &&
2539 O.getParent()->getParent() !=
Epilog)
2541 if (
O.getParent()->getParent() == OrigKernel &&
O.getParent()->isPHI())
2547 if (!UsesAfterLoop.
empty()) {
2549 MachineInstr *NewPhi =
2551 TII->get(TargetOpcode::PHI), PhiReg)
2558 for (MachineOperand *MO : UsesAfterLoop)
2569 if (!LoopPhis.
empty()) {
2570 for (MachineInstr *Phi : LoopPhis) {
2572 getPhiRegs(*Phi, OrigKernel, InitReg, LoopReg);
2574 MachineInstr *NewPhi =
2575 BuildMI(*NewPreheader, NewPreheader->getFirstNonPHI(),
2576 Phi->getDebugLoc(),
TII->get(TargetOpcode::PHI), NewInit)
2587void ModuloScheduleExpanderMVE::generateProlog(
2588 SmallVectorImpl<ValueMapTy> &PrologVRMap) {
2589 PrologVRMap.
clear();
2590 PrologVRMap.
resize(Schedule.getNumStages() - 1);
2591 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2592 for (
int PrologNum = 0; PrologNum < Schedule.getNumStages() - 1;
2594 for (MachineInstr *
MI : Schedule.getInstructions()) {
2597 int StageNum = Schedule.getStage(
MI);
2598 if (StageNum > PrologNum)
2601 updateInstrDef(NewMI, PrologVRMap[PrologNum],
false);
2602 NewMIMap[NewMI] = {PrologNum, StageNum};
2603 Prolog->push_back(NewMI);
2608 for (
auto I : NewMIMap) {
2609 MachineInstr *
MI =
I.first;
2610 int PrologNum =
I.second.first;
2611 int StageNum =
I.second.second;
2612 updateInstrUse(
MI, StageNum, PrologNum, PrologVRMap,
nullptr);
2616 dbgs() <<
"prolog:\n";
2621void ModuloScheduleExpanderMVE::generateKernel(
2622 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2623 SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) {
2624 KernelVRMap.
clear();
2625 KernelVRMap.
resize(NumUnroll);
2627 PhiVRMap.
resize(NumUnroll);
2628 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2629 for (
int UnrollNum = 0; UnrollNum < NumUnroll; ++UnrollNum) {
2630 for (MachineInstr *
MI : Schedule.getInstructions()) {
2633 int StageNum = Schedule.getStage(
MI);
2635 if (UnrollNum == NumUnroll - 1)
2636 LastStage0Insts[
MI] = NewMI;
2637 updateInstrDef(NewMI, KernelVRMap[UnrollNum],
2638 (UnrollNum == NumUnroll - 1 && StageNum == 0));
2639 generatePhi(
MI, UnrollNum, PrologVRMap, KernelVRMap, PhiVRMap);
2640 NewMIMap[NewMI] = {UnrollNum, StageNum};
2641 NewKernel->push_back(NewMI);
2646 for (
auto I : NewMIMap) {
2647 MachineInstr *
MI =
I.first;
2648 int UnrollNum =
I.second.first;
2649 int StageNum =
I.second.second;
2650 updateInstrUse(
MI, StageNum, UnrollNum, KernelVRMap, &PhiVRMap);
2654 insertCondBranch(*NewKernel, NumUnroll - 1, LastStage0Insts, *NewKernel,
2658 dbgs() <<
"kernel:\n";
2663void ModuloScheduleExpanderMVE::generateEpilog(
2664 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2665 SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) {
2666 EpilogVRMap.
clear();
2667 EpilogVRMap.
resize(Schedule.getNumStages() - 1);
2668 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2669 for (
int EpilogNum = 0; EpilogNum < Schedule.getNumStages() - 1;
2671 for (MachineInstr *
MI : Schedule.getInstructions()) {
2674 int StageNum = Schedule.getStage(
MI);
2675 if (StageNum <= EpilogNum)
2678 updateInstrDef(NewMI, EpilogVRMap[EpilogNum], StageNum - 1 == EpilogNum);
2679 NewMIMap[NewMI] = {EpilogNum, StageNum};
2680 Epilog->push_back(NewMI);
2685 for (
auto I : NewMIMap) {
2686 MachineInstr *
MI =
I.first;
2687 int EpilogNum =
I.second.first;
2688 int StageNum =
I.second.second;
2689 updateInstrUse(
MI, StageNum, EpilogNum, EpilogVRMap, &KernelVRMap);
2696 insertCondBranch(*
Epilog, 0, LastStage0Insts, *NewPreheader, *NewExit);
2699 dbgs() <<
"epilog:\n";
2705void ModuloScheduleExpanderMVE::calcNumUnroll() {
2706 DenseMap<MachineInstr *, unsigned> Inst2Idx;
2708 for (
unsigned I = 0;
I < Schedule.getInstructions().
size(); ++
I)
2709 Inst2Idx[Schedule.getInstructions()[
I]] =
I;
2711 for (MachineInstr *
MI : Schedule.getInstructions()) {
2714 int StageNum = Schedule.getStage(
MI);
2715 for (
const MachineOperand &MO :
MI->uses()) {
2722 int NumUnrollLocal = 1;
2729 NumUnrollLocal += StageNum - Schedule.getStage(
DefMI);
2730 if (Inst2Idx[
MI] <= Inst2Idx[
DefMI])
2732 NumUnroll = std::max(NumUnroll, NumUnrollLocal);
2741void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
2744 for (MachineOperand &MO : NewMI->
all_defs()) {
2751 VRMap[
Reg] = NewReg;
2753 mergeRegUsesAfterPipeline(
Reg, NewReg);
2758 OrigKernel = Schedule.getLoop()->getTopBlock();
2759 OrigPreheader = Schedule.getLoop()->getLoopPreheader();
2760 OrigExit = Schedule.getLoop()->getExitBlock();
2764 generatePipelinedLoop();
2769 if (!L.getExitBlock()) {
2770 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: No single exit block.\n");
2786 if (
Ref.getParent() != BB ||
Ref.isPHI()) {
2787 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A phi result is "
2788 "referenced outside of the loop or by phi.\n");
2797 if (!
Register(LoopVal).isVirtual() || MRI.getDefBlock(LoopVal) != BB) {
2799 dbgs() <<
"Can not apply MVE expander: A phi source value coming "
2800 "from the loop is not defined in the loop.\n");
2803 if (UsedByPhi.
count(LoopVal)) {
2804 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A value defined in the "
2805 "loop is referenced by two or more phis.\n");
2808 UsedByPhi.
insert(LoopVal);
2845char ModuloScheduleTest::ID = 0;
2848 "Modulo Schedule test pass",
false,
false)
2855 MachineLoopInfo &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
2856 for (
auto *L : MLI) {
2857 if (L->getTopBlock() != L->getBottomBlock())
2866 std::pair<StringRef, StringRef> StageAndCycle =
getToken(S,
"_");
2867 std::pair<StringRef, StringRef> StageTokenAndValue =
2868 getToken(StageAndCycle.first,
"-");
2869 std::pair<StringRef, StringRef> CycleTokenAndValue =
2870 getToken(StageAndCycle.second,
"-");
2871 if (StageTokenAndValue.first !=
"Stage" ||
2872 CycleTokenAndValue.first !=
"_Cycle") {
2874 "Bad post-instr symbol syntax: see comment in ModuloScheduleTest");
2878 StageTokenAndValue.second.drop_front().getAsInteger(10, Stage);
2879 CycleTokenAndValue.second.drop_front().getAsInteger(10, Cycle);
2881 dbgs() <<
" Stage=" << Stage <<
", Cycle=" << Cycle <<
"\n";
2884void ModuloScheduleTest::runOnLoop(
MachineFunction &MF, MachineLoop &L) {
2885 LiveIntervals &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
2886 MachineBasicBlock *BB =
L.getTopBlock();
2887 dbgs() <<
"--- ModuloScheduleTest running on BB#" << BB->
getNumber() <<
"\n";
2889 DenseMap<MachineInstr *, int> Cycle, Stage;
2890 std::vector<MachineInstr *> Instrs;
2891 for (MachineInstr &
MI : *BB) {
2892 if (
MI.isTerminator())
2894 Instrs.push_back(&
MI);
2895 if (MCSymbol *Sym =
MI.getPostInstrSymbol()) {
2896 dbgs() <<
"Parsing post-instr symbol for " <<
MI;
2901 ModuloSchedule MS(MF, &L, std::move(Instrs), std::move(Cycle),
2903 ModuloScheduleExpander MSE(
2917 OS <<
"Stage-" << S.getStage(
MI) <<
"_Cycle-" << S.getCycle(
MI);
2918 MCSymbol *Sym = MF.getContext().getOrCreateSymbol(OS.
str());
2919 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 Register getLoopPhiReg(const MachineInstr &Phi, const MachineBasicBlock *LoopBB)
Return the Phi register value that comes the loop block.
static void getPhiRegs(const MachineInstr &Phi, const MachineBasicBlock *Loop, Register &InitVal, Register &LoopVal)
Return the register values for the operands of a Phi instruction.
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 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.
static MachineBasicBlock * createDedicatedExit(MachineBasicBlock *Loop, MachineBasicBlock *Exit, LiveIntervals &LIS, MachineDomTreeUpdater &MDTU)
Create a dedicated exit for Loop.
static void eraseBlock(MachineBasicBlock *MBB, LiveIntervals &LIS, MachineDomTreeUpdater &MDTU)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
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.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
void splitCriticalEdge(BasicBlockT *FromBB, BasicBlockT *ToBB, BasicBlockT *NewBB)
Apply updates that the critical edge (FromBB, ToBB) has been split with NewBB.
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)
Adds an empty block MBB to the SlotIndexes and regmask maps.
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()
iterator_range< succ_iterator > successors()
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
LLVM_ABI void deleteBB(MachineBasicBlock *DelBB)
Delete DelBB.
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 LLVM_READONLY 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...
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 LLVM_READONLY 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.
MachineDomTreeUpdater MDTU
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.
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.
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.
LLVM_ABI MachineBasicBlock * PeelSingleBlockLoop(LoopPeelDirection Direction, MachineBasicBlock *Loop, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, MachineDomTreeUpdater *MDTU=nullptr)
Peels a single block loop.
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.