63 #define DEBUG_TYPE "regalloc" 65 STATISTIC(numJoins ,
"Number of interval joins performed");
66 STATISTIC(numCrossRCs ,
"Number of cross class joins performed");
67 STATISTIC(numCommutes ,
"Number of instruction commuting performed");
68 STATISTIC(numExtends ,
"Number of copies extended");
69 STATISTIC(NumReMats ,
"Number of instructions re-materialized");
70 STATISTIC(NumInflated ,
"Number of register classes inflated");
71 STATISTIC(NumLaneConflicts,
"Number of dead lane conflicts tested");
72 STATISTIC(NumLaneResolves,
"Number of dead lane conflicts resolved");
73 STATISTIC(NumShrinkToUses,
"Number of shrinkToUses called");
76 cl::desc(
"Coalesce copies (default=true)"),
91 cl::desc(
"Coalesce copies that span blocks (default=subtarget)"),
96 cl::desc(
"Verify machine instrs before and after register coalescing"),
101 cl::desc(
"During rematerialization for a copy, if the def instruction has " 102 "many other copy uses to be rematerialized, delay the multiple " 103 "separate live interval update work and do them all at once after " 104 "all those rematerialization are done. It will save a lot of " 127 bool ShrinkMainRange;
131 bool JoinGlobalCopies;
157 void eliminateDeadDefs();
163 void coalesceLocals();
166 void joinAllIntervals();
181 void lateLiveIntervalUpdate();
251 void updateRegDefsUses(
unsigned SrcReg,
unsigned DstReg,
unsigned SubIdx);
316 void releaseMemory()
override;
332 "Simple Register Coalescing",
false,
false)
341 unsigned &Src,
unsigned &Dst,
342 unsigned &SrcSub,
unsigned &DstSub) {
344 Dst = MI->getOperand(0).getReg();
345 DstSub = MI->getOperand(0).getSubReg();
346 Src = MI->getOperand(1).getReg();
347 SrcSub = MI->getOperand(1).getSubReg();
348 }
else if (MI->isSubregToReg()) {
349 Dst = MI->getOperand(0).getReg();
350 DstSub = tri.composeSubRegIndices(MI->getOperand(0).getSubReg(),
351 MI->getOperand(3).getImm());
352 Src = MI->getOperand(2).getReg();
353 SrcSub = MI->getOperand(2).getSubReg();
368 for (
const auto &MI : *MBB) {
379 Flipped = CrossClass =
false;
381 unsigned Src, Dst, SrcSub, DstSub;
382 if (!
isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
384 Partial = SrcSub || DstSub;
401 if (!Dst)
return false;
408 if (!Dst)
return false;
418 if (SrcSub && DstSub) {
420 if (Src == Dst && SrcSub != DstSub)
446 if (DstIdx && !SrcIdx) {
452 CrossClass = NewRC != DstRC || NewRC != SrcRC;
457 "Cannot have a physical SubIdx");
475 unsigned Src, Dst, SrcSub, DstSub;
476 if (!
isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
483 }
else if (Src != SrcReg) {
491 assert(!DstIdx && !SrcIdx &&
"Inconsistent CoalescerPair state.");
497 return DstReg == Dst;
499 return TRI.
getSubReg(DstReg, SrcSub) == Dst;
510 void RegisterCoalescer::getAnalysisUsage(
AnalysisUsage &AU)
const {
522 void RegisterCoalescer::eliminateDeadDefs() {
528 void RegisterCoalescer::LRE_WillEraseInstruction(
MachineInstr *MI) {
536 assert(!CP.
isPhys() &&
"This doesn't work for physreg copies.");
561 if (BS == IntB.
end())
return false;
562 VNInfo *BValNo = BS->valno;
567 if (BValNo->
def != CopyIdx)
return false;
573 if (AS == IntA.end())
return false;
574 VNInfo *AValNo = AS->valno;
586 if (ValS == IntB.
end())
599 if (ValS+1 != BS)
return false;
603 SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
607 BValNo->
def = FillerStart;
615 if (BValNo != ValS->valno)
624 S.removeSegment(*SS,
true);
627 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
630 if (SubBValNo != SubValSNo)
631 S.MergeValueNumberInto(SubBValNo, SubValSNo);
647 bool RecomputeLiveRange = AS->end == CopyIdx;
648 if (!RecomputeLiveRange) {
651 if (SS != S.end() && SS->end == CopyIdx) {
652 RecomputeLiveRange =
true;
657 if (RecomputeLiveRange)
664 bool RegisterCoalescer::hasOtherReachingDefs(
LiveInterval &IntA,
674 if (ASeg.
valno != AValNo)
continue;
677 if (BI != IntB.
begin())
679 for (; BI != IntB.
end() && ASeg.
end >= BI->start; ++BI) {
680 if (BI->valno == BValNo)
682 if (BI->start <= ASeg.
start && BI->end > ASeg.
start)
684 if (BI->start > ASeg.
start && BI->start < ASeg.
end)
693 static std::pair<bool,bool>
696 bool Changed =
false;
697 bool MergedWithDead =
false;
699 if (S.
valno != SrcValNo)
710 MergedWithDead =
true;
713 return std::make_pair(Changed, MergedWithDead);
717 RegisterCoalescer::removeCopyByCommutingDef(
const CoalescerPair &CP,
750 assert(BValNo !=
nullptr && BValNo->
def == CopyIdx);
756 return {
false,
false };
759 return {
false,
false };
761 return {
false,
false };
768 return {
false,
false };
781 return {
false,
false };
784 unsigned NewReg = NewDstMO.
getReg();
786 return {
false,
false };
790 if (hasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
791 return {
false,
false };
800 if (US == IntA.end() || US->valno != AValNo)
804 return {
false,
false };
816 return {
false,
false };
820 return {
false,
false };
821 if (NewMI != DefMI) {
854 assert(US != IntA.end() &&
"Use must be live");
855 if (US->valno != AValNo)
881 VNInfo *SubDVNI = S.getVNInfoAt(DefIdx);
884 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
886 S.MergeValueNumberInto(SubDVNI, SubBValNo);
894 bool ShrinkB =
false;
897 if (!IntA.hasSubRanges()) {
899 IntA.createSubRangeFrom(Allocator, Mask, IntA);
907 VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
908 assert(ASubValNo !=
nullptr);
909 MaskA |= SA.LaneMask;
912 [&Allocator,&SA,CopyIdx,ASubValNo,&ShrinkB]
914 VNInfo *BSubValNo = SR.empty()
915 ? SR.getNextValue(CopyIdx, Allocator)
916 : SR.getVNInfoAt(CopyIdx);
917 assert(BSubValNo != nullptr);
918 auto P = addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo);
921 BSubValNo->def = ASubValNo->def;
928 if ((SB.LaneMask & MaskA).any())
932 SB.removeSegment(*S,
true);
936 BValNo->
def = AValNo->
def;
945 return {
true, ShrinkB };
995 bool RegisterCoalescer::removePartialRedundancy(
const CoalescerPair &CP,
1026 bool FoundReverseCopy =
false;
1045 bool ValB_Changed =
false;
1046 for (
auto VNI : IntB.
valnos) {
1047 if (VNI->isUnused())
1050 ValB_Changed =
true;
1058 FoundReverseCopy =
true;
1062 if (!FoundReverseCopy)
1072 if (CopyLeftBB && CopyLeftBB->
succ_size() > 1)
1083 if (InsPos != CopyLeftBB->
end()) {
1089 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Move the copy to " 1094 TII->
get(TargetOpcode::COPY), IntB.
reg)
1105 ErasedInstrs.
erase(NewCopyMI);
1107 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Remove the copy from " 1116 deleteInstr(&CopyMI);
1130 VNInfo *BValNo = SR.Query(CopyIdx).valueOutOrDead();
1131 assert(BValNo &&
"All sublanes should be live");
1140 for (
unsigned I = 0;
I != EndPoints.
size(); ) {
1142 EndPoints[
I] = EndPoints.
back();
1151 shrinkToUses(&IntB);
1154 shrinkToUses(&IntA);
1162 "This code cannot handle physreg aliasing");
1164 if (!
Op.isReg() || !
Op.isDef() ||
Op.getReg() !=
Reg)
1168 if (
Op.getSubReg() == 0 ||
Op.isUndef())
1174 bool RegisterCoalescer::reMaterializeTrivialDef(
const CoalescerPair &CP,
1205 bool SawStore =
false;
1213 unsigned CopyDstReg = DstOperand.
getReg();
1222 if (SrcIdx && DstIdx)
1228 unsigned NewDstReg = DstReg;
1233 NewDstReg = TRI->
getSubReg(DstReg, NewDstIdx);
1243 "Only expect to deal with virtual or physical registers");
1251 TII->
reMaterialize(*MBB, MII, DstReg, SrcIdx, *DefMI, *TRI);
1265 &&
"Shouldn't have SrcIdx+DstIdx at this point");
1269 if (CommonRC !=
nullptr) {
1288 assert(MO.
isImplicit() &&
"No explicit operands after implicit operands.");
1297 ErasedInstrs.
insert(CopyMI);
1317 if (DefRC !=
nullptr) {
1322 assert(NewRC &&
"subreg chosen for remat incompatible with instruction");
1332 updateRegDefsUses(DstReg, DstReg, DstIdx);
1360 if (!SR.liveAt(DefIndex))
1361 SR.createDeadDef(DefIndex, Alloc);
1362 MaxMask &= ~SR.LaneMask;
1364 if (MaxMask.
any()) {
1382 bool UpdatedSubRanges =
false;
1384 if ((SR.LaneMask & DstMask).none()) {
1386 <<
"Removing undefined SubRange " 1390 SR.removeValNo(RmValNo);
1391 UpdatedSubRanges =
true;
1395 if (UpdatedSubRanges)
1402 "Only expect virtual or physical registers in remat");
1405 CopyDstReg,
true ,
true ,
false ));
1437 for (
unsigned i = 0, e = NewMIImplDefs.
size(); i != e; ++i) {
1438 unsigned Reg = NewMIImplDefs[i];
1454 UseMO.substPhysReg(DstReg, *TRI);
1456 UseMO.setReg(DstReg);
1465 if (ToBeUpdated.
count(SrcReg))
1468 unsigned NumCopyUses = 0;
1470 if (UseMO.getParent()->isCopyLike())
1475 shrinkToUses(&SrcInt, &DeadDefs);
1476 if (!DeadDefs.
empty())
1477 eliminateDeadDefs();
1479 ToBeUpdated.
insert(SrcReg);
1496 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
1497 isMoveInstr(*TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
1505 if ((SR.LaneMask & SrcMask).none())
1510 }
else if (SrcLI.
liveAt(Idx))
1518 assert(Seg !=
nullptr &&
"No segment for defining instruction");
1520 if (V->isPHIDef()) {
1521 CopyMI->
setDesc(TII->
get(TargetOpcode::IMPLICIT_DEF));
1544 if ((SR.LaneMask & DstMask).none())
1547 VNInfo *SVNI = SR.getVNInfoAt(RegIndex);
1549 SR.removeValNo(SVNI);
1566 if ((SR.LaneMask & UseMask).none())
1568 if (SR.liveAt(UseIdx)) {
1574 isLive = DstLI.
liveAt(UseIdx);
1577 MO.setIsUndef(
true);
1587 if (MO.isReg() && MO.isDef() && MO.getReg() == DstReg)
1588 MO.setIsUndef(
true);
1599 bool IsUndef =
true;
1601 if ((S.LaneMask & Mask).none())
1603 if (S.liveAt(UseIdx)) {
1616 ShrinkMainRange =
true;
1620 void RegisterCoalescer::updateRegDefsUses(
unsigned SrcReg,
1626 if (DstInt && DstInt->
hasSubRanges() && DstReg != SrcReg) {
1629 if (SubReg == 0 || MO.
isUndef())
1635 addUndefFlag(*DstInt, UseIdx, MO, SubReg);
1650 if (SrcReg == DstReg && !Visited.
insert(UseMI).second)
1659 if (DstInt && !Reads && SubIdx && !UseMI->
isDebugValue())
1663 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1669 if (SubIdx && MO.
isDef())
1684 addUndefFlag(*DstInt, UseIdx, MO, SubIdx);
1694 dbgs() <<
"\t\tupdated: ";
1702 bool RegisterCoalescer::canJoinPhys(
const CoalescerPair &CP) {
1707 LLVM_DEBUG(
dbgs() <<
"\tCan only merge into reserved registers.\n");
1716 dbgs() <<
"\tCannot join complex intervals into reserved register.\n");
1720 bool RegisterCoalescer::joinCopy(
MachineInstr *CopyMI,
bool &Again) {
1725 if (!CP.setRegisters(CopyMI)) {
1730 if (CP.getNewRC()) {
1733 unsigned SrcIdx = CP.getSrcIdx();
1734 unsigned DstIdx = CP.getDstIdx();
1735 if (CP.isFlipped()) {
1740 CP.getNewRC(), *LIS)) {
1752 eliminateDeadDefs();
1759 if (
MachineInstr *UndefMI = eliminateUndefCopy(CopyMI)) {
1760 if (UndefMI->isImplicitDef())
1762 deleteInstr(CopyMI);
1770 if (CP.getSrcReg() == CP.getDstReg()) {
1772 LLVM_DEBUG(
dbgs() <<
"\tCopy already coalesced: " << LI <<
'\n');
1777 assert(ReadVNI &&
"No value before copy and no <undef> flag.");
1778 assert(ReadVNI != DefVNI &&
"Cannot read and define the same value.");
1786 S.MergeValueNumberInto(SDefVNI, SReadVNI);
1791 deleteInstr(CopyMI);
1799 <<
printReg(CP.getDstReg(),
TRI, CP.getSrcIdx()) <<
'\n');
1800 if (!canJoinPhys(CP)) {
1804 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
1817 dbgs() <<
"\tConsidering merging to " 1819 if (CP.getDstIdx() && CP.getSrcIdx())
1822 <<
printReg(CP.getSrcReg()) <<
" in " 1826 <<
printReg(CP.getDstReg(),
TRI, CP.getSrcIdx()) <<
'\n';
1831 ShrinkMainRange =
false;
1837 if (!joinIntervals(CP)) {
1843 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
1848 if (!CP.isPartial() && !CP.isPhys()) {
1849 bool Changed = adjustCopiesBackFrom(CP, CopyMI);
1850 bool Shrink =
false;
1852 std::tie(Changed, Shrink) = removeCopyByCommutingDef(CP, CopyMI);
1854 deleteInstr(CopyMI);
1856 unsigned DstReg = CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg();
1858 shrinkToUses(&DstLI);
1868 if (!CP.isPartial() && !CP.isPhys())
1869 if (removePartialRedundancy(CP, *CopyMI))
1880 if (CP.isCrossClass()) {
1893 ErasedInstrs.
erase(CopyMI);
1898 updateRegDefsUses(CP.getDstReg(), CP.getDstReg(), CP.getDstIdx());
1899 updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx());
1902 if (ShrinkMask.any()) {
1905 if ((S.LaneMask & ShrinkMask).none())
1917 if (ToBeUpdated.
count(CP.getSrcReg()))
1918 ShrinkMainRange =
true;
1920 if (ShrinkMainRange) {
1933 dbgs() <<
"\tSuccess: " <<
printReg(CP.getSrcReg(),
TRI, CP.getSrcIdx())
1934 <<
" -> " <<
printReg(CP.getDstReg(),
TRI, CP.getDstIdx()) <<
'\n';
1935 dbgs() <<
"\tResult = ";
1947 bool RegisterCoalescer::joinReservedPhysReg(
CoalescerPair &CP) {
1955 assert(RHS.containsOneValue() &&
"Invalid join with reserved register");
1981 !RegMaskUsable.
test(DstReg)) {
2044 <<
printReg(DstReg, TRI) <<
" at " << CopyRegIdx <<
"\n");
2054 deleteInstr(CopyMI);
2142 const unsigned SubIdx;
2150 const bool SubRangeJoin;
2153 const bool TrackSubRegLiveness;
2168 enum ConflictResolution {
2199 ConflictResolution Resolution = CR_Keep;
2209 VNInfo *RedefVNI =
nullptr;
2212 VNInfo *OtherVNI =
nullptr;
2225 bool ErasableImplicitDef =
false;
2229 bool Pruned =
false;
2232 bool PrunedComputed =
false;
2239 bool Identical =
false;
2243 bool isAnalyzed()
const {
return WriteLanes.
any(); }
2255 std::pair<const VNInfo*,unsigned> followCopyChain(
const VNInfo *VNI)
const;
2257 bool valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
const JoinVals &
Other)
const;
2266 ConflictResolution analyzeValue(
unsigned ValNo, JoinVals &Other);
2271 void computeAssignment(
unsigned ValNo, JoinVals &Other);
2289 taintExtent(
unsigned ValNo,
LaneBitmask TaintedLanes, JoinVals &Other,
2302 bool isPrunedValue(
unsigned ValNo, JoinVals &Other);
2308 bool TrackSubRegLiveness)
2309 : LR(LR),
Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
2310 SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
2316 bool mapValues(JoinVals &Other);
2320 bool resolveConflicts(JoinVals &Other);
2340 void pruneMainSegments(
LiveInterval &LI,
bool &ShrinkMainRange);
2351 void removeImplicitDefs();
2354 const int *getAssignments()
const {
return Assignments.
data(); }
2373 std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain(
2374 const VNInfo *VNI)
const {
2375 unsigned TrackReg =
Reg;
2379 MachineInstr *MI = Indexes->getInstructionFromIndex(Def);
2380 assert(MI &&
"No defining instruction");
2382 return std::make_pair(VNI, TrackReg);
2385 return std::make_pair(VNI, TrackReg);
2400 if ((SMask & LaneMask).none())
2408 return std::make_pair(VNI, TrackReg);
2411 if (ValueIn ==
nullptr) {
2418 return std::make_pair(
nullptr, SrcReg);
2423 return std::make_pair(VNI, TrackReg);
2426 bool JoinVals::valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
2427 const JoinVals &
Other)
const {
2430 std::tie(Orig0, Reg0) = followCopyChain(Value0);
2431 if (Orig0 == Value1 && Reg0 == Other.Reg)
2436 std::tie(Orig1, Reg1) = Other.followCopyChain(Value1);
2440 if (Orig0 ==
nullptr || Orig1 ==
nullptr)
2441 return Orig0 == Orig1 && Reg0 == Reg1;
2447 return Orig0->
def == Orig1->
def && Reg0 == Reg1;
2450 JoinVals::ConflictResolution
2451 JoinVals::analyzeValue(
unsigned ValNo, JoinVals &Other) {
2452 Val &V = Vals[ValNo];
2453 assert(!V.isAnalyzed() &&
"Value has already been analyzed!");
2454 VNInfo *VNI = LR.getValNumInfo(ValNo);
2455 if (VNI->isUnused()) {
2462 if (VNI->isPHIDef()) {
2466 V.ValidLanes = V.WriteLanes = Lanes;
2468 DefMI = Indexes->getInstructionFromIndex(VNI->def);
2469 assert(DefMI !=
nullptr);
2475 V.ErasableImplicitDef =
true;
2479 V.ValidLanes = V.WriteLanes = computeWriteLanes(DefMI, Redef);
2497 V.RedefVNI = LR.Query(VNI->def).valueIn();
2498 assert((TrackSubRegLiveness || V.RedefVNI) &&
2499 "Instruction is reading nonexistent value");
2500 if (V.RedefVNI !=
nullptr) {
2501 computeAssignment(V.RedefVNI->id, Other);
2502 V.ValidLanes |= Vals[V.RedefVNI->id].ValidLanes;
2514 V.ErasableImplicitDef =
true;
2531 if (OtherVNI->def < VNI->def)
2532 Other.computeAssignment(OtherVNI->id, *
this);
2533 else if (VNI->def < OtherVNI->def && OtherLRQ.
valueIn()) {
2536 V.OtherVNI = OtherLRQ.
valueIn();
2537 return CR_Impossible;
2539 V.OtherVNI = OtherVNI;
2540 Val &OtherV = Other.Vals[OtherVNI->id];
2542 if (!OtherV.isAnalyzed())
2547 if (VNI->isPHIDef())
2549 if ((V.ValidLanes & OtherV.ValidLanes).any())
2551 return CR_Impossible;
2557 V.OtherVNI = OtherLRQ.
valueIn();
2566 Other.computeAssignment(V.OtherVNI->id, *
this);
2567 Val &OtherV = Other.Vals[V.OtherVNI->id];
2569 if (OtherV.ErasableImplicitDef) {
2578 DefMI->
getParent() != Indexes->getMBBFromIndex(V.OtherVNI->def)) {
2579 LLVM_DEBUG(
dbgs() <<
"IMPLICIT_DEF defined at " << V.OtherVNI->def
2582 <<
", keeping it.\n");
2583 OtherV.ErasableImplicitDef =
false;
2586 OtherV.ValidLanes &= ~OtherV.WriteLanes;
2592 if (VNI->isPHIDef())
2599 if (TrackSubRegLiveness
2600 && (V.WriteLanes & (OtherV.ValidLanes | OtherV.WriteLanes)).none())
2610 V.ValidLanes &= ~V.WriteLanes | OtherV.ValidLanes;
2625 valuesIdentical(VNI, V.OtherVNI, Other)) {
2648 if ((V.WriteLanes & OtherV.ValidLanes).none())
2660 assert(VNI->def.isEarlyClobber() &&
2661 "Only early clobber defs can overlap a kill");
2662 return CR_Impossible;
2670 return CR_Impossible;
2676 if (OtherLRQ.
endPoint() >= Indexes->getMBBEndIdx(MBB))
2677 return CR_Impossible;
2686 return CR_Unresolved;
2689 void JoinVals::computeAssignment(
unsigned ValNo, JoinVals &Other) {
2690 Val &V = Vals[ValNo];
2691 if (V.isAnalyzed()) {
2694 assert(Assignments[ValNo] != -1 &&
"Bad recursion?");
2697 switch ((V.Resolution = analyzeValue(ValNo, Other))) {
2701 assert(V.OtherVNI &&
"OtherVNI not assigned, can't merge.");
2702 assert(Other.Vals[V.OtherVNI->id].isAnalyzed() &&
"Missing recursion");
2703 Assignments[ValNo] = Other.Assignments[V.OtherVNI->id];
2705 << LR.getValNumInfo(ValNo)->def <<
" into " 2706 <<
printReg(Other.Reg) <<
':' << V.OtherVNI->id <<
'@' 2707 << V.OtherVNI->def <<
" --> @" 2708 << NewVNInfo[Assignments[ValNo]]->def <<
'\n');
2711 case CR_Unresolved: {
2713 assert(V.OtherVNI &&
"OtherVNI not assigned, can't prune");
2714 Val &OtherV = Other.Vals[V.OtherVNI->id];
2717 if (OtherV.ErasableImplicitDef &&
2718 TrackSubRegLiveness &&
2719 (OtherV.WriteLanes & ~V.ValidLanes).any()) {
2720 LLVM_DEBUG(
dbgs() <<
"Cannot erase implicit_def with missing values\n");
2722 OtherV.ErasableImplicitDef =
false;
2729 OtherV.Pruned =
true;
2734 Assignments[ValNo] = NewVNInfo.size();
2735 NewVNInfo.push_back(LR.getValNumInfo(ValNo));
2740 bool JoinVals::mapValues(JoinVals &Other) {
2741 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
2742 computeAssignment(i, Other);
2743 if (Vals[i].Resolution == CR_Impossible) {
2745 <<
'@' << LR.getValNumInfo(i)->def <<
'\n');
2753 taintExtent(
unsigned ValNo,
LaneBitmask TaintedLanes, JoinVals &Other,
2755 VNInfo *VNI = LR.getValNumInfo(ValNo);
2757 SlotIndex MBBEnd = Indexes->getMBBEndIdx(MBB);
2761 assert(OtherI != Other.LR.end() &&
"No conflict?");
2766 if (End >= MBBEnd) {
2768 << OtherI->valno->id <<
'@' << OtherI->start <<
'\n');
2772 << OtherI->valno->id <<
'@' << OtherI->start <<
" to " 2777 TaintExtent.push_back(std::make_pair(End, TaintedLanes));
2780 if (++OtherI == Other.LR.end() || OtherI->start >= MBBEnd)
2784 const Val &OV = Other.Vals[OtherI->valno->id];
2785 TaintedLanes &= ~OV.WriteLanes;
2788 }
while (TaintedLanes.
any());
2792 bool JoinVals::usesLanes(
const MachineInstr &MI,
unsigned Reg,
unsigned SubIdx,
2808 bool JoinVals::resolveConflicts(JoinVals &Other) {
2809 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
2811 assert(V.Resolution != CR_Impossible &&
"Unresolvable conflict");
2812 if (V.Resolution != CR_Unresolved)
2815 << LR.getValNumInfo(i)->def <<
'\n');
2820 assert(V.OtherVNI &&
"Inconsistent conflict resolution.");
2821 VNInfo *VNI = LR.getValNumInfo(i);
2822 const Val &OtherV = Other.Vals[V.OtherVNI->id];
2827 LaneBitmask TaintedLanes = V.WriteLanes & OtherV.ValidLanes;
2829 if (!taintExtent(i, TaintedLanes, Other, TaintExtent))
2833 assert(!TaintExtent.
empty() &&
"There should be at least one conflict.");
2839 MI = Indexes->getInstructionFromIndex(VNI->
def);
2844 "Interference ends on VNI->def. Should have been handled earlier");
2846 Indexes->getInstructionFromIndex(TaintExtent.
front().first);
2847 assert(LastMI &&
"Range must end at a proper instruction");
2848 unsigned TaintNum = 0;
2850 assert(MI != MBB->end() &&
"Bad LastMI");
2851 if (usesLanes(*MI, Other.Reg, Other.SubIdx, TaintedLanes)) {
2856 if (&*MI == LastMI) {
2857 if (++TaintNum == TaintExtent.
size())
2859 LastMI = Indexes->getInstructionFromIndex(TaintExtent[TaintNum].
first);
2860 assert(LastMI &&
"Range must end at a proper instruction");
2861 TaintedLanes = TaintExtent[TaintNum].second;
2867 V.Resolution = CR_Replace;
2873 bool JoinVals::isPrunedValue(
unsigned ValNo, JoinVals &Other) {
2874 Val &V = Vals[ValNo];
2875 if (V.Pruned || V.PrunedComputed)
2878 if (V.Resolution != CR_Erase && V.Resolution != CR_Merge)
2883 V.PrunedComputed =
true;
2884 V.Pruned = Other.isPrunedValue(V.OtherVNI->id, *
this);
2888 void JoinVals::pruneValues(JoinVals &Other,
2890 bool changeInstrs) {
2891 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
2893 switch (Vals[i].Resolution) {
2903 Val &OtherV = Other.Vals[Vals[i].OtherVNI->id];
2904 bool EraseImpDef = OtherV.ErasableImplicitDef &&
2905 OtherV.Resolution == CR_Keep;
2912 Indexes->getInstructionFromIndex(Def)->operands()) {
2926 <<
": " << Other.LR <<
'\n');
2931 if (isPrunedValue(i, Other)) {
2938 << Def <<
": " << LR <<
'\n');
2989 bool DidPrune =
false;
2990 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
2994 if (V.Resolution != CR_Erase &&
2995 (V.Resolution != CR_Keep || !V.ErasableImplicitDef || !V.Pruned))
3002 OtherDef = V.OtherVNI->def;
3005 LLVM_DEBUG(
dbgs() <<
"\t\tExpecting instruction removal at " << Def
3013 if (ValueOut !=
nullptr && Q.
valueIn() ==
nullptr) {
3015 <<
" at " << Def <<
"\n");
3022 if (V.Identical && S.Query(OtherDef).valueOut()) {
3036 ShrinkMask |= S.LaneMask;
3047 if (
VNInfo *VNI = SR.Query(Def).valueOutOrDead())
3048 if (VNI->
def == Def)
3054 void JoinVals::pruneMainSegments(
LiveInterval &LI,
bool &ShrinkMainRange) {
3055 assert(&static_cast<LiveRange&>(LI) == &LR);
3057 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
3058 if (Vals[i].Resolution != CR_Keep)
3060 VNInfo *VNI = LR.getValNumInfo(i);
3063 Vals[i].Pruned =
true;
3064 ShrinkMainRange =
true;
3068 void JoinVals::removeImplicitDefs() {
3069 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
3071 if (V.Resolution != CR_Keep || !V.ErasableImplicitDef || !V.Pruned)
3074 VNInfo *VNI = LR.getValNumInfo(i);
3076 LR.removeValNo(VNI);
3083 for (
unsigned i = 0, e = LR.getNumValNums(); i != e; ++i) {
3086 switch (Vals[i].Resolution) {
3091 if (!Vals[i].ErasableImplicitDef || !Vals[i].Pruned)
3101 VNInfo *VNI = LR.getValNumInfo(i);
3105 if (LI !=
nullptr) {
3114 LR.removeValNo(VNI);
3120 assert(static_cast<LiveRange*>(LI) == &LR);
3130 ED = ED.
isValid() ? std::min(ED, I->start) : I->start;
3135 NewEnd = std::min(NewEnd, LE);
3137 NewEnd = std::min(NewEnd, ED);
3143 if (S != LR.begin())
3144 std::prev(S)->end = NewEnd;
3148 dbgs() <<
"\t\tremoved " << i <<
'@' << Def <<
": " << LR <<
'\n';
3150 dbgs() <<
"\t\t LHS = " << *LI <<
'\n';
3156 MachineInstr *MI = Indexes->getInstructionFromIndex(Def);
3157 assert(MI &&
"No instruction to erase");
3181 NewVNInfo,
CP, LIS,
TRI,
true,
true);
3182 JoinVals LHSVals(LRange, CP.getDstReg(), CP.getDstIdx(), LaneMask,
3183 NewVNInfo,
CP, LIS,
TRI,
true,
true);
3190 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals)) {
3195 if (!LHSVals.resolveConflicts(RHSVals) ||
3196 !RHSVals.resolveConflicts(LHSVals)) {
3207 LHSVals.pruneValues(RHSVals, EndPoints,
false);
3208 RHSVals.pruneValues(LHSVals, EndPoints,
false);
3210 LHSVals.removeImplicitDefs();
3211 RHSVals.removeImplicitDefs();
3217 LRange.
join(RRange, LHSVals.getAssignments(), RHSVals.getAssignments(),
3221 <<
' ' << LRange <<
"\n");
3222 if (EndPoints.
empty())
3228 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3229 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3230 dbgs() << EndPoints[i];
3234 dbgs() <<
": " << LRange <<
'\n';
3236 LIS->extendToIndices(LRange, EndPoints);
3239 void RegisterCoalescer::mergeSubRangeInto(
LiveInterval &LI,
3247 SR.
assign(ToMerge, Allocator);
3250 LiveRange RangeCopy(ToMerge, Allocator);
3251 joinSubRegRanges(SR, RangeCopy, SR.
LaneMask, CP);
3262 NewVNInfo,
CP, LIS,
TRI,
false, TrackSubRegLiveness);
3264 NewVNInfo,
CP, LIS,
TRI,
false, TrackSubRegLiveness);
3266 LLVM_DEBUG(
dbgs() <<
"\t\tRHS = " << RHS <<
"\n\t\tLHS = " << LHS <<
'\n');
3270 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals))
3274 if (!LHSVals.resolveConflicts(RHSVals) || !RHSVals.resolveConflicts(LHSVals))
3283 unsigned DstIdx = CP.getDstIdx();
3286 : TRI->getSubRegIndexLaneMask(DstIdx);
3290 }
else if (DstIdx != 0) {
3293 LaneBitmask Mask = TRI->composeSubRegIndexLaneMask(DstIdx, R.LaneMask);
3301 unsigned SrcIdx = CP.getSrcIdx();
3304 : TRI->getSubRegIndexLaneMask(SrcIdx);
3305 mergeSubRangeInto(LHS, RHS, Mask, CP);
3309 LaneBitmask Mask = TRI->composeSubRegIndexLaneMask(SrcIdx, R.LaneMask);
3310 mergeSubRangeInto(LHS, R, Mask, CP);
3317 LHSVals.pruneMainSegments(LHS, ShrinkMainRange);
3319 LHSVals.pruneSubRegValues(LHS, ShrinkMask);
3320 RHSVals.pruneSubRegValues(LHS, ShrinkMask);
3328 LHSVals.pruneValues(RHSVals, EndPoints,
true);
3329 RHSVals.pruneValues(LHSVals, EndPoints,
true);
3334 LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, &LHS);
3335 RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
3336 while (!ShrinkRegs.
empty())
3337 shrinkToUses(&LIS->getInterval(ShrinkRegs.
pop_back_val()));
3340 LHS.
join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
3348 if (!EndPoints.
empty()) {
3352 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3353 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3354 dbgs() << EndPoints[i];
3358 dbgs() <<
": " << LHS <<
'\n';
3360 LIS->extendToIndices((
LiveRange&)LHS, EndPoints);
3367 return CP.
isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(CP);
3373 struct MBBPriorityInfo {
3379 : MBB(mbb),
Depth(depth), IsSplit(issplit) {}
3389 const MBBPriorityInfo *RHS) {
3391 if (LHS->Depth != RHS->Depth)
3392 return LHS->Depth > RHS->Depth ? -1 : 1;
3395 if (LHS->IsSplit != RHS->IsSplit)
3396 return LHS->IsSplit ? -1 : 1;
3400 unsigned cl = LHS->MBB->pred_size() + LHS->MBB->succ_size();
3401 unsigned cr = RHS->MBB->pred_size() + RHS->MBB->succ_size();
3403 return cl > cr ? -1 : 1;
3406 return LHS->MBB->getNumber() < RHS->MBB->getNumber() ? -1 : 1;
3427 void RegisterCoalescer::lateLiveIntervalUpdate() {
3428 for (
unsigned reg : ToBeUpdated) {
3432 shrinkToUses(&LI, &DeadDefs);
3433 if (!DeadDefs.
empty())
3434 eliminateDeadDefs();
3436 ToBeUpdated.clear();
3439 bool RegisterCoalescer::
3441 bool Progress =
false;
3442 for (
unsigned i = 0, e = CurrList.
size(); i != e; ++i) {
3447 if (ErasedInstrs.
count(CurrList[i])) {
3448 CurrList[i] =
nullptr;
3452 bool Success = joinCopy(CurrList[i], Again);
3454 if (Success || !Again)
3455 CurrList[i] =
nullptr;
3472 bool RegisterCoalescer::applyTerminalRule(
const MachineInstr &Copy)
const {
3476 unsigned DstReg, DstSubReg, SrcReg, SrcSubReg;
3477 isMoveInstr(*TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg);
3500 unsigned OtherReg, OtherSubReg, OtherSrcReg, OtherSrcSubReg;
3501 isMoveInstr(*TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg,
3503 if (OtherReg == SrcReg)
3504 OtherReg = OtherSrcReg;
3525 const unsigned PrevSize = WorkList.
size();
3526 if (JoinGlobalCopies) {
3535 if (!MII->isCopyLike())
3537 bool ApplyTerminalRule = applyTerminalRule(*MII);
3539 if (ApplyTerminalRule)
3544 if (ApplyTerminalRule)
3551 LocalWorkList.
append(LocalTerminals.
begin(), LocalTerminals.
end());
3557 if (MII.isCopyLike()) {
3558 if (applyTerminalRule(MII))
3570 CurrList(WorkList.
begin() + PrevSize, WorkList.
end());
3571 if (copyCoalesceWorkList(CurrList))
3573 nullptr), WorkList.
end());
3576 void RegisterCoalescer::coalesceLocals() {
3577 copyCoalesceWorkList(LocalWorkList);
3578 for (
unsigned j = 0, je = LocalWorkList.
size(); j != je; ++j) {
3579 if (LocalWorkList[j])
3582 LocalWorkList.
clear();
3585 void RegisterCoalescer::joinAllIntervals() {
3586 LLVM_DEBUG(
dbgs() <<
"********** JOINING INTERVALS ***********\n");
3587 assert(WorkList.
empty() && LocalWorkList.
empty() &&
"Old data still around.");
3589 std::vector<MBBPriorityInfo> MBBs;
3590 MBBs.reserve(MF->
size());
3593 MBBs.push_back(MBBPriorityInfo(MBB, Loops->
getLoopDepth(MBB),
3600 for (
unsigned i = 0, e = MBBs.size(); i != e; ++i) {
3602 if (JoinGlobalCopies && MBBs[i].
Depth < CurrDepth) {
3604 CurrDepth = MBBs[i].Depth;
3606 copyCoalesceInMBB(MBBs[i].MBB);
3608 lateLiveIntervalUpdate();
3613 while (copyCoalesceWorkList(WorkList))
3615 lateLiveIntervalUpdate();
3618 void RegisterCoalescer::releaseMemory() {
3619 ErasedInstrs.
clear();
3622 InflateRegs.
clear();
3631 LIS = &getAnalysis<LiveIntervals>();
3632 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
3633 Loops = &getAnalysis<MachineLoopInfo>();
3644 LLVM_DEBUG(
dbgs() <<
"********** SIMPLE REGISTER COALESCING **********\n" 3645 <<
"********** Function: " << MF->
getName() <<
'\n');
3648 MF->
verify(
this,
"Before register coalescing");
3660 InflateRegs.
erase(std::unique(InflateRegs.
begin(), InflateRegs.
end()),
3664 for (
unsigned i = 0, e = InflateRegs.
size(); i != e; ++i) {
3665 unsigned Reg = InflateRegs[i];
3685 assert((S.LaneMask & ~MaxMask).none());
3695 MF->
verify(
this,
"After register coalescing");
bool reg_nodbg_empty(unsigned RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions...
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B, const MVT::SimpleValueType SVT=MVT::SimpleValueType::Any) const
Find the largest common subclass of A and B.
static bool isSplitEdge(const MachineBasicBlock *MBB)
Return true if this block should be vacated by the coalescer to eliminate branches.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
iterator_range< reg_instr_nodbg_iterator > reg_nodbg_instructions(unsigned Reg) const
A common definition of LaneBitmask for use in TableGen and CodeGen.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool contains(unsigned Reg) const
Return true if the specified register is included in this register class.
virtual bool enableJoinGlobalCopies() const
True if the subtarget should enable joining global copies.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex def
The index of the defining instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const
Returns a mask covering all bits that can appear in lane masks of subregisters of the virtual registe...
This class represents lattice values for constants.
bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const
Returns true if VNI is killed by any PHI-def values in LI.
void removePhysRegDefAt(unsigned Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
A Module instance is used to store all the information related to an LLVM module. ...
bool isCoalescable(const MachineInstr *) const
Return true if MI is a copy instruction that will become an identity copy after coalescing.
static cl::opt< bool > VerifyCoalescing("verify-coalescing", cl::desc("Verify machine instrs before and after register coalescing"), cl::Hidden)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
Segments::iterator iterator
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
LiveInterval - This class represents the liveness of a register, or stack slot.
iterator_range< use_nodbg_iterator > use_nodbg_operands(unsigned Reg) const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
void setIsUndef(bool Val=true)
void eliminateDeadDefs(SmallVectorImpl< MachineInstr *> &Dead, ArrayRef< unsigned > RegsBeingSpilled=None, AliasAnalysis *AA=nullptr)
eliminateDeadDefs - Try to delete machine instructions that are now dead (allDefsAreDead returns true...
static cl::opt< bool > EnableJoining("join-liveintervals", cl::desc("Coalesce copies (default=true)"), cl::init(true), cl::Hidden)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator_range< reg_nodbg_iterator > reg_nodbg_operands(unsigned Reg) const
static bool isLocalCopy(MachineInstr *Copy, const LiveIntervals *LIS)
MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const
This method commutes the operands of the given machine instruction MI.
unsigned getSubReg() const
bool test(unsigned Idx) const
static bool definesFullReg(const MachineInstr &MI, unsigned Reg)
Returns true if MI defines the full vreg Reg, as opposed to just defining a subregister.
iterator_range< reg_iterator > reg_operands(unsigned Reg) const
char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
bool isDead() const
isDead - Returns true if this is a dead def kill slot.
unsigned getLoopDepth(const MachineBasicBlock *BB) const
Return the loop nesting level of the specified block.
A live range for subregisters.
bool isValid() const
Returns true if this is a valid index.
This represents a simple continuous liveness interval for a value.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
bool isPhys() const
Return true if DstReg is a physical register.
void markUnused()
Mark this value as unused.
void reserve(size_type N)
SubRange * createSubRangeFrom(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, const LiveRange &CopyFrom)
Like createSubRange() but the new range is filled with a copy of the liveness information in CopyFrom...
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
VNInfo - Value Number Information.
void print(raw_ostream &O, const Module *=nullptr) const override
Implement the dump method.
iterator_range< mop_iterator > operands()
void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo &)
substVirtReg - Substitute the current register with the virtual subregister Reg:SubReg.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool checkRegMaskInterference(LiveInterval &LI, BitVector &UsableRegs)
Test if LI is live across any register mask instructions, and compute a bit mask of physical register...
Callback methods for LiveRangeEdit owners.
void initializeRegisterCoalescerPass(PassRegistry &)
static MachineOperand CreateReg(unsigned 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)
This class represents the liveness of a register, stack slot, etc.
static bool isDefInSubRange(LiveInterval &LI, SlotIndex Def)
Check if any of the subranges of LI contain a definition at Def.
bool isUnused() const
Returns true if this value is unused.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
unsigned getDstReg() const
Return the register (virtual or physical) that will remain after coalescing.
bool isEarlyClobber() const
const char * getRegClassName(const TargetRegisterClass *Class) const
Returns the name of the register class.
bool isPartial() const
Return true if the original copy instruction did not copy the full register, but was a subreg operati...
void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isBlock() const
isBlock - Returns true if this is a block boundary slot.
void pruneValue(LiveRange &LR, SlotIndex Kill, SmallVectorImpl< SlotIndex > *EndPoints)
If LR has a live value at Kill, prune its live range by removing any liveness reachable from Kill...
static use_iterator use_end()
void verify() const
Walk the range and assert if any invariants fail to hold.
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const
Re-issue the specified 'original' instruction at the specific location targeting a new destination re...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum, const TargetRegisterInfo *TRI, const MachineFunction &MF) const
Given a machine instruction descriptor, returns the register class constraint for OpNum...
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
VNInfo::Allocator & getVNInfoAllocator()
A helper class for register coalescers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator_range< subrange_iterator > subranges()
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Result of a LiveRange query.
static cl::opt< bool > EnableJoinSplits("join-splitedges", cl::desc("Coalesce copies on split edges (default=subtarget)"), cl::Hidden)
Temporary flag to test critical edge unsplitting.
static constexpr LaneBitmask getAll()
bool hasSubRanges() const
Returns true if subregister liveness information is available.
static constexpr LaneBitmask getNone()
Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
static reg_instr_iterator reg_instr_end()
SlotIndex getNextNonNullIndex(SlotIndex Index)
Returns the next non-null index, if one exists.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
defusechain_iterator - This class provides iterator support for machine operands in the function that...
void extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
const TargetRegisterClass * getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, const TargetRegisterClass *RCB, unsigned SubB, unsigned &PreA, unsigned &PreB) const
Find a common super-register class if it exists.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
void clearKillFlags(unsigned Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
MCRegUnitRootIterator enumerates the root registers of a register unit.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
VNInfo * MergeValueNumberInto(VNInfo *V1, VNInfo *V2)
MergeValueNumberInto - This method is called when two value numbers are found to be equivalent...
AnalysisUsage & addPreservedID(const void *ID)
const char * getSubRegIndexName(unsigned SubIdx) const
Return the human-readable symbolic target-specific name for the specified SubRegIndex.
virtual const TargetInstrInfo * getInstrInfo() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
bool isKill() const
Return true if the live-in value is killed by this instruction.
bool setRegisters(const MachineInstr *)
Set registers to match the copy instruction MI.
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool allDefsAreDead() const
Return true if all the defs of this instruction are dead.
LiveRange * getCachedRegUnit(unsigned Unit)
Return the live range for register unit Unit if it has already been computed, or nullptr if it hasn't...
static constexpr LaneBitmask getLane(unsigned Lane)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static cl::opt< unsigned > LateRematUpdateThreshold("late-remat-update-threshold", cl::Hidden, cl::desc("During rematerialization for a copy, if the def instruction has " "many other copy uses to be rematerialized, delay the multiple " "separate live interval update work and do them all at once after " "all those rematerialization are done. It will save a lot of " "repeated work. "), cl::init(100))
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
bool containsOneValue() const
TargetInstrInfo - Interface to description of machine instruction set.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
static const unsigned CommuteAnyOperandIndex
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
unsigned const MachineRegisterInfo * MRI
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
bool hasInterval(unsigned Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static int compareMBBPriority(const MBBPriorityInfo *LHS, const MBBPriorityInfo *RHS)
C-style comparator that sorts first based on the loop depth of the basic block (the unsigned)...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Allocate memory in an ever growing pool, as if by bump-pointer.
void removeInterval(unsigned Reg)
Interval removal.
bool liveAt(SlotIndex index) const
MachineInstrBuilder & UseMI
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval *> &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
unsigned composeSubRegIndices(unsigned a, unsigned b) const
Return the subregister index you get from composing two subregister indices.
std::pair< iterator, bool > insert(const ValueT &V)
SlotIndex getIndexBefore(const MachineInstr &MI) const
getIndexBefore - Returns the index of the last indexed instruction before MI, or the start index of i...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
Represent the analysis usage information of a pass.
bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr *> *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses...
void substPhysReg(unsigned Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx=nullptr) const
Return true if the use operand of the specified index is tied to a def operand.
virtual const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const
Return a subclass of the specified register class A so that each register in it has a sub-register of...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static bool isTerminalReg(unsigned DstReg, const MachineInstr &Copy, const MachineRegisterInfo *MRI)
Check if DstReg is a terminal node.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
constexpr bool all() const
void join(LiveRange &Other, const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVectorImpl< VNInfo *> &NewVNInfo)
join - Join two live ranges (this, and other) together.
std::pair< bool, bool > readsWritesVirtualRegister(unsigned Reg, SmallVectorImpl< unsigned > *Ops=nullptr) const
Return a pair of bools (reads, writes) indicating if this instruction reads or writes Reg...
iterator_range< pred_iterator > predecessors()
void runOnMachineFunction(const MachineFunction &MF)
runOnFunction - Prepare to answer questions about MF.
bool isFlipped() const
Return true when getSrcReg is the register being defined by the original copy instruction.
void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, std::function< void(LiveInterval::SubRange &)> Apply)
Refines the subranges to support LaneMask.
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
unsigned getSrcReg() const
Return the virtual register that will be coalesced away.
virtual void updateRegAllocHint(unsigned Reg, unsigned NewReg, MachineFunction &MF) const
A callback to allow target a chance to update register allocation hints when a register is "changed" ...
bool isImplicitDef() const
iterator erase(const_iterator CI)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isDebugInstr() const
SlotIndex endPoint() const
Return the end point of the last live range segment to interact with the instruction, if any.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isConstantPhysReg(unsigned PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing", "Simple Register Coalescing", false, false) INITIALIZE_PASS_END(RegisterCoalescer
static cl::opt< cl::boolOrDefault > EnableGlobalCopies("join-globalcopies", cl::desc("Coalesce copies that span blocks (default=subtarget)"), cl::init(cl::BOU_UNSET), cl::Hidden)
Temporary flag to test global copy optimization.
unsigned getSrcIdx() const
Return the subregister index that SrcReg will be coalesced into, or 0.
void setIsKill(bool Val=true)
virtual bool isAsCheapAsAMove(const MachineInstr &MI) const
Return true if the instruction is as cheap as a move instruction.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
virtual bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const
Subtarget Hooks.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
unsigned getDstIdx() const
Return the subregister index that DstReg will be coalesced into, or 0.
iterator_range< use_iterator > use_operands(unsigned Reg) const
simple register coalescing
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
MachineInstrBuilder MachineInstrBuilder & DefMI
Promote Memory to Register
LLVM_NODISCARD T pop_back_val()
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
LiveInterval & getInterval(unsigned Reg)
bool recomputeRegClass(unsigned Reg)
recomputeRegClass - Try to find a legal super-class of Reg's register class that still satisfies the ...
unsigned pred_size() const
virtual bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void clearSubRanges()
Removes all subregister liveness information.
LaneBitmask composeSubRegIndexLaneMask(unsigned IdxA, LaneBitmask Mask) const
Transforms a LaneMask computed for one subregister to the lanemask that would have been computed when...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx...
void setDebugLoc(DebugLoc dl)
Replace current source information with new such.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
bool isUnconditionalBranch(QueryType Type=AnyInBundle) const
Return true if this is a branch which always transfers control flow to some other block...
unsigned succ_size() const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
unsigned getNumValNums() const
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static cl::opt< bool > UseTerminalRule("terminal-rule", cl::desc("Apply the terminal rule"), cl::init(false), cl::Hidden)
pointer data()
Return a pointer to the vector's buffer, even if empty().
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
void assign(const LiveRange &Other, BumpPtrAllocator &Allocator)
Copies values numbers and live segments from Other into this range.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
bool isEHPad() const
Returns true if the block is a landing pad.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use...
LLVM_NODISCARD bool empty() const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
simple register Simple Register static false bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI, unsigned &Src, unsigned &Dst, unsigned &SrcSub, unsigned &DstSub)
void setReg(unsigned Reg)
Change the register this operand corresponds to.
constexpr bool any() const
void setSubReg(unsigned subReg)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
bool flip()
Swap SrcReg and DstReg.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool shouldTrackSubRegLiveness(const TargetRegisterClass &RC) const
Returns true if liveness for register class RC should be tracked at the subregister level...
bool isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx=nullptr) const
Given the index of a register def operand, check if the register def is tied to a source operand...
SlotIndexes * getSlotIndexes() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
If LI is confined to a single basic block, return a pointer to that block.
auto upper_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const TargetRegisterClass * getNewRC() const
Return the register class of the coalesced register.
use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const
simple register Simple Register Coalescing
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
void setRegClass(unsigned Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none...
bool isValid() const
Check if the iterator is at the end of the list.
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
const MachineOperand & getOperand(unsigned i) const
SlotIndex - An opaque wrapper around machine indexes.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
bool isTriviallyReMaterializable(const MachineInstr &MI, AliasAnalysis *AA=nullptr) const
Return true if the instruction is trivially rematerializable, meaning it has no side effects and requ...
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a use of the specific register or -1 if it is not found...
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
reg_instr_iterator reg_instr_begin(unsigned RegNo) const
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
bool isProperSubClass(const TargetRegisterClass *RC) const
isProperSubClass - Returns true if RC has a legal super-class with more allocatable registers...
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
static std::pair< bool, bool > addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo, const LiveRange &Src, const VNInfo *SrcValNo)
Copy segments with value number SrcValNo from liverange Src to live range and use value number DstVa...
void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos)
Remove value number and related live segments of LI and its subranges that start at position Pos...