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;
87 int UseStage = Schedule.getStage(&
UseMI);
89 if (UseStage != -1 && UseStage >= DefStage)
90 Diff = UseStage - DefStage;
92 if (isLoopCarried(*
MI))
97 MaxDiff = std::max(Diff, MaxDiff);
99 RegToStageDiff[Reg] = std::make_pair(MaxDiff, PhiIsSwapped);
103 generatePipelinedLoop();
106void ModuloScheduleExpander::generatePipelinedLoop() {
119 ValueMapTy *VRMap =
new ValueMapTy[(MaxStageCount + 1) * 2];
124 ValueMapTy *VRMapPhi =
new ValueMapTy[(MaxStageCount + 1) * 2];
131 generateProlog(MaxStageCount, KernelBB, VRMap, PrologBBs);
140 unsigned StageNum = Schedule.
getStage(CI);
142 updateInstruction(NewMI,
false, MaxStageCount, StageNum, VRMap);
145 InstrMap[NewMI] = CI;
152 updateInstruction(NewMI,
false, MaxStageCount, 0, VRMap);
155 InstrMap[NewMI] = &
MI;
158 NewKernel = KernelBB;
162 generateExistingPhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap,
163 VRMapPhi, InstrMap, MaxStageCount, MaxStageCount,
false);
164 generatePhis(KernelBB, PrologBBs.
back(), KernelBB, KernelBB, VRMap, VRMapPhi,
165 InstrMap, MaxStageCount, MaxStageCount,
false);
169 SmallVector<MachineBasicBlock *, 4> EpilogBBs;
171 generateEpilog(MaxStageCount, KernelBB, BB, VRMap, VRMapPhi, EpilogBBs,
176 splitLifetimes(KernelBB, EpilogBBs);
179 removeDeadInstructions(KernelBB, EpilogBBs);
182 addBranches(*Preheader, PrologBBs, KernelBB, EpilogBBs, VRMap);
191 LIS.RemoveMachineInstrFromMaps(
I);
193 BB->eraseFromParent();
197void ModuloScheduleExpander::generateProlog(
unsigned LastStage,
200 MBBVectorTy &PrologBBs) {
207 for (
unsigned i = 0; i < LastStage; ++i) {
220 for (
int StageNum = i; StageNum >= 0; --StageNum) {
224 if (Schedule.
getStage(&*BBI) == StageNum) {
228 cloneAndChangeInstr(&*BBI, i, (
unsigned)StageNum);
229 updateInstruction(NewMI,
false, i, (
unsigned)StageNum, VRMap);
232 InstrMap[NewMI] = &*BBI;
236 rewritePhiValues(NewBB, i, VRMap, InstrMap);
238 dbgs() <<
"prolog:\n";
247 unsigned numBranches = TII->removeBranch(*Preheader);
250 TII->insertBranch(*Preheader, PrologBBs[0],
nullptr,
Cond,
DebugLoc());
257void ModuloScheduleExpander::generateEpilog(
259 ValueMapTy *VRMap, ValueMapTy *VRMapPhi, MBBVectorTy &EpilogBBs,
260 MBBVectorTy &PrologBBs) {
263 MachineBasicBlock *
TBB =
nullptr, *FBB =
nullptr;
265 bool checkBranch = TII->analyzeBranch(*KernelBB,
TBB, FBB,
Cond);
266 assert(!checkBranch &&
"generateEpilog must be able to analyze the branch");
271 if (*LoopExitI == KernelBB)
273 assert(LoopExitI != KernelBB->
succ_end() &&
"Expecting a successor");
274 MachineBasicBlock *LoopExitBB = *LoopExitI;
276 MachineBasicBlock *PredBB = KernelBB;
277 MachineBasicBlock *EpilogStart = LoopExitBB;
283 int EpilogStage = LastStage + 1;
284 for (
unsigned i = LastStage; i >= 1; --i, ++EpilogStage) {
285 MachineBasicBlock *NewBB = MF.CreateMachineBasicBlock();
287 MF.insert(BB->getIterator(), NewBB);
291 LIS.insertMBBInMaps(NewBB);
293 if (EpilogStart == LoopExitBB)
298 for (
unsigned StageNum = i; StageNum <= LastStage; ++StageNum) {
299 for (
auto &BBI : *BB) {
302 MachineInstr *
In = &BBI;
303 if ((
unsigned)Schedule.getStage(In) == StageNum) {
306 MachineInstr *NewMI = cloneInstr(In, UINT_MAX, 0);
307 updateInstruction(NewMI, i == 1, EpilogStage, 0, VRMap);
309 LIS.InsertMachineInstrInMaps(*NewMI);
310 InstrMap[NewMI] =
In;
314 generateExistingPhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap,
315 VRMapPhi, InstrMap, LastStage, EpilogStage, i == 1);
316 generatePhis(NewBB, PrologBBs[i - 1], PredBB, KernelBB, VRMap, VRMapPhi,
317 InstrMap, LastStage, EpilogStage, i == 1);
321 dbgs() <<
"epilog:\n";
331 TII->removeBranch(*KernelBB);
332 assert((OrigBB ==
TBB || OrigBB == FBB) &&
333 "Unable to determine looping branch direction");
335 TII->insertBranch(*KernelBB, EpilogStart, KernelBB,
Cond,
DebugLoc());
337 TII->insertBranch(*KernelBB, KernelBB, EpilogStart,
Cond,
DebugLoc());
339 if (EpilogBBs.size() > 0) {
340 MachineBasicBlock *LastEpilogBB = EpilogBBs.back();
342 TII->insertBranch(*LastEpilogBB, LoopExitBB,
nullptr, Cond1,
DebugLoc());
353 if (O.getParent()->getParent() !=
MBB)
362 if (
UseMI.getParent() != BB)
370void ModuloScheduleExpander::generateExistingPhis(
373 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
378 unsigned PrologStage = 0;
379 unsigned PrevStage = 0;
380 bool InKernel = (LastStageNum == CurStageNum);
382 PrologStage = LastStageNum - 1;
383 PrevStage = CurStageNum;
385 PrologStage = LastStageNum - (CurStageNum - LastStageNum);
386 PrevStage = LastStageNum + (CurStageNum - LastStageNum) - 1;
390 BBE = BB->getFirstNonPHI();
402 if (
auto It = VRMap[LastStageNum].
find(LoopVal);
403 It != VRMap[LastStageNum].end())
406 int StageScheduled = Schedule.getStage(&*BBI);
407 int LoopValStage = Schedule.getStage(MRI.getVRegDef(LoopVal));
408 unsigned NumStages = getStagesForReg(Def, CurStageNum);
409 if (NumStages == 0) {
412 Register NewReg = VRMap[PrevStage][LoopVal];
413 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, 0, &*BBI, Def,
415 auto It = VRMap[CurStageNum].find(LoopVal);
416 if (It != VRMap[CurStageNum].
end()) {
418 VRMap[CurStageNum][
Def] =
Reg;
425 unsigned MaxPhis = PrologStage + 2;
426 if (!InKernel && (
int)PrologStage <= LoopValStage)
427 MaxPhis = std::max((
int)MaxPhis - LoopValStage, 1);
428 unsigned NumPhis = std::min(NumStages, MaxPhis);
431 unsigned AccessStage = (LoopValStage != -1) ? LoopValStage : StageScheduled;
438 if (!InKernel && StageScheduled >= LoopValStage && AccessStage == 0 &&
443 if (InKernel && LoopValStage != -1 && StageScheduled > LoopValStage)
444 StageDiff = StageScheduled - LoopValStage;
445 for (
unsigned np = 0; np < NumPhis; ++np) {
449 if (np > PrologStage || StageScheduled >= (
int)LastStageNum)
452 else if (PrologStage >= AccessStage + StageDiff + np &&
453 VRMap[PrologStage - StageDiff - np].
count(LoopVal) != 0)
454 PhiOp1 = VRMap[PrologStage - StageDiff - np][LoopVal];
457 else if (PrologStage >= AccessStage + StageDiff + np) {
461 MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1);
463 while (InstOp1 && InstOp1->
isPHI() && InstOp1->
getParent() == BB) {
464 int PhiStage = Schedule.getStage(InstOp1);
465 if ((
int)(PrologStage - StageDiff - np) < PhiStage + Indirects)
469 InstOp1 = MRI.getVRegDef(PhiOp1);
470 int PhiOpStage = Schedule.getStage(InstOp1);
471 int StageAdj = (PhiOpStage != -1 ? PhiStage - PhiOpStage : 0);
472 if (PhiOpStage != -1 && PrologStage - StageAdj >= Indirects + np) {
473 auto &
M = VRMap[PrologStage - StageAdj - Indirects - np];
474 if (
auto It =
M.find(PhiOp1); It !=
M.end()) {
485 if (MachineInstr *InstOp1 = MRI.getVRegDef(PhiOp1))
489 MachineInstr *PhiInst = MRI.getVRegDef(LoopVal);
490 bool LoopDefIsPhi = PhiInst && PhiInst->
isPHI();
495 int StageDiffAdj = 0;
496 if (LoopValStage != -1 && StageScheduled > LoopValStage)
497 StageDiffAdj = StageScheduled - LoopValStage;
500 if (np == 0 && PrevStage == LastStageNum &&
501 (StageScheduled != 0 || LoopValStage != 0) &&
502 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal))
504 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj, LoopVal);
507 else if (np > 0 && PrevStage == LastStageNum &&
508 getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def))
509 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np + 1, Def);
511 else if (
static_cast<unsigned>(LoopValStage) > PrologStage + 1 &&
512 getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
514 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - StageDiffAdj - np,
518 else if (getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def) &&
519 (!LoopDefIsPhi || (PrevStage != LastStageNum) ||
520 (LoopValStage == StageScheduled)))
521 PhiOp2 = getMapPhiReg(VRMap, VRMapPhi, PrevStage - np, Def);
529 if (
static_cast<int>(PrologStage - np) >= StageScheduled) {
530 int LVNumStages = getStagesForPhi(LoopVal);
531 int StageDiff = (StageScheduled - LoopValStage);
532 LVNumStages -= StageDiff;
534 if (LVNumStages > (
int)np && VRMap[CurStageNum].
count(LoopVal)) {
536 unsigned ReuseStage = CurStageNum;
537 if (isLoopCarried(*PhiInst))
538 ReuseStage -= LVNumStages;
541 if (VRMap[ReuseStage - np].
count(LoopVal)) {
542 NewReg = VRMap[ReuseStage - np][LoopVal];
544 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI,
547 VRMap[CurStageNum - np][
Def] = NewReg;
549 if (VRMap[LastStageNum - np - 1].
count(LoopVal))
550 PhiOp2 = VRMap[LastStageNum - np - 1][LoopVal];
552 if (IsLast && np == NumPhis - 1)
558 if (InKernel && StageDiff > 0 &&
559 VRMap[CurStageNum - StageDiff - np].
count(LoopVal))
560 PhiOp2 = VRMap[CurStageNum - StageDiff - np][LoopVal];
564 NewReg = MRI.createVirtualRegister(RC);
566 MachineInstrBuilder NewPhi =
568 TII->get(TargetOpcode::PHI), NewReg);
571 LIS.InsertMachineInstrInMaps(*NewPhi);
573 InstrMap[NewPhi] = &*BBI;
579 if (InKernel && VRMap[PrevStage - np].
count(LoopVal))
580 PrevReg = VRMap[PrevStage - np][LoopVal];
581 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
584 if (VRMap[CurStageNum - np].
count(Def)) {
586 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, R,
593 if (IsLast && np == NumPhis - 1)
601 VRMap[CurStageNum - np][
Def] = NewReg;
604 while (NumPhis++ < NumStages) {
605 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, NumPhis, &*BBI, Def,
611 if (NumStages == 0 && IsLast) {
612 auto &CurStageMap = VRMap[CurStageNum];
613 auto It = CurStageMap.find(LoopVal);
614 if (It != CurStageMap.end())
623void ModuloScheduleExpander::generatePhis(
626 InstrMapTy &InstrMap,
unsigned LastStageNum,
unsigned CurStageNum,
630 unsigned PrologStage = 0;
631 unsigned PrevStage = 0;
632 unsigned StageDiff = CurStageNum - LastStageNum;
633 bool InKernel = (StageDiff == 0);
635 PrologStage = LastStageNum - 1;
636 PrevStage = CurStageNum;
638 PrologStage = LastStageNum - StageDiff;
639 PrevStage = LastStageNum + StageDiff - 1;
643 BBE = BB->instr_end();
645 for (
unsigned i = 0, e = BBI->getNumOperands(); i != e; ++i) {
646 MachineOperand &MO = BBI->getOperand(i);
650 int StageScheduled = Schedule.getStage(&*BBI);
651 assert(StageScheduled != -1 &&
"Expecting scheduled instruction.");
653 unsigned NumPhis = getStagesForReg(Def, CurStageNum);
657 if (!InKernel && NumPhis == 0 && StageScheduled == 0 &&
660 if (!InKernel && (
unsigned)StageScheduled > PrologStage)
665 PhiOp2 = VRMap[PrevStage][
Def];
666 if (MachineInstr *InstOp2 = MRI.getVRegDef(PhiOp2))
667 if (InstOp2->isPHI() && InstOp2->getParent() == NewBB)
672 if (NumPhis > PrologStage + 1 - StageScheduled)
673 NumPhis = PrologStage + 1 - StageScheduled;
674 for (
unsigned np = 0; np < NumPhis; ++np) {
698 if (np <= PrologStage)
699 PhiOp1 = VRMap[PrologStage - np][
Def];
701 if (PrevStage == LastStageNum && np == 0)
702 PhiOp2 = VRMap[LastStageNum][
Def];
704 PhiOp2 = VRMapPhi[PrevStage - np][
Def];
708 Register NewReg = MRI.createVirtualRegister(RC);
710 MachineInstrBuilder NewPhi =
712 TII->get(TargetOpcode::PHI), NewReg);
715 LIS.InsertMachineInstrInMaps(*NewPhi);
717 InstrMap[NewPhi] = &*BBI;
722 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp1,
724 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, PhiOp2,
728 VRMapPhi[PrevStage - np - 1][
Def] = NewReg;
730 VRMapPhi[CurStageNum - np][
Def] = NewReg;
731 if (np == NumPhis - 1)
732 rewriteScheduledInstr(NewBB, InstrMap, CurStageNum, np, &*BBI, Def,
735 if (IsLast && np == NumPhis - 1)
747 MBBVectorTy &EpilogBBs) {
755 if (
MI->isInlineAsm()) {
759 bool SawStore =
false;
762 if (!
MI->isSafeToMove(SawStore) && !
MI->isPHI()) {
767 for (
const MachineOperand &MO :
MI->all_defs()) {
776 unsigned realUses = 0;
777 for (
const MachineInstr &
UseMI : MRI.use_instructions(reg)) {
780 if (
UseMI.getParent() != BB) {
791 LIS.RemoveMachineInstrFromMaps(*
MI);
792 MI++->eraseFromParent();
801 if (MRI.use_begin(reg) == MRI.use_end()) {
802 LIS.RemoveMachineInstrFromMaps(
MI);
803 MI.eraseFromParent();
819 MBBVectorTy &EpilogBBs) {
820 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
821 for (
auto &
PHI : KernelBB->
phis()) {
826 E = MRI.use_instr_end();
828 if (
I->isPHI() &&
I->getParent() == KernelBB) {
833 MachineInstr *
MI = MRI.getVRegDef(LCDef);
834 if (!
MI ||
MI->getParent() != KernelBB ||
MI->isPHI())
841 if (BBJ.readsRegister(Def,
nullptr)) {
844 SplitReg = MRI.createVirtualRegister(MRI.getRegClass(Def));
845 MachineInstr *newCopy =
847 TII->get(TargetOpcode::COPY), SplitReg)
849 LIS.InsertMachineInstrInMaps(*newCopy);
851 BBJ.substituteRegister(Def, SplitReg, 0, *
TRI);
856 for (
auto &
Epilog : EpilogBBs)
858 if (
I.readsRegister(Def,
nullptr))
859 I.substituteRegister(Def, SplitReg, 0, *
TRI);
870 MBBVectorTy &PrologBBs,
872 MBBVectorTy &EpilogBBs,
874 assert(PrologBBs.size() == EpilogBBs.size() &&
"Prolog/Epilog mismatch");
875 MachineBasicBlock *LastPro = KernelBB;
876 MachineBasicBlock *LastEpi = KernelBB;
880 unsigned MaxIter = PrologBBs.
size() - 1;
881 for (
unsigned i = 0, j = MaxIter; i <= MaxIter; ++i, --
j) {
884 MachineBasicBlock *
Prolog = PrologBBs[
j];
885 MachineBasicBlock *
Epilog = EpilogBBs[i];
888 std::optional<bool> StaticallyGreater =
889 LoopInfo->createTripCountGreaterCondition(j + 1, *
Prolog,
Cond);
890 unsigned numAdded = 0;
891 if (!StaticallyGreater) {
894 }
else if (*StaticallyGreater ==
false) {
896 Prolog->removeSuccessor(LastPro);
899 Epilog->removePHIsIncomingValuesForPredecessor(*LastEpi);
901 if (LastPro != LastEpi) {
902 for (
auto &
MI : *LastEpi)
903 LIS.RemoveMachineInstrFromMaps(
MI);
905 LastEpi->eraseFromParent();
907 if (LastPro == KernelBB) {
908 LoopInfo->disposed(&LIS);
911 for (
auto &
MI : *LastPro)
912 LIS.RemoveMachineInstrFromMaps(
MI);
914 LastPro->eraseFromParent();
917 Epilog->removePHIsIncomingValuesForPredecessor(*
Prolog);
923 I !=
E && numAdded > 0; ++
I, --numAdded)
924 updateInstruction(&*
I,
false, j, 0, VRMap);
928 LoopInfo->setPreheader(PrologBBs[MaxIter]);
929 LoopInfo->adjustTripCount(-(MaxIter + 1));
935bool ModuloScheduleExpander::computeDelta(
MachineInstr &
MI,
unsigned &Delta) {
936 const TargetRegisterInfo *
TRI = MF.getSubtarget().getRegisterInfo();
937 const MachineOperand *BaseOp;
939 bool OffsetIsScalable;
940 if (!TII->getMemOperandWithOffset(
MI, BaseOp,
Offset, OffsetIsScalable,
TRI))
944 if (OffsetIsScalable)
947 if (!BaseOp->
isReg())
954 MachineRegisterInfo &MRI = MF.getRegInfo();
956 MachineInstr *BaseDef = MRI.getVRegDef(BaseReg);
957 if (BaseDef && BaseDef->
isPHI()) {
959 BaseDef = MRI.getVRegDef(BaseReg);
965 if (!TII->getIncrementValue(*BaseDef,
D) &&
D >= 0)
975void ModuloScheduleExpander::updateMemOperands(
MachineInstr &NewMI,
985 for (MachineMemOperand *MMO : NewMI.
memoperands()) {
987 if (MMO->isVolatile() || MMO->isAtomic() ||
988 (MMO->isInvariant() && MMO->isDereferenceable()) ||
989 (!MMO->getValue())) {
994 if (Num != UINT_MAX && computeDelta(OldMI, Delta)) {
995 int64_t AdjOffset = Delta * Num;
997 MF.getMachineMemOperand(MMO, AdjOffset, MMO->getSize()));
999 NewMMOs.
push_back(MF.getMachineMemOperand(
1009 unsigned CurStageNum,
1010 unsigned InstStageNum) {
1011 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1012 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1019MachineInstr *ModuloScheduleExpander::cloneAndChangeInstr(
1020 MachineInstr *OldMI,
unsigned CurStageNum,
unsigned InstStageNum) {
1021 MachineInstr *NewMI = MF.CloneMachineInstr(OldMI);
1022 auto It = InstrChanges.find(OldMI);
1023 if (It != InstrChanges.end()) {
1024 std::pair<Register, int64_t> RegAndOffset = It->second;
1025 unsigned BasePos, OffsetPos;
1026 if (!TII->getBaseAndOffsetPosition(*OldMI, BasePos, OffsetPos))
1029 MachineInstr *LoopDef = findDefInLoop(RegAndOffset.first);
1030 if (Schedule.getStage(LoopDef) > (
signed)InstStageNum)
1031 NewOffset += RegAndOffset.second * (CurStageNum - InstStageNum);
1034 updateMemOperands(*NewMI, *OldMI, CurStageNum - InstStageNum);
1040void ModuloScheduleExpander::updateInstruction(
MachineInstr *NewMI,
1042 unsigned CurStageNum,
1043 unsigned InstrStageNum,
1044 ValueMapTy *VRMap) {
1045 for (MachineOperand &MO : NewMI->
operands()) {
1052 Register NewReg = MRI.createVirtualRegister(RC);
1054 VRMap[CurStageNum][reg] = NewReg;
1057 }
else if (MO.
isUse()) {
1058 MachineInstr *
Def = MRI.getVRegDef(reg);
1060 int DefStageNum = Schedule.getStage(Def);
1061 unsigned StageNum = CurStageNum;
1062 if (DefStageNum != -1 && (
int)InstrStageNum > DefStageNum) {
1064 unsigned StageDiff = (InstrStageNum - DefStageNum);
1066 StageNum -= StageDiff;
1068 if (
auto It = VRMap[StageNum].
find(reg); It != VRMap[StageNum].end())
1078 SmallPtrSet<MachineInstr *, 8> Visited;
1079 MachineInstr *
Def = MRI.getVRegDef(
Reg);
1080 while (
Def->isPHI()) {
1081 if (!Visited.
insert(Def).second)
1083 for (
unsigned i = 1, e =
Def->getNumOperands(); i < e; i += 2)
1084 if (
Def->getOperand(i + 1).getMBB() == BB) {
1085 Def = MRI.getVRegDef(
Def->getOperand(i).getReg());
1093Register ModuloScheduleExpander::getPrevMapVal(
1094 unsigned StageNum,
unsigned PhiStage,
Register LoopVal,
unsigned LoopStage,
1097 if (StageNum > PhiStage) {
1098 MachineInstr *LoopInst = MRI.getVRegDef(LoopVal);
1099 if (PhiStage == LoopStage && VRMap[StageNum - 1].
count(LoopVal))
1101 PrevVal = VRMap[StageNum - 1][LoopVal];
1102 else if (VRMap[StageNum].
count(LoopVal))
1105 PrevVal = VRMap[StageNum][LoopVal];
1109 else if (StageNum == PhiStage + 1)
1112 else if (StageNum > PhiStage + 1 && LoopInst->
getParent() == BB)
1115 getPrevMapVal(StageNum - 1, PhiStage,
getLoopPhiReg(*LoopInst, BB),
1116 LoopStage, VRMap, BB);
1128 InstrMapTy &InstrMap) {
1129 for (
auto &
PHI : BB->phis()) {
1135 unsigned PhiStage = (unsigned)Schedule.getStage(MRI.getVRegDef(PhiDef));
1136 unsigned LoopStage = (unsigned)Schedule.getStage(MRI.getVRegDef(LoopVal));
1137 unsigned NumPhis = getStagesForPhi(PhiDef);
1138 if (NumPhis > StageNum)
1140 for (
unsigned np = 0; np <= NumPhis; ++np) {
1142 getPrevMapVal(StageNum - np, PhiStage, LoopVal, LoopStage, VRMap, BB);
1145 rewriteScheduledInstr(NewBB, InstrMap, StageNum - np, np, &
PHI, PhiDef,
1154void ModuloScheduleExpander::rewriteScheduledInstr(
1158 bool InProlog = (CurStageNum < (unsigned)Schedule.getNumStages() - 1);
1159 int StagePhi = Schedule.getStage(Phi) + PhiNum;
1162 for (MachineOperand &UseOp :
1164 MachineInstr *
UseMI = UseOp.getParent();
1174 assert(OrigInstr != InstrMap.end() &&
"Instruction not scheduled.");
1175 MachineInstr *OrigMI = OrigInstr->second;
1176 int StageSched = Schedule.getStage(OrigMI);
1177 int CycleSched = Schedule.getCycle(OrigMI);
1180 if (StagePhi == StageSched &&
Phi->isPHI()) {
1181 int CyclePhi = Schedule.getCycle(Phi);
1182 if (PrevReg && InProlog)
1183 ReplaceReg = PrevReg;
1184 else if (PrevReg && !isLoopCarried(*Phi) &&
1185 (CyclePhi <= CycleSched || OrigMI->isPHI()))
1186 ReplaceReg = PrevReg;
1188 ReplaceReg = NewReg;
1192 if (!InProlog && StagePhi + 1 == StageSched && !isLoopCarried(*Phi))
1193 ReplaceReg = NewReg;
1194 if (StagePhi > StageSched &&
Phi->isPHI())
1195 ReplaceReg = NewReg;
1196 if (!InProlog && !
Phi->isPHI() && StagePhi < StageSched)
1197 ReplaceReg = NewReg;
1200 MRI.constrainRegClass(ReplaceReg, MRI.getRegClass(OldReg));
1202 UseOp.setReg(ReplaceReg);
1204 Register SplitReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg));
1206 TII->
get(TargetOpcode::COPY), SplitReg)
1208 UseOp.setReg(SplitReg);
1209 LIS.InsertMachineInstrInMaps(*newCopy);
1215bool ModuloScheduleExpander::isLoopCarried(
MachineInstr &Phi) {
1218 int DefCycle = Schedule.getCycle(&Phi);
1219 int DefStage = Schedule.getStage(&Phi);
1224 MachineInstr *
Use = MRI.getVRegDef(LoopVal);
1225 if (!Use ||
Use->isPHI())
1227 int LoopCycle = Schedule.getCycle(Use);
1228 int LoopStage = Schedule.getStage(Use);
1229 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
1252 MI.eraseFromParent();
1254 }
else if (!KeepSingleSrcPhi &&
MI.getNumExplicitOperands() == 3) {
1258 assert(ConstrainRegClass &&
1259 "Expected a valid constrained register class!");
1260 (void)ConstrainRegClass;
1262 MI.getOperand(1).getReg());
1265 MI.eraseFromParent();
1274class KernelRewriter {
1276 MachineBasicBlock *BB;
1277 MachineBasicBlock *PreheaderBB, *ExitBB;
1278 MachineRegisterInfo &MRI;
1279 const TargetInstrInfo *
TII;
1283 DenseMap<const TargetRegisterClass *, Register> Undefs;
1286 DenseMap<std::pair<Register, Register>,
Register> Phis;
1288 DenseMap<Register, Register> UndefPhis;
1302 KernelRewriter(MachineLoop &L, ModuloSchedule &S, MachineBasicBlock *LoopBB,
1303 LiveIntervals *LIS =
nullptr);
1310 : S(S), BB(LoopBB), PreheaderBB(
L.getLoopPreheader()),
1311 ExitBB(
L.getExitBlock()), MRI(BB->
getParent()->getRegInfo()),
1312 TII(BB->
getParent()->getSubtarget().getInstrInfo()), LIS(LIS) {
1314 if (PreheaderBB == BB)
1318void KernelRewriter::rewrite() {
1324 MachineInstr *FirstMI =
nullptr;
1328 if (
MI->getParent())
1329 MI->removeFromParent();
1334 assert(FirstMI &&
"Failed to find first MI in schedule");
1341 (
I++)->eraseFromParent();
1345 for (MachineInstr &
MI : *BB) {
1346 if (
MI.isPHI() ||
MI.isTerminator())
1348 for (MachineOperand &MO :
MI.uses()) {
1355 EliminateDeadPhis(BB, MRI, LIS);
1361 for (
auto MI = BB->getFirstNonPHI();
MI != BB->end(); ++
MI) {
1368 for (MachineOperand &Def :
MI->defs()) {
1370 if (
MI.getParent() != BB) {
1391 int ProducerStage = S.
getStage(Producer);
1392 assert(ConsumerStage != -1 &&
1393 "In-loop consumer should always be scheduled!");
1394 assert(ConsumerStage >= ProducerStage);
1395 unsigned StageDiff = ConsumerStage - ProducerStage;
1397 for (
unsigned I = 0;
I < StageDiff; ++
I)
1407 while (LoopProducer->isPHI() && LoopProducer->getParent() == BB) {
1413 int LoopProducerStage = S.
getStage(LoopProducer);
1415 std::optional<Register> IllegalPhiDefault;
1417 if (LoopProducerStage == -1) {
1419 }
else if (LoopProducerStage > ConsumerStage) {
1425 int LoopProducerCycle = S.
getCycle(LoopProducer);
1428 assert(LoopProducerCycle <= ConsumerCycle);
1429 assert(LoopProducerStage == ConsumerStage + 1);
1436 IllegalPhiDefault = Defaults.
front();
1439 assert(ConsumerStage >= LoopProducerStage);
1440 int StageDiff = ConsumerStage - LoopProducerStage;
1441 if (StageDiff > 0) {
1443 <<
" to " << (Defaults.
size() + StageDiff) <<
"\n");
1448 Defaults.
empty() ? std::optional<Register>()
1454 auto DefaultI = Defaults.
rbegin();
1455 while (DefaultI != Defaults.
rend())
1458 if (IllegalPhiDefault) {
1466 MachineInstr *IllegalPhi =
1468 .
addReg(*IllegalPhiDefault)
1474 S.
setStage(IllegalPhi, LoopProducerStage);
1481Register KernelRewriter::phi(
Register LoopReg, std::optional<Register> InitReg,
1485 auto I = Phis.find({LoopReg, *InitReg});
1486 if (
I != Phis.end())
1489 for (
auto &KV : Phis) {
1490 if (KV.first.first == LoopReg)
1497 auto I = UndefPhis.
find(LoopReg);
1498 if (
I != UndefPhis.
end()) {
1507 Phis.insert({{LoopReg, *InitReg},
R});
1510 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1511 (void)ConstrainRegClass;
1523 assert(ConstrainRegClass &&
"Expected a valid constrained register class!");
1524 (void)ConstrainRegClass;
1527 .
addReg(InitReg ? *InitReg : undef(RC))
1532 UndefPhis[LoopReg] =
R;
1534 Phis[{LoopReg, *InitReg}] =
R;
1547 TII->get(TargetOpcode::IMPLICIT_DEF), R);
1556class KernelOperandInfo {
1557 MachineBasicBlock *BB;
1558 MachineRegisterInfo &MRI;
1560 MachineOperand *Source;
1561 MachineOperand *Target;
1564 KernelOperandInfo(MachineOperand *MO, MachineRegisterInfo &MRI,
1565 const SmallPtrSetImpl<MachineInstr *> &IllegalPhis)
1569 while (isRegInLoop(MO)) {
1571 if (
MI->isFullCopy()) {
1572 MO = &
MI->getOperand(1);
1579 MO = &
MI->getOperand(3);
1584 MO =
MI->getOperand(2).
getMBB() == BB ? &
MI->getOperand(1)
1585 : &
MI->getOperand(3);
1592 return PhiDefaults.
size() ==
Other.PhiDefaults.size();
1595 void print(raw_ostream &OS)
const {
1596 OS <<
"use of " << *
Source <<
": distance(" << PhiDefaults.
size() <<
") in "
1601 bool isRegInLoop(MachineOperand *MO) {
1615 for (
auto I =
BB->begin(), NI = NewBB->
begin(); !
I->isTerminator();
1631 if (Stage == -1 || Stage >= MinStage)
1644 for (
auto &
Sub : Subs)
1645 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1646 *
MRI.getTargetRegisterInfo());
1649 LIS->RemoveMachineInstrFromMaps(*
MI);
1650 MI->eraseFromParent();
1667 auto RC =
MRI.getRegClass(PhiR);
1680 MI.removeFromParent();
1684 BlockMIs.erase({SourceBB, KernelMI});
1694 assert(Def->findRegisterDefOperandIdx(
MI.getOperand(1).getReg(),
1696 MRI.replaceRegWith(
MI.getOperand(0).getReg(),
MI.getOperand(1).getReg());
1697 MI.getOperand(0).setReg(PhiReg);
1701 for (
auto *
P : PhiToDelete)
1702 P->eraseFromParent();
1708 DestBB->
insert(InsertPt, NewMI);
1709 Register OrigR = Phi->getOperand(0).getReg();
1730 if (
Use &&
Use->isPHI() &&
Use->getParent() == SourceBB) {
1745 for (
unsigned I = 0;
I < distance; ++
I) {
1748 unsigned LoopRegIdx = 3, InitRegIdx = 1;
1752 CanonicalUse =
MRI.getVRegDef(CanonicalUseReg);
1754 return CanonicalUseReg;
1765 for (
int I = 0;
I <
Schedule.getNumStages() - 1; ++
I) {
1779 EliminateDeadPhis(ExitingBB,
MRI,
LIS,
true);
1796 for (
int I = 1;
I <=
Schedule.getNumStages() - 1; ++
I) {
1802 EliminateDeadPhis(
B,
MRI,
LIS,
true);
1806 for (
size_t I = 0;
I <
Epilogs.size();
I++) {
1808 for (
size_t J =
I; J <
Epilogs.size(); J++) {
1810 unsigned Stage =
Schedule.getNumStages() - 1 +
I - J;
1812 for (
size_t K = Iteration; K >
I; K--)
1826 for (; PI !=
Prologs.end(); ++PI, ++EI) {
1828 (*PI)->addSuccessor(*EI);
1832 if (
Use &&
Use->getParent() == Pred) {
1834 if (CanonicalUse->
isPHI()) {
1855 for (
auto I =
B->instr_rbegin();
1856 I != std::next(
B->getFirstNonPHI()->getReverseIterator());) {
1863 LIS->RemoveMachineInstrFromMaps(*
MI);
1864 MI->eraseFromParent();
1870 EliminateDeadPhis(
B,
MRI,
LIS);
1871 EliminateDeadPhis(ExitingBB,
MRI,
LIS);
1878 Exit = *std::next(
BB->succ_begin());
1881 MF.insert(std::next(
BB->getIterator()), NewBB);
1885 auto RC =
MRI.getRegClass(
MI.getOperand(0).getReg());
1890 if (
Use.getParent() !=
BB)
1893 Use->substituteRegister(OldR, R, 0,
1894 *
MRI.getTargetRegisterInfo());
1901 BB->replaceSuccessor(Exit, NewBB);
1902 Exit->replacePhiUsesWith(
BB, NewBB);
1907 bool CanAnalyzeBr = !
TII->analyzeBranch(*
BB,
TBB, FBB,
Cond);
1909 assert(CanAnalyzeBr &&
"Must be able to analyze the loop branch!");
1910 TII->removeBranch(*
BB);
1911 TII->insertBranch(*
BB,
TBB == Exit ? NewBB :
TBB, FBB == Exit ? NewBB : FBB,
1913 TII->insertUnconditionalBranch(*NewBB, Exit,
DebugLoc());
1921 unsigned OpIdx =
MI->findRegisterDefOperandIdx(Reg,
nullptr);
1933 R =
MI->getOperand(1).getReg();
1934 MRI.setRegClass(R,
MRI.getRegClass(PhiR));
1935 MRI.replaceRegWith(PhiR, R);
1938 MI->getOperand(0).setReg(PhiR);
1944 if (Stage == -1 ||
LiveStages.count(
MI->getParent()) == 0 ||
1959 for (
auto &
Sub : Subs)
1960 Sub.first->substituteRegister(DefMO.getReg(),
Sub.second, 0,
1961 *
MRI.getTargetRegisterInfo());
1964 LIS->RemoveMachineInstrFromMaps(*
MI);
1965 MI->eraseFromParent();
1970 bool KernelDisposed =
false;
1971 int TC =
Schedule.getNumStages() - 1;
1979 std::optional<bool> StaticallyGreater =
1981 if (!StaticallyGreater) {
1985 }
else if (*StaticallyGreater ==
false) {
1989 Prolog->removeSuccessor(Fallthrough);
1995 KernelDisposed =
true;
2007 if (!KernelDisposed) {
2038 std::string ScheduleDump;
2044 assert(
LIS &&
"Requires LiveIntervals!");
2049 if (!ExpandedKernel) {
2065 for (
auto NI =
BB->getFirstNonPHI(); NI !=
BB->end(); ++NI) {
2067 IllegalPhis.
insert(&*NI);
2073 auto OI = ExpandedKernel->
begin();
2074 auto NI =
BB->begin();
2075 for (; !OI->isTerminator() && !NI->isTerminator(); ++OI, ++NI) {
2076 while (OI->isPHI() || OI->isFullCopy())
2078 while (NI->isPHI() || NI->isFullCopy())
2080 assert(OI->getOpcode() == NI->getOpcode() &&
"Opcodes don't match?!");
2082 for (
auto OOpI = OI->operands_begin(), NOpI = NI->operands_begin();
2083 OOpI != OI->operands_end(); ++OOpI, ++NOpI)
2085 KernelOperandInfo(&*NOpI,
MRI, IllegalPhis));
2089 for (
auto &OldAndNew : KOIs) {
2090 if (OldAndNew.first == OldAndNew.second)
2093 errs() <<
"Modulo kernel validation error: [\n";
2094 errs() <<
" [golden] ";
2095 OldAndNew.first.print(
errs());
2097 OldAndNew.second.print(
errs());
2102 errs() <<
"Golden reference kernel:\n";
2104 errs() <<
"New kernel:\n";
2106 errs() << ScheduleDump;
2108 "Modulo kernel validation (-pipeliner-experimental-cg) failed");
2132 if (Exit->pred_size() == 1)
2148 else if (FBB ==
Loop)
2154 Loop->replaceSuccessor(Exit, NewExit);
2155 TII->insertUnconditionalBranch(*NewExit, Exit,
DebugLoc());
2158 Exit->replacePhiUsesWith(
Loop, NewExit);
2166void ModuloScheduleExpanderMVE::insertCondBranch(MachineBasicBlock &
MBB,
2168 InstrMapTy &LastStage0Insts,
2169 MachineBasicBlock &GreaterThan,
2170 MachineBasicBlock &Otherwise) {
2172 LoopInfo->createRemainingIterationsGreaterCondition(RequiredTC,
MBB,
Cond,
2191void ModuloScheduleExpanderMVE::generatePipelinedLoop() {
2266 assert(LoopInfo &&
"Must be able to analyze loop!");
2270 Check = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2271 Prolog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2272 NewKernel = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2273 Epilog = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2274 NewPreheader = MF.CreateMachineBasicBlock(OrigKernel->getBasicBlock());
2276 MF.insert(OrigKernel->getIterator(),
Check);
2278 MF.insert(OrigKernel->getIterator(),
Prolog);
2280 MF.insert(OrigKernel->getIterator(), NewKernel);
2282 MF.insert(OrigKernel->getIterator(),
Epilog);
2284 MF.insert(OrigKernel->getIterator(), NewPreheader);
2289 NewPreheader->transferSuccessorsAndUpdatePHIs(OrigPreheader);
2290 TII->insertUnconditionalBranch(*NewPreheader, OrigKernel,
DebugLoc());
2292 OrigPreheader->addSuccessor(
Check);
2297 Check->addSuccessor(NewPreheader);
2299 Prolog->addSuccessor(NewKernel);
2301 NewKernel->addSuccessor(NewKernel);
2302 NewKernel->addSuccessor(
Epilog);
2304 Epilog->addSuccessor(NewPreheader);
2305 Epilog->addSuccessor(NewExit);
2307 InstrMapTy LastStage0Insts;
2308 insertCondBranch(*
Check, Schedule.getNumStages() + NumUnroll - 2,
2309 LastStage0Insts, *
Prolog, *NewPreheader);
2314 generateProlog(PrologVRMap);
2315 generateKernel(PrologVRMap, KernelVRMap, LastStage0Insts);
2316 generateEpilog(KernelVRMap, EpilogVRMap, LastStage0Insts);
2320void ModuloScheduleExpanderMVE::updateInstrUse(
2321 MachineInstr *
MI,
int StageNum,
int PhaseNum,
2322 SmallVectorImpl<ValueMapTy> &CurVRMap,
2323 SmallVectorImpl<ValueMapTy> *PrevVRMap) {
2330 for (MachineOperand &UseMO :
MI->uses()) {
2331 if (!UseMO.isReg() || !UseMO.getReg().isVirtual())
2335 MachineInstr *DefInst = MRI.
getVRegDef(OrigReg);
2336 if (!DefInst || DefInst->
getParent() != OrigKernel)
2340 if (DefInst->
isPHI()) {
2343 getPhiRegs(*DefInst, OrigKernel, InitReg, LoopReg);
2348 unsigned DefStageNum = Schedule.getStage(DefInst);
2349 DiffStage += StageNum - DefStageNum;
2351 if (PhaseNum >= DiffStage && CurVRMap[PhaseNum - DiffStage].
count(DefReg))
2353 NewReg = CurVRMap[PhaseNum - DiffStage][DefReg];
2354 else if (!PrevVRMap)
2363 NewReg = (*PrevVRMap)[PrevVRMap->
size() - (DiffStage - PhaseNum)][DefReg];
2368 UseMO.setReg(NewReg);
2371 MachineInstr *NewCopy =
BuildMI(*OrigKernel,
MI,
MI->getDebugLoc(),
2372 TII->get(TargetOpcode::COPY), SplitReg)
2375 UseMO.setReg(SplitReg);
2393void ModuloScheduleExpanderMVE::generatePhi(
2394 MachineInstr *OrigMI,
int UnrollNum,
2395 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2396 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2397 SmallVectorImpl<ValueMapTy> &PhiVRMap) {
2398 int StageNum = Schedule.getStage(OrigMI);
2400 if (Schedule.getNumStages() - NumUnroll + UnrollNum - 1 >= StageNum)
2401 UsePrologReg =
true;
2402 else if (Schedule.getNumStages() - NumUnroll + UnrollNum == StageNum)
2403 UsePrologReg =
false;
2438 for (MachineOperand &DefMO : OrigMI->
defs()) {
2439 if (!DefMO.isReg() || DefMO.isDead())
2442 auto NewReg = KernelVRMap[UnrollNum].find(OrigReg);
2443 if (NewReg == KernelVRMap[UnrollNum].
end())
2447 int PrologNum = Schedule.getNumStages() - NumUnroll + UnrollNum - 1;
2448 CorrespondReg = PrologVRMap[PrologNum][OrigReg];
2458 MachineInstr *NewPhi =
2460 TII->get(TargetOpcode::PHI), PhiReg)
2466 PhiVRMap[UnrollNum][OrigReg] = PhiReg;
2472 for (
unsigned Idx = 1; Idx < Phi.getNumOperands(); Idx += 2) {
2473 if (Phi.getOperand(Idx).getReg() == OrigReg) {
2474 Phi.getOperand(Idx).setReg(NewReg);
2475 Phi.getOperand(Idx + 1).setMBB(NewMBB);
2482void ModuloScheduleExpanderMVE::mergeRegUsesAfterPipeline(
Register OrigReg,
2489 MachineOperand &
O = *
I;
2490 if (
O.getParent()->getParent() != OrigKernel &&
2491 O.getParent()->getParent() !=
Prolog &&
2492 O.getParent()->getParent() != NewKernel &&
2493 O.getParent()->getParent() !=
Epilog)
2495 if (
O.getParent()->getParent() == OrigKernel &&
O.getParent()->isPHI())
2501 if (!UsesAfterLoop.
empty()) {
2503 MachineInstr *NewPhi =
2505 TII->get(TargetOpcode::PHI), PhiReg)
2512 for (MachineOperand *MO : UsesAfterLoop)
2523 if (!LoopPhis.
empty()) {
2524 for (MachineInstr *Phi : LoopPhis) {
2526 getPhiRegs(*Phi, OrigKernel, InitReg, LoopReg);
2528 MachineInstr *NewPhi =
2529 BuildMI(*NewPreheader, NewPreheader->getFirstNonPHI(),
2530 Phi->getDebugLoc(),
TII->get(TargetOpcode::PHI), NewInit)
2541void ModuloScheduleExpanderMVE::generateProlog(
2542 SmallVectorImpl<ValueMapTy> &PrologVRMap) {
2543 PrologVRMap.
clear();
2544 PrologVRMap.
resize(Schedule.getNumStages() - 1);
2545 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2546 for (
int PrologNum = 0; PrologNum < Schedule.getNumStages() - 1;
2548 for (MachineInstr *
MI : Schedule.getInstructions()) {
2551 int StageNum = Schedule.getStage(
MI);
2552 if (StageNum > PrologNum)
2555 updateInstrDef(NewMI, PrologVRMap[PrologNum],
false);
2556 NewMIMap[NewMI] = {PrologNum, StageNum};
2557 Prolog->push_back(NewMI);
2562 for (
auto I : NewMIMap) {
2563 MachineInstr *
MI =
I.first;
2564 int PrologNum =
I.second.first;
2565 int StageNum =
I.second.second;
2566 updateInstrUse(
MI, StageNum, PrologNum, PrologVRMap,
nullptr);
2570 dbgs() <<
"prolog:\n";
2575void ModuloScheduleExpanderMVE::generateKernel(
2576 SmallVectorImpl<ValueMapTy> &PrologVRMap,
2577 SmallVectorImpl<ValueMapTy> &KernelVRMap, InstrMapTy &LastStage0Insts) {
2578 KernelVRMap.
clear();
2579 KernelVRMap.
resize(NumUnroll);
2581 PhiVRMap.
resize(NumUnroll);
2582 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2583 for (
int UnrollNum = 0; UnrollNum < NumUnroll; ++UnrollNum) {
2584 for (MachineInstr *
MI : Schedule.getInstructions()) {
2587 int StageNum = Schedule.getStage(
MI);
2589 if (UnrollNum == NumUnroll - 1)
2590 LastStage0Insts[
MI] = NewMI;
2591 updateInstrDef(NewMI, KernelVRMap[UnrollNum],
2592 (UnrollNum == NumUnroll - 1 && StageNum == 0));
2593 generatePhi(
MI, UnrollNum, PrologVRMap, KernelVRMap, PhiVRMap);
2594 NewMIMap[NewMI] = {UnrollNum, StageNum};
2595 NewKernel->push_back(NewMI);
2600 for (
auto I : NewMIMap) {
2601 MachineInstr *
MI =
I.first;
2602 int UnrollNum =
I.second.first;
2603 int StageNum =
I.second.second;
2604 updateInstrUse(
MI, StageNum, UnrollNum, KernelVRMap, &PhiVRMap);
2608 insertCondBranch(*NewKernel, NumUnroll - 1, LastStage0Insts, *NewKernel,
2612 dbgs() <<
"kernel:\n";
2617void ModuloScheduleExpanderMVE::generateEpilog(
2618 SmallVectorImpl<ValueMapTy> &KernelVRMap,
2619 SmallVectorImpl<ValueMapTy> &EpilogVRMap, InstrMapTy &LastStage0Insts) {
2620 EpilogVRMap.
clear();
2621 EpilogVRMap.
resize(Schedule.getNumStages() - 1);
2622 DenseMap<MachineInstr *, std::pair<int, int>> NewMIMap;
2623 for (
int EpilogNum = 0; EpilogNum < Schedule.getNumStages() - 1;
2625 for (MachineInstr *
MI : Schedule.getInstructions()) {
2628 int StageNum = Schedule.getStage(
MI);
2629 if (StageNum <= EpilogNum)
2632 updateInstrDef(NewMI, EpilogVRMap[EpilogNum], StageNum - 1 == EpilogNum);
2633 NewMIMap[NewMI] = {EpilogNum, StageNum};
2634 Epilog->push_back(NewMI);
2639 for (
auto I : NewMIMap) {
2640 MachineInstr *
MI =
I.first;
2641 int EpilogNum =
I.second.first;
2642 int StageNum =
I.second.second;
2643 updateInstrUse(
MI, StageNum, EpilogNum, EpilogVRMap, &KernelVRMap);
2650 insertCondBranch(*
Epilog, 0, LastStage0Insts, *NewPreheader, *NewExit);
2653 dbgs() <<
"epilog:\n";
2659void ModuloScheduleExpanderMVE::calcNumUnroll() {
2660 DenseMap<MachineInstr *, unsigned> Inst2Idx;
2662 for (
unsigned I = 0;
I < Schedule.getInstructions().
size(); ++
I)
2663 Inst2Idx[Schedule.getInstructions()[
I]] =
I;
2665 for (MachineInstr *
MI : Schedule.getInstructions()) {
2668 int StageNum = Schedule.getStage(
MI);
2669 for (
const MachineOperand &MO :
MI->uses()) {
2676 int NumUnrollLocal = 1;
2683 NumUnrollLocal += StageNum - Schedule.getStage(
DefMI);
2684 if (Inst2Idx[
MI] <= Inst2Idx[
DefMI])
2686 NumUnroll = std::max(NumUnroll, NumUnrollLocal);
2695void ModuloScheduleExpanderMVE::updateInstrDef(MachineInstr *NewMI,
2698 for (MachineOperand &MO : NewMI->
all_defs()) {
2705 VRMap[
Reg] = NewReg;
2707 mergeRegUsesAfterPipeline(
Reg, NewReg);
2712 OrigKernel = Schedule.getLoop()->getTopBlock();
2713 OrigPreheader = Schedule.getLoop()->getLoopPreheader();
2714 OrigExit = Schedule.getLoop()->getExitBlock();
2718 generatePipelinedLoop();
2723 if (!L.getExitBlock()) {
2724 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: No single exit block.\n");
2740 if (
Ref.getParent() != BB ||
Ref.isPHI()) {
2741 LLVM_DEBUG(
dbgs() <<
"Can not apply MVE expander: A phi result is "
2742 "referenced outside of the loop or by phi.\n");
2751 if (!
Register(LoopVal).isVirtual() || MRI.getDefBlock(LoopVal) != 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.
#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)
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()
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 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...
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 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.
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.
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.