45 #define DEBUG_TYPE "regalloc"
47 STATISTIC(numJoins ,
"Number of interval joins performed");
48 STATISTIC(numCrossRCs ,
"Number of cross class joins performed");
49 STATISTIC(numCommutes ,
"Number of instruction commuting performed");
50 STATISTIC(numExtends ,
"Number of copies extended");
51 STATISTIC(NumReMats ,
"Number of instructions re-materialized");
52 STATISTIC(NumInflated ,
"Number of register classes inflated");
53 STATISTIC(NumLaneConflicts,
"Number of dead lane conflicts tested");
54 STATISTIC(NumLaneResolves,
"Number of dead lane conflicts resolved");
58 cl::desc(
"Coalesce copies (default=true)"),
73 cl::desc(
"Coalesce copies that span blocks (default=subtarget)"),
78 cl::desc(
"Verify machine instrs before and after register coalescing"),
100 bool ShrinkMainRange;
104 bool JoinGlobalCopies;
125 void eliminateDeadDefs();
131 void coalesceLocals();
134 void joinAllIntervals();
207 void updateRegDefsUses(
unsigned SrcReg,
unsigned DstReg,
unsigned SubIdx);
231 unsigned NumComps = ConEQ.Classify(LI);
235 for (
unsigned i = 1; i != NumComps; ++i) {
236 unsigned VReg = MRI->createVirtualRegister(MRI->getRegClass(LI->
reg));
237 NewComps.push_back(&LIS->createEmptyInterval(VReg));
240 ConEQ.Distribute(&NewComps[0], *MRI);
248 if (LIS->shrinkToUses(LI,
Dead))
261 void releaseMemory()
override;
274 "Simple Register Coalescing",
false,
false)
282 char RegisterCoalescer::
ID = 0;
285 unsigned &Src,
unsigned &Dst,
286 unsigned &SrcSub,
unsigned &DstSub) {
288 Dst = MI->getOperand(0).getReg();
289 DstSub = MI->getOperand(0).getSubReg();
290 Src = MI->getOperand(1).getReg();
291 SrcSub = MI->getOperand(1).getSubReg();
292 }
else if (MI->isSubregToReg()) {
293 Dst = MI->getOperand(0).getReg();
294 DstSub = tri.composeSubRegIndices(MI->getOperand(0).getSubReg(),
295 MI->getOperand(3).getImm());
296 Src = MI->getOperand(2).getReg();
297 SrcSub = MI->getOperand(2).getSubReg();
312 for (
const auto &
MI : *MBB) {
313 if (!
MI.isCopyLike() && !
MI.isUnconditionalBranch())
323 Flipped = CrossClass =
false;
325 unsigned Src, Dst, SrcSub, DstSub;
326 if (!
isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
328 Partial = SrcSub || DstSub;
345 if (!Dst)
return false;
352 if (!Dst)
return false;
362 if (SrcSub && DstSub) {
364 if (Src == Dst && SrcSub != DstSub)
390 if (DstIdx && !SrcIdx) {
396 CrossClass = NewRC != DstRC || NewRC != SrcRC;
401 "Cannot have a physical SubIdx");
419 unsigned Src, Dst, SrcSub, DstSub;
420 if (!
isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub))
427 }
else if (Src != SrcReg) {
435 assert(!DstIdx && !SrcIdx &&
"Inconsistent CoalescerPair state.");
441 return DstReg == Dst;
443 return TRI.
getSubReg(DstReg, SrcSub) == Dst;
454 void RegisterCoalescer::getAnalysisUsage(
AnalysisUsage &AU)
const {
466 void RegisterCoalescer::eliminateDeadDefs() {
472 void RegisterCoalescer::LRE_WillEraseInstruction(
MachineInstr *
MI) {
474 ErasedInstrs.insert(MI);
479 assert(!CP.
isPartial() &&
"This doesn't work for partial copies.");
480 assert(!CP.
isPhys() &&
"This doesn't work for physreg copies.");
505 if (BS == IntB.
end())
return false;
506 VNInfo *BValNo = BS->valno;
511 if (BValNo->
def != CopyIdx)
return false;
517 if (AS == IntA.end())
return false;
518 VNInfo *AValNo = AS->valno;
530 if (ValS == IntB.
end())
536 LIS->getInstructionFromIndex(ValS->end.getPrevSlot());
543 if (ValS+1 != BS)
return false;
547 SlotIndex FillerStart = ValS->end, FillerEnd = BS->start;
551 BValNo->
def = FillerStart;
556 IntB.
addSegment(LiveInterval::Segment(FillerStart, FillerEnd, BValNo));
559 if (BValNo != ValS->valno)
564 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
565 S.addSegment(LiveInterval::Segment(FillerStart, FillerEnd, SubBValNo));
567 if (SubBValNo != SubValSNo)
568 S.MergeValueNumberInto(SubBValNo, SubValSNo);
571 DEBUG(
dbgs() <<
" result = " << IntB <<
'\n');
584 if (AS->end == CopyIdx)
591 bool RegisterCoalescer::hasOtherReachingDefs(
LiveInterval &IntA,
597 if (LIS->hasPHIKill(IntA, AValNo))
601 if (ASeg.
valno != AValNo)
continue;
604 if (BI != IntB.
begin())
606 for (; BI != IntB.
end() && ASeg.
end >= BI->start; ++BI) {
607 if (BI->valno == BValNo)
609 if (BI->start <= ASeg.
start && BI->end > ASeg.
start)
611 if (BI->start > ASeg.
start && BI->start < ASeg.
end)
624 if (S.
valno != SrcValNo)
630 bool RegisterCoalescer::removeCopyByCommutingDef(
const CoalescerPair &CP,
663 assert(BValNo !=
nullptr && BValNo->
def == CopyIdx);
667 assert(AValNo && !AValNo->
isUnused() &&
"COPY source not live");
678 assert(DefIdx != -1);
682 unsigned Op1, Op2, NewDstIdx;
683 if (!
TII->findCommutedOpIndices(DefMI, Op1, Op2))
687 else if (Op2 == UseOpIdx)
693 unsigned NewReg = NewDstMO.
getReg();
699 if (hasOtherReachingDefs(IntA, IntB, AValNo, BValNo))
707 SlotIndex UseIdx = LIS->getInstructionIndex(UseMI);
709 if (US == IntA.end() || US->valno != AValNo)
716 DEBUG(
dbgs() <<
"\tremoveCopyByCommutingDef: " << AValNo->
def <<
'\t'
727 !MRI->constrainRegClass(IntB.
reg, MRI->getRegClass(IntA.reg)))
729 if (NewMI != DefMI) {
730 LIS->ReplaceMachineInstrInMaps(DefMI, NewMI);
762 assert(US != IntA.end() &&
"Use must be live");
763 if (US->valno != AValNo)
785 DEBUG(
dbgs() <<
"\t\tnoop: " << DefIdx <<
'\t' << *UseMI);
786 assert(DVNI->
def == DefIdx);
789 VNInfo *SubDVNI = S.getVNInfoAt(DefIdx);
792 VNInfo *SubBValNo = S.getVNInfoAt(CopyIdx);
793 assert(SubBValNo->
def == CopyIdx);
794 S.MergeValueNumberInto(SubDVNI, SubBValNo);
797 ErasedInstrs.insert(UseMI);
798 LIS->RemoveMachineInstrFromMaps(UseMI);
806 if (!IntA.hasSubRanges()) {
807 unsigned Mask = MRI->getMaxLaneMaskForVReg(IntA.reg);
808 IntA.createSubRangeFrom(Allocator, Mask, IntA);
812 VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
813 assert(ASubValNo !=
nullptr);
815 unsigned AMask = SA.LaneMask;
817 unsigned BMask = SB.LaneMask;
818 unsigned Common = BMask & AMask;
823 dbgs() <<
format(
"\t\tCopy+Merge %04X into %04X\n", BMask, Common));
824 unsigned BRest = BMask & ~AMask;
839 assert(BSubValNo->
def == CopyIdx);
840 BSubValNo->
def = ASubValNo->
def;
853 BValNo->
def = AValNo->
def;
855 DEBUG(
dbgs() <<
"\t\textended: " << IntB <<
'\n');
857 LIS->removeVRegDefAt(IntA, AValNo->
def);
859 DEBUG(
dbgs() <<
"\t\ttrimmed: " << IntA <<
'\n');
868 "This code cannot handle physreg aliasing");
870 if (!Op.isReg() || !Op.isDef() || Op.getReg() !=
Reg)
874 if (Op.getSubReg() == 0 || Op.isUndef())
880 bool RegisterCoalescer::reMaterializeTrivialDef(
const CoalescerPair &CP,
892 SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
894 assert(ValNo &&
"CopyMI input register not live");
904 if (!
TII->isAsCheapAsAMove(DefMI))
906 if (!
TII->isTriviallyReMaterializable(DefMI, AA))
918 unsigned CopyDstReg = DstOperand.
getReg();
927 if (SrcIdx && DstIdx)
933 unsigned NewDstReg = DstReg;
935 unsigned NewDstIdx = TRI->composeSubRegIndices(CP.
getSrcIdx(),
938 NewDstReg = TRI->getSubReg(DstReg, NewDstIdx);
948 "Only expect to deal with virtual or physical registers");
955 TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, DefMI, *TRI);
968 &&
"Shouldn't have SrcIdx+DstIdx at this point");
971 TRI->getCommonSubClass(DefRC, DstRC);
972 if (CommonRC !=
nullptr) {
980 LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI);
982 ErasedInstrs.insert(CopyMI);
1001 if (DefRC !=
nullptr) {
1003 NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx);
1005 NewRC = TRI->getCommonSubClass(NewRC, DefRC);
1006 assert(NewRC &&
"subreg chosen for remat incompatible with instruction");
1008 MRI->setRegClass(DstReg, NewRC);
1010 updateRegDefsUses(DstReg, DstReg, DstIdx);
1016 "Only expect virtual or physical registers in remat");
1038 SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
1041 if (
LiveRange *LR = LIS->getCachedRegUnit(*Units))
1042 LR->createDeadDef(NewMIIdx.
getRegSlot(), LIS->getVNInfoAllocator());
1054 assert(MO.
isImplicit() &&
"No explicit operands after implict operands.");
1062 SlotIndex NewMIIdx = LIS->getInstructionIndex(NewMI);
1063 for (
unsigned i = 0, e = NewMIImplDefs.
size(); i != e; ++i) {
1064 unsigned Reg = NewMIImplDefs[i];
1066 if (
LiveRange *LR = LIS->getCachedRegUnit(*Units))
1067 LR->createDeadDef(NewMIIdx.
getRegSlot(), LIS->getVNInfoAllocator());
1074 shrinkToUses(&SrcInt, &DeadDefs);
1075 if (!DeadDefs.empty()) {
1082 DEBUG(
dbgs() <<
"\t\tupdated: " << *UseMI);
1085 eliminateDeadDefs();
1091 bool RegisterCoalescer::eliminateUndefCopy(
MachineInstr *CopyMI) {
1103 unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
1104 isMoveInstr(*TRI, CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
1106 SlotIndex Idx = LIS->getInstructionIndex(CopyMI);
1110 unsigned SrcMask = TRI->getSubRegIndexLaneMask(SrcSubIdx);
1112 if ((SR.LaneMask & SrcMask) == 0)
1117 }
else if (SrcLI.
liveAt(Idx))
1120 DEBUG(
dbgs() <<
"\tEliminating copy of <undef> value\n");
1131 unsigned DstMask = TRI->getSubRegIndexLaneMask(DstSubIdx);
1133 if ((SR.LaneMask & DstMask) == 0)
1136 VNInfo *SVNI = SR.getVNInfoAt(RegIndex);
1138 SR.removeValNo(SVNI);
1142 LIS->removeVRegDefAt(DstLI, RegIndex);
1149 SlotIndex UseIdx = LIS->getInstructionIndex(&MI);
1150 unsigned UseMask = TRI->getSubRegIndexLaneMask(MO.
getSubReg());
1155 if ((SR.LaneMask & UseMask) == 0)
1157 if (SR.liveAt(UseIdx)) {
1163 isLive = DstLI.
liveAt(UseIdx);
1167 DEBUG(
dbgs() <<
"\tnew undef: " << UseIdx <<
'\t' << MI);
1172 void RegisterCoalescer::updateRegDefsUses(
unsigned SrcReg,
1176 LiveInterval *DstInt = DstIsPhys ?
nullptr : &LIS->getInterval(DstReg);
1180 I = MRI->reg_instr_begin(SrcReg), E = MRI->reg_instr_end();
1189 if (SrcReg == DstReg && !Visited.
insert(UseMI).second)
1198 if (DstInt && !Reads && SubIdx)
1199 Reads = DstInt->
liveAt(LIS->getInstructionIndex(UseMI));
1202 for (
unsigned i = 0, e = Ops.
size(); i != e; ++i) {
1208 if (SubIdx && MO.
isDef())
1213 if (SubIdx != 0 && MO.
isUse() && MRI->shouldTrackSubRegLiveness(DstReg)) {
1216 unsigned Mask = MRI->getMaxLaneMaskForVReg(DstInt->
reg);
1219 unsigned Mask = TRI->getSubRegIndexLaneMask(SubIdx);
1220 bool IsUndef =
true;
1222 ? LIS->getSlotIndexes()->getIndexBefore(UseMI)
1223 : LIS->getInstructionIndex(UseMI);
1226 if ((S.LaneMask & Mask) == 0)
1228 if (S.liveAt(UseIdx)) {
1241 ShrinkMainRange =
true;
1252 dbgs() <<
"\t\tupdated: ";
1254 dbgs() << LIS->getInstructionIndex(UseMI) <<
"\t";
1260 bool RegisterCoalescer::canJoinPhys(
const CoalescerPair &CP) {
1265 DEBUG(
dbgs() <<
"\tCan only merge into reserved registers.\n");
1273 DEBUG(
dbgs() <<
"\tCannot join complex intervals into reserved register.\n");
1277 bool RegisterCoalescer::joinCopy(
MachineInstr *CopyMI,
bool &Again) {
1280 DEBUG(
dbgs() << LIS->getInstructionIndex(CopyMI) <<
'\t' << *CopyMI);
1284 DEBUG(
dbgs() <<
"\tNot coalescable.\n");
1289 auto SrcRC = MRI->getRegClass(CP.
getSrcReg());
1290 auto DstRC = MRI->getRegClass(CP.
getDstReg());
1297 if (!TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx,
1299 DEBUG(
dbgs() <<
"\tSubtarget bailed on coalescing.\n");
1309 DeadDefs.push_back(CopyMI);
1310 eliminateDeadDefs();
1315 if (!CP.
isPhys() && eliminateUndefCopy(CopyMI)) {
1316 LIS->RemoveMachineInstrFromMaps(CopyMI);
1326 DEBUG(
dbgs() <<
"\tCopy already coalesced: " << LI <<
'\n');
1327 const SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI);
1331 assert(ReadVNI &&
"No value before copy and no <undef> flag.");
1332 assert(ReadVNI != DefVNI &&
"Cannot read and define the same value.");
1340 S.MergeValueNumberInto(SDefVNI, SReadVNI);
1343 DEBUG(
dbgs() <<
"\tMerged values: " << LI <<
'\n');
1345 LIS->RemoveMachineInstrFromMaps(CopyMI);
1355 if (!canJoinPhys(CP)) {
1359 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
1372 dbgs() <<
"\tConsidering merging to "
1373 << TRI->getRegClassName(CP.
getNewRC()) <<
" with ";
1376 << TRI->getSubRegIndexName(CP.
getDstIdx()) <<
" and "
1378 << TRI->getSubRegIndexName(CP.
getSrcIdx()) <<
'\n';
1386 ShrinkMainRange =
false;
1392 if (!joinIntervals(CP)) {
1398 if (reMaterializeTrivialDef(CP, CopyMI, IsDefCopy))
1404 if (adjustCopiesBackFrom(CP, CopyMI) ||
1405 removeCopyByCommutingDef(CP, CopyMI)) {
1406 LIS->RemoveMachineInstrFromMaps(CopyMI);
1428 if (!CP.
isPhys() && RegClassInfo.isProperSubClass(CP.
getNewRC()))
1434 ErasedInstrs.erase(CopyMI);
1443 if (ShrinkMask != 0) {
1446 if ((S.LaneMask & ShrinkMask) == 0)
1448 DEBUG(
dbgs() <<
"Shrink LaneUses (Lane "
1449 <<
format(
"%04X", S.LaneMask) <<
")\n");
1450 LIS->shrinkToUses(S, LI.
reg);
1454 if (ShrinkMainRange) {
1469 dbgs() <<
"\tResult = ";
1481 bool RegisterCoalescer::joinReservedPhysReg(
CoalescerPair &CP) {
1483 assert(CP.
isPhys() &&
"Must be a physreg copy");
1484 assert(MRI->isReserved(DstReg) &&
"Not a reserved register");
1486 DEBUG(
dbgs() <<
"\t\tRHS = " << RHS <<
'\n');
1488 assert(RHS.containsOneValue() &&
"Invalid join with reserved register");
1498 if (RHS.overlaps(LIS->getRegUnit(*UI))) {
1511 CopyMI = MRI->getVRegDef(RHS.reg);
1513 if (!MRI->hasOneNonDBGUse(RHS.reg)) {
1514 DEBUG(
dbgs() <<
"\t\tMultiple vreg uses!\n");
1519 CopyMI = &*MRI->use_instr_nodbg_begin(RHS.reg);
1531 DEBUG(
dbgs() <<
"\t\tInterference (read): " << *MI);
1536 for (
const auto &MO : MI->
operands()) {
1538 DEBUG(
dbgs() <<
"\t\tInterference (regmask clobber): " << *MI);
1546 DEBUG(
dbgs() <<
"\t\tRemoving phys reg def of " << DstReg <<
" at "
1547 << CopyRegIdx <<
"\n");
1549 LIS->removePhysRegDefAt(DstReg, CopyRegIdx);
1557 LIS->RemoveMachineInstrFromMaps(CopyMI);
1644 const unsigned SubIdx;
1647 const unsigned LaneMask;
1651 const bool SubRangeJoin;
1653 const bool TrackSubRegLiveness;
1668 enum ConflictResolution {
1699 ConflictResolution Resolution;
1702 unsigned WriteLanes;
1706 unsigned ValidLanes;
1725 bool ErasableImplicitDef;
1732 bool PrunedComputed;
1734 Val() : Resolution(CR_Keep), WriteLanes(0), ValidLanes(0),
1735 RedefVNI(nullptr), OtherVNI(nullptr), ErasableImplicitDef(
false),
1738 bool isAnalyzed()
const {
return WriteLanes != 0; }
1747 unsigned computeWriteLanes(
const MachineInstr *DefMI,
bool &Redef)
const;
1750 std::pair<const VNInfo*,unsigned> followCopyChain(
const VNInfo *VNI)
const;
1761 ConflictResolution analyzeValue(
unsigned ValNo, JoinVals &
Other);
1766 void computeAssignment(
unsigned ValNo, JoinVals &
Other);
1783 bool taintExtent(
unsigned,
unsigned, JoinVals&,
1788 bool usesLanes(
const MachineInstr *MI,
unsigned,
unsigned,
unsigned)
const;
1796 bool isPrunedValue(
unsigned ValNo, JoinVals &
Other);
1799 JoinVals(
LiveRange &LR,
unsigned Reg,
unsigned SubIdx,
unsigned LaneMask,
1802 bool TrackSubRegLiveness)
1803 : LR(LR), Reg(Reg), SubIdx(SubIdx), LaneMask(LaneMask),
1804 SubRangeJoin(SubRangeJoin), TrackSubRegLiveness(TrackSubRegLiveness),
1805 NewVNInfo(newVNInfo), CP(cp), LIS(lis), Indexes(LIS->getSlotIndexes()),
1806 TRI(TRI), Assignments(LR.getNumValNums(), -1), Vals(LR.getNumValNums())
1811 bool mapValues(JoinVals &
Other);
1815 bool resolveConflicts(JoinVals &
Other);
1826 void pruneSubRegValues(
LiveInterval &LI,
unsigned &ShrinkMask);
1836 void removeImplicitDefs();
1839 const int *getAssignments()
const {
return Assignments.data(); }
1843 unsigned JoinVals::computeWriteLanes(
const MachineInstr *DefMI,
bool &Redef)
1849 L |= TRI->getSubRegIndexLaneMask(
1850 TRI->composeSubRegIndices(SubIdx, MO.
getSubReg()));
1857 std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain(
1858 const VNInfo *VNI)
const {
1859 unsigned Reg = this->
Reg;
1864 assert(MI &&
"No defining instruction");
1866 return std::make_pair(VNI, Reg);
1869 return std::make_pair(VNI, Reg);
1882 unsigned SMask = TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
1883 if ((SMask & LaneMask) == 0)
1890 if (ValueIn ==
nullptr)
1895 return std::make_pair(VNI, Reg);
1898 bool JoinVals::valuesIdentical(
VNInfo *Value0,
VNInfo *Value1,
1899 const JoinVals &
Other)
const {
1902 std::tie(Orig0, Reg0) = followCopyChain(Value0);
1903 if (Orig0 == Value1)
1908 std::tie(Orig1, Reg1) = Other.followCopyChain(Value1);
1914 return Orig0->
def == Orig1->
def && Reg0 == Reg1;
1917 JoinVals::ConflictResolution
1918 JoinVals::analyzeValue(
unsigned ValNo, JoinVals &Other) {
1919 Val &V = Vals[ValNo];
1920 assert(!V.isAnalyzed() &&
"Value has already been analyzed!");
1922 if (VNI->isUnused()) {
1929 if (VNI->isPHIDef()) {
1931 unsigned Lanes = SubRangeJoin ? 1 : TRI->getSubRegIndexLaneMask(SubIdx);
1932 V.ValidLanes = V.WriteLanes = Lanes;
1935 assert(DefMI !=
nullptr);
1938 V.WriteLanes = V.ValidLanes = 1;
1941 V.ErasableImplicitDef =
true;
1945 V.ValidLanes = V.WriteLanes = computeWriteLanes(DefMI, Redef);
1964 assert((TrackSubRegLiveness || V.RedefVNI) &&
1965 "Instruction is reading nonexistent value");
1966 if (V.RedefVNI !=
nullptr) {
1967 computeAssignment(V.RedefVNI->id, Other);
1968 V.ValidLanes |= Vals[V.RedefVNI->id].ValidLanes;
1977 V.ErasableImplicitDef =
true;
1978 V.ValidLanes &= ~V.WriteLanes;
1995 if (OtherVNI->def < VNI->def)
1996 Other.computeAssignment(OtherVNI->id, *
this);
1997 else if (VNI->def < OtherVNI->def && OtherLRQ.
valueIn()) {
2000 V.OtherVNI = OtherLRQ.
valueIn();
2001 return CR_Impossible;
2003 V.OtherVNI = OtherVNI;
2004 Val &OtherV = Other.Vals[OtherVNI->id];
2006 if (!OtherV.isAnalyzed())
2011 if (VNI->isPHIDef())
2013 if (V.ValidLanes & OtherV.ValidLanes)
2015 return CR_Impossible;
2021 V.OtherVNI = OtherLRQ.
valueIn();
2030 Other.computeAssignment(V.OtherVNI->id, *
this);
2031 Val &OtherV = Other.Vals[V.OtherVNI->id];
2040 if (OtherV.ErasableImplicitDef && DefMI &&
2042 DEBUG(
dbgs() <<
"IMPLICIT_DEF defined at " << V.OtherVNI->def
2044 <<
", keeping it.\n");
2045 OtherV.ErasableImplicitDef =
false;
2050 if (VNI->isPHIDef())
2057 if (TrackSubRegLiveness
2058 && (V.WriteLanes & (OtherV.ValidLanes | OtherV.WriteLanes)) == 0)
2068 V.ValidLanes &= ~V.WriteLanes | OtherV.ValidLanes;
2083 && valuesIdentical(VNI, V.OtherVNI, Other))
2098 if ((V.WriteLanes & OtherV.ValidLanes) == 0)
2110 assert(VNI->def.isEarlyClobber() &&
2111 "Only early clobber defs can overlap a kill");
2112 return CR_Impossible;
2119 if ((TRI->getSubRegIndexLaneMask(Other.SubIdx) & ~V.WriteLanes) == 0)
2120 return CR_Impossible;
2127 return CR_Impossible;
2136 return CR_Unresolved;
2139 void JoinVals::computeAssignment(
unsigned ValNo, JoinVals &Other) {
2140 Val &V = Vals[ValNo];
2141 if (V.isAnalyzed()) {
2144 assert(Assignments[ValNo] != -1 &&
"Bad recursion?");
2147 switch ((V.Resolution = analyzeValue(ValNo, Other))) {
2151 assert(V.OtherVNI &&
"OtherVNI not assigned, can't merge.");
2152 assert(Other.Vals[V.OtherVNI->id].isAnalyzed() &&
"Missing recursion");
2153 Assignments[ValNo] = Other.Assignments[V.OtherVNI->id];
2156 <<
PrintReg(Other.Reg) <<
':' << V.OtherVNI->id <<
'@'
2157 << V.OtherVNI->def <<
" --> @"
2158 << NewVNInfo[Assignments[ValNo]]->def <<
'\n');
2161 case CR_Unresolved: {
2163 assert(V.OtherVNI &&
"OtherVNI not assigned, can't prune");
2164 Val &OtherV = Other.Vals[V.OtherVNI->id];
2167 if ((OtherV.WriteLanes & ~V.ValidLanes) != 0 && TrackSubRegLiveness)
2168 OtherV.ErasableImplicitDef =
false;
2169 OtherV.Pruned =
true;
2174 Assignments[ValNo] = NewVNInfo.size();
2180 bool JoinVals::mapValues(JoinVals &Other) {
2182 computeAssignment(i, Other);
2183 if (Vals[i].Resolution == CR_Impossible) {
2193 taintExtent(
unsigned ValNo,
unsigned TaintedLanes, JoinVals &Other,
2201 assert(OtherI != Other.LR.end() &&
"No conflict?");
2206 if (End >= MBBEnd) {
2208 << OtherI->valno->id <<
'@' << OtherI->start <<
'\n');
2212 << OtherI->valno->id <<
'@' << OtherI->start
2213 <<
" to " << End <<
'\n');
2217 TaintExtent.push_back(std::make_pair(End, TaintedLanes));
2220 if (++OtherI == Other.LR.end() || OtherI->start >= MBBEnd)
2224 const Val &OV = Other.Vals[OtherI->valno->id];
2225 TaintedLanes &= ~OV.WriteLanes;
2228 }
while (TaintedLanes);
2232 bool JoinVals::usesLanes(
const MachineInstr *MI,
unsigned Reg,
unsigned SubIdx,
2233 unsigned Lanes)
const {
2241 if (Lanes & TRI->getSubRegIndexLaneMask(
2242 TRI->composeSubRegIndices(SubIdx, MO.
getSubReg())))
2248 bool JoinVals::resolveConflicts(JoinVals &Other) {
2251 assert (V.Resolution != CR_Impossible &&
"Unresolvable conflict");
2252 if (V.Resolution != CR_Unresolved)
2260 assert(V.OtherVNI &&
"Inconsistent conflict resolution.");
2262 const Val &OtherV = Other.Vals[V.OtherVNI->id];
2267 unsigned TaintedLanes = V.WriteLanes & OtherV.ValidLanes;
2269 if (!taintExtent(i, TaintedLanes, Other, TaintExtent))
2273 assert(!TaintExtent.
empty() &&
"There should be at least one conflict.");
2284 "Interference ends on VNI->def. Should have been handled earlier");
2287 assert(LastMI &&
"Range must end at a proper instruction");
2288 unsigned TaintNum = 0;
2290 assert(MI != MBB->end() &&
"Bad LastMI");
2291 if (usesLanes(MI, Other.Reg, Other.SubIdx, TaintedLanes)) {
2292 DEBUG(
dbgs() <<
"\t\ttainted lanes used by: " << *MI);
2296 if (&*MI == LastMI) {
2297 if (++TaintNum == TaintExtent.
size())
2300 assert(LastMI &&
"Range must end at a proper instruction");
2301 TaintedLanes = TaintExtent[TaintNum].second;
2307 V.Resolution = CR_Replace;
2313 bool JoinVals::isPrunedValue(
unsigned ValNo, JoinVals &Other) {
2314 Val &V = Vals[ValNo];
2315 if (V.Pruned || V.PrunedComputed)
2318 if (V.Resolution != CR_Erase && V.Resolution != CR_Merge)
2323 V.PrunedComputed =
true;
2324 V.Pruned = Other.isPrunedValue(V.OtherVNI->id, *
this);
2328 void JoinVals::pruneValues(JoinVals &Other,
2330 bool changeInstrs) {
2333 switch (Vals[i].Resolution) {
2338 LIS->pruneValue(Other.LR, Def, &EndPoints);
2343 Val &OtherV = Other.Vals[Vals[i].OtherVNI->id];
2344 bool EraseImpDef = OtherV.ErasableImplicitDef &&
2345 OtherV.Resolution == CR_Keep;
2365 <<
": " << Other.LR <<
'\n');
2370 if (isPrunedValue(i, Other)) {
2375 LIS->pruneValue(LR, Def, &EndPoints);
2377 << Def <<
": " << LR <<
'\n');
2387 void JoinVals::pruneSubRegValues(
LiveInterval &LI,
unsigned &ShrinkMask)
2390 bool DidPrune =
false;
2392 if (Vals[i].Resolution != CR_Erase)
2403 if (ValueOut !=
nullptr && Q.
valueIn() ==
nullptr) {
2405 <<
" at " << Def <<
"\n");
2406 LIS->pruneValue(S, Def,
nullptr);
2415 DEBUG(
dbgs() <<
"\t\tDead uses at sublane "
2416 <<
format(
"%04X", S.LaneMask) <<
" at " << Def <<
"\n");
2417 ShrinkMask |= S.LaneMask;
2425 void JoinVals::removeImplicitDefs() {
2428 if (V.Resolution != CR_Keep || !V.ErasableImplicitDef || !V.Pruned)
2442 switch (Vals[i].Resolution) {
2447 if (!Vals[i].ErasableImplicitDef || !Vals[i].Pruned)
2455 DEBUG(
dbgs() <<
"\t\tremoved " << i <<
'@' << Def <<
": " << LR <<
'\n');
2461 assert(MI &&
"No instruction to erase");
2469 DEBUG(
dbgs() <<
"\t\terased:\t" << Def <<
'\t' << *MI);
2470 LIS->RemoveMachineInstrFromMaps(MI);
2485 NewVNInfo,
CP, LIS, TRI,
true,
true);
2486 JoinVals LHSVals(LRange, CP.getDstReg(), CP.getDstIdx(), LaneMask,
2487 NewVNInfo,
CP, LIS, TRI,
true,
true);
2494 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals)) {
2495 DEBUG(
dbgs() <<
"*** Couldn't join subrange!\n");
2498 if (!LHSVals.resolveConflicts(RHSVals) ||
2499 !RHSVals.resolveConflicts(LHSVals)) {
2500 DEBUG(
dbgs() <<
"*** Couldn't join subrange!\n");
2509 LHSVals.pruneValues(RHSVals, EndPoints,
false);
2510 RHSVals.pruneValues(LHSVals, EndPoints,
false);
2512 LHSVals.removeImplicitDefs();
2513 RHSVals.removeImplicitDefs();
2519 LRange.
join(RRange, LHSVals.getAssignments(), RHSVals.getAssignments(),
2522 DEBUG(
dbgs() <<
"\t\tjoined lanes: " << LRange <<
"\n");
2523 if (EndPoints.
empty())
2528 DEBUG(
dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size()
2529 <<
" points: " << LRange <<
'\n');
2530 LIS->extendToIndices(LRange, EndPoints);
2534 bool RegisterCoalescer::mergeSubRangeInto(
LiveInterval &LI,
2539 unsigned RMask = R.LaneMask;
2541 unsigned Common = RMask & LaneMask;
2546 DEBUG(
dbgs() <<
format(
"\t\tCopy+Merge %04X into %04X\n", RMask, Common));
2549 unsigned LRest = RMask & ~LaneMask;
2561 LiveRange RangeCopy(ToMerge, Allocator);
2562 if (!joinSubRegRanges(*CommonRange, RangeCopy, Common, CP))
2567 if (LaneMask != 0) {
2578 bool TrackSubRegLiveness = MRI->shouldTrackSubRegLiveness(*CP.
getNewRC());
2580 TRI,
false, TrackSubRegLiveness);
2581 JoinVals LHSVals(LHS, CP.getDstReg(), CP.getDstIdx(), 0, NewVNInfo,
CP, LIS,
2582 TRI,
false, TrackSubRegLiveness);
2585 <<
"\n\t\tLHS = " << LHS
2590 if (!LHSVals.mapValues(RHSVals) || !RHSVals.mapValues(LHSVals))
2594 if (!LHSVals.resolveConflicts(RHSVals) || !RHSVals.resolveConflicts(LHSVals))
2603 unsigned DstIdx = CP.getDstIdx();
2605 unsigned Mask = DstIdx == 0 ? CP.getNewRC()->getLaneMask()
2606 : TRI->getSubRegIndexLaneMask(DstIdx);
2610 }
else if (DstIdx != 0) {
2613 unsigned Mask = TRI->composeSubRegIndexLaneMask(DstIdx, R.LaneMask);
2618 <<
' ' << LHS <<
'\n');
2621 unsigned SrcIdx = CP.getSrcIdx();
2624 unsigned Mask = SrcIdx == 0 ? CP.getNewRC()->getLaneMask()
2625 : TRI->getSubRegIndexLaneMask(SrcIdx);
2626 if (!mergeSubRangeInto(LHS, RHS, Mask, CP))
2631 unsigned Mask = TRI->composeSubRegIndexLaneMask(SrcIdx, R.LaneMask);
2632 if (!mergeSubRangeInto(LHS, R, Mask, CP)) {
2646 CP.getNewRC()->getLaneMask())
2647 &&
"SubRange merge should only fail when merging into bit 32.");
2648 DEBUG(
dbgs() <<
"\tSubrange join aborted!\n");
2652 DEBUG(
dbgs() <<
"\tJoined SubRanges " << LHS <<
"\n");
2654 LHSVals.pruneSubRegValues(LHS, ShrinkMask);
2655 RHSVals.pruneSubRegValues(LHS, ShrinkMask);
2664 LHSVals.pruneValues(RHSVals, EndPoints,
true);
2665 RHSVals.pruneValues(LHSVals, EndPoints,
true);
2670 LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
2671 RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
2672 while (!ShrinkRegs.
empty())
2673 shrinkToUses(&LIS->getInterval(ShrinkRegs.
pop_back_val()));
2676 LHS.
join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
2681 MRI->clearKillFlags(LHS.
reg);
2682 MRI->clearKillFlags(RHS.
reg);
2684 if (!EndPoints.
empty()) {
2687 DEBUG(
dbgs() <<
"\t\trestoring liveness to " << EndPoints.
size()
2688 <<
" points: " << LHS <<
'\n');
2689 LIS->extendToIndices((
LiveRange&)LHS, EndPoints);
2696 return CP.
isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(CP);
2701 struct MBBPriorityInfo {
2707 : MBB(mbb), Depth(depth), IsSplit(issplit) {}
2716 const MBBPriorityInfo *RHS) {
2718 if (LHS->Depth != RHS->Depth)
2719 return LHS->Depth > RHS->Depth ? -1 : 1;
2722 if (LHS->IsSplit != RHS->IsSplit)
2723 return LHS->IsSplit ? -1 : 1;
2727 unsigned cl = LHS->MBB->pred_size() + LHS->MBB->succ_size();
2728 unsigned cr = RHS->MBB->pred_size() + RHS->MBB->succ_size();
2730 return cl > cr ? -1 : 1;
2733 return LHS->MBB->getNumber() < RHS->MBB->getNumber() ? -1 : 1;
2754 bool RegisterCoalescer::
2756 bool Progress =
false;
2757 for (
unsigned i = 0, e = CurrList.
size(); i != e; ++i) {
2762 if (ErasedInstrs.
erase(CurrList[i])) {
2763 CurrList[i] =
nullptr;
2767 bool Success = joinCopy(CurrList[i], Again);
2768 Progress |= Success;
2769 if (Success || !Again)
2770 CurrList[i] =
nullptr;
2787 bool RegisterCoalescer::applyTerminalRule(
const MachineInstr &Copy)
const {
2791 unsigned DstReg, DstSubReg, SrcReg, SrcSubReg;
2792 isMoveInstr(*TRI, &Copy, SrcReg, DstReg, SrcSubReg, DstSubReg);
2806 for (
const MachineInstr &MI : MRI->reg_nodbg_instructions(SrcReg)) {
2815 unsigned OtherReg, OtherSubReg, OtherSrcReg, OtherSrcSubReg;
2816 isMoveInstr(*TRI, &Copy, OtherSrcReg, OtherReg, OtherSrcSubReg,
2818 if (OtherReg == SrcReg)
2819 OtherReg = OtherSrcReg;
2825 if (LIS->getInterval(OtherReg).overlaps(DstLI)) {
2839 const unsigned PrevSize = WorkList.size();
2840 if (JoinGlobalCopies) {
2849 if (!MII->isCopyLike())
2851 bool ApplyTerminalRule = applyTerminalRule(*MII);
2853 if (ApplyTerminalRule)
2856 LocalWorkList.push_back(&(*MII));
2858 if (ApplyTerminalRule)
2861 WorkList.push_back(&(*MII));
2865 LocalWorkList.append(LocalTerminals.
begin(), LocalTerminals.
end());
2866 WorkList.append(GlobalTerminals.
begin(), GlobalTerminals.
end());
2872 if (MII->isCopyLike()) {
2873 if (applyTerminalRule(*MII))
2876 WorkList.push_back(MII);
2879 WorkList.append(Terminals.
begin(), Terminals.
end());
2885 CurrList(WorkList.begin() + PrevSize, WorkList.end());
2886 if (copyCoalesceWorkList(CurrList))
2887 WorkList.erase(
std::remove(WorkList.begin() + PrevSize, WorkList.end(),
2891 void RegisterCoalescer::coalesceLocals() {
2892 copyCoalesceWorkList(LocalWorkList);
2893 for (
unsigned j = 0, je = LocalWorkList.size(); j != je; ++j) {
2894 if (LocalWorkList[j])
2895 WorkList.push_back(LocalWorkList[j]);
2897 LocalWorkList.clear();
2900 void RegisterCoalescer::joinAllIntervals() {
2901 DEBUG(
dbgs() <<
"********** JOINING INTERVALS ***********\n");
2902 assert(WorkList.empty() && LocalWorkList.empty() &&
"Old data still around.");
2904 std::vector<MBBPriorityInfo> MBBs;
2905 MBBs.reserve(MF->size());
2908 MBBs.push_back(MBBPriorityInfo(MBB,
Loops->getLoopDepth(MBB),
2914 unsigned CurrDepth = UINT_MAX;
2915 for (
unsigned i = 0, e = MBBs.size(); i != e; ++i) {
2917 if (JoinGlobalCopies && MBBs[i].Depth < CurrDepth) {
2919 CurrDepth = MBBs[i].Depth;
2921 copyCoalesceInMBB(MBBs[i].MBB);
2927 while (copyCoalesceWorkList(WorkList))
2931 void RegisterCoalescer::releaseMemory() {
2932 ErasedInstrs.
clear();
2935 InflateRegs.clear();
2945 LIS = &getAnalysis<LiveIntervals>();
2946 AA = &getAnalysis<AliasAnalysis>();
2947 Loops = &getAnalysis<MachineLoopInfo>();
2958 DEBUG(
dbgs() <<
"********** SIMPLE REGISTER COALESCING **********\n"
2959 <<
"********** Function: " << MF->getName() <<
'\n');
2962 MF->verify(
this,
"Before register coalescing");
2964 RegClassInfo.runOnMachineFunction(fn);
2974 InflateRegs.erase(std::unique(InflateRegs.begin(), InflateRegs.end()),
2976 DEBUG(
dbgs() <<
"Trying to inflate " << InflateRegs.size() <<
" regs.\n");
2977 for (
unsigned i = 0, e = InflateRegs.size(); i != e; ++i) {
2978 unsigned Reg = InflateRegs[i];
2979 if (MRI->reg_nodbg_empty(Reg))
2981 if (MRI->recomputeRegClass(Reg)) {
2983 << TRI->getRegClassName(MRI->getRegClass(Reg)) <<
'\n');
2985 unsigned MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
2995 assert ((S.LaneMask & ~MaxMask) == 0);
3005 MF->verify(
this,
"After register coalescing");
unsigned succ_size() const
static bool isSplitEdge(const MachineBasicBlock *MBB)
Return true if this block should be vacated by the coalescer to eliminate branches.
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Segments::iterator iterator
SlotIndex def
The index of the defining instruction.
unsigned getDstReg() const
Return the register (virtual or physical) that will remain after coalescing.
STATISTIC(NumFunctions,"Total number of functions")
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
int getNumber() const
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
A Module instance is used to store all the information related to an LLVM module. ...
INITIALIZE_PASS_BEGIN(RegisterCoalescer,"simple-register-coalescing","Simple Register Coalescing", false, false) INITIALIZE_PASS_END(RegisterCoalescer
static cl::opt< bool > VerifyCoalescing("verify-coalescing", cl::desc("Verify machine instrs before and after register coalescing"), cl::Hidden)
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
static bool isImpreciseLaneMask(unsigned LaneMask)
Returns true if the given lane mask is imprecise.
char & MachineDominatorsID
MachineDominators - This pass is a machine dominators analysis pass.
LiveInterval - This class represents the liveness of a register, or stack slot.
Describe properties that are true of each instruction in the target description file.
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
static bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI, unsigned &Src, unsigned &Dst, unsigned &SrcSub, unsigned &DstSub)
static bool isLocalCopy(MachineInstr *Copy, const LiveIntervals *LIS)
static bool definesFullReg(const MachineInstr &MI, unsigned Reg)
Returns true if MI defines the full vreg Reg, as opposed to just defining a subregister.
PrintRegUnit - Helper class for printing register units on a raw_ostream.
char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
bool isKill() const
Return true if the live-in value is killed by this instruction.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
A live range for subregisters.
This represents a simple continuous liveness interval for a value.
const TargetRegisterClass * getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B) const
getCommonSubClass - find the largest common subclass of A and B.
void setIsDead(bool Val=true)
SlotIndex endPoint() const
Return the end point of the last live range segment to interact with the instruction, if any.
void markUnused()
Mark this value as unused.
VNInfo - Value Number Information.
iterator_range< mop_iterator > operands()
void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo &)
substVirtReg - Substitute the current register with the virtual subregister Reg:SubReg.
unsigned getNumValNums() const
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Callback methods for LiveRangeEdit owners.
void initializeRegisterCoalescerPass(PassRegistry &)
bool allDefsAreDead() const
Return true if all the defs of this instruction are dead.
This class represents the liveness of a register, stack slot, etc.
SubRange * createSubRangeFrom(BumpPtrAllocator &Allocator, unsigned LaneMask, const LiveRange &CopyFrom)
Like createSubRange() but the new range is filled with a copy of the liveness information in CopyFrom...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isCrossClass() const
Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's.
MachineBasicBlock * intervalIsInOneMBB(const LiveInterval &LI) const
intervalIsInOneMBB - If LI is confined to a single basic block, return a pointer to that block...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
bool isFlipped() const
Return true when getSrcReg is the register being defined by the original copy instruction.
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A helper class for register coalescers.
std::pair< bool, bool > readsWritesVirtualRegister(unsigned Reg, SmallVectorImpl< unsigned > *Ops=nullptr) const
Return a pair of bools (reads, writes) indicating if this instruction reads or writes Reg...
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
iterator_range< subrange_iterator > subranges()
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Result of a LiveRange query.
static cl::opt< bool > EnableJoinSplits("join-splitedges", cl::desc("Coalesce copies on split edges (default=subtarget)"), cl::Hidden)
Temporary flag to test critical edge unsplitting.
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
iterator_range< reg_instr_nodbg_iterator > reg_nodbg_instructions(unsigned Reg) const
bool isBlock() const
isBlock - Returns true if this is a block boundary slot.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isUnused() const
Returns true if this value is unused.
SlotIndex getNextNonNullIndex(SlotIndex Index)
Returns the next non-null index, if one exists.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
virtual bool enableJoinGlobalCopies() const
True if the subtarget should enable joining global copies.
PrintReg - Helper class for printing registers on a raw_ostream.
bool isDead() const
isDead - Returns true if this is a dead def kill slot.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
VNInfo * MergeValueNumberInto(VNInfo *V1, VNInfo *V2)
MergeValueNumberInto - This method is called when two value numbers are found to be equivalent...
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
getMatchingSuperReg - Return a super-register of the specified register Reg so its sub-register of in...
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
virtual const TargetRegisterClass * getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const
getMatchingSuperRegClass - Return a subclass of the specified register class A so that each register ...
AnalysisUsage & addPreservedID(const void *ID)
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
size_t size() const
size - Get the array size.
bool setRegisters(const MachineInstr *)
Set registers to match the copy instruction MI.
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
const MachineBasicBlock * getParent() const
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
bool isImplicitDef() const
const TargetRegisterClass * getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, const TargetRegisterClass *RCB, unsigned SubB, unsigned &PreA, unsigned &PreB) const
getCommonSuperRegClass - Find a common super-register class if it exists.
bundle_iterator< MachineInstr, instr_iterator > iterator
void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
const TargetRegisterClass * getNewRC() const
Return the register class of the coalesced register.
initializer< Ty > init(const Ty &Val)
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static int compareMBBPriority(const MBBPriorityInfo *LHS, const MBBPriorityInfo *RHS)
C-style comparator that sorts first based on the loop depth of the basic block (the unsigned)...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Allocate memory in an ever growing pool, as if by bump-pointer.
static void addSegmentsWithValNo(LiveRange &Dst, VNInfo *DstValNo, const LiveRange &Src, const VNInfo *SrcValNo)
Copy segements with value number SrcValNo from liverange Src to live range and use value number DstV...
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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...
Represent the analysis usage information of a pass.
void substPhysReg(unsigned Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
VNInfo * valueDefined() const
Return the value defined by this instruction, if any.
static bool isTerminalReg(unsigned DstReg, const MachineInstr &Copy, const MachineRegisterInfo *MRI)
Check if DstReg is a terminal node.
void verify() const
Walk the range and assert if any invariants fail to hold.
#define INITIALIZE_AG_DEPENDENCY(depName)
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool liveAt(SlotIndex index) const
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
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.
void setIsKill(bool Val=true)
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
static cl::opt< bool > EnableJoining("join-liveintervals", cl::desc("Coalesce copies (default=true)"), cl::init(true))
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a use of the specific register or -1 if it is not found...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool isPhys() const
Return true if DstReg is a physical register.
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
static bool isSameInstr(SlotIndex A, SlotIndex B)
isSameInstr - Return true if A and B refer to the same instruction.
simple register Simple Register false
simple register coalescing
ConnectedVNInfoEqClasses - Helper class that can divide VNInfos in a LiveInterval into equivalence cl...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
Promote Memory to Register
void setPreservesCFG()
This function should be called by the pass, iff they do not:
LiveInterval & getInterval(unsigned Reg)
bool isCoalescable(const MachineInstr *) const
Return true if MI is a copy instruction that will become an identity copy after coalescing.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void clearSubRanges()
Removes all subregister liveness information.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
StringRef getName() const
getName - Return the name of the corresponding LLVM basic block, or "(null)".
unsigned getDstIdx() const
Return the subregister index that DstReg will be coalesced into, or 0.
VNInfo * getValNumInfo(unsigned ValNo)
getValNumInfo - Returns pointer to the specified val#.
bool containsOneValue() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
unsigned getSrcIdx() const
Return the subregister index that SrcReg will be coalesced into, or 0.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
static cl::opt< bool > UseTerminalRule("terminal-rule", cl::desc("Apply the terminal rule"), cl::init(false), cl::Hidden)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
VNInfo * createDeadDef(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
createDeadDef - Make sure the range has a value defined at Def.
SubRange * createSubRange(BumpPtrAllocator &Allocator, unsigned LaneMask)
Creates a new empty subregister live range.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
void setSubReg(unsigned subReg)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool flip()
Swap SrcReg and DstReg.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
unsigned getReg() const
getReg - Returns the register number.
VNInfo * getNextValue(SlotIndex def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
bool isPartial() const
Return true if the original copy instruction did not copy the full register, but was a subreg operati...
void eliminateDeadDefs(SmallVectorImpl< MachineInstr * > &Dead, ArrayRef< unsigned > RegsBeingSpilled=None)
eliminateDeadDefs - Try to delete machine instructions that are now dead (allDefsAreDead returns true...
virtual const TargetInstrInfo * getInstrInfo() const
simple register Simple Register Coalescing
unsigned getSrcReg() const
Return the virtual register that will be coalesced away.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
BasicBlockListType::iterator iterator
This class implements an extremely fast bulk output stream that can only output to a stream...
Primary interface to the complete machine description for the target machine.
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx=nullptr) const
Return true if the use operand of the specified index is tied to a def operand.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
unsigned composeSubRegIndices(unsigned a, unsigned b) const
composeSubRegIndices - Return the subregister index you get from composing two subregister indices...
void join(LiveRange &Other, const int *ValNoAssignments, const int *RHSValNoAssignments, SmallVectorImpl< VNInfo * > &NewVNInfo)
join - Join two live ranges (this, and other) together.
iterator FindSegmentContaining(SlotIndex Idx)
Return an iterator to the segment that contains the specified index, or end() if there is none...
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
SlotIndex - An opaque wrapper around machine indexes.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
unsigned pred_size() const
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.