66#define DEBUG_TYPE "regalloc"
68STATISTIC(numJoins,
"Number of interval joins performed");
69STATISTIC(numCrossRCs,
"Number of cross class joins performed");
70STATISTIC(numCommutes,
"Number of instruction commuting performed");
72STATISTIC(NumReMats,
"Number of instructions re-materialized");
73STATISTIC(NumInflated,
"Number of register classes inflated");
74STATISTIC(NumLaneConflicts,
"Number of dead lane conflicts tested");
75STATISTIC(NumLaneResolves,
"Number of dead lane conflicts resolved");
76STATISTIC(NumShrinkToUses,
"Number of shrinkToUses called");
79 cl::desc(
"Coalesce copies (default=true)"),
94 cl::desc(
"Coalesce copies that span blocks (default=subtarget)"),
99 cl::desc(
"Verify machine instrs before and after register coalescing"),
104 cl::desc(
"During rematerialization for a copy, if the def instruction has "
105 "many other copy uses to be rematerialized, delay the multiple "
106 "separate live interval update work and do them all at once after "
107 "all those rematerialization are done. It will save a lot of "
113 cl::desc(
"If the valnos size of an interval is larger than the threshold, "
114 "it is regarded as a large interval. "),
119 cl::desc(
"For a large interval, if it is coalesced with other live "
120 "intervals many times more than the threshold, stop its "
121 "coalescing to control the compile time. "),
146 DenseMap<unsigned, PHIValPos> PHIValToPos;
150 DenseMap<Register, SmallVector<unsigned, 2>> RegToPHIIdx;
155 using DbgValueLoc = std::pair<SlotIndex, MachineInstr *>;
156 DenseMap<Register, std::vector<DbgValueLoc>> DbgVRegToValues;
160 LaneBitmask ShrinkMask;
164 bool ShrinkMainRange =
false;
168 bool JoinGlobalCopies =
false;
172 bool JoinSplitEdges =
false;
175 SmallVector<MachineInstr *, 8> WorkList;
176 SmallVector<MachineInstr *, 8> LocalWorkList;
180 SmallPtrSet<MachineInstr *, 8> ErasedInstrs;
183 SmallVector<MachineInstr *, 8> DeadDefs;
191 DenseSet<Register> ToBeUpdated;
195 DenseMap<Register, unsigned long> LargeLIVisitCounter;
198 void eliminateDeadDefs(LiveRangeEdit *Edit =
nullptr);
201 void LRE_WillEraseInstruction(MachineInstr *
MI)
override;
204 void coalesceLocals();
207 void joinAllIntervals();
211 void copyCoalesceInMBB(MachineBasicBlock *
MBB);
222 void lateLiveIntervalUpdate();
227 bool copyValueUndefInPredecessors(
LiveRange &S,
const MachineBasicBlock *
MBB,
228 LiveQueryResult SLRQ);
232 void setUndefOnPrunedSubRegUses(LiveInterval &LI,
Register Reg,
233 LaneBitmask PrunedLanes);
240 bool joinCopy(MachineInstr *CopyMI,
bool &Again,
241 SmallPtrSetImpl<MachineInstr *> &CurrentErasedInstrs);
246 bool joinIntervals(CoalescerPair &CP);
249 bool joinVirtRegs(CoalescerPair &CP);
254 bool isHighCostLiveInterval(LiveInterval &LI);
257 bool joinReservedPhysReg(CoalescerPair &CP);
264 void mergeSubRangeInto(LiveInterval &LI,
const LiveRange &ToMerge,
265 LaneBitmask LaneMask, CoalescerPair &CP,
271 LaneBitmask LaneMask,
const CoalescerPair &CP);
277 bool adjustCopiesBackFrom(
const CoalescerPair &CP, MachineInstr *CopyMI);
281 bool hasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB,
282 VNInfo *AValNo, VNInfo *BValNo);
292 std::pair<bool, bool> removeCopyByCommutingDef(
const CoalescerPair &CP,
293 MachineInstr *CopyMI);
296 bool removePartialRedundancy(
const CoalescerPair &CP, MachineInstr &CopyMI);
300 bool reMaterializeDef(
const CoalescerPair &CP, MachineInstr *CopyMI,
304 bool canJoinPhys(
const CoalescerPair &CP);
319 void addUndefFlag(
const LiveInterval &
Int, SlotIndex UseIdx,
320 MachineOperand &MO,
unsigned SubRegIdx);
326 MachineInstr *eliminateUndefCopy(MachineInstr *CopyMI);
340 bool applyTerminalRule(
const MachineInstr &Copy)
const;
346 SmallVectorImpl<MachineInstr *> *Dead =
nullptr) {
348 if (LIS->shrinkToUses(LI, Dead)) {
352 LIS->splitSeparateComponents(*LI, SplitLIs);
360 void deleteInstr(MachineInstr *
MI) {
361 ErasedInstrs.insert(
MI);
362 LIS->RemoveMachineInstrFromMaps(*
MI);
363 MI->eraseFromParent();
372 void checkMergingChangesDbgValues(CoalescerPair &CP,
LiveRange &
LHS,
381 RegisterCoalescer() =
default;
382 RegisterCoalescer &operator=(RegisterCoalescer &&
Other) =
default;
384 RegisterCoalescer(LiveIntervals *LIS, SlotIndexes *SI,
385 const MachineLoopInfo *Loops)
386 : LIS(LIS), SI(SI), Loops(Loops) {}
388 bool run(MachineFunction &MF);
395 RegisterCoalescerLegacy() : MachineFunctionPass(ID) {
399 void getAnalysisUsage(AnalysisUsage &AU)
const override;
401 MachineFunctionProperties getClearedProperties()
const override {
402 return MachineFunctionProperties().setIsSSA();
406 bool runOnMachineFunction(MachineFunction &)
override;
411char RegisterCoalescerLegacy::ID = 0;
416 "Register Coalescer",
false,
false)
428 Dst = MI->getOperand(0).getReg();
429 DstSub = MI->getOperand(0).getSubReg();
430 Src = MI->getOperand(1).getReg();
431 SrcSub = MI->getOperand(1).getSubReg();
432 }
else if (
MI->isSubregToReg()) {
433 Dst = MI->getOperand(0).getReg();
434 DstSub = tri.composeSubRegIndices(MI->getOperand(0).getSubReg(),
435 MI->getOperand(3).getImm());
436 Src = MI->getOperand(2).getReg();
437 SrcSub = MI->getOperand(2).getSubReg();
449 if (
MBB->pred_size() != 1 ||
MBB->succ_size() != 1)
452 for (
const auto &
MI : *
MBB) {
453 if (!
MI.isCopyLike() && !
MI.isUnconditionalBranch())
463 Flipped = CrossClass =
false;
466 unsigned SrcSub = 0, DstSub = 0;
469 Partial = SrcSub || DstSub;
472 if (Src.isPhysical()) {
473 if (Dst.isPhysical())
483 if (Dst.isPhysical()) {
486 Dst = TRI.getSubReg(Dst, DstSub);
494 Dst = TRI.getMatchingSuperReg(Dst, SrcSub, SrcRC);
505 if (SrcSub && DstSub) {
507 if (Src == Dst && SrcSub != DstSub)
510 NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub, SrcIdx,
517 NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
521 NewRC = TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub);
524 NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
533 if (DstIdx && !SrcIdx) {
539 CrossClass = NewRC != DstRC || NewRC != SrcRC;
542 assert(Src.isVirtual() &&
"Src must be virtual");
543 assert(!(Dst.isPhysical() && DstSub) &&
"Cannot have a physical SubIdx");
550 if (DstReg.isPhysical())
562 unsigned SrcSub = 0, DstSub = 0;
570 }
else if (Src != SrcReg) {
575 if (DstReg.isPhysical()) {
576 if (!Dst.isPhysical())
578 assert(!DstIdx && !SrcIdx &&
"Inconsistent CoalescerPair state.");
581 Dst = TRI.getSubReg(Dst, DstSub);
584 return DstReg == Dst;
586 return Register(TRI.getSubReg(DstReg, SrcSub)) == Dst;
593 return TRI.composeSubRegIndices(SrcIdx, SrcSub) ==
594 TRI.composeSubRegIndices(DstIdx, DstSub);
597void RegisterCoalescerLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
609void RegisterCoalescer::eliminateDeadDefs(
LiveRangeEdit *Edit) {
619void RegisterCoalescer::LRE_WillEraseInstruction(
MachineInstr *
MI) {
624bool RegisterCoalescer::adjustCopiesBackFrom(
const CoalescerPair &CP,
626 assert(!
CP.isPartial() &&
"This doesn't work for partial copies.");
627 assert(!
CP.isPhys() &&
"This doesn't work for physreg copies.");
652 if (BS == IntB.
end())
654 VNInfo *BValNo = BS->valno;
659 if (BValNo->
def != CopyIdx)
666 if (AS == IntA.
end())
668 VNInfo *AValNo = AS->valno;
674 if (!
CP.isCoalescable(ACopyMI) || !ACopyMI->
isFullCopy())
680 if (ValS == IntB.
end())
698 SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
702 BValNo->
def = FillerStart;
710 if (BValNo != ValS->valno)
719 S.removeSegment(*SS,
true);
723 if (!S.getVNInfoAt(FillerStart)) {
726 S.extendInBlock(BBStart, FillerStart);
728 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
731 if (SubBValNo != SubValSNo)
732 S.MergeValueNumberInto(SubBValNo, SubValSNo);
749 bool RecomputeLiveRange = AS->end == CopyIdx;
750 if (!RecomputeLiveRange) {
753 if (SS != S.end() &&
SS->end == CopyIdx) {
754 RecomputeLiveRange =
true;
759 if (RecomputeLiveRange)
766bool RegisterCoalescer::hasOtherReachingDefs(
LiveInterval &IntA,
775 if (ASeg.
valno != AValNo)
778 if (BI != IntB.
begin())
780 for (; BI != IntB.
end() && ASeg.
end >= BI->start; ++BI) {
781 if (BI->valno == BValNo)
783 if (BI->start <= ASeg.
start && BI->end > ASeg.
start)
785 if (BI->start > ASeg.
start && BI->start < ASeg.
end)
799 bool MergedWithDead =
false;
801 if (S.
valno != SrcValNo)
812 MergedWithDead =
true;
815 return std::make_pair(
Changed, MergedWithDead);
819RegisterCoalescer::removeCopyByCommutingDef(
const CoalescerPair &CP,
852 assert(BValNo !=
nullptr && BValNo->
def == CopyIdx);
858 return {
false,
false};
861 return {
false,
false};
863 return {
false,
false};
870 return {
false,
false};
882 if (!
TII->findCommutedOpIndices(*
DefMI, UseOpIdx, NewDstIdx))
883 return {
false,
false};
888 return {
false,
false};
892 if (hasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
893 return {
false,
false};
902 if (US == IntA.
end() || US->valno != AValNo)
906 return {
false,
false};
916 TII->commuteInstruction(*
DefMI,
false, UseOpIdx, NewDstIdx);
918 return {
false,
false};
920 !
MRI->constrainRegClass(IntB.
reg(),
MRI->getRegClass(IntA.
reg())))
921 return {
false,
false};
922 if (NewMI !=
DefMI) {
947 UseMO.setReg(NewReg);
952 assert(US != IntA.
end() &&
"Use must be live");
953 if (US->valno != AValNo)
956 UseMO.setIsKill(
false);
958 UseMO.substPhysReg(NewReg, *
TRI);
960 UseMO.setReg(NewReg);
979 VNInfo *SubDVNI = S.getVNInfoAt(DefIdx);
982 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
984 S.MergeValueNumberInto(SubDVNI, SubBValNo);
992 bool ShrinkB =
false;
1006 VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
1015 MaskA |= SA.LaneMask;
1021 VNInfo *BSubValNo = SR.empty() ? SR.getNextValue(CopyIdx, Allocator)
1022 : SR.getVNInfoAt(CopyIdx);
1023 assert(BSubValNo != nullptr);
1024 auto P = addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo);
1025 ShrinkB |= P.second;
1027 BSubValNo->def = ASubValNo->def;
1035 if ((SB.LaneMask & MaskA).any())
1039 SB.removeSegment(*S,
true);
1043 BValNo->
def = AValNo->
def;
1045 ShrinkB |=
P.second;
1052 return {
true, ShrinkB};
1102bool RegisterCoalescer::removePartialRedundancy(
const CoalescerPair &CP,
1135 bool FoundReverseCopy =
false;
1154 bool ValB_Changed =
false;
1155 for (
auto *VNI : IntB.
valnos) {
1156 if (VNI->isUnused())
1159 ValB_Changed =
true;
1167 FoundReverseCopy =
true;
1171 if (!FoundReverseCopy)
1181 if (CopyLeftBB && CopyLeftBB->
succ_size() > 1)
1192 if (InsPos != CopyLeftBB->
end()) {
1198 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Move the copy to "
1203 TII->get(TargetOpcode::COPY), IntB.
reg())
1214 ErasedInstrs.
erase(NewCopyMI);
1216 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Remove the copy from "
1227 deleteInstr(&CopyMI);
1243 if (!IntB.
liveAt(UseIdx))
1244 MO.setIsUndef(
true);
1254 VNInfo *BValNo = SR.Query(CopyIdx).valueOutOrDead();
1255 assert(BValNo &&
"All sublanes should be live");
1264 for (
unsigned I = 0;
I != EndPoints.
size();) {
1266 EndPoints[
I] = EndPoints.
back();
1288 assert(!
Reg.isPhysical() &&
"This code cannot handle physreg aliasing");
1291 if (
Op.getReg() !=
Reg)
1295 if (
Op.getSubReg() == 0 ||
Op.isUndef())
1301bool RegisterCoalescer::reMaterializeDef(
const CoalescerPair &CP,
1305 Register SrcReg =
CP.isFlipped() ?
CP.getDstReg() :
CP.getSrcReg();
1306 unsigned SrcIdx =
CP.isFlipped() ?
CP.getDstIdx() :
CP.getSrcIdx();
1307 Register DstReg =
CP.isFlipped() ?
CP.getSrcReg() :
CP.getDstReg();
1308 unsigned DstIdx =
CP.isFlipped() ?
CP.getSrcIdx() :
CP.getDstIdx();
1329 if (!
TII->isReMaterializable(*
DefMI))
1334 bool SawStore =
false;
1338 if (
MCID.getNumDefs() != 1)
1346 if (SrcIdx && DstIdx)
1381 unsigned NewDstIdx =
TRI->composeSubRegIndices(
CP.getSrcIdx(), DefSubIdx);
1383 NewDstReg =
TRI->getSubReg(DstReg, NewDstIdx);
1393 "Only expect to deal with virtual or physical registers");
1407 LiveRangeEdit Edit(&SrcInt, NewRegs, *MF, *LIS,
nullptr,
this);
1421 assert(SrcIdx == 0 &&
CP.isFlipped() &&
1422 "Shouldn't have SrcIdx+DstIdx at this point");
1425 TRI->getCommonSubClass(DefRC, DstRC);
1426 if (CommonRC !=
nullptr) {
1434 if (MO.isReg() && MO.getReg() == DstReg && MO.getSubReg() == DstIdx) {
1456 "No explicit operands after implicit operands.");
1459 "unexpected implicit virtual register def");
1465 ErasedInstrs.
insert(CopyMI);
1489 ((
TRI->getSubReg(MO.
getReg(), DefSubIdx) ==
1502 assert(!
MRI->shouldTrackSubRegLiveness(DstReg) &&
1503 "subrange update for implicit-def of super register may not be "
1504 "properly handled");
1512 if (DefRC !=
nullptr) {
1514 NewRC =
TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx);
1516 NewRC =
TRI->getCommonSubClass(NewRC, DefRC);
1517 assert(NewRC &&
"subreg chosen for remat incompatible with instruction");
1523 SR.LaneMask =
TRI->composeSubRegIndexLaneMask(DstIdx, SR.LaneMask);
1525 MRI->setRegClass(DstReg, NewRC);
1528 updateRegDefsUses(DstReg, DstReg, DstIdx);
1547 MRI->shouldTrackSubRegLiveness(DstReg)) {
1577 if (!SR.liveAt(DefIndex))
1578 SR.createDeadDef(DefIndex,
Alloc);
1579 MaxMask &= ~SR.LaneMask;
1581 if (MaxMask.
any()) {
1599 bool UpdatedSubRanges =
false;
1614 if (!SR.
liveAt(DefIndex))
1620 if ((SR.
LaneMask & DstMask).none()) {
1622 <<
"Removing undefined SubRange "
1635 UpdatedSubRanges =
true;
1638 if (UpdatedSubRanges)
1645 "Only expect virtual or physical registers in remat");
1653 bool HasDefMatchingCopy =
false;
1660 if (DstReg != CopyDstReg)
1663 HasDefMatchingCopy =
true;
1667 if (!HasDefMatchingCopy)
1669 CopyDstReg,
true ,
true ,
false ));
1711 if (
MRI->use_nodbg_empty(SrcReg)) {
1717 UseMO.substPhysReg(DstReg, *
TRI);
1719 UseMO.setReg(DstReg);
1728 if (ToBeUpdated.
count(SrcReg))
1731 unsigned NumCopyUses = 0;
1733 if (UseMO.getParent()->isCopyLike())
1739 if (!DeadDefs.
empty())
1740 eliminateDeadDefs(&Edit);
1742 ToBeUpdated.
insert(SrcReg);
1760 unsigned SrcSubIdx = 0, DstSubIdx = 0;
1761 if (!
isMoveInstr(*
TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
1770 if ((SR.
LaneMask & SrcMask).none())
1775 }
else if (SrcLI.
liveAt(Idx))
1783 assert(Seg !=
nullptr &&
"No segment for defining instruction");
1788 if (((V &&
V->isPHIDef()) || (!V && !DstLI.
liveAt(Idx)))) {
1796 CopyMI->
getOpcode() == TargetOpcode::SUBREG_TO_REG);
1801 CopyMI->
setDesc(
TII->get(TargetOpcode::IMPLICIT_DEF));
1818 if ((SR.
LaneMask & DstMask).none())
1840 if ((SR.
LaneMask & UseMask).none())
1848 isLive = DstLI.
liveAt(UseIdx);
1861 if (MO.
getReg() == DstReg)
1873 bool IsUndef =
true;
1875 if ((S.LaneMask & Mask).none())
1877 if (S.liveAt(UseIdx)) {
1890 ShrinkMainRange =
true;
1899 if (DstInt && DstInt->
hasSubRanges() && DstReg != SrcReg) {
1908 if (
MI.isDebugInstr())
1911 addUndefFlag(*DstInt, UseIdx, MO,
SubReg);
1917 E =
MRI->reg_instr_end();
1926 if (SrcReg == DstReg && !Visited.
insert(
UseMI).second)
1939 for (
unsigned Op :
Ops) {
1945 if (SubIdx && MO.
isDef())
1951 unsigned SubUseIdx =
TRI->composeSubRegIndices(SubIdx, MO.
getSubReg());
1952 if (SubUseIdx != 0 &&
MRI->shouldTrackSubRegLiveness(DstReg)) {
1969 addUndefFlag(*DstInt, UseIdx, MO, SubUseIdx);
1980 dbgs() <<
"\t\tupdated: ";
1988bool RegisterCoalescer::canJoinPhys(
const CoalescerPair &CP) {
1992 if (!
MRI->isReserved(
CP.getDstReg())) {
1993 LLVM_DEBUG(
dbgs() <<
"\tCan only merge into reserved registers.\n");
2002 dbgs() <<
"\tCannot join complex intervals into reserved register.\n");
2006bool RegisterCoalescer::copyValueUndefInPredecessors(
2020void RegisterCoalescer::setUndefOnPrunedSubRegUses(
LiveInterval &LI,
2027 if (SubRegIdx == 0 || MO.
isUndef())
2033 if (!S.
liveAt(Pos) && (PrunedLanes & SubRegMask).any()) {
2049bool RegisterCoalescer::joinCopy(
2056 if (!
CP.setRegisters(CopyMI)) {
2061 if (
CP.getNewRC()) {
2064 <<
"are available for allocation\n");
2068 auto SrcRC =
MRI->getRegClass(
CP.getSrcReg());
2069 auto DstRC =
MRI->getRegClass(
CP.getDstReg());
2070 unsigned SrcIdx =
CP.getSrcIdx();
2071 unsigned DstIdx =
CP.getDstIdx();
2072 if (
CP.isFlipped()) {
2076 if (!
TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx,
2077 CP.getNewRC(), *LIS)) {
2089 eliminateDeadDefs();
2096 if (
MachineInstr *UndefMI = eliminateUndefCopy(CopyMI)) {
2097 if (UndefMI->isImplicitDef())
2099 deleteInstr(CopyMI);
2107 if (
CP.getSrcReg() ==
CP.getDstReg()) {
2109 LLVM_DEBUG(
dbgs() <<
"\tCopy already coalesced: " << LI <<
'\n');
2114 assert(ReadVNI &&
"No value before copy and no <undef> flag.");
2115 assert(ReadVNI != DefVNI &&
"Cannot read and define the same value.");
2130 if (copyValueUndefInPredecessors(S,
MBB, SLRQ)) {
2131 LLVM_DEBUG(
dbgs() <<
"Incoming sublane value is undef at copy\n");
2132 PrunedLanes |= S.LaneMask;
2139 if (PrunedLanes.
any()) {
2140 LLVM_DEBUG(
dbgs() <<
"Pruning undef incoming lanes: " << PrunedLanes
2142 setUndefOnPrunedSubRegUses(LI,
CP.getSrcReg(), PrunedLanes);
2147 deleteInstr(CopyMI);
2156 if (!canJoinPhys(CP)) {
2159 bool IsDefCopy =
false;
2160 if (reMaterializeDef(CP, CopyMI, IsDefCopy))
2173 dbgs() <<
"\tConsidering merging to "
2174 <<
TRI->getRegClassName(
CP.getNewRC()) <<
" with ";
2175 if (
CP.getDstIdx() &&
CP.getSrcIdx())
2177 <<
TRI->getSubRegIndexName(
CP.getDstIdx()) <<
" and "
2179 <<
TRI->getSubRegIndexName(
CP.getSrcIdx()) <<
'\n';
2187 ShrinkMainRange =
false;
2193 if (!joinIntervals(CP)) {
2197 bool IsDefCopy =
false;
2198 if (reMaterializeDef(CP, CopyMI, IsDefCopy))
2203 if (!
CP.isPartial() && !
CP.isPhys()) {
2204 bool Changed = adjustCopiesBackFrom(CP, CopyMI);
2205 bool Shrink =
false;
2207 std::tie(
Changed, Shrink) = removeCopyByCommutingDef(CP, CopyMI);
2209 deleteInstr(CopyMI);
2211 Register DstReg =
CP.isFlipped() ?
CP.getSrcReg() :
CP.getDstReg();
2223 if (!
CP.isPartial() && !
CP.isPhys())
2224 if (removePartialRedundancy(CP, *CopyMI))
2235 if (
CP.isCrossClass()) {
2237 MRI->setRegClass(
CP.getDstReg(),
CP.getNewRC());
2248 if (ErasedInstrs.
erase(CopyMI))
2250 CurrentErasedInstrs.
insert(CopyMI);
2255 updateRegDefsUses(
CP.getDstReg(),
CP.getDstReg(),
CP.getDstIdx());
2256 updateRegDefsUses(
CP.getSrcReg(),
CP.getDstReg(),
CP.getSrcIdx());
2259 if (ShrinkMask.
any()) {
2262 if ((S.LaneMask & ShrinkMask).none())
2267 ShrinkMainRange =
true;
2275 if (ToBeUpdated.
count(
CP.getSrcReg()))
2276 ShrinkMainRange =
true;
2278 if (ShrinkMainRange) {
2288 TRI->updateRegAllocHint(
CP.getSrcReg(),
CP.getDstReg(), *MF);
2293 dbgs() <<
"\tResult = ";
2305bool RegisterCoalescer::joinReservedPhysReg(
CoalescerPair &CP) {
2308 assert(
CP.isPhys() &&
"Must be a physreg copy");
2309 assert(
MRI->isReserved(DstReg) &&
"Not a reserved register");
2313 assert(
RHS.containsOneValue() &&
"Invalid join with reserved register");
2322 if (!
MRI->isConstantPhysReg(DstReg)) {
2326 if (!
MRI->isReserved(*RI))
2339 !RegMaskUsable.
test(DstReg.
id())) {
2352 if (
CP.isFlipped()) {
2360 CopyMI =
MRI->getVRegDef(SrcReg);
2361 deleteInstr(CopyMI);
2370 if (!
MRI->hasOneNonDBGUse(SrcReg)) {
2381 CopyMI = &*
MRI->use_instr_nodbg_begin(SrcReg);
2385 if (!
MRI->isConstantPhysReg(DstReg)) {
2393 if (
MI->readsRegister(DstReg,
TRI)) {
2403 <<
printReg(DstReg,
TRI) <<
" at " << CopyRegIdx <<
"\n");
2406 deleteInstr(CopyMI);
2416 MRI->clearKillFlags(
CP.getSrcReg());
2501 const unsigned SubIdx;
2505 const LaneBitmask LaneMask;
2509 const bool SubRangeJoin;
2512 const bool TrackSubRegLiveness;
2515 SmallVectorImpl<VNInfo *> &NewVNInfo;
2517 const CoalescerPair &
CP;
2519 SlotIndexes *Indexes;
2520 const TargetRegisterInfo *
TRI;
2524 SmallVector<int, 8> Assignments;
2528 enum ConflictResolution {
2560 ConflictResolution Resolution = CR_Keep;
2563 LaneBitmask WriteLanes;
2567 LaneBitmask ValidLanes;
2570 VNInfo *RedefVNI =
nullptr;
2573 VNInfo *OtherVNI =
nullptr;
2586 bool ErasableImplicitDef =
false;
2590 bool Pruned =
false;
2593 bool PrunedComputed =
false;
2600 bool Identical =
false;
2604 bool isAnalyzed()
const {
return WriteLanes.
any(); }
2608 void mustKeepImplicitDef(
const TargetRegisterInfo &
TRI,
2609 const MachineInstr &ImpDef) {
2611 ErasableImplicitDef =
false;
2622 LaneBitmask computeWriteLanes(
const MachineInstr *
DefMI,
bool &Redef)
const;
2625 std::pair<const VNInfo *, Register> followCopyChain(
const VNInfo *VNI)
const;
2627 bool valuesIdentical(VNInfo *Value0, VNInfo *Value1,
2628 const JoinVals &
Other)
const;
2637 ConflictResolution analyzeValue(
unsigned ValNo, JoinVals &
Other);
2642 void computeAssignment(
unsigned ValNo, JoinVals &
Other);
2660 taintExtent(
unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &
Other,
2661 SmallVectorImpl<std::pair<SlotIndex, LaneBitmask>> &TaintExtent);
2665 bool usesLanes(
const MachineInstr &
MI,
Register,
unsigned, LaneBitmask)
const;
2673 bool isPrunedValue(
unsigned ValNo, JoinVals &
Other);
2677 SmallVectorImpl<VNInfo *> &newVNInfo,
const CoalescerPair &cp,
2678 LiveIntervals *lis,
const TargetRegisterInfo *
TRI,
bool SubRangeJoin,
2679 bool TrackSubRegLiveness)
2680 : LR(LR),
Reg(
Reg), SubIdx(SubIdx), LaneMask(LaneMask),
2681 SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
2682 NewVNInfo(newVNInfo),
CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
2683 TRI(
TRI), Assignments(LR.getNumValNums(), -1),
2684 Vals(LR.getNumValNums()) {}
2688 bool mapValues(JoinVals &
Other);
2692 bool resolveConflicts(JoinVals &
Other);
2697 void pruneValues(JoinVals &
Other, SmallVectorImpl<SlotIndex> &EndPoints,
2703 void pruneSubRegValues(LiveInterval &LI, LaneBitmask &ShrinkMask);
2712 void pruneMainSegments(LiveInterval &LI,
bool &ShrinkMainRange);
2718 void eraseInstrs(SmallPtrSetImpl<MachineInstr *> &ErasedInstrs,
2719 SmallVectorImpl<Register> &ShrinkRegs,
2720 LiveInterval *LI =
nullptr);
2723 void removeImplicitDefs();
2726 const int *getAssignments()
const {
return Assignments.
data(); }
2729 ConflictResolution getResolution(
unsigned Num)
const {
2730 return Vals[Num].Resolution;
2737 bool &Redef)
const {
2742 L |=
TRI->getSubRegIndexLaneMask(
2750std::pair<const VNInfo *, Register>
2751JoinVals::followCopyChain(
const VNInfo *VNI)
const {
2757 assert(
MI &&
"No defining instruction");
2758 if (!
MI->isFullCopy())
2759 return std::make_pair(VNI, TrackReg);
2760 Register SrcReg =
MI->getOperand(1).getReg();
2762 return std::make_pair(VNI, TrackReg);
2776 LaneBitmask SMask =
TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
2777 if ((SMask & LaneMask).
none())
2785 return std::make_pair(VNI, TrackReg);
2788 if (ValueIn ==
nullptr) {
2795 return std::make_pair(
nullptr, SrcReg);
2800 return std::make_pair(VNI, TrackReg);
2803bool JoinVals::valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
2804 const JoinVals &
Other)
const {
2807 std::tie(Orig0, Reg0) = followCopyChain(Value0);
2808 if (Orig0 == Value1 && Reg0 ==
Other.Reg)
2813 std::tie(Orig1, Reg1) =
Other.followCopyChain(Value1);
2817 if (Orig0 ==
nullptr || Orig1 ==
nullptr)
2818 return Orig0 == Orig1 && Reg0 == Reg1;
2824 return Orig0->
def == Orig1->
def && Reg0 == Reg1;
2827JoinVals::ConflictResolution JoinVals::analyzeValue(
unsigned ValNo,
2829 Val &
V = Vals[ValNo];
2830 assert(!
V.isAnalyzed() &&
"Value has already been analyzed!");
2842 :
TRI->getSubRegIndexLaneMask(SubIdx);
2843 V.ValidLanes =
V.WriteLanes = Lanes;
2852 V.ErasableImplicitDef =
true;
2856 V.ValidLanes =
V.WriteLanes = computeWriteLanes(
DefMI, Redef);
2875 assert((TrackSubRegLiveness ||
V.RedefVNI) &&
2876 "Instruction is reading nonexistent value");
2877 if (
V.RedefVNI !=
nullptr) {
2878 computeAssignment(
V.RedefVNI->id,
Other);
2879 V.ValidLanes |= Vals[
V.RedefVNI->id].ValidLanes;
2891 V.ErasableImplicitDef =
true;
2908 if (OtherVNI->
def < VNI->
def)
2909 Other.computeAssignment(OtherVNI->
id, *
this);
2914 return CR_Impossible;
2916 V.OtherVNI = OtherVNI;
2917 Val &OtherV =
Other.Vals[OtherVNI->
id];
2921 if (!OtherV.isAnalyzed() ||
Other.Assignments[OtherVNI->
id] == -1)
2928 if ((
V.ValidLanes & OtherV.ValidLanes).any())
2930 return CR_Impossible;
2944 Other.computeAssignment(
V.OtherVNI->id, *
this);
2945 Val &OtherV =
Other.Vals[
V.OtherVNI->id];
2947 if (OtherV.ErasableImplicitDef) {
2967 <<
", keeping it.\n");
2968 OtherV.mustKeepImplicitDef(*
TRI, *OtherImpDef);
2975 dbgs() <<
"IMPLICIT_DEF defined at " <<
V.OtherVNI->def
2976 <<
" may be live into EH pad successors, keeping it.\n");
2977 OtherV.mustKeepImplicitDef(*
TRI, *OtherImpDef);
2980 OtherV.ValidLanes &= ~OtherV.WriteLanes;
2995 if (
CP.isCoalescable(
DefMI)) {
2998 V.ValidLanes &= ~V.WriteLanes | OtherV.ValidLanes;
3013 valuesIdentical(VNI,
V.OtherVNI,
Other)) {
3036 if ((
V.WriteLanes & OtherV.ValidLanes).none())
3049 "Only early clobber defs can overlap a kill");
3050 return CR_Impossible;
3057 if ((
TRI->getSubRegIndexLaneMask(
Other.SubIdx) & ~
V.WriteLanes).none())
3058 return CR_Impossible;
3060 if (TrackSubRegLiveness) {
3065 if (!OtherLI.hasSubRanges()) {
3067 return (OtherMask &
V.WriteLanes).none() ? CR_Replace : CR_Impossible;
3075 TRI->composeSubRegIndexLaneMask(
Other.SubIdx, OtherSR.LaneMask);
3076 if ((OtherMask &
V.WriteLanes).none())
3079 auto OtherSRQ = OtherSR.Query(VNI->
def);
3080 if (OtherSRQ.valueIn() && OtherSRQ.endPoint() > VNI->
def) {
3082 return CR_Impossible;
3095 return CR_Impossible;
3104 return CR_Unresolved;
3107void JoinVals::computeAssignment(
unsigned ValNo, JoinVals &
Other) {
3108 Val &
V = Vals[ValNo];
3109 if (
V.isAnalyzed()) {
3112 assert(Assignments[ValNo] != -1 &&
"Bad recursion?");
3115 switch ((
V.Resolution = analyzeValue(ValNo,
Other))) {
3119 assert(
V.OtherVNI &&
"OtherVNI not assigned, can't merge.");
3120 assert(
Other.Vals[
V.OtherVNI->id].isAnalyzed() &&
"Missing recursion");
3121 Assignments[ValNo] =
Other.Assignments[
V.OtherVNI->id];
3125 <<
V.OtherVNI->def <<
" --> @"
3126 << NewVNInfo[Assignments[ValNo]]->def <<
'\n');
3129 case CR_Unresolved: {
3131 assert(
V.OtherVNI &&
"OtherVNI not assigned, can't prune");
3132 Val &OtherV =
Other.Vals[
V.OtherVNI->id];
3133 OtherV.Pruned =
true;
3138 Assignments[ValNo] = NewVNInfo.
size();
3144bool JoinVals::mapValues(JoinVals &
Other) {
3146 computeAssignment(i,
Other);
3147 if (Vals[i].Resolution == CR_Impossible) {
3156bool JoinVals::taintExtent(
3165 assert(OtherI !=
Other.LR.end() &&
"No conflict?");
3170 if (End >= MBBEnd) {
3172 << OtherI->valno->id <<
'@' << OtherI->start <<
'\n');
3176 << OtherI->valno->id <<
'@' << OtherI->start <<
" to "
3181 TaintExtent.push_back(std::make_pair(End, TaintedLanes));
3184 if (++OtherI ==
Other.LR.end() || OtherI->start >= MBBEnd)
3188 const Val &OV =
Other.Vals[OtherI->valno->id];
3189 TaintedLanes &= ~OV.WriteLanes;
3192 }
while (TaintedLanes.
any());
3198 if (
MI.isDebugOrPseudoInstr())
3205 unsigned S =
TRI->composeSubRegIndices(SubIdx, MO.
getSubReg());
3206 if ((Lanes &
TRI->getSubRegIndexLaneMask(S)).any())
3212bool JoinVals::resolveConflicts(JoinVals &
Other) {
3215 assert(
V.Resolution != CR_Impossible &&
"Unresolvable conflict");
3216 if (
V.Resolution != CR_Unresolved)
3225 assert(
V.OtherVNI &&
"Inconsistent conflict resolution.");
3227 const Val &OtherV =
Other.Vals[
V.OtherVNI->id];
3232 LaneBitmask TaintedLanes =
V.WriteLanes & OtherV.ValidLanes;
3234 if (!taintExtent(i, TaintedLanes,
Other, TaintExtent))
3238 assert(!TaintExtent.
empty() &&
"There should be at least one conflict.");
3251 "Interference ends on VNI->def. Should have been handled earlier");
3254 assert(LastMI &&
"Range must end at a proper instruction");
3255 unsigned TaintNum = 0;
3258 if (usesLanes(*
MI,
Other.Reg,
Other.SubIdx, TaintedLanes)) {
3263 if (&*
MI == LastMI) {
3264 if (++TaintNum == TaintExtent.
size())
3267 assert(LastMI &&
"Range must end at a proper instruction");
3268 TaintedLanes = TaintExtent[TaintNum].second;
3274 V.Resolution = CR_Replace;
3280bool JoinVals::isPrunedValue(
unsigned ValNo, JoinVals &
Other) {
3281 Val &
V = Vals[ValNo];
3282 if (
V.Pruned ||
V.PrunedComputed)
3285 if (
V.Resolution != CR_Erase &&
V.Resolution != CR_Merge)
3290 V.PrunedComputed =
true;
3291 V.Pruned =
Other.isPrunedValue(
V.OtherVNI->id, *
this);
3295void JoinVals::pruneValues(JoinVals &
Other,
3297 bool changeInstrs) {
3300 switch (Vals[i].Resolution) {
3310 Val &OtherV =
Other.Vals[Vals[i].OtherVNI->id];
3312 OtherV.ErasableImplicitDef && OtherV.Resolution == CR_Keep;
3313 if (!
Def.isBlock()) {
3333 <<
": " <<
Other.LR <<
'\n');
3338 if (isPrunedValue(i,
Other)) {
3345 << Def <<
": " << LR <<
'\n');
3403 bool DidPrune =
false;
3408 if (
V.Resolution != CR_Erase &&
3409 (
V.Resolution != CR_Keep || !
V.ErasableImplicitDef || !
V.Pruned))
3416 OtherDef =
V.OtherVNI->def;
3419 LLVM_DEBUG(
dbgs() <<
"\t\tExpecting instruction removal at " << Def
3427 if (ValueOut !=
nullptr &&
3429 (
V.Identical &&
V.Resolution == CR_Erase && ValueOut->
def == Def))) {
3431 <<
" at " << Def <<
"\n");
3438 if (
V.Identical && S.Query(OtherDef).valueOutOrDead()) {
3448 ShrinkMask |= S.LaneMask;
3462 ShrinkMask |= S.LaneMask;
3474 if (VNI->
def == Def)
3480void JoinVals::pruneMainSegments(
LiveInterval &LI,
bool &ShrinkMainRange) {
3484 if (Vals[i].Resolution != CR_Keep)
3489 Vals[i].Pruned =
true;
3490 ShrinkMainRange =
true;
3494void JoinVals::removeImplicitDefs() {
3497 if (
V.Resolution != CR_Keep || !
V.ErasableImplicitDef || !
V.Pruned)
3513 switch (Vals[i].Resolution) {
3518 if (!Vals[i].ErasableImplicitDef || !Vals[i].Pruned)
3530 if (LI !=
nullptr) {
3555 ED = ED.
isValid() ? std::min(ED,
I->start) :
I->start;
3557 LE =
LE.isValid() ? std::max(LE,
I->end) :
I->
end;
3560 NewEnd = std::min(NewEnd, LE);
3562 NewEnd = std::min(NewEnd, ED);
3568 if (S != LR.
begin())
3569 std::prev(S)->end = NewEnd;
3573 dbgs() <<
"\t\tremoved " << i <<
'@' <<
Def <<
": " << LR <<
'\n';
3575 dbgs() <<
"\t\t LHS = " << *LI <<
'\n';
3582 assert(
MI &&
"No instruction to erase");
3591 MI->eraseFromParent();
3604 JoinVals RHSVals(RRange,
CP.getSrcReg(),
CP.getSrcIdx(), LaneMask, NewVNInfo,
3605 CP, LIS,
TRI,
true,
true);
3606 JoinVals LHSVals(LRange,
CP.getDstReg(),
CP.getDstIdx(), LaneMask, NewVNInfo,
3607 CP, LIS,
TRI,
true,
true);
3614 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals)) {
3619 if (!LHSVals.resolveConflicts(RHSVals) ||
3620 !RHSVals.resolveConflicts(LHSVals)) {
3631 LHSVals.pruneValues(RHSVals, EndPoints,
false);
3632 RHSVals.pruneValues(LHSVals, EndPoints,
false);
3634 LHSVals.removeImplicitDefs();
3635 RHSVals.removeImplicitDefs();
3640 LRange.
join(RRange, LHSVals.getAssignments(), RHSVals.getAssignments(),
3645 if (EndPoints.
empty())
3651 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3652 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3653 dbgs() << EndPoints[i];
3657 dbgs() <<
": " << LRange <<
'\n';
3662void RegisterCoalescer::mergeSubRangeInto(
LiveInterval &LI,
3666 unsigned ComposeSubRegIdx) {
3676 joinSubRegRanges(SR, RangeCopy, SR.
LaneMask, CP);
3682bool RegisterCoalescer::isHighCostLiveInterval(
LiveInterval &LI) {
3685 auto &Counter = LargeLIVisitCounter[LI.
reg()];
3697 bool TrackSubRegLiveness =
MRI->shouldTrackSubRegLiveness(*
CP.getNewRC());
3699 NewVNInfo, CP, LIS,
TRI,
false, TrackSubRegLiveness);
3701 NewVNInfo, CP, LIS,
TRI,
false, TrackSubRegLiveness);
3705 if (isHighCostLiveInterval(
LHS) || isHighCostLiveInterval(
RHS))
3710 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals))
3714 if (!LHSVals.resolveConflicts(RHSVals) || !RHSVals.resolveConflicts(LHSVals))
3718 if (
RHS.hasSubRanges() ||
LHS.hasSubRanges()) {
3723 unsigned DstIdx =
CP.getDstIdx();
3724 if (!
LHS.hasSubRanges()) {
3726 :
TRI->getSubRegIndexLaneMask(DstIdx);
3730 }
else if (DstIdx != 0) {
3741 unsigned SrcIdx =
CP.getSrcIdx();
3742 if (!
RHS.hasSubRanges()) {
3744 :
TRI->getSubRegIndexLaneMask(SrcIdx);
3745 mergeSubRangeInto(
LHS,
RHS, Mask, CP, DstIdx);
3750 mergeSubRangeInto(
LHS, R, Mask, CP, DstIdx);
3757 LHSVals.pruneMainSegments(
LHS, ShrinkMainRange);
3759 LHSVals.pruneSubRegValues(
LHS, ShrinkMask);
3760 RHSVals.pruneSubRegValues(
LHS, ShrinkMask);
3761 }
else if (TrackSubRegLiveness && !
CP.getDstIdx() &&
CP.getSrcIdx()) {
3763 CP.getNewRC()->getLaneMask(),
LHS);
3764 mergeSubRangeInto(
LHS,
RHS,
TRI->getSubRegIndexLaneMask(
CP.getSrcIdx()), CP,
3766 LHSVals.pruneMainSegments(
LHS, ShrinkMainRange);
3767 LHSVals.pruneSubRegValues(
LHS, ShrinkMask);
3775 LHSVals.pruneValues(RHSVals, EndPoints,
true);
3776 RHSVals.pruneValues(LHSVals, EndPoints,
true);
3781 LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, &
LHS);
3782 RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
3783 while (!ShrinkRegs.
empty())
3787 checkMergingChangesDbgValues(CP,
LHS, LHSVals,
RHS, RHSVals);
3791 auto RegIt = RegToPHIIdx.
find(
CP.getSrcReg());
3792 if (RegIt != RegToPHIIdx.
end()) {
3794 for (
unsigned InstID : RegIt->second) {
3795 auto PHIIt = PHIValToPos.
find(InstID);
3800 auto LII =
RHS.find(
SI);
3801 if (LII ==
RHS.end() || LII->start >
SI)
3816 if (
CP.getSrcIdx() != 0 ||
CP.getDstIdx() != 0)
3819 if (PHIIt->second.SubReg && PHIIt->second.SubReg !=
CP.getSrcIdx())
3823 PHIIt->second.Reg =
CP.getDstReg();
3827 if (
CP.getSrcIdx() != 0)
3828 PHIIt->second.SubReg =
CP.getSrcIdx();
3834 auto InstrNums = RegIt->second;
3835 RegToPHIIdx.
erase(RegIt);
3839 RegIt = RegToPHIIdx.
find(
CP.getDstReg());
3840 if (RegIt != RegToPHIIdx.
end())
3843 RegToPHIIdx.
insert({
CP.getDstReg(), InstrNums});
3847 LHS.join(
RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
3852 MRI->clearKillFlags(
LHS.reg());
3853 MRI->clearKillFlags(
RHS.reg());
3855 if (!EndPoints.
empty()) {
3859 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3860 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3861 dbgs() << EndPoints[i];
3865 dbgs() <<
": " <<
LHS <<
'\n';
3874 return CP.isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(
CP);
3884 for (
auto *
X : ToInsert) {
3885 for (
const auto &
Op :
X->debug_operands()) {
3886 if (
Op.isReg() &&
Op.getReg().isVirtual())
3887 DbgVRegToValues[
Op.getReg()].push_back({
Slot,
X});
3897 for (
auto &
MBB : MF) {
3900 for (
auto &
MI :
MBB) {
3901 if (
MI.isDebugValue()) {
3903 return MO.isReg() && MO.getReg().isVirtual();
3905 ToInsert.push_back(&
MI);
3906 }
else if (!
MI.isDebugOrPseudoInstr()) {
3908 CloseNewDVRange(CurrentSlot);
3917 for (
auto &Pair : DbgVRegToValues)
3921void RegisterCoalescer::checkMergingChangesDbgValues(
CoalescerPair &CP,
3925 JoinVals &RHSVals) {
3927 checkMergingChangesDbgValuesImpl(
Reg,
RHS,
LHS, LHSVals);
3931 checkMergingChangesDbgValuesImpl(
Reg,
LHS,
RHS, RHSVals);
3935 ScanForSrcReg(
CP.getSrcReg());
3936 ScanForDstReg(
CP.getDstReg());
3939void RegisterCoalescer::checkMergingChangesDbgValuesImpl(
Register Reg,
3942 JoinVals &RegVals) {
3944 auto VRegMapIt = DbgVRegToValues.
find(
Reg);
3945 if (VRegMapIt == DbgVRegToValues.
end())
3948 auto &DbgValueSet = VRegMapIt->second;
3949 auto DbgValueSetIt = DbgValueSet.begin();
3950 auto SegmentIt = OtherLR.
begin();
3952 bool LastUndefResult =
false;
3957 auto ShouldUndef = [&RegVals, &
RegLR, &LastUndefResult,
3962 if (LastUndefIdx == Idx)
3963 return LastUndefResult;
3969 auto OtherIt =
RegLR.find(Idx);
3970 if (OtherIt ==
RegLR.end())
3979 auto Resolution = RegVals.getResolution(OtherIt->valno->id);
3981 Resolution != JoinVals::CR_Keep && Resolution != JoinVals::CR_Erase;
3983 return LastUndefResult;
3989 while (DbgValueSetIt != DbgValueSet.end() && SegmentIt != OtherLR.
end()) {
3990 if (DbgValueSetIt->first < SegmentIt->end) {
3993 if (DbgValueSetIt->first >= SegmentIt->start) {
3994 bool HasReg = DbgValueSetIt->second->hasDebugOperandForReg(
Reg);
3995 bool ShouldUndefReg = ShouldUndef(DbgValueSetIt->first);
3996 if (HasReg && ShouldUndefReg) {
3998 DbgValueSetIt->second->setDebugValueUndef();
4012struct MBBPriorityInfo {
4013 MachineBasicBlock *
MBB;
4017 MBBPriorityInfo(MachineBasicBlock *mbb,
unsigned depth,
bool issplit)
4018 :
MBB(mbb),
Depth(depth), IsSplit(issplit) {}
4028 const MBBPriorityInfo *
RHS) {
4030 if (
LHS->Depth !=
RHS->Depth)
4031 return LHS->Depth >
RHS->Depth ? -1 : 1;
4034 if (
LHS->IsSplit !=
RHS->IsSplit)
4035 return LHS->IsSplit ? -1 : 1;
4039 unsigned cl =
LHS->MBB->pred_size() +
LHS->MBB->succ_size();
4040 unsigned cr =
RHS->MBB->pred_size() +
RHS->MBB->succ_size();
4042 return cl > cr ? -1 : 1;
4045 return LHS->MBB->getNumber() <
RHS->MBB->getNumber() ? -1 : 1;
4050 if (!Copy->isCopy())
4053 if (Copy->getOperand(1).isUndef())
4056 Register SrcReg = Copy->getOperand(1).getReg();
4057 Register DstReg = Copy->getOperand(0).getReg();
4065void RegisterCoalescer::lateLiveIntervalUpdate() {
4071 if (!DeadDefs.
empty())
4072 eliminateDeadDefs();
4074 ToBeUpdated.
clear();
4077bool RegisterCoalescer::copyCoalesceWorkList(
4079 bool Progress =
false;
4091 bool Success = joinCopy(
MI, Again, CurrentErasedInstrs);
4097 if (!CurrentErasedInstrs.
empty()) {
4099 if (
MI && CurrentErasedInstrs.
count(
MI))
4103 if (
MI && CurrentErasedInstrs.
count(
MI))
4114 assert(Copy.isCopyLike());
4117 if (&
MI != &Copy &&
MI.isCopyLike())
4122bool RegisterCoalescer::applyTerminalRule(
const MachineInstr &Copy)
const {
4127 unsigned SrcSubReg = 0, DstSubReg = 0;
4128 if (!
isMoveInstr(*
TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg))
4149 if (&
MI == &Copy || !
MI.isCopyLike() ||
MI.getParent() != OrigBB)
4152 unsigned OtherSrcSubReg = 0, OtherSubReg = 0;
4153 if (!
isMoveInstr(*
TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg,
4156 if (OtherReg == SrcReg)
4157 OtherReg = OtherSrcReg;
4176 const unsigned PrevSize = WorkList.
size();
4177 if (JoinGlobalCopies) {
4183 if (!
MI.isCopyLike())
4185 bool ApplyTerminalRule = applyTerminalRule(
MI);
4187 if (ApplyTerminalRule)
4192 if (ApplyTerminalRule)
4199 LocalWorkList.
append(LocalTerminals.
begin(), LocalTerminals.
end());
4206 if (MII.isCopyLike()) {
4207 if (applyTerminalRule(MII))
4220 if (copyCoalesceWorkList(CurrList))
4222 std::remove(WorkList.
begin() + PrevSize, WorkList.
end(),
nullptr),
4226void RegisterCoalescer::coalesceLocals() {
4227 copyCoalesceWorkList(LocalWorkList);
4232 LocalWorkList.clear();
4235void RegisterCoalescer::joinAllIntervals() {
4236 LLVM_DEBUG(
dbgs() <<
"********** JOINING INTERVALS ***********\n");
4237 assert(WorkList.
empty() && LocalWorkList.empty() &&
"Old data still around.");
4239 std::vector<MBBPriorityInfo> MBBs;
4240 MBBs.reserve(MF->size());
4242 MBBs.push_back(MBBPriorityInfo(&
MBB,
Loops->getLoopDepth(&
MBB),
4248 unsigned CurrDepth = std::numeric_limits<unsigned>::max();
4249 for (MBBPriorityInfo &
MBB : MBBs) {
4251 if (JoinGlobalCopies &&
MBB.Depth < CurrDepth) {
4253 CurrDepth =
MBB.Depth;
4255 copyCoalesceInMBB(
MBB.MBB);
4257 lateLiveIntervalUpdate();
4262 while (copyCoalesceWorkList(WorkList))
4264 lateLiveIntervalUpdate();
4274 RegisterCoalescer Impl(&LIS,
SI, &
Loops);
4286bool RegisterCoalescerLegacy::runOnMachineFunction(
MachineFunction &MF) {
4287 auto *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
4288 auto *
Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
4289 auto *SIWrapper = getAnalysisIfAvailable<SlotIndexesWrapperPass>();
4290 SlotIndexes *
SI = SIWrapper ? &SIWrapper->getSI() :
nullptr;
4291 RegisterCoalescer Impl(LIS,
SI,
Loops);
4292 return Impl.run(MF);
4296 LLVM_DEBUG(
dbgs() <<
"********** REGISTER COALESCER **********\n"
4297 <<
"********** Function: " << fn.
getName() <<
'\n');
4309 dbgs() <<
"* Skipped as it exposes functions that returns twice.\n");
4329 unsigned SubReg = DebugPHI.second.SubReg;
4332 PHIValToPos.
insert(std::make_pair(DebugPHI.first,
P));
4333 RegToPHIIdx[
Reg].push_back(DebugPHI.first);
4342 MF->
verify(LIS,
SI,
"Before register coalescing", &
errs());
4344 DbgVRegToValues.
clear();
4361 if (
MRI->reg_nodbg_empty(
Reg))
4363 if (
MRI->recomputeRegClass(
Reg)) {
4365 <<
TRI->getRegClassName(
MRI->getRegClass(
Reg)) <<
'\n');
4372 if (!
MRI->shouldTrackSubRegLiveness(
Reg)) {
4380 assert((S.LaneMask & ~MaxMask).none());
4391 auto it = PHIValToPos.
find(
p.first);
4393 p.second.Reg = it->second.Reg;
4394 p.second.SubReg = it->second.SubReg;
4397 PHIValToPos.
clear();
4398 RegToPHIIdx.
clear();
4403 MF->
verify(LIS,
SI,
"After register coalescing", &
errs());
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
const HexagonInstrInfo * TII
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
A common definition of LaneBitmask for use in TableGen and CodeGen.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
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.
static bool isLocalCopy(MachineInstr *Copy, const LiveIntervals *LIS)
static bool isSplitEdge(const MachineBasicBlock *MBB)
Return true if this block should be vacated by the coalescer to eliminate branches.
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),...
static cl::opt< unsigned > LargeIntervalSizeThreshold("large-interval-size-threshold", cl::Hidden, cl::desc("If the valnos size of an interval is larger than the threshold, " "it is regarded as a large interval. "), cl::init(100))
static bool isDefInSubRange(LiveInterval &LI, SlotIndex Def)
Check if any of the subranges of LI contain a definition at Def.
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 @Dst and use value number D...
static bool isLiveThrough(const LiveQueryResult Q)
static bool isTerminalReg(Register DstReg, const MachineInstr &Copy, const MachineRegisterInfo *MRI)
Check if DstReg is a terminal node.
static cl::opt< bool > VerifyCoalescing("verify-coalescing", cl::desc("Verify machine instrs before and after register coalescing"), cl::Hidden)
register Register static false bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI, Register &Src, Register &Dst, unsigned &SrcSub, unsigned &DstSub)
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 cl::opt< bool > EnableJoining("join-liveintervals", cl::desc("Coalesce copies (default=true)"), cl::init(true), cl::Hidden)
static cl::opt< unsigned > LargeIntervalFreqThreshold("large-interval-freq-threshold", cl::Hidden, cl::desc("For a large interval, if it is coalesced with other live " "intervals many times more than the threshold, stop its " "coalescing to control the compile time. "), cl::init(256))
static bool definesFullReg(const MachineInstr &MI, Register Reg)
Returns true if MI defines the full vreg Reg, as opposed to just defining a subregister.
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))
static cl::opt< bool > UseTerminalRule("terminal-rule", cl::desc("Apply the terminal rule"), cl::init(false), cl::Hidden)
SI Optimize VGPR LiveRange
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static DenseMap< Register, std::vector< std::pair< SlotIndex, MachineInstr * > > > buildVRegToDbgValueMap(MachineFunction &MF, const LiveIntervals *Liveness)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
Represents analyses that only rely on functions' control flow.
A helper class for register coalescers.
bool flip()
Swap SrcReg and DstReg.
bool isCoalescable(const MachineInstr *) const
Return true if MI is a copy instruction that will become an identity copy after coalescing.
bool setRegisters(const MachineInstr *)
Set registers to match the copy instruction MI.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool isAsCheapAsAMove(const MachineInstr &MI) const override
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
bool hasSubRanges() const
Returns true if subregister liveness information is available.
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...
iterator_range< subrange_iterator > subranges()
LLVM_ABI void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, std::function< void(LiveInterval::SubRange &)> Apply, const SlotIndexes &Indexes, const TargetRegisterInfo &TRI, unsigned ComposeSubRegIdx=0)
Refines the subranges to support LaneMask.
LLVM_ABI void computeSubRangeUndefs(SmallVectorImpl< SlotIndex > &Undefs, LaneBitmask LaneMask, const MachineRegisterInfo &MRI, const SlotIndexes &Indexes) const
For a given lane mask LaneMask, compute indexes at which the lane is marked undefined by subregister ...
SubRange * createSubRange(BumpPtrAllocator &Allocator, LaneBitmask LaneMask)
Creates a new empty subregister live range.
LLVM_ABI void clearSubRanges()
Removes all subregister liveness information.
bool hasInterval(Register Reg) const
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
LLVM_ABI bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const
Returns true if VNI is killed by any PHI-def values in LI.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI bool checkRegMaskInterference(const LiveInterval &LI, BitVector &UsableRegs)
Test if LI is live across any register mask instructions, and compute a bit mask of physical register...
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
VNInfo::Allocator & getVNInfoAllocator()
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
LiveRange * getCachedRegUnit(unsigned Unit)
Return the live range for register unit Unit if it has already been computed, or nullptr if it hasn't...
LiveInterval & getInterval(Register Reg)
LLVM_ABI 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.
void removeInterval(Register Reg)
Interval removal.
LLVM_ABI MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
If LI is confined to a single basic block, return a pointer to that block.
LLVM_ABI void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos)
Remove value number and related live segments of LI and its subranges that start at position Pos.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LLVM_ABI void extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
LLVM_ABI void dump() const
LLVM_ABI void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
bool isLiveInToMBB(const LiveRange &LR, const MachineBasicBlock *mbb) const
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
Result of a LiveRange query.
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
SlotIndex endPoint() const
Return the end point of the last live range segment to interact with the instruction,...
bool isKill() const
Return true if the live-in value is killed by this instruction.
Callback methods for LiveRangeEdit owners.
SlotIndex rematerializeAt(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, const Remat &RM, const TargetRegisterInfo &, bool Late=false, unsigned SubIdx=0, MachineInstr *ReplaceIndexMI=nullptr)
rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an instruction into MBB before...
void eliminateDeadDefs(SmallVectorImpl< MachineInstr * > &Dead, ArrayRef< Register > RegsBeingSpilled={})
eliminateDeadDefs - Try to delete machine instructions that are now dead (allDefsAreDead returns true...
This class represents the liveness of a register, stack slot, etc.
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
LLVM_ABI iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
Segments::iterator iterator
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
LLVM_ABI void join(LiveRange &Other, const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVectorImpl< VNInfo * > &NewVNInfo)
join - Join two live ranges (this, and other) together.
bool liveAt(SlotIndex index) const
LLVM_ABI VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
LLVM_ABI void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
bool overlaps(const LiveRange &other) const
overlaps - Return true if the intersection of the two live ranges is not empty.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarily including Idx,...
bool verify() const
Walk the range and assert if any invariants fail to hold.
LLVM_ABI VNInfo * MergeValueNumberInto(VNInfo *V1, VNInfo *V2)
MergeValueNumberInto - This method is called when two value numbers are found to be equivalent.
unsigned getNumValNums() const
bool containsOneValue() const
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none.
void assign(const LiveRange &Other, BumpPtrAllocator &Allocator)
Copies values numbers and live segments from Other into this range.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
LLVM_ABI iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
MCRegUnitRootIterator enumerates the root registers of a register unit.
bool isValid() const
Check if the iterator is at the end of the list.
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
unsigned pred_size() const
LLVM_ABI bool hasEHPadSuccessor() const
bool isEHPad() const
Returns true if the block is a landing pad.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< pred_iterator > predecessors()
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 '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
Analysis pass which computes a MachineDominatorTree.
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool verify(Pass *p=nullptr, const char *Banner=nullptr, raw_ostream *OS=nullptr, bool AbortOnError=true) const
Run the current MachineFunction through the machine code verifier, useful for debugger use.
DenseMap< unsigned, DebugPHIRegallocPos > DebugPHIPositions
Map of debug instruction numbers to the position of their PHI instructions during register allocation...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void setRegisterDefReadUndef(Register Reg, bool IsUndef=true)
Mark all subregister defs of register Reg with the undef flag.
bool isImplicitDef() const
const MachineBasicBlock * getParent() const
bool isCopyLike() const
Return true if the instruction behaves like a copy.
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
LLVM_ABI std::pair< bool, bool > readsWritesVirtualRegister(Register Reg, SmallVectorImpl< unsigned > *Ops=nullptr) const
Return a pair of bools (reads, writes) indicating if this instruction reads or writes Reg.
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx=nullptr) const
Return true if the use operand of the specified index is tied to a def operand.
LLVM_ABI bool isSafeToMove(bool &SawStore) const
Return true if it is safe to move this instruction.
bool isDebugInstr() const
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
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,...
LLVM_ABI int findRegisterUseOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false) const
Returns the operand index that is a use of the specific register or -1 if it is not found.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
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,...
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
LLVM_ABI void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
LLVM_ABI bool allDefsAreDead() const
Return true if all the defs of this instruction are dead.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
LLVM_ABI void substVirtReg(Register Reg, unsigned SubIdx, const TargetRegisterInfo &)
substVirtReg - Substitute the current register with the virtual subregister Reg:SubReg.
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
LLVM_ABI void substPhysReg(MCRegister Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
void setIsUndef(bool Val=true)
bool isEarlyClobber() const
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)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_instr_iterator< true, true, false, true > reg_instr_iterator
reg_instr_iterator/reg_instr_begin/reg_instr_end - Walk all defs and uses of the specified register,...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool isProperSubClass(const TargetRegisterClass *RC) const
isProperSubClass - Returns true if RC has a legal super-class with more allocatable registers.
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr unsigned id() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
SlotIndex - An opaque wrapper around machine indexes.
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
bool isEarlyClobber() const
isEarlyClobber - Returns true if this is an early-clobber slot.
bool isValid() const
Returns true if this is a valid index.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
bool isDead() const
isDead - Returns true if this is a dead def kill slot.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the index past the last valid index in the given basic block.
SlotIndex getNextNonNullIndex(SlotIndex Index)
Returns the next non-null index, if one exists.
SlotIndex getInstructionIndex(const MachineInstr &MI, bool IgnoreBundle=false) const
Returns the base index for the given instruction.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
SlotIndex getIndexBefore(const MachineInstr &MI) const
getIndexBefore - Returns the index of the last indexed instruction before MI, or the start index of i...
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
static const unsigned CommuteAnyOperandIndex
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual bool enableJoinGlobalCopies() const
True if the subtarget should enable joining global copies.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
VNInfo - Value Number Information.
void markUnused()
Mark this value as unused.
BumpPtrAllocator Allocator
bool isUnused() const
Returns true if this value is unused.
unsigned id
The ID number of this value.
SlotIndex def
The index of the defining instruction.
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
static bool allUsesAvailableAt(const MachineInstr *MI, SlotIndex UseIdx, const LiveIntervals &LIS, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
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()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This namespace contains all of the command line option processing machinery.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
LLVM_ABI char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
LLVM_ABI Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
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...
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
auto unique(Range &&R, Predicate P)
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI void initializeRegisterCoalescerLegacyPass(PassRegistry &)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned MCRegUnit
Register units are used to compute register aliasing.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Success
The lock was released successfully.
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI void eraseInstrs(ArrayRef< MachineInstr * > DeadInstrs, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static constexpr LaneBitmask getLane(unsigned Lane)
static constexpr LaneBitmask getAll()
constexpr bool any() const
static constexpr LaneBitmask getNone()
Remat - Information needed to rematerialize at a specific location.
This represents a simple continuous liveness interval for a value.