63#define DEBUG_TYPE "regalloc"
65STATISTIC(numJoins ,
"Number of interval joins performed");
66STATISTIC(numCrossRCs ,
"Number of cross class joins performed");
67STATISTIC(numCommutes ,
"Number of instruction commuting performed");
69STATISTIC(NumReMats ,
"Number of instructions re-materialized");
70STATISTIC(NumInflated ,
"Number of register classes inflated");
71STATISTIC(NumLaneConflicts,
"Number of dead lane conflicts tested");
72STATISTIC(NumLaneResolves,
"Number of dead lane conflicts resolved");
73STATISTIC(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 "
110 cl::desc(
"If the valnos size of an interval is larger than the threshold, "
111 "it is regarded as a large interval. "),
116 cl::desc(
"For a large interval, if it is coalesed with other live "
117 "intervals many times more than the threshold, stop its "
118 "coalescing to control the compile time. "),
153 using DbgValueLoc = std::pair<SlotIndex, MachineInstr*>;
162 bool ShrinkMainRange =
false;
166 bool JoinGlobalCopies =
false;
170 bool JoinSplitEdges =
false;
202 void coalesceLocals();
205 void joinAllIntervals();
220 void lateLiveIntervalUpdate();
225 bool copyValueUndefInPredecessors(
LiveRange &S,
291 std::pair<bool,bool> removeCopyByCommutingDef(
const CoalescerPair &CP,
362 MI->eraseFromParent();
389 MachineFunctionProperties::Property::IsSSA);
403char RegisterCoalescer::ID = 0;
408 "Register Coalescer",
false,
false)
421 Dst =
MI->getOperand(0).getReg();
422 DstSub =
MI->getOperand(0).getSubReg();
423 Src =
MI->getOperand(1).getReg();
424 SrcSub =
MI->getOperand(1).getSubReg();
425 }
else if (
MI->isSubregToReg()) {
426 Dst =
MI->getOperand(0).getReg();
427 DstSub = tri.composeSubRegIndices(
MI->getOperand(0).getSubReg(),
428 MI->getOperand(3).getImm());
429 Src =
MI->getOperand(2).getReg();
430 SrcSub =
MI->getOperand(2).getSubReg();
445 for (
const auto &
MI : *
MBB) {
446 if (!
MI.isCopyLike() && !
MI.isUnconditionalBranch())
456 Flipped = CrossClass =
false;
459 unsigned SrcSub = 0, DstSub = 0;
462 Partial = SrcSub || DstSub;
465 if (Src.isPhysical()) {
466 if (Dst.isPhysical())
475 if (Dst.isPhysical()) {
478 Dst =
TRI.getSubReg(Dst, DstSub);
479 if (!Dst)
return false;
485 Dst =
TRI.getMatchingSuperReg(Dst, SrcSub,
MRI.getRegClass(Src));
486 if (!Dst)
return false;
487 }
else if (!
MRI.getRegClass(Src)->contains(Dst)) {
496 if (SrcSub && DstSub) {
498 if (Src == Dst && SrcSub != DstSub)
501 NewRC =
TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub,
508 NewRC =
TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
512 NewRC =
TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub);
515 NewRC =
TRI.getCommonSubClass(DstRC, SrcRC);
524 if (DstIdx && !SrcIdx) {
530 CrossClass = NewRC != DstRC || NewRC != SrcRC;
533 assert(Src.isVirtual() &&
"Src must be virtual");
534 assert(!(Dst.isPhysical() && DstSub) &&
"Cannot have a physical SubIdx");
553 unsigned SrcSub = 0, DstSub = 0;
561 }
else if (Src != SrcReg) {
567 if (!Dst.isPhysical())
569 assert(!DstIdx && !SrcIdx &&
"Inconsistent CoalescerPair state.");
572 Dst =
TRI.getSubReg(Dst, DstSub);
575 return DstReg == Dst;
577 return Register(
TRI.getSubReg(DstReg, SrcSub)) == Dst;
583 return TRI.composeSubRegIndices(SrcIdx, SrcSub) ==
584 TRI.composeSubRegIndices(DstIdx, DstSub);
588void RegisterCoalescer::getAnalysisUsage(
AnalysisUsage &AU)
const {
600void RegisterCoalescer::eliminateDeadDefs(
LiveRangeEdit *Edit) {
610void RegisterCoalescer::LRE_WillEraseInstruction(
MachineInstr *
MI) {
615bool RegisterCoalescer::adjustCopiesBackFrom(
const CoalescerPair &CP,
617 assert(!
CP.isPartial() &&
"This doesn't work for partial copies.");
618 assert(!
CP.isPhys() &&
"This doesn't work for physreg copies.");
643 if (BS == IntB.
end())
return false;
644 VNInfo *BValNo = BS->valno;
649 if (BValNo->
def != CopyIdx)
return false;
655 if (AS == IntA.
end())
return false;
656 VNInfo *AValNo = AS->valno;
662 if (!
CP.isCoalescable(ACopyMI) || !ACopyMI->
isFullCopy())
668 if (ValS == IntB.
end())
681 if (ValS+1 != BS)
return false;
685 SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
689 BValNo->
def = FillerStart;
697 if (BValNo != ValS->valno)
706 S.removeSegment(*SS,
true);
710 if (!S.getVNInfoAt(FillerStart)) {
713 S.extendInBlock(BBStart, FillerStart);
715 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
718 if (SubBValNo != SubValSNo)
719 S.MergeValueNumberInto(SubBValNo, SubValSNo);
736 bool RecomputeLiveRange = AS->end == CopyIdx;
737 if (!RecomputeLiveRange) {
740 if (SS != S.end() &&
SS->end == CopyIdx) {
741 RecomputeLiveRange =
true;
746 if (RecomputeLiveRange)
753bool RegisterCoalescer::hasOtherReachingDefs(
LiveInterval &IntA,
763 if (ASeg.
valno != AValNo)
continue;
765 if (BI != IntB.
begin())
767 for (; BI != IntB.
end() && ASeg.
end >= BI->start; ++BI) {
768 if (BI->valno == BValNo)
770 if (BI->start <= ASeg.
start && BI->end > ASeg.
start)
772 if (BI->start > ASeg.
start && BI->start < ASeg.
end)
781static std::pair<bool,bool>
784 bool Changed =
false;
785 bool MergedWithDead =
false;
787 if (S.
valno != SrcValNo)
798 MergedWithDead =
true;
801 return std::make_pair(Changed, MergedWithDead);
805RegisterCoalescer::removeCopyByCommutingDef(
const CoalescerPair &CP,
838 assert(BValNo !=
nullptr && BValNo->
def == CopyIdx);
844 return {
false,
false };
847 return {
false,
false };
849 return {
false,
false };
856 return {
false,
false };
868 if (!
TII->findCommutedOpIndices(*
DefMI, UseOpIdx, NewDstIdx))
869 return {
false,
false };
874 return {
false,
false };
878 if (hasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
879 return {
false,
false };
888 if (US == IntA.
end() || US->valno != AValNo)
892 return {
false,
false };
902 TII->commuteInstruction(*
DefMI,
false, UseOpIdx, NewDstIdx);
904 return {
false,
false };
906 !
MRI->constrainRegClass(IntB.
reg(),
MRI->getRegClass(IntA.
reg())))
907 return {
false,
false };
908 if (NewMI !=
DefMI) {
933 UseMO.setReg(NewReg);
938 assert(US != IntA.
end() &&
"Use must be live");
939 if (US->valno != AValNo)
942 UseMO.setIsKill(
false);
944 UseMO.substPhysReg(NewReg, *
TRI);
946 UseMO.setReg(NewReg);
965 VNInfo *SubDVNI = S.getVNInfoAt(DefIdx);
968 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
970 S.MergeValueNumberInto(SubDVNI, SubBValNo);
978 bool ShrinkB =
false;
992 VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
1001 MaskA |= SA.LaneMask;
1004 Allocator, SA.LaneMask,
1005 [&Allocator, &SA, CopyIdx, ASubValNo,
1007 VNInfo *BSubValNo = SR.empty() ? SR.getNextValue(CopyIdx, Allocator)
1008 : SR.getVNInfoAt(CopyIdx);
1009 assert(BSubValNo != nullptr);
1010 auto P = addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo);
1011 ShrinkB |= P.second;
1013 BSubValNo->def = ASubValNo->def;
1021 if ((SB.LaneMask & MaskA).any())
1025 SB.removeSegment(*S,
true);
1029 BValNo->
def = AValNo->
def;
1031 ShrinkB |=
P.second;
1038 return {
true, ShrinkB };
1088bool RegisterCoalescer::removePartialRedundancy(
const CoalescerPair &CP,
1121 bool FoundReverseCopy =
false;
1140 bool ValB_Changed =
false;
1141 for (
auto *VNI : IntB.
valnos) {
1142 if (VNI->isUnused())
1145 ValB_Changed =
true;
1153 FoundReverseCopy =
true;
1157 if (!FoundReverseCopy)
1167 if (CopyLeftBB && CopyLeftBB->
succ_size() > 1)
1178 if (InsPos != CopyLeftBB->
end()) {
1184 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Move the copy to "
1189 TII->get(TargetOpcode::COPY), IntB.
reg())
1200 ErasedInstrs.
erase(NewCopyMI);
1202 LLVM_DEBUG(
dbgs() <<
"\tremovePartialRedundancy: Remove the copy from "
1213 deleteInstr(&CopyMI);
1229 if (!IntB.
liveAt(UseIdx))
1230 MO.setIsUndef(
true);
1240 VNInfo *BValNo = SR.Query(CopyIdx).valueOutOrDead();
1241 assert(BValNo &&
"All sublanes should be live");
1250 for (
unsigned I = 0;
I != EndPoints.
size(); ) {
1252 EndPoints[
I] = EndPoints.
back();
1274 assert(!Reg.isPhysical() &&
"This code cannot handle physreg aliasing");
1277 if (
Op.getReg() != Reg)
1281 if (
Op.getSubReg() == 0 ||
Op.isUndef())
1287bool RegisterCoalescer::reMaterializeTrivialDef(
const CoalescerPair &CP,
1291 Register SrcReg =
CP.isFlipped() ?
CP.getDstReg() :
CP.getSrcReg();
1292 unsigned SrcIdx =
CP.isFlipped() ?
CP.getDstIdx() :
CP.getSrcIdx();
1293 Register DstReg =
CP.isFlipped() ?
CP.getSrcReg() :
CP.getDstReg();
1294 unsigned DstIdx =
CP.isFlipped() ?
CP.getSrcIdx() :
CP.getDstIdx();
1316 LiveRangeEdit Edit(&SrcInt, NewRegs, *MF, *LIS,
nullptr,
this);
1322 bool SawStore =
false;
1339 if (SrcIdx && DstIdx)
1348 unsigned NewDstIdx =
TRI->composeSubRegIndices(
CP.getSrcIdx(), DefSubIdx);
1350 NewDstReg =
TRI->getSubReg(DstReg, NewDstIdx);
1360 "Only expect to deal with virtual or physical registers");
1386 if (DstReg.
isVirtual() && DefSubIdx && !
CP.getSrcIdx() && !
CP.getDstIdx() &&
1387 MRI->shouldTrackSubRegLiveness(DstReg)) {
1407 assert(SrcIdx == 0 &&
CP.isFlipped()
1408 &&
"Shouldn't have SrcIdx+DstIdx at this point");
1411 TRI->getCommonSubClass(DefRC, DstRC);
1412 if (CommonRC !=
nullptr) {
1420 if (MO.isReg() && MO.getReg() == DstReg && MO.getSubReg() == DstIdx) {
1441 assert(MO.
isImplicit() &&
"No explicit operands after implicit operands.");
1444 "unexpected implicit virtual register def");
1450 ErasedInstrs.
insert(CopyMI);
1464 bool NewMIDefinesFullReg =
false;
1474 if (MO.
getReg() == DstReg)
1475 NewMIDefinesFullReg =
true;
1480 ((
TRI->getSubReg(MO.
getReg(), DefSubIdx) ==
1493 assert(!
MRI->shouldTrackSubRegLiveness(DstReg) &&
1494 "subrange update for implicit-def of super register may not be "
1495 "properly handled");
1503 if (DefRC !=
nullptr) {
1505 NewRC =
TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx);
1507 NewRC =
TRI->getCommonSubClass(NewRC, DefRC);
1508 assert(NewRC &&
"subreg chosen for remat incompatible with instruction");
1514 SR.LaneMask =
TRI->composeSubRegIndexLaneMask(DstIdx, SR.LaneMask);
1516 MRI->setRegClass(DstReg, NewRC);
1519 updateRegDefsUses(DstReg, DstReg, DstIdx);
1547 if (!SR.liveAt(DefIndex))
1548 SR.createDeadDef(DefIndex,
Alloc);
1549 MaxMask &= ~SR.LaneMask;
1551 if (MaxMask.
any()) {
1569 bool UpdatedSubRanges =
false;
1574 if ((SR.
LaneMask & DstMask).none()) {
1576 <<
"Removing undefined SubRange "
1589 UpdatedSubRanges =
true;
1600 if (UpdatedSubRanges)
1607 "Only expect virtual or physical registers in remat");
1610 if (!NewMIDefinesFullReg) {
1612 CopyDstReg,
true ,
true ,
false ));
1655 if (
MRI->use_nodbg_empty(SrcReg)) {
1661 UseMO.substPhysReg(DstReg, *
TRI);
1663 UseMO.setReg(DstReg);
1672 if (ToBeUpdated.
count(SrcReg))
1675 unsigned NumCopyUses = 0;
1677 if (UseMO.getParent()->isCopyLike())
1683 if (!DeadDefs.
empty())
1684 eliminateDeadDefs(&Edit);
1686 ToBeUpdated.
insert(SrcReg);
1704 unsigned SrcSubIdx = 0, DstSubIdx = 0;
1705 if(!
isMoveInstr(*
TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
1714 if ((SR.
LaneMask & SrcMask).none())
1727 assert(Seg !=
nullptr &&
"No segment for defining instruction");
1732 if (((V &&
V->isPHIDef()) || (!V && !DstLI.
liveAt(
Idx)))) {
1740 CopyMI->
getOpcode() == TargetOpcode::SUBREG_TO_REG);
1745 CopyMI->
setDesc(
TII->get(TargetOpcode::IMPLICIT_DEF));
1762 if ((SR.
LaneMask & DstMask).none())
1784 if ((SR.
LaneMask & UseMask).none())
1792 isLive = DstLI.
liveAt(UseIdx);
1805 if (MO.
getReg() == DstReg)
1817 bool IsUndef =
true;
1819 if ((S.LaneMask & Mask).none())
1821 if (S.liveAt(UseIdx)) {
1834 ShrinkMainRange =
true;
1843 if (DstInt && DstInt->
hasSubRanges() && DstReg != SrcReg) {
1852 if (
MI.isDebugInstr())
1855 addUndefFlag(*DstInt, UseIdx, MO,
SubReg);
1861 I =
MRI->reg_instr_begin(SrcReg), E =
MRI->reg_instr_end();
1870 if (SrcReg == DstReg && !Visited.
insert(
UseMI).second)
1883 for (
unsigned Op : Ops) {
1889 if (SubIdx && MO.
isDef())
1895 unsigned SubUseIdx =
TRI->composeSubRegIndices(SubIdx, MO.
getSubReg());
1896 if (SubUseIdx != 0 &&
MRI->shouldTrackSubRegLiveness(DstReg)) {
1913 addUndefFlag(*DstInt, UseIdx, MO, SubUseIdx);
1924 dbgs() <<
"\t\tupdated: ";
1932bool RegisterCoalescer::canJoinPhys(
const CoalescerPair &CP) {
1936 if (!
MRI->isReserved(
CP.getDstReg())) {
1937 LLVM_DEBUG(
dbgs() <<
"\tCan only merge into reserved registers.\n");
1946 dbgs() <<
"\tCannot join complex intervals into reserved register.\n");
1950bool RegisterCoalescer::copyValueUndefInPredecessors(
1964void RegisterCoalescer::setUndefOnPrunedSubRegUses(
LiveInterval &LI,
1971 if (SubRegIdx == 0 || MO.
isUndef())
1977 if (!S.
liveAt(Pos) && (PrunedLanes & SubRegMask).any()) {
1993bool RegisterCoalescer::joinCopy(
2000 if (!
CP.setRegisters(CopyMI)) {
2005 if (
CP.getNewRC()) {
2006 auto SrcRC =
MRI->getRegClass(
CP.getSrcReg());
2007 auto DstRC =
MRI->getRegClass(
CP.getDstReg());
2008 unsigned SrcIdx =
CP.getSrcIdx();
2009 unsigned DstIdx =
CP.getDstIdx();
2010 if (
CP.isFlipped()) {
2014 if (!
TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx,
2015 CP.getNewRC(), *LIS)) {
2027 eliminateDeadDefs();
2034 if (
MachineInstr *UndefMI = eliminateUndefCopy(CopyMI)) {
2035 if (UndefMI->isImplicitDef())
2037 deleteInstr(CopyMI);
2045 if (
CP.getSrcReg() ==
CP.getDstReg()) {
2047 LLVM_DEBUG(
dbgs() <<
"\tCopy already coalesced: " << LI <<
'\n');
2052 assert(ReadVNI &&
"No value before copy and no <undef> flag.");
2053 assert(ReadVNI != DefVNI &&
"Cannot read and define the same value.");
2068 if (copyValueUndefInPredecessors(S,
MBB, SLRQ)) {
2069 LLVM_DEBUG(
dbgs() <<
"Incoming sublane value is undef at copy\n");
2070 PrunedLanes |= S.LaneMask;
2077 if (PrunedLanes.
any()) {
2079 << PrunedLanes <<
'\n');
2080 setUndefOnPrunedSubRegUses(LI,
CP.getSrcReg(), PrunedLanes);
2085 deleteInstr(CopyMI);
2094 if (!canJoinPhys(CP)) {
2097 bool IsDefCopy =
false;
2098 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
2111 dbgs() <<
"\tConsidering merging to "
2112 <<
TRI->getRegClassName(
CP.getNewRC()) <<
" with ";
2113 if (
CP.getDstIdx() &&
CP.getSrcIdx())
2115 <<
TRI->getSubRegIndexName(
CP.getDstIdx()) <<
" and "
2117 <<
TRI->getSubRegIndexName(
CP.getSrcIdx()) <<
'\n';
2125 ShrinkMainRange =
false;
2131 if (!joinIntervals(CP)) {
2136 bool IsDefCopy =
false;
2137 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
2142 if (!
CP.isPartial() && !
CP.isPhys()) {
2143 bool Changed = adjustCopiesBackFrom(CP, CopyMI);
2144 bool Shrink =
false;
2146 std::tie(Changed, Shrink) = removeCopyByCommutingDef(CP, CopyMI);
2148 deleteInstr(CopyMI);
2150 Register DstReg =
CP.isFlipped() ?
CP.getSrcReg() :
CP.getDstReg();
2162 if (!
CP.isPartial() && !
CP.isPhys())
2163 if (removePartialRedundancy(CP, *CopyMI))
2174 if (
CP.isCrossClass()) {
2176 MRI->setRegClass(
CP.getDstReg(),
CP.getNewRC());
2187 if (ErasedInstrs.
erase(CopyMI))
2189 CurrentErasedInstrs.
insert(CopyMI);
2194 updateRegDefsUses(
CP.getDstReg(),
CP.getDstReg(),
CP.getDstIdx());
2195 updateRegDefsUses(
CP.getSrcReg(),
CP.getDstReg(),
CP.getSrcIdx());
2198 if (ShrinkMask.
any()) {
2201 if ((S.LaneMask & ShrinkMask).none())
2206 ShrinkMainRange =
true;
2214 if (ToBeUpdated.
count(
CP.getSrcReg()))
2215 ShrinkMainRange =
true;
2217 if (ShrinkMainRange) {
2227 TRI->updateRegAllocHint(
CP.getSrcReg(),
CP.getDstReg(), *MF);
2232 dbgs() <<
"\tResult = ";
2244bool RegisterCoalescer::joinReservedPhysReg(
CoalescerPair &CP) {
2247 assert(
CP.isPhys() &&
"Must be a physreg copy");
2248 assert(
MRI->isReserved(DstReg) &&
"Not a reserved register");
2252 assert(
RHS.containsOneValue() &&
"Invalid join with reserved register");
2261 if (!
MRI->isConstantPhysReg(DstReg)) {
2265 if (!
MRI->isReserved(*RI))
2278 !RegMaskUsable.
test(DstReg)) {
2291 if (
CP.isFlipped()) {
2299 CopyMI =
MRI->getVRegDef(SrcReg);
2300 deleteInstr(CopyMI);
2309 if (!
MRI->hasOneNonDBGUse(SrcReg)) {
2320 CopyMI = &*
MRI->use_instr_nodbg_begin(SrcReg);
2324 if (!
MRI->isConstantPhysReg(DstReg)) {
2332 if (
MI->readsRegister(DstReg,
TRI)) {
2342 <<
printReg(DstReg,
TRI) <<
" at " << CopyRegIdx <<
"\n");
2345 deleteInstr(CopyMI);
2355 MRI->clearKillFlags(
CP.getSrcReg());
2440 const unsigned SubIdx;
2448 const bool SubRangeJoin;
2451 const bool TrackSubRegLiveness;
2467 enum ConflictResolution {
2499 ConflictResolution Resolution = CR_Keep;
2509 VNInfo *RedefVNI =
nullptr;
2512 VNInfo *OtherVNI =
nullptr;
2525 bool ErasableImplicitDef =
false;
2529 bool Pruned =
false;
2532 bool PrunedComputed =
false;
2539 bool Identical =
false;
2543 bool isAnalyzed()
const {
return WriteLanes.
any(); }
2550 ErasableImplicitDef =
false;
2564 std::pair<const VNInfo *, Register> followCopyChain(
const VNInfo *VNI)
const;
2566 bool valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
const JoinVals &
Other)
const;
2575 ConflictResolution analyzeValue(
unsigned ValNo, JoinVals &
Other);
2580 void computeAssignment(
unsigned ValNo, JoinVals &
Other);
2611 bool isPrunedValue(
unsigned ValNo, JoinVals &
Other);
2617 bool TrackSubRegLiveness)
2618 : LR(LR),
Reg(
Reg), SubIdx(SubIdx), LaneMask(LaneMask),
2619 SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
2620 NewVNInfo(newVNInfo),
CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
2621 TRI(
TRI), Assignments(LR.getNumValNums(), -1),
2622 Vals(LR.getNumValNums()) {}
2626 bool mapValues(JoinVals &
Other);
2630 bool resolveConflicts(JoinVals &
Other);
2650 void pruneMainSegments(
LiveInterval &LI,
bool &ShrinkMainRange);
2661 void removeImplicitDefs();
2664 const int *getAssignments()
const {
return Assignments.
data(); }
2667 ConflictResolution getResolution(
unsigned Num)
const {
2668 return Vals[Num].Resolution;
2680 L |=
TRI->getSubRegIndexLaneMask(
2688std::pair<const VNInfo *, Register>
2689JoinVals::followCopyChain(
const VNInfo *VNI)
const {
2695 assert(
MI &&
"No defining instruction");
2696 if (!
MI->isFullCopy())
2697 return std::make_pair(VNI, TrackReg);
2698 Register SrcReg =
MI->getOperand(1).getReg();
2700 return std::make_pair(VNI, TrackReg);
2714 LaneBitmask SMask =
TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
2715 if ((SMask & LaneMask).
none())
2723 return std::make_pair(VNI, TrackReg);
2726 if (ValueIn ==
nullptr) {
2733 return std::make_pair(
nullptr, SrcReg);
2738 return std::make_pair(VNI, TrackReg);
2741bool JoinVals::valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
2742 const JoinVals &
Other)
const {
2745 std::tie(Orig0, Reg0) = followCopyChain(Value0);
2746 if (Orig0 == Value1 && Reg0 ==
Other.Reg)
2751 std::tie(Orig1, Reg1) =
Other.followCopyChain(Value1);
2755 if (Orig0 ==
nullptr || Orig1 ==
nullptr)
2756 return Orig0 == Orig1 && Reg0 == Reg1;
2762 return Orig0->
def == Orig1->
def && Reg0 == Reg1;
2765JoinVals::ConflictResolution
2766JoinVals::analyzeValue(
unsigned ValNo, JoinVals &
Other) {
2767 Val &
V = Vals[ValNo];
2768 assert(!
V.isAnalyzed() &&
"Value has already been analyzed!");
2780 :
TRI->getSubRegIndexLaneMask(SubIdx);
2781 V.ValidLanes =
V.WriteLanes = Lanes;
2790 V.ErasableImplicitDef =
true;
2794 V.ValidLanes =
V.WriteLanes = computeWriteLanes(
DefMI, Redef);
2813 assert((TrackSubRegLiveness ||
V.RedefVNI) &&
2814 "Instruction is reading nonexistent value");
2815 if (
V.RedefVNI !=
nullptr) {
2816 computeAssignment(
V.RedefVNI->id,
Other);
2817 V.ValidLanes |= Vals[
V.RedefVNI->id].ValidLanes;
2829 V.ErasableImplicitDef =
true;
2846 if (OtherVNI->
def < VNI->
def)
2847 Other.computeAssignment(OtherVNI->
id, *
this);
2852 return CR_Impossible;
2854 V.OtherVNI = OtherVNI;
2855 Val &OtherV =
Other.Vals[OtherVNI->
id];
2859 if (!OtherV.isAnalyzed() ||
Other.Assignments[OtherVNI->
id] == -1)
2866 if ((
V.ValidLanes & OtherV.ValidLanes).any())
2868 return CR_Impossible;
2883 Other.computeAssignment(
V.OtherVNI->id, *
this);
2884 Val &OtherV =
Other.Vals[
V.OtherVNI->id];
2886 if (OtherV.ErasableImplicitDef) {
2906 <<
", keeping it.\n");
2907 OtherV.mustKeepImplicitDef(*
TRI, *OtherImpDef);
2914 dbgs() <<
"IMPLICIT_DEF defined at " <<
V.OtherVNI->def
2915 <<
" may be live into EH pad successors, keeping it.\n");
2916 OtherV.mustKeepImplicitDef(*
TRI, *OtherImpDef);
2919 OtherV.ValidLanes &= ~OtherV.WriteLanes;
2934 if (
CP.isCoalescable(
DefMI)) {
2937 V.ValidLanes &= ~V.WriteLanes | OtherV.ValidLanes;
2952 valuesIdentical(VNI,
V.OtherVNI,
Other)) {
2975 if ((
V.WriteLanes & OtherV.ValidLanes).none())
2988 "Only early clobber defs can overlap a kill");
2989 return CR_Impossible;
2996 if ((
TRI->getSubRegIndexLaneMask(
Other.SubIdx) & ~
V.WriteLanes).none())
2997 return CR_Impossible;
2999 if (TrackSubRegLiveness) {
3004 if (!OtherLI.hasSubRanges()) {
3006 return (OtherMask &
V.WriteLanes).none() ? CR_Replace : CR_Impossible;
3014 TRI->composeSubRegIndexLaneMask(
Other.SubIdx, OtherSR.LaneMask);
3015 if ((OtherMask &
V.WriteLanes).none())
3018 auto OtherSRQ = OtherSR.Query(VNI->
def);
3019 if (OtherSRQ.valueIn() && OtherSRQ.endPoint() > VNI->
def) {
3021 return CR_Impossible;
3034 return CR_Impossible;
3043 return CR_Unresolved;
3046void JoinVals::computeAssignment(
unsigned ValNo, JoinVals &
Other) {
3047 Val &
V = Vals[ValNo];
3048 if (
V.isAnalyzed()) {
3051 assert(Assignments[ValNo] != -1 &&
"Bad recursion?");
3054 switch ((
V.Resolution = analyzeValue(ValNo,
Other))) {
3058 assert(
V.OtherVNI &&
"OtherVNI not assigned, can't merge.");
3059 assert(
Other.Vals[
V.OtherVNI->id].isAnalyzed() &&
"Missing recursion");
3060 Assignments[ValNo] =
Other.Assignments[
V.OtherVNI->id];
3064 <<
V.OtherVNI->def <<
" --> @"
3065 << NewVNInfo[Assignments[ValNo]]->def <<
'\n');
3068 case CR_Unresolved: {
3070 assert(
V.OtherVNI &&
"OtherVNI not assigned, can't prune");
3071 Val &OtherV =
Other.Vals[
V.OtherVNI->id];
3072 OtherV.Pruned =
true;
3077 Assignments[ValNo] = NewVNInfo.
size();
3083bool JoinVals::mapValues(JoinVals &
Other) {
3085 computeAssignment(i,
Other);
3086 if (Vals[i].Resolution == CR_Impossible) {
3104 assert(OtherI !=
Other.LR.end() &&
"No conflict?");
3109 if (
End >= MBBEnd) {
3111 << OtherI->valno->id <<
'@' << OtherI->start <<
'\n');
3115 << OtherI->valno->id <<
'@' << OtherI->start <<
" to "
3120 TaintExtent.push_back(std::make_pair(
End, TaintedLanes));
3123 if (++OtherI ==
Other.LR.end() || OtherI->start >= MBBEnd)
3127 const Val &OV =
Other.Vals[OtherI->valno->id];
3128 TaintedLanes &= ~OV.WriteLanes;
3131 }
while (TaintedLanes.
any());
3137 if (
MI.isDebugOrPseudoInstr())
3144 unsigned S =
TRI->composeSubRegIndices(SubIdx, MO.
getSubReg());
3145 if ((Lanes &
TRI->getSubRegIndexLaneMask(S)).any())
3151bool JoinVals::resolveConflicts(JoinVals &
Other) {
3154 assert(
V.Resolution != CR_Impossible &&
"Unresolvable conflict");
3155 if (
V.Resolution != CR_Unresolved)
3164 assert(
V.OtherVNI &&
"Inconsistent conflict resolution.");
3166 const Val &OtherV =
Other.Vals[
V.OtherVNI->id];
3171 LaneBitmask TaintedLanes =
V.WriteLanes & OtherV.ValidLanes;
3173 if (!taintExtent(i, TaintedLanes,
Other, TaintExtent))
3177 assert(!TaintExtent.
empty() &&
"There should be at least one conflict.");
3190 "Interference ends on VNI->def. Should have been handled earlier");
3193 assert(LastMI &&
"Range must end at a proper instruction");
3194 unsigned TaintNum = 0;
3197 if (usesLanes(*
MI,
Other.Reg,
Other.SubIdx, TaintedLanes)) {
3202 if (&*
MI == LastMI) {
3203 if (++TaintNum == TaintExtent.
size())
3206 assert(LastMI &&
"Range must end at a proper instruction");
3207 TaintedLanes = TaintExtent[TaintNum].second;
3213 V.Resolution = CR_Replace;
3219bool JoinVals::isPrunedValue(
unsigned ValNo, JoinVals &
Other) {
3220 Val &
V = Vals[ValNo];
3221 if (
V.Pruned ||
V.PrunedComputed)
3224 if (
V.Resolution != CR_Erase &&
V.Resolution != CR_Merge)
3229 V.PrunedComputed =
true;
3230 V.Pruned =
Other.isPrunedValue(
V.OtherVNI->id, *
this);
3234void JoinVals::pruneValues(JoinVals &
Other,
3236 bool changeInstrs) {
3239 switch (Vals[i].Resolution) {
3249 Val &OtherV =
Other.Vals[Vals[i].OtherVNI->id];
3250 bool EraseImpDef = OtherV.ErasableImplicitDef &&
3251 OtherV.Resolution == CR_Keep;
3252 if (!
Def.isBlock()) {
3259 if (MO.
getReg() == Reg) {
3272 <<
": " <<
Other.LR <<
'\n');
3277 if (isPrunedValue(i,
Other)) {
3284 << Def <<
": " << LR <<
'\n');
3342 bool DidPrune =
false;
3347 if (
V.Resolution != CR_Erase &&
3348 (
V.Resolution != CR_Keep || !
V.ErasableImplicitDef || !
V.Pruned))
3355 OtherDef =
V.OtherVNI->def;
3358 LLVM_DEBUG(
dbgs() <<
"\t\tExpecting instruction removal at " << Def
3366 if (ValueOut !=
nullptr && (Q.
valueIn() ==
nullptr ||
3367 (
V.Identical &&
V.Resolution == CR_Erase &&
3368 ValueOut->
def == Def))) {
3370 <<
" at " << Def <<
"\n");
3377 if (
V.Identical && S.Query(OtherDef).valueOutOrDead()) {
3387 ShrinkMask |= S.LaneMask;
3401 ShrinkMask |= S.LaneMask;
3413 if (VNI->
def == Def)
3419void JoinVals::pruneMainSegments(
LiveInterval &LI,
bool &ShrinkMainRange) {
3423 if (Vals[i].Resolution != CR_Keep)
3428 Vals[i].Pruned =
true;
3429 ShrinkMainRange =
true;
3433void JoinVals::removeImplicitDefs() {
3436 if (
V.Resolution != CR_Keep || !
V.ErasableImplicitDef || !
V.Pruned)
3452 switch (Vals[i].Resolution) {
3457 if (!Vals[i].ErasableImplicitDef || !Vals[i].Pruned)
3469 if (LI !=
nullptr) {
3494 ED = ED.
isValid() ? std::min(ED,
I->start) :
I->start;
3496 LE =
LE.isValid() ? std::max(LE,
I->end) :
I->
end;
3499 NewEnd = std::min(NewEnd, LE);
3501 NewEnd = std::min(NewEnd, ED);
3507 if (S != LR.
begin())
3508 std::prev(S)->end = NewEnd;
3512 dbgs() <<
"\t\tremoved " << i <<
'@' <<
Def <<
": " << LR <<
'\n';
3514 dbgs() <<
"\t\t LHS = " << *LI <<
'\n';
3521 assert(
MI &&
"No instruction to erase");
3524 if (
Reg.isVirtual() && Reg !=
CP.getSrcReg() && Reg !=
CP.getDstReg())
3530 MI->eraseFromParent();
3543 JoinVals RHSVals(RRange,
CP.getSrcReg(),
CP.getSrcIdx(), LaneMask,
3544 NewVNInfo, CP, LIS,
TRI,
true,
true);
3545 JoinVals LHSVals(LRange,
CP.getDstReg(),
CP.getDstIdx(), LaneMask,
3546 NewVNInfo, CP, LIS,
TRI,
true,
true);
3553 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals)) {
3558 if (!LHSVals.resolveConflicts(RHSVals) ||
3559 !RHSVals.resolveConflicts(LHSVals)) {
3570 LHSVals.pruneValues(RHSVals, EndPoints,
false);
3571 RHSVals.pruneValues(LHSVals, EndPoints,
false);
3573 LHSVals.removeImplicitDefs();
3574 RHSVals.removeImplicitDefs();
3579 LRange.
join(RRange, LHSVals.getAssignments(), RHSVals.getAssignments(),
3583 <<
' ' << LRange <<
"\n");
3584 if (EndPoints.
empty())
3590 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3591 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3592 dbgs() << EndPoints[i];
3596 dbgs() <<
": " << LRange <<
'\n';
3601void RegisterCoalescer::mergeSubRangeInto(
LiveInterval &LI,
3605 unsigned ComposeSubRegIdx) {
3608 Allocator, LaneMask,
3611 SR.assign(ToMerge, Allocator);
3614 LiveRange RangeCopy(ToMerge, Allocator);
3615 joinSubRegRanges(SR, RangeCopy, SR.LaneMask, CP);
3621bool RegisterCoalescer::isHighCostLiveInterval(
LiveInterval &LI) {
3624 auto &Counter = LargeLIVisitCounter[LI.
reg()];
3636 bool TrackSubRegLiveness =
MRI->shouldTrackSubRegLiveness(*
CP.getNewRC());
3638 NewVNInfo, CP, LIS,
TRI,
false, TrackSubRegLiveness);
3640 NewVNInfo, CP, LIS,
TRI,
false, TrackSubRegLiveness);
3642 LLVM_DEBUG(
dbgs() <<
"\t\tRHS = " << RHS <<
"\n\t\tLHS = " << LHS <<
'\n');
3644 if (isHighCostLiveInterval(LHS) || isHighCostLiveInterval(RHS))
3649 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals))
3653 if (!LHSVals.resolveConflicts(RHSVals) || !RHSVals.resolveConflicts(LHSVals))
3657 if (
RHS.hasSubRanges() ||
LHS.hasSubRanges()) {
3662 unsigned DstIdx =
CP.getDstIdx();
3663 if (!
LHS.hasSubRanges()) {
3665 :
TRI->getSubRegIndexLaneMask(DstIdx);
3668 LHS.createSubRangeFrom(Allocator, Mask, LHS);
3669 }
else if (DstIdx != 0) {
3680 unsigned SrcIdx =
CP.getSrcIdx();
3681 if (!
RHS.hasSubRanges()) {
3683 :
TRI->getSubRegIndexLaneMask(SrcIdx);
3684 mergeSubRangeInto(LHS, RHS, Mask, CP, DstIdx);
3689 mergeSubRangeInto(LHS, R, Mask, CP, DstIdx);
3696 LHSVals.pruneMainSegments(LHS, ShrinkMainRange);
3698 LHSVals.pruneSubRegValues(LHS, ShrinkMask);
3699 RHSVals.pruneSubRegValues(LHS, ShrinkMask);
3700 }
else if (TrackSubRegLiveness && !
CP.getDstIdx() &&
CP.getSrcIdx()) {
3702 CP.getNewRC()->getLaneMask(), LHS);
3703 mergeSubRangeInto(LHS, RHS,
TRI->getSubRegIndexLaneMask(
CP.getSrcIdx()), CP,
3705 LHSVals.pruneMainSegments(LHS, ShrinkMainRange);
3706 LHSVals.pruneSubRegValues(LHS, ShrinkMask);
3714 LHSVals.pruneValues(RHSVals, EndPoints,
true);
3715 RHSVals.pruneValues(LHSVals, EndPoints,
true);
3720 LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs, &LHS);
3721 RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
3722 while (!ShrinkRegs.
empty())
3726 checkMergingChangesDbgValues(CP, LHS, LHSVals, RHS, RHSVals);
3730 auto RegIt = RegToPHIIdx.
find(
CP.getSrcReg());
3731 if (RegIt != RegToPHIIdx.
end()) {
3733 for (
unsigned InstID : RegIt->second) {
3734 auto PHIIt = PHIValToPos.
find(InstID);
3739 auto LII =
RHS.find(SI);
3740 if (LII ==
RHS.end() || LII->start > SI)
3755 if (
CP.getSrcIdx() != 0 ||
CP.getDstIdx() != 0)
3758 if (PHIIt->second.SubReg && PHIIt->second.SubReg !=
CP.getSrcIdx())
3762 PHIIt->second.Reg =
CP.getDstReg();
3766 if (
CP.getSrcIdx() != 0)
3767 PHIIt->second.SubReg =
CP.getSrcIdx();
3773 auto InstrNums = RegIt->second;
3774 RegToPHIIdx.
erase(RegIt);
3778 RegIt = RegToPHIIdx.
find(
CP.getDstReg());
3779 if (RegIt != RegToPHIIdx.
end())
3780 RegIt->second.insert(RegIt->second.end(), InstrNums.begin(),
3783 RegToPHIIdx.
insert({
CP.getDstReg(), InstrNums});
3787 LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
3792 MRI->clearKillFlags(
LHS.reg());
3793 MRI->clearKillFlags(
RHS.reg());
3795 if (!EndPoints.
empty()) {
3799 dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size() <<
" points: ";
3800 for (
unsigned i = 0, n = EndPoints.
size(); i != n; ++i) {
3801 dbgs() << EndPoints[i];
3805 dbgs() <<
": " <<
LHS <<
'\n';
3814 return CP.isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(
CP);
3825 for (
auto *
X : ToInsert) {
3826 for (
const auto &
Op :
X->debug_operands()) {
3827 if (
Op.isReg() &&
Op.getReg().isVirtual())
3838 for (
auto &
MBB : MF) {
3841 for (
auto &
MI :
MBB) {
3842 if (
MI.isDebugValue()) {
3844 return MO.isReg() && MO.getReg().isVirtual();
3846 ToInsert.push_back(&
MI);
3847 }
else if (!
MI.isDebugOrPseudoInstr()) {
3849 CloseNewDVRange(CurrentSlot);
3858 for (
auto &Pair : DbgVRegToValues)
3862void RegisterCoalescer::checkMergingChangesDbgValues(
CoalescerPair &CP,
3866 JoinVals &RHSVals) {
3868 checkMergingChangesDbgValuesImpl(Reg, RHS, LHS, LHSVals);
3872 checkMergingChangesDbgValuesImpl(Reg, LHS, RHS, RHSVals);
3876 ScanForSrcReg(
CP.getSrcReg());
3877 ScanForDstReg(
CP.getDstReg());
3880void RegisterCoalescer::checkMergingChangesDbgValuesImpl(
Register Reg,
3883 JoinVals &RegVals) {
3885 auto VRegMapIt = DbgVRegToValues.
find(Reg);
3886 if (VRegMapIt == DbgVRegToValues.
end())
3889 auto &DbgValueSet = VRegMapIt->second;
3890 auto DbgValueSetIt = DbgValueSet.begin();
3891 auto SegmentIt = OtherLR.
begin();
3893 bool LastUndefResult =
false;
3898 auto ShouldUndef = [&RegVals, &
RegLR, &LastUndefResult,
3903 if (LastUndefIdx ==
Idx)
3904 return LastUndefResult;
3911 if (OtherIt ==
RegLR.end())
3920 auto Resolution = RegVals.getResolution(OtherIt->valno->id);
3921 LastUndefResult = Resolution != JoinVals::CR_Keep &&
3922 Resolution != JoinVals::CR_Erase;
3924 return LastUndefResult;
3930 while (DbgValueSetIt != DbgValueSet.end() && SegmentIt != OtherLR.
end()) {
3931 if (DbgValueSetIt->first < SegmentIt->end) {
3934 if (DbgValueSetIt->first >= SegmentIt->start) {
3935 bool HasReg = DbgValueSetIt->second->hasDebugOperandForReg(Reg);
3936 bool ShouldUndefReg = ShouldUndef(DbgValueSetIt->first);
3937 if (HasReg && ShouldUndefReg) {
3939 DbgValueSetIt->second->setDebugValueUndef();
3953struct MBBPriorityInfo {
3959 :
MBB(mbb),
Depth(depth), IsSplit(issplit) {}
3969 const MBBPriorityInfo *RHS) {
3971 if (
LHS->Depth !=
RHS->Depth)
3972 return LHS->Depth >
RHS->Depth ? -1 : 1;
3975 if (
LHS->IsSplit !=
RHS->IsSplit)
3976 return LHS->IsSplit ? -1 : 1;
3980 unsigned cl =
LHS->MBB->pred_size() +
LHS->MBB->succ_size();
3981 unsigned cr =
RHS->MBB->pred_size() +
RHS->MBB->succ_size();
3983 return cl > cr ? -1 : 1;
3986 return LHS->MBB->getNumber() <
RHS->MBB->getNumber() ? -1 : 1;
3991 if (!Copy->isCopy())
3994 if (Copy->getOperand(1).isUndef())
3997 Register SrcReg = Copy->getOperand(1).getReg();
3998 Register DstReg = Copy->getOperand(0).getReg();
4006void RegisterCoalescer::lateLiveIntervalUpdate() {
4012 if (!DeadDefs.
empty())
4013 eliminateDeadDefs();
4015 ToBeUpdated.clear();
4018bool RegisterCoalescer::
4020 bool Progress =
false;
4032 bool Success = joinCopy(
MI, Again, CurrentErasedInstrs);
4038 if (!CurrentErasedInstrs.
empty()) {
4040 if (
MI && CurrentErasedInstrs.
count(
MI))
4044 if (
MI && CurrentErasedInstrs.
count(
MI))
4055 assert(Copy.isCopyLike());
4058 if (&
MI != &Copy &&
MI.isCopyLike())
4063bool RegisterCoalescer::applyTerminalRule(
const MachineInstr &Copy)
const {
4068 unsigned SrcSubReg = 0, DstSubReg = 0;
4069 if (!
isMoveInstr(*
TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg))
4090 if (&
MI == &Copy || !
MI.isCopyLike() ||
MI.getParent() != OrigBB)
4093 unsigned OtherSrcSubReg = 0, OtherSubReg = 0;
4094 if (!
isMoveInstr(*
TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg,
4097 if (OtherReg == SrcReg)
4098 OtherReg = OtherSrcReg;
4118 const unsigned PrevSize = WorkList.
size();
4119 if (JoinGlobalCopies) {
4127 if (!
MI.isCopyLike())
4129 bool ApplyTerminalRule = applyTerminalRule(
MI);
4131 if (ApplyTerminalRule)
4136 if (ApplyTerminalRule)
4143 LocalWorkList.
append(LocalTerminals.
begin(), LocalTerminals.
end());
4149 if (MII.isCopyLike()) {
4150 if (applyTerminalRule(MII))
4162 CurrList(WorkList.
begin() + PrevSize, WorkList.
end());
4163 if (copyCoalesceWorkList(CurrList))
4164 WorkList.
erase(std::remove(WorkList.
begin() + PrevSize, WorkList.
end(),
4165 nullptr), WorkList.
end());
4168void RegisterCoalescer::coalesceLocals() {
4169 copyCoalesceWorkList(LocalWorkList);
4174 LocalWorkList.clear();
4177void RegisterCoalescer::joinAllIntervals() {
4178 LLVM_DEBUG(
dbgs() <<
"********** JOINING INTERVALS ***********\n");
4179 assert(WorkList.
empty() && LocalWorkList.empty() &&
"Old data still around.");
4181 std::vector<MBBPriorityInfo> MBBs;
4182 MBBs.reserve(MF->size());
4184 MBBs.push_back(MBBPriorityInfo(&
MBB,
Loops->getLoopDepth(&
MBB),
4190 unsigned CurrDepth = std::numeric_limits<unsigned>::max();
4191 for (MBBPriorityInfo &
MBB : MBBs) {
4193 if (JoinGlobalCopies &&
MBB.Depth < CurrDepth) {
4195 CurrDepth =
MBB.Depth;
4197 copyCoalesceInMBB(
MBB.MBB);
4199 lateLiveIntervalUpdate();
4204 while (copyCoalesceWorkList(WorkList))
4206 lateLiveIntervalUpdate();
4209void RegisterCoalescer::releaseMemory() {
4210 ErasedInstrs.
clear();
4213 InflateRegs.
clear();
4214 LargeLIVisitCounter.
clear();
4218 LLVM_DEBUG(
dbgs() <<
"********** REGISTER COALESCER **********\n"
4219 <<
"********** Function: " << fn.
getName() <<
'\n');
4231 dbgs() <<
"* Skipped as it exposes functions that returns twice.\n");
4240 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
4241 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
4242 Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
4251 for (
const auto &DebugPHI : MF->DebugPHIPositions) {
4254 unsigned SubReg = DebugPHI.second.SubReg;
4257 PHIValToPos.
insert(std::make_pair(DebugPHI.first,
P));
4258 RegToPHIIdx[
Reg].push_back(DebugPHI.first);
4267 MF->verify(
this,
"Before register coalescing", &
errs());
4269 DbgVRegToValues.
clear();
4286 if (
MRI->reg_nodbg_empty(Reg))
4288 if (
MRI->recomputeRegClass(Reg)) {
4290 <<
TRI->getRegClassName(
MRI->getRegClass(Reg)) <<
'\n');
4297 if (!
MRI->shouldTrackSubRegLiveness(Reg)) {
4305 assert((S.LaneMask & ~MaxMask).none());
4315 for (
auto &p : MF->DebugPHIPositions) {
4316 auto it = PHIValToPos.
find(
p.first);
4318 p.second.Reg = it->second.Reg;
4319 p.second.SubReg = it->second.SubReg;
4322 PHIValToPos.
clear();
4323 RegToPHIIdx.
clear();
4327 MF->verify(
this,
"After register coalescing", &
errs());
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseSet and SmallDenseSet classes.
std::optional< std::vector< StOtherPiece > > Other
SmallVector< uint32_t, 0 > Writes
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
A common definition of LaneBitmask for use in TableGen and CodeGen.
unsigned const TargetRegisterInfo * TRI
#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),...
register Register Coalescer
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 cl::opt< unsigned > LargeIntervalFreqThreshold("large-interval-freq-threshold", cl::Hidden, cl::desc("For a large interval, if it is coalesed with other live " "intervals many times more than the threshold, stop its " "coalescing to control the compile time. "), cl::init(256))
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 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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 DenseMap< Register, std::vector< std::pair< SlotIndex, MachineInstr * > > > buildVRegToDbgValueMap(MachineFunction &MF, const LiveIntervals *Liveness)
static void shrinkToUses(LiveInterval &LI, LiveIntervals &LIS)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Represent the analysis usage information of a pass.
AnalysisUsage & addPreservedID(const void *ID)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
Allocate memory in an ever growing pool, as if by bump-pointer.
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.
This class represents an Operation in the Expression.
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
bool isAsCheapAsAMove(const MachineInstr &MI) const override
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
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()
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.
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.
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.
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)
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)
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.
MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
If LI is confined to a single basic block, return a pointer to that block.
void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos)
Remove value number and related live segments of LI and its subranges that start at position Pos.
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 extendToIndices(LiveRange &LR, ArrayRef< SlotIndex > Indices, ArrayRef< SlotIndex > Undefs)
Extend the live range LR to reach all points in Indices.
void print(raw_ostream &O) const
Implement the dump method.
void removePhysRegDefAt(MCRegister Reg, SlotIndex Pos)
Remove value numbers and related live segments starting at position Pos that are part of any liverang...
void splitSeparateComponents(LiveInterval &LI, SmallVectorImpl< LiveInterval * > &SplitLIs)
Split separate components in LiveInterval LI into separate intervals.
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.
virtual void LRE_WillEraseInstruction(MachineInstr *MI)
Called immediately before erasing a dead machine instruction.
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...
bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI)
checkRematerializable - Manually add VNI to the list of rematerializable values if DefMI may be remat...
bool canRematerializeAt(Remat &RM, VNInfo *OrigVNI, SlotIndex UseIdx, bool cheapAsAMove)
canRematerializeAt - Determine if ParentVNI can be rematerialized at UseIdx.
This class represents the liveness of a register, stack slot, etc.
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
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
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNIAlloc)
createDeadDef - Make sure the range has a value defined at Def.
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.
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.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
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.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
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.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
unsigned pred_size() const
bool hasEHPadSuccessor() const
bool isEHPad() const
Returns true if the block is a landing pad.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
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 '...
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual MachineFunctionProperties getClearedProperties() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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.
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.
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.
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.
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.
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,...
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,...
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
iterator_range< mop_iterator > operands()
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.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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
iterator_range< filtered_mop_iterator > all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
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.
bool allDefsAreDead() const
Return true if all the defs of this instruction are dead.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
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.
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)
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
virtual void releaseMemory()
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
bool isProperSubClass(const TargetRegisterClass *RC) const
isProperSubClass - Returns true if RC has a legal super-class with more allocatable registers.
void runOnMachineFunction(const MachineFunction &MF)
runOnFunction - Prepare to answer questions about MF.
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 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 last index in the given basic block number.
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 TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
VNInfo - Value Number Information.
void markUnused()
Mark this value as unused.
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...
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
void initializeRegisterCoalescerPass(PassRegistry &)
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
Printable printRegUnit(unsigned Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
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.
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...
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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.
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.
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.