28#define DEBUG_TYPE "amdgpucfgstructurizer"
32class PHILinearizeDestIterator;
35 friend class PHILinearizeDestIterator;
38 using PHISourceT = std::pair<unsigned, MachineBasicBlock *>;
42 using PHIInfoElementT =
struct {
50 static unsigned phiInfoElementGetDest(PHIInfoElementT *
Info);
51 static void phiInfoElementSetDef(PHIInfoElementT *
Info,
unsigned NewDef);
52 static PHISourcesT &phiInfoElementGetSources(PHIInfoElementT *
Info);
53 static void phiInfoElementAddSource(PHIInfoElementT *
Info,
unsigned SourceReg,
55 static void phiInfoElementRemoveSource(PHIInfoElementT *
Info,
58 PHIInfoElementT *findPHIInfoElement(
unsigned DestReg);
59 PHIInfoElementT *findPHIInfoElementFromSource(
unsigned SourceReg,
65 void addDest(
unsigned DestReg,
const DebugLoc &
DL);
66 void replaceDef(
unsigned OldDestReg,
unsigned NewDestReg);
67 void deleteDef(
unsigned DestReg);
68 void addSource(
unsigned DestReg,
unsigned SourceReg,
70 void removeSource(
unsigned DestReg,
unsigned SourceReg,
75 unsigned getNumSources(
unsigned DestReg);
80 using dest_iterator = PHILinearizeDestIterator;
82 dest_iterator dests_begin();
83 dest_iterator dests_end();
85 source_iterator sources_begin(
unsigned Reg);
86 source_iterator sources_end(
unsigned Reg);
89class PHILinearizeDestIterator {
96 unsigned operator*() {
return PHILinearize::phiInfoElementGetDest(*Iter); }
97 PHILinearizeDestIterator &operator++() {
101 bool operator==(
const PHILinearizeDestIterator &
I)
const {
102 return I.Iter == Iter;
104 bool operator!=(
const PHILinearizeDestIterator &
I)
const {
105 return I.Iter != Iter;
111unsigned PHILinearize::phiInfoElementGetDest(PHIInfoElementT *Info) {
112 return Info->DestReg;
115void PHILinearize::phiInfoElementSetDef(PHIInfoElementT *Info,
117 Info->DestReg = NewDef;
121PHILinearize::phiInfoElementGetSources(PHIInfoElementT *Info) {
122 return Info->Sources;
125void PHILinearize::phiInfoElementAddSource(PHIInfoElementT *Info,
133 for (
auto SI : phiInfoElementGetSources(Info)) {
134 assert((
SI.second != SourceMBB || SourceReg ==
SI.first));
138 phiInfoElementGetSources(Info).insert(PHISourceT(SourceReg, SourceMBB));
141void PHILinearize::phiInfoElementRemoveSource(PHIInfoElementT *Info,
144 auto &Sources = phiInfoElementGetSources(Info);
146 for (
auto SI : Sources) {
147 if (
SI.first == SourceReg &&
148 (
SI.second ==
nullptr ||
SI.second == SourceMBB)) {
153 for (
auto &Source : ElimiatedSources) {
154 Sources.erase(Source);
158PHILinearize::PHIInfoElementT *
159PHILinearize::findPHIInfoElement(
unsigned DestReg) {
160 for (
auto *
I : PHIInfo) {
161 if (phiInfoElementGetDest(
I) == DestReg) {
168PHILinearize::PHIInfoElementT *
169PHILinearize::findPHIInfoElementFromSource(
unsigned SourceReg,
171 for (
auto *
I : PHIInfo) {
172 for (
auto SI : phiInfoElementGetSources(
I)) {
173 if (
SI.first == SourceReg &&
174 (
SI.second ==
nullptr ||
SI.second == SourceMBB)) {
184 bool FoundSource =
false;
185 for (
auto *
I : PHIInfo) {
186 for (
auto SI : phiInfoElementGetSources(
I)) {
187 if (
SI.second == SourceMBB) {
196void PHILinearize::addDest(
unsigned DestReg,
const DebugLoc &
DL) {
197 assert(findPHIInfoElement(DestReg) ==
nullptr &&
"Dest already exists");
198 PHISourcesT EmptySet;
199 PHIInfoElementT *NewElement =
new PHIInfoElementT();
200 NewElement->DestReg = DestReg;
202 NewElement->Sources = EmptySet;
203 PHIInfo.
insert(NewElement);
206void PHILinearize::replaceDef(
unsigned OldDestReg,
unsigned NewDestReg) {
207 phiInfoElementSetDef(findPHIInfoElement(OldDestReg), NewDestReg);
210void PHILinearize::deleteDef(
unsigned DestReg) {
211 PHIInfoElementT *InfoElement = findPHIInfoElement(DestReg);
212 PHIInfo.erase(InfoElement);
216void PHILinearize::addSource(
unsigned DestReg,
unsigned SourceReg,
218 phiInfoElementAddSource(findPHIInfoElement(DestReg), SourceReg, SourceMBB);
221void PHILinearize::removeSource(
unsigned DestReg,
unsigned SourceReg,
223 phiInfoElementRemoveSource(findPHIInfoElement(DestReg), SourceReg, SourceMBB);
228 PHIInfoElementT *InfoElement =
229 findPHIInfoElementFromSource(SourceReg, SourceMBB);
230 if (InfoElement !=
nullptr) {
231 DestReg = phiInfoElementGetDest(InfoElement);
239 return findDest(Reg, SourceMBB, DestReg);
242unsigned PHILinearize::getNumSources(
unsigned DestReg) {
243 return phiInfoElementGetSources(findPHIInfoElement(DestReg)).size();
246#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
249 dbgs() <<
"=PHIInfo Start=\n";
250 for (
auto *PII : this->PHIInfo) {
251 PHIInfoElementT &Element = *PII;
254 for (
auto &SI : Element.Sources) {
260 dbgs() <<
"=PHIInfo End=\n";
264void PHILinearize::clear() { PHIInfo = PHIInfoT(); }
266PHILinearize::dest_iterator PHILinearize::dests_begin() {
267 return PHILinearizeDestIterator(PHIInfo.begin());
270PHILinearize::dest_iterator PHILinearize::dests_end() {
271 return PHILinearizeDestIterator(PHIInfo.end());
274PHILinearize::source_iterator PHILinearize::sources_begin(
unsigned Reg) {
275 auto InfoElement = findPHIInfoElement(Reg);
276 return phiInfoElementGetSources(InfoElement).begin();
279PHILinearize::source_iterator PHILinearize::sources_end(
unsigned Reg) {
280 auto InfoElement = findPHIInfoElement(Reg);
281 return phiInfoElementGetSources(InfoElement).end();
286 return (
PHI.getNumOperands() - 1) / 2;
291 return PHI.getOperand(
Index * 2 + 2).getMBB();
296 PHI.getOperand(
Index * 2 + 2).setMBB(NewPred);
301 return PHI.getOperand(
Index * 2 + 1).getReg();
306 return PHI.getOperand(0).getReg();
314class LinearizedRegion {
323 LinearizedRegion *Parent;
334 PHILinearize &PHIInfo);
338 RegionMRT *TopRegion);
345 RegionMRT *TopRegion =
nullptr);
351 ~LinearizedRegion() =
default;
355 RegionMRT *getRegionMRT() {
return RMRT; }
357 void setParent(LinearizedRegion *
P) { Parent =
P; }
359 LinearizedRegion *
getParent() {
return Parent; }
363 void setBBSelectRegIn(
unsigned Reg);
365 unsigned getBBSelectRegIn();
367 void setBBSelectRegOut(
unsigned Reg,
bool IsLiveOut);
369 unsigned getBBSelectRegOut();
371 void setHasLoop(
bool Value);
375 void addLiveOut(
unsigned VReg);
377 void removeLiveOut(
unsigned Reg);
379 void replaceLiveOut(
unsigned OldReg,
unsigned NewReg);
383 bool ReplaceOutside,
bool IncludeLoopPHIs);
385 void replaceRegisterInsideRegion(
unsigned Register,
unsigned NewRegister,
386 bool IncludeLoopPHIs,
389 void replaceRegisterOutsideRegion(
unsigned Register,
unsigned NewRegister,
390 bool IncludeLoopPHIs,
405 void addMBBs(LinearizedRegion *InnerRegion);
422 unsigned BBSelectRegIn;
423 unsigned BBSelectRegOut;
426 virtual ~MRT() =
default;
428 unsigned getBBSelectRegIn() {
return BBSelectRegIn; }
430 unsigned getBBSelectRegOut() {
return BBSelectRegOut; }
432 void setBBSelectRegIn(
unsigned Reg) { BBSelectRegIn =
Reg; }
434 void setBBSelectRegOut(
unsigned Reg) { BBSelectRegOut =
Reg; }
436 virtual RegionMRT *getRegionMRT() {
return nullptr; }
438 virtual MBBMRT *getMBBMRT() {
return nullptr; }
440 bool isRegion() {
return getRegionMRT() !=
nullptr; }
442 bool isMBB() {
return getMBBMRT() !=
nullptr; }
444 bool isRoot() {
return Parent ==
nullptr; }
448 RegionMRT *
getParent() {
return Parent; }
461 void dumpDepth(
int depth) {
462 for (
int i = depth; i > 0; --i) {
468class MBBMRT :
public MRT {
474 setBBSelectRegOut(0);
478 MBBMRT *getMBBMRT()
override {
return this; }
484 dbgs() <<
"MBB: " << getMBB()->getNumber();
490class RegionMRT :
public MRT {
493 LinearizedRegion *LRegion =
nullptr;
500 setBBSelectRegOut(0);
504 ~RegionMRT()
override {
509 for (
auto *CI : Children) {
514 RegionMRT *getRegionMRT()
override {
return this; }
516 void setLinearizedRegion(LinearizedRegion *LinearizeRegion) {
517 LRegion = LinearizeRegion;
520 LinearizedRegion *getLinearizedRegion() {
return LRegion; }
524 unsigned getInnerOutputRegister() {
525 return (*(
Children.begin()))->getBBSelectRegOut();
528 void addChild(MRT *Tree) {
Children.insert(Tree); }
540 dbgs() <<
"Succ: " << getSucc()->getNumber() <<
"\n";
542 dbgs() <<
"Succ: none \n";
543 for (
auto *MRTI : Children) {
544 MRTI->dump(
TRI, depth + 1);
548 MRT *getEntryTree() {
return Children.back(); }
550 MRT *getExitTree() {
return Children.front(); }
554 return (Tree->isRegion()) ? Tree->getRegionMRT()->getEntry()
555 : Tree->getMBBMRT()->getMBB();
560 return (Tree->isRegion()) ? Tree->getRegionMRT()->getExit()
561 : Tree->getMBBMRT()->getMBB();
569 for (
auto *CI : Children) {
571 if (
MBB == CI->getMBBMRT()->getMBB())
574 if (CI->getRegionMRT()->contains(
MBB))
576 if (CI->getRegionMRT()->getLinearizedRegion() !=
nullptr &&
577 CI->getRegionMRT()->getLinearizedRegion()->contains(
MBB))
584 void replaceLiveOutReg(
unsigned Register,
unsigned NewRegister) {
585 LinearizedRegion *LRegion = getLinearizedRegion();
586 LRegion->replaceLiveOut(
Register, NewRegister);
587 for (
auto &CI : Children) {
588 if (CI->isRegion()) {
589 CI->getRegionMRT()->replaceLiveOutReg(
Register, NewRegister);
599 return MRI->createVirtualRegister(
TII->getPreferredSelectRegClass(32));
605 for (
auto &MFI : MF) {
621 RegionMRT *
Result =
new RegionMRT(TopLevelRegion);
622 RegionMap[TopLevelRegion] =
Result;
629 MBBMRT *ExitMRT =
new MBBMRT(Exit);
631 ExitMRT->setBBSelectRegIn(BBSelectRegIn);
642 MBBMRT *NewMBB =
new MBBMRT(
MBB);
647 RegionMRT *NewMRTRegion =
new RegionMRT(
Region);
648 RegionMap[
Region] = NewMRTRegion;
652 while (RegionMap.
count(Parent) == 0) {
653 RegionMRT *NewMRTParent =
new RegionMRT(Parent);
654 NewMRTParent->addChild(NewMRTRegion);
655 NewMRTRegion->setParent(NewMRTParent);
656 RegionMap[Parent] = NewMRTParent;
657 NewMRTRegion = NewMRTParent;
660 RegionMap[Parent]->addChild(NewMRTRegion);
661 NewMRTRegion->setParent(RegionMap[Parent]);
665 RegionMap[
Region]->addChild(NewMBB);
666 NewMBB->setParent(RegionMap[
Region]);
676 PHILinearize &PHIInfo) {
677 if (
Reg.isVirtual()) {
682 if (PHIInfo.isSource(Reg)) {
687 for (
auto &UI :
MRI->use_operands(Reg)) {
688 if (UI.getParent()->getParent() !=
MBB) {
700 if ((&(*MII)) == DefInstr) {
712void LinearizedRegion::storeLiveOutRegRegion(RegionMRT *
Region,
Register Reg,
716 PHILinearize &PHIInfo) {
717 if (
Reg.isVirtual()) {
720 for (
auto &UI :
MRI->use_operands(Reg)) {
733 PHILinearize &PHIInfo) {
736 for (
auto &
II : *
MBB) {
737 for (
auto &RI :
II.defs()) {
740 for (
auto &IRI :
II.implicit_operands()) {
750 for (
auto &
II : *Succ) {
754 for (
int i = 0; i < numPreds; ++i) {
774 PHILinearize &PHIInfo,
775 RegionMRT *TopRegion) {
776 for (
auto &
II : *
MBB) {
777 for (
auto &RI :
II.defs()) {
778 storeLiveOutRegRegion(TopRegion, RI.getReg(), RI.getParent(),
MRI,
TRI,
781 for (
auto &IRI :
II.implicit_operands()) {
783 storeLiveOutRegRegion(TopRegion, IRI.getReg(), IRI.getParent(),
MRI,
790void LinearizedRegion::storeLiveOuts(RegionMRT *
Region,
793 PHILinearize &PHIInfo,
794 RegionMRT *CurrentTopRegion) {
797 RegionMRT *TopRegion =
798 CurrentTopRegion ==
nullptr ?
Region : CurrentTopRegion;
805 for (
auto *CI : *Children) {
807 auto MBB = CI->getMBBMRT()->getMBB();
808 storeMBBLiveOuts(
MBB,
MRI,
TRI, PHIInfo, TopRegion);
810 LinearizedRegion *SubRegion = CI->getRegionMRT()->getLinearizedRegion();
813 for (
auto *
MBBI : SubRegion->MBBs) {
814 storeMBBLiveOuts(
MBBI,
MRI,
TRI, PHIInfo, TopRegion);
819 if (CurrentTopRegion ==
nullptr) {
820 auto Succ =
Region->getSucc();
821 for (
auto &
II : *Succ) {
825 for (
int i = 0; i < numPreds; ++i) {
840 OS <<
"Linearized Region {";
842 for (
auto *
MBB : MBBs) {
850 OS <<
"} (" <<
Entry->getNumber() <<
", "
851 << (
Exit ==
nullptr ? -1 :
Exit->getNumber())
853 <<
" Out:" <<
printReg(getBBSelectRegOut(),
TRI) <<
" {";
854 for (
auto &LI : LiveOuts) {
861unsigned LinearizedRegion::getBBSelectRegIn() {
862 return getRegionMRT()->getBBSelectRegIn();
865unsigned LinearizedRegion::getBBSelectRegOut() {
866 return getRegionMRT()->getBBSelectRegOut();
869void LinearizedRegion::setHasLoop(
bool Value) { HasLoop =
Value; }
871bool LinearizedRegion::getHasLoop() {
return HasLoop; }
873void LinearizedRegion::addLiveOut(
unsigned VReg) { LiveOuts.insert(VReg); }
875void LinearizedRegion::removeLiveOut(
unsigned Reg) {
880void LinearizedRegion::replaceLiveOut(
unsigned OldReg,
unsigned NewReg) {
882 removeLiveOut(OldReg);
887void LinearizedRegion::replaceRegister(
unsigned Register,
890 bool ReplaceInside,
bool ReplaceOutside,
891 bool IncludeLoopPHI) {
892 assert(
Register != NewRegister &&
"Cannot replace a reg with itself");
895 dbgs() <<
"Preparing to replace register (region): "
897 <<
printReg(NewRegister,
MRI->getTargetRegisterInfo()) <<
"\n");
900 if (ReplaceOutside &&
902 LinearizedRegion *Current =
this;
903 while (Current !=
nullptr && Current->getEntry() !=
nullptr) {
906 Current->replaceLiveOut(
Register, NewRegister);
909 Current = Current->getParent();
923 bool IsInside =
contains(
O.getParent()->getParent());
924 bool IsLoopPHI = IsInside && (
O.getParent()->isPHI() &&
925 O.getParent()->getParent() == getEntry());
926 bool ShouldReplace = (IsInside && ReplaceInside) ||
927 (!IsInside && ReplaceOutside) ||
928 (IncludeLoopPHI && IsLoopPHI);
933 <<
printReg(NewRegister,
MRI->getTargetRegisterInfo())
940 <<
printReg(NewRegister,
MRI->getTargetRegisterInfo())
942 O.setReg(NewRegister);
948void LinearizedRegion::replaceRegisterInsideRegion(
unsigned Register,
949 unsigned NewRegister,
950 bool IncludeLoopPHIs,
952 replaceRegister(
Register, NewRegister,
MRI,
true,
false, IncludeLoopPHIs);
955void LinearizedRegion::replaceRegisterOutsideRegion(
unsigned Register,
956 unsigned NewRegister,
957 bool IncludeLoopPHIs,
959 replaceRegister(
Register, NewRegister,
MRI,
false,
true, IncludeLoopPHIs);
976void LinearizedRegion::addMBBs(LinearizedRegion *InnerRegion) {
977 for (
auto *
MBB : InnerRegion->MBBs) {
983 return MBBs.contains(
MBB);
986bool LinearizedRegion::isLiveOut(
unsigned Reg) {
987 return LiveOuts.contains(Reg);
991 return MRI->def_begin(Reg) ==
MRI->def_end();
1000 for (
auto *
MBBI : MBBs) {
1002 for (
auto &
II : *
MBB) {
1003 for (
auto &RI :
II.uses()) {
1006 if (
Reg.isVirtual()) {
1007 if (hasNoDef(Reg,
MRI))
1009 if (!
MRI->hasOneDef(Reg)) {
1014 if (
MRI->def_begin(Reg) ==
MRI->def_end()) {
1017 <<
" has NO defs\n");
1018 }
else if (!
MRI->hasOneDef(Reg)) {
1021 <<
" has multiple defs\n");
1024 assert(
MRI->hasOneDef(Reg) &&
"Register has multiple definitions");
1027 bool UseIsOutsideDefMBB =
Def->getParent()->getParent() !=
MBB;
1028 if (UseIsOutsideDefMBB && UseOperand->
isKill()) {
1040void LinearizedRegion::initLiveOut(RegionMRT *
Region,
1043 PHILinearize &PHIInfo) {
1050 PHILinearize &PHIInfo) {
1058LinearizedRegion::LinearizedRegion() {
1072 PHILinearize PHIInfo;
1083 void storePHILinearizationInfoDest(
1093 unsigned *ReplaceReg);
1107 unsigned CombinedSourceReg,
1108 LinearizedRegion *LRegion);
1113 LinearizedRegion *LRegion);
1116 void rewriteRegionEntryPHIs(LinearizedRegion *
Region,
1119 bool regionIsSimpleIf(RegionMRT *
Region);
1121 void transformSimpleIfRegion(RegionMRT *
Region);
1131 unsigned IfSourceRegister,
unsigned CodeSourceRegister,
1132 bool IsUndefIfSource =
false);
1141 void createEntryPHI(LinearizedRegion *CurrentRegion,
unsigned DestReg);
1143 void createEntryPHIs(LinearizedRegion *CurrentRegion);
1150 LinearizedRegion *LRegion,
1151 unsigned BBSelectRegIn,
1152 unsigned BBSelectRegOut);
1157 unsigned BBSelectRegIn,
unsigned BBSelectRegOut);
1162 unsigned BBSelectReg);
1167 LinearizedRegion *InnerRegion,
unsigned DestReg,
1168 unsigned SourceReg);
1173 LinearizedRegion *InnerRegion,
1174 LinearizedRegion *LRegion);
1179 LinearizedRegion *LRegion);
1185 LinearizedRegion *initLinearizedRegion(RegionMRT *
Region);
1187 bool structurizeComplexRegion(RegionMRT *
Region);
1189 bool structurizeRegion(RegionMRT *
Region);
1191 bool structurizeRegions(RegionMRT *
Region,
bool isTopRegion);
1207 void createLinearizedRegion(RegionMRT *
Region,
unsigned SelectOut);
1209 unsigned initializeSelectRegisters(MRT *MRT,
unsigned ExistingExitReg,
1213 void setRegionMRT(RegionMRT *RegionTree) { RMRT = RegionTree; }
1215 RegionMRT *getRegionMRT() {
return RMRT; }
1222char AMDGPUMachineCFGStructurizer::ID = 0;
1224bool AMDGPUMachineCFGStructurizer::regionIsSimpleIf(RegionMRT *
Region) {
1227 bool FoundBypass =
false;
1228 bool FoundIf =
false;
1230 if (
Entry->succ_size() != 2) {
1235 if (Current == Succ) {
1237 }
else if ((Current->succ_size() == 1) &&
1238 *(Current->succ_begin()) == Succ) {
1243 return FoundIf && FoundBypass;
1246void AMDGPUMachineCFGStructurizer::transformSimpleIfRegion(RegionMRT *
Region) {
1249 TII->convertNonUniformIfRegion(Entry, Exit);
1256 for (
auto &UI : TI.uses()) {
1257 if (UI.isMBB() && UI.getMBB() != Succ) {
1268 LinearizedRegion *LRegion =
Region->getLinearizedRegion();
1269 auto Exit = LRegion->getExit();
1273 if (LRegion->contains(Succ)) {
1275 assert(InternalSucc ==
nullptr);
1276 InternalSucc = Succ;
1279 assert(ExternalSucc ==
nullptr);
1280 ExternalSucc = Succ;
1284 for (
auto &TI : Exit->terminators()) {
1285 for (
auto &UI : TI.uses()) {
1287 auto Target = UI.getMBB();
1288 if (
Target != InternalSucc &&
Target != ExternalSucc) {
1289 UI.setMBB(ExternalSucc);
1300 auto Children =
Region->getChildren();
1301 for (
auto *CI : *Children) {
1302 if (!CI->isRegion()) {
1303 if (CI->getMBBMRT()->getMBB()->succ_size() > 1) {
1312 auto Children =
Region->getChildren();
1313 for (
auto *CI : *Children) {
1314 if (!CI->isRegion()) {
1322void AMDGPUMachineCFGStructurizer::getPHIRegionIndices(
1326 for (
unsigned i = 0; i < NumInputs; ++i) {
1334void AMDGPUMachineCFGStructurizer::getPHIRegionIndices(
1338 for (
unsigned i = 0; i < NumInputs; ++i) {
1346void AMDGPUMachineCFGStructurizer::getPHINonRegionIndices(
1350 for (
unsigned i = 0; i < NumInputs; ++i) {
1358void AMDGPUMachineCFGStructurizer::storePHILinearizationInfoDest(
1361 if (RegionIndices) {
1362 for (
auto i : *RegionIndices) {
1367 for (
unsigned i = 0; i < NumInputs; ++i) {
1373unsigned AMDGPUMachineCFGStructurizer::storePHILinearizationInfo(
1377 MRI->createVirtualRegister(
MRI->getRegClass(DestReg));
1378 PHIInfo.addDest(LinearizeDestReg,
PHI.getDebugLoc());
1379 storePHILinearizationInfoDest(LinearizeDestReg,
PHI, RegionIndices);
1380 return LinearizeDestReg;
1391 if (
Instr.isPHI()) {
1396 PHIInfo.addDest(PHIDestReg,
Instr.getDebugLoc());
1397 storePHILinearizationInfoDest(PHIDestReg, Instr);
1401 for (
auto *PI : PHIs) {
1402 PI->eraseFromParent();
1413 unsigned *ReplaceReg) {
1414 return shrinkPHI(
PHI, 0,
nullptr, PHIIndices, ReplaceReg);
1418 unsigned CombinedSourceReg,
1421 unsigned *ReplaceReg) {
1427 bool Replaced =
false;
1429 int SingleExternalEntryIndex = -1;
1430 for (
unsigned i = 0; i < NumInputs; ++i) {
1432 if (SingleExternalEntryIndex == -1) {
1434 SingleExternalEntryIndex = i;
1437 SingleExternalEntryIndex = -2;
1442 if (SingleExternalEntryIndex > -1) {
1453 MIB.
addReg(CombinedSourceReg);
1459 for (
unsigned i = 0; i < NumInputs; ++i) {
1472 PHI.eraseFromParent();
1476void AMDGPUMachineCFGStructurizer::replacePHI(
1484 bool HasExternalEdge =
false;
1486 for (
unsigned i = 0; i < NumInputs; ++i) {
1488 HasExternalEdge =
true;
1492 if (HasExternalEdge) {
1497 MIB.
addReg(CombinedSourceReg);
1501 for (
unsigned i = 0; i < NumInputs; ++i) {
1516 PHI.eraseFromParent();
1519void AMDGPUMachineCFGStructurizer::replaceEntryPHI(
1527 unsigned NumNonRegionInputs = NumInputs;
1528 for (
unsigned i = 0; i < NumInputs; ++i) {
1530 NumNonRegionInputs--;
1534 if (NumNonRegionInputs == 0) {
1536 replaceRegisterWith(DestReg, CombinedSourceReg);
1539 PHI.eraseFromParent();
1546 MIB.
addReg(CombinedSourceReg);
1551 for (
unsigned i = 0; i < NumInputs; ++i) {
1563 PHI.eraseFromParent();
1567void AMDGPUMachineCFGStructurizer::replaceLiveOutRegs(
1569 unsigned CombinedSourceReg, LinearizedRegion *LRegion) {
1570 bool WasLiveOut =
false;
1571 for (
auto PII : PHIRegionIndices) {
1573 if (LRegion->isLiveOut(Reg)) {
1579 if (MO.getParent()->getParent() != DefMBB)
1583 << (
IsDead ?
"dead" :
"alive")
1584 <<
" after PHI replace\n");
1586 LRegion->removeLiveOut(Reg);
1593 LRegion->addLiveOut(CombinedSourceReg);
1596void AMDGPUMachineCFGStructurizer::rewriteRegionExitPHI(RegionMRT *
Region,
1599 LinearizedRegion *LRegion) {
1601 getPHIRegionIndices(
Region,
PHI, PHIRegionIndices);
1602 unsigned LinearizedSourceReg =
1603 storePHILinearizationInfo(
PHI, &PHIRegionIndices);
1605 replacePHI(
PHI, LinearizedSourceReg, LastMerge, PHIRegionIndices);
1606 replaceLiveOutRegs(
PHI, PHIRegionIndices, LinearizedSourceReg, LRegion);
1609void AMDGPUMachineCFGStructurizer::rewriteRegionEntryPHI(LinearizedRegion *
Region,
1613 getPHINonRegionIndices(
Region,
PHI, PHINonRegionIndices);
1614 unsigned LinearizedSourceReg =
1615 storePHILinearizationInfo(
PHI, &PHINonRegionIndices);
1616 replaceEntryPHI(
PHI, LinearizedSourceReg, IfMBB, PHINonRegionIndices);
1621 for (
auto &BBI : *
MBB) {
1628void AMDGPUMachineCFGStructurizer::rewriteRegionExitPHIs(RegionMRT *
Region,
1630 LinearizedRegion *LRegion) {
1633 if (Exit ==
nullptr)
1638 for (
auto *PHII : PHIs) {
1639 rewriteRegionExitPHI(
Region, LastMerge, *PHII, LRegion);
1643void AMDGPUMachineCFGStructurizer::rewriteRegionEntryPHIs(LinearizedRegion *
Region,
1650 for (
auto *PHII : PHIs) {
1651 rewriteRegionEntryPHI(
Region, IfMBB, *PHII);
1659 <<
" -> " << Dest->
getNumber() <<
"\n");
1662 if (HasTerminator) {
1663 TII->ReplaceTailWithBranchTo(Terminator, Dest);
1666 TII->insertUnconditionalBranch(*
MBB, Dest,
DL);
1672 for (
auto &MFI : MF) {
1673 if (MFI.succ_empty()) {
1674 if (result ==
nullptr) {
1690AMDGPUMachineCFGStructurizer::createLinearizedExitBlock(RegionMRT *
Region) {
1700 if (Exit ==
nullptr) {
1702 MF->
insert(ExitIter, LastMerge);
1705 MF->
insert(ExitIter, LastMerge);
1707 insertUnconditionalBranch(LastMerge, Exit);
1717 unsigned DestRegister,
1718 unsigned IfSourceRegister,
1719 unsigned CodeSourceRegister,
1720 bool IsUndefIfSource) {
1726 <<
"): " <<
printReg(DestRegister,
TRI) <<
" = PHI("
1733 TII->get(TargetOpcode::PHI), DestRegister);
1734 if (IsUndefIfSource &&
false) {
1737 MIB.
addReg(IfSourceRegister);
1740 MIB.
addReg(CodeSourceRegister);
1749 (
MBB)->removeSuccessor(*PI);
1761 unsigned SuccSize = StartMBB->
succ_size();
1767 if (Succ != StartMBB &&
1768 !(Succ == StartMBBSucc && StartMBB != EndMBB && SuccSize == 1)) {
1770 std::pair<MachineBasicBlock *, MachineBasicBlock *>(EndMBB, Succ));
1777 Succs.
insert(std::pair(Pred, StartMBB));
1779 for (
auto SI : Succs) {
1780 std::pair<MachineBasicBlock *, MachineBasicBlock *> Edge = SI;
1783 Edge.first->removeSuccessor(Edge.second);
1790 bool InheritPreds) {
1796 if (Pred != CodeBBEnd)
1805 MF->
insert(MergeIter, IfBB);
1806 MF->
splice(MergeIter, CodeBBStartI, ++CodeBBEndI);
1826 TII->insertEQ(IfBB, IfBB->
begin(),
DL, IfReg,
1829 TII->materializeImmediate(*IfBB, IfBB->
begin(),
DL, IfReg,
1839void AMDGPUMachineCFGStructurizer::ensureCondIsNotKilled(
1841 if (
Cond.size() != 1)
1848 MO.setIsKill(
false);
1851void AMDGPUMachineCFGStructurizer::rewriteCodeBBTerminator(
MachineBasicBlock *CodeBB,
1853 unsigned BBSelectReg) {
1862 if (FalseBB ==
nullptr && TrueBB ==
nullptr && FallthroughBB ==
nullptr) {
1868 insertUnconditionalBranch(CodeBB, MergeBB,
DL);
1872 if (FalseBB ==
nullptr && TrueBB ==
nullptr) {
1873 TrueBB = FallthroughBB;
1874 }
else if (TrueBB !=
nullptr) {
1876 (FallthroughBB && (FallthroughBB != TrueBB)) ? FallthroughBB : FalseBB;
1879 if ((TrueBB !=
nullptr && FalseBB ==
nullptr) || (TrueBB == FalseBB)) {
1884 Register TrueBBReg =
MRI->createVirtualRegister(RegClass);
1885 Register FalseBBReg =
MRI->createVirtualRegister(RegClass);
1890 ensureCondIsNotKilled(
Cond);
1892 BBSelectReg,
Cond, TrueBBReg, FalseBBReg);
1895 insertUnconditionalBranch(CodeBB, MergeBB,
DL);
1898MachineInstr *AMDGPUMachineCFGStructurizer::getDefInstr(
unsigned Reg) {
1899 if (
MRI->def_begin(Reg) ==
MRI->def_end()) {
1902 <<
" has NO defs\n");
1903 }
else if (!
MRI->hasOneDef(Reg)) {
1906 <<
" has multiple defs\n");
1908 for (
auto DI =
MRI->def_begin(Reg), DE =
MRI->def_end(); DI != DE; ++DI) {
1914 assert(
MRI->hasOneDef(Reg) &&
"Register has multiple definitions");
1915 return (*(
MRI->def_begin(Reg))).getParent();
1921 LinearizedRegion *InnerRegion,
1923 unsigned SourceReg) {
1927 bool IsSingleBB = InnerRegion->getEntry() == InnerRegion->getExit();
1929 if (DefInstr->
isPHI() && DefInstr->
getParent() == CodeBB && IsSingleBB) {
1934 InnerRegion->replaceRegisterInsideRegion(SourceReg, DestReg,
true,
MRI);
1938 storePHILinearizationInfoDest(DestReg, *DefInstr);
1941 PHIInfo.removeSource(DestReg, SourceReg, CodeBB);
1945 if (IsSingleBB && DefInstr->
getParent() == InnerRegion->getEntry()) {
1948 InnerRegion->replaceRegisterOutsideRegion(SourceReg, DestReg,
false,
MRI);
1951 Register NextDestReg =
MRI->createVirtualRegister(RegClass);
1952 bool IsLastDef = PHIInfo.getNumSources(DestReg) == 1;
1954 insertMergePHI(IfBB, InnerRegion->getExit(), MergeBB, DestReg, NextDestReg,
1955 SourceReg, IsLastDef);
1957 PHIInfo.removeSource(DestReg, SourceReg, CodeBB);
1962 PHIInfo.deleteDef(DestReg);
1964 PHIInfo.replaceDef(DestReg, NextDestReg);
1970 LinearizedRegion *InnerRegion,
1972 return getDefInstr(
Register)->getParent() ==
MBB ||
1979 LinearizedRegion *InnerRegion,
1980 LinearizedRegion *LRegion) {
1983 bool IsSingleBB = InnerRegion->getEntry() == InnerRegion->getExit();
1984 for (
auto OLI : *LiveOuts) {
1988 for (
auto LI : OldLiveOuts) {
1990 if (!containsDef(CodeBB, InnerRegion, LI) ||
1991 (!IsSingleBB && (getDefInstr(LI)->
getParent() == LRegion->getExit()))) {
2000 if ( Reg != InnerRegion->getBBSelectRegOut()) {
2011 Register PHIDestReg =
MRI->createVirtualRegister(RegClass);
2012 Register IfSourceReg =
MRI->createVirtualRegister(RegClass);
2019 InnerRegion->replaceRegisterOutsideRegion(Reg, PHIDestReg,
true,
MRI);
2021 insertMergePHI(IfBB, InnerRegion->getExit(), MergeBB, PHIDestReg,
2022 IfSourceReg, Reg,
true);
2029 if (PHIInfo.findSourcesFromMBB(CodeBB, Sources)) {
2032 for (
auto SI : Sources) {
2034 PHIInfo.findDest(SI, CodeBB, DestReg);
2035 insertChainedPHI(IfBB, CodeBB, MergeBB, InnerRegion, DestReg, SI);
2048 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2051 unsigned DestReg = *DRI;
2052 auto SE = PHIInfo.sources_end(DestReg);
2054 bool MBBContainsPHISource =
false;
2056 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2057 unsigned SourceReg = (*SRI).first;
2059 if (
Def->getParent()->getParent() ==
MBB) {
2060 MBBContainsPHISource =
true;
2066 if (MBBContainsPHISource) {
2067 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2068 PHILinearize::PHISourceT
Source = *SRI;
2069 unsigned SourceReg =
Source.first;
2072 if (
Def->getParent()->getParent() !=
MBB) {
2073 ElimiatedSources.
push_back(std::tuple(DestReg, SourceReg, SourceMBB));
2080 for (
auto &SourceInfo : ElimiatedSources) {
2081 PHIInfo.removeSource(std::get<0>(SourceInfo), std::get<1>(SourceInfo),
2082 std::get<2>(SourceInfo));
2088void AMDGPUMachineCFGStructurizer::createEntryPHI(LinearizedRegion *CurrentRegion,
2094 << (*(
Entry->pred_begin()))->getNumber() <<
"\n");
2097 auto SE = PHIInfo.sources_end(DestReg);
2099 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2103 if (NumSources == 1) {
2104 auto SRI = PHIInfo.sources_begin(DestReg);
2105 unsigned SourceReg = (*SRI).first;
2106 replaceRegisterWith(DestReg, SourceReg);
2110 TII->get(TargetOpcode::PHI), DestReg);
2113 unsigned CurrentBackedgeReg = 0;
2115 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2116 unsigned SourceReg = (*SRI).first;
2118 if (CurrentRegion->contains((*SRI).second)) {
2119 if (CurrentBackedgeReg == 0) {
2120 CurrentBackedgeReg = SourceReg;
2125 MRI->getRegClass(CurrentBackedgeReg);
2126 Register NewBackedgeReg =
MRI->createVirtualRegister(RegClass);
2129 TII->get(TargetOpcode::PHI), NewBackedgeReg);
2130 BackedgePHI.
addReg(CurrentBackedgeReg);
2133 BackedgePHI.
addMBB((*SRI).second);
2134 CurrentBackedgeReg = NewBackedgeReg;
2136 <<
"Inserting backedge PHI: "
2145 MIB.
addMBB((*SRI).second);
2152 if (CurrentBackedgeReg != 0) {
2153 MIB.
addReg(CurrentBackedgeReg);
2163void AMDGPUMachineCFGStructurizer::createEntryPHIs(LinearizedRegion *CurrentRegion) {
2166 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2169 unsigned DestReg = *DRI;
2170 createEntryPHI(CurrentRegion, DestReg);
2175void AMDGPUMachineCFGStructurizer::replaceRegisterWith(
2177 assert(
Register != NewRegister &&
"Cannot replace a reg with itself");
2186 <<
printReg(NewRegister,
MRI->getTargetRegisterInfo())
2196 <<
printReg(NewRegister,
MRI->getTargetRegisterInfo())
2198 O.setReg(NewRegister);
2203 getRegionMRT()->replaceLiveOutReg(
Register, NewRegister);
2208void AMDGPUMachineCFGStructurizer::resolvePHIInfos(
MachineBasicBlock *FunctionEntry) {
2211 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2213 unsigned DestReg = *DRI;
2215 auto SRI = PHIInfo.sources_begin(DestReg);
2216 unsigned SourceReg = (*SRI).first;
2218 <<
" SourceReg: " <<
printReg(SourceReg,
TRI) <<
"\n");
2220 assert(PHIInfo.sources_end(DestReg) == ++SRI &&
2221 "More than one phi source in entry node");
2222 replaceRegisterWith(DestReg, SourceReg);
2232 LinearizedRegion *CurrentRegion,
unsigned BBSelectRegIn,
2233 unsigned BBSelectRegOut) {
2237 rewriteCodeBBTerminator(CodeBB, MergeBB, BBSelectRegOut);
2238 resolvePHIInfos(CodeBB);
2241 CurrentRegion->addMBB(CodeBB);
2244 if (CurrentRegion->getEntry() == CodeBB && !CurrentRegion->getHasLoop()) {
2250 if (CodeBBEndIter != MergeIter) {
2251 MF->
splice(MergeIter, CodeBBStartIter, CodeBBEndIter);
2253 rewriteCodeBBTerminator(CodeBB, MergeBB, BBSelectRegOut);
2254 prunePHIInfo(CodeBB);
2255 createEntryPHIs(CurrentRegion);
2258 CurrentRegion->addMBB(CodeBB);
2263 Register CodeBBSelectReg =
MRI->createVirtualRegister(RegClass);
2264 rewriteCodeBBTerminator(CodeBB, MergeBB, CodeBBSelectReg);
2265 bool IsRegionEntryBB = CurrentRegion->getEntry() == CodeBB;
2267 BBSelectRegIn, IsRegionEntryBB);
2268 CurrentRegion->addMBB(IfBB);
2271 if (IsRegionEntryBB) {
2272 CurrentRegion->setEntry(IfBB);
2274 if (CurrentRegion->getHasLoop()) {
2287 CurrentRegion->getRegionMRT()->getInnerOutputRegister(),
2288 CurrentRegion->getRegionMRT()->getEntry()->
getNumber());
2299 CurrentRegion->addMBB(CodeBB);
2300 LinearizedRegion InnerRegion(CodeBB,
MRI,
TRI, PHIInfo);
2302 InnerRegion.setParent(CurrentRegion);
2304 insertMergePHI(IfBB, CodeBB, MergeBB, BBSelectRegOut, BBSelectRegIn,
2306 InnerRegion.addMBB(MergeBB);
2309 rewriteLiveOutRegs(IfBB, CodeBB, MergeBB, &InnerRegion, CurrentRegion);
2310 extractKilledPHIs(CodeBB);
2311 if (IsRegionEntryBB)
2312 createEntryPHIs(CurrentRegion);
2319 unsigned BBSelectRegIn,
unsigned BBSelectRegOut) {
2320 unsigned CodeBBSelectReg =
2321 InnerRegion->getRegionMRT()->getInnerOutputRegister();
2325 SelectBB, BBSelectRegIn,
true);
2326 CurrentRegion->addMBB(IfBB);
2327 bool isEntry = CurrentRegion->getEntry() == InnerRegion->getEntry();
2330 if (CurrentRegion->getHasLoop()) {
2343 CurrentRegion->getRegionMRT()->getInnerOutputRegister(),
2344 CurrentRegion->getRegionMRT()->getEntry()->
getNumber());
2355 CurrentRegion->addMBBs(InnerRegion);
2357 insertMergePHI(IfBB, CodeExitBB, MergeBB, BBSelectRegOut, BBSelectRegIn,
2360 rewriteLiveOutRegs(IfBB, CodeExitBB, MergeBB, InnerRegion,
2363 rewriteRegionEntryPHIs(InnerRegion, IfBB);
2366 CurrentRegion->setEntry(IfBB);
2370 createEntryPHIs(CurrentRegion);
2379 LinearizedRegion *LRegion) {
2381 getPHIRegionIndices(LRegion,
PHI, PHIRegionIndices);
2385 unsigned RegionIndex = PHIRegionIndices[0];
2389 unsigned PHISource = PHIDest;
2390 unsigned ReplaceReg;
2392 if (shrinkPHI(
PHI, PHIRegionIndices, &ReplaceReg)) {
2393 PHISource = ReplaceReg;
2397 Register NewDestReg =
MRI->createVirtualRegister(RegClass);
2398 LRegion->replaceRegisterInsideRegion(PHIDest, NewDestReg,
false,
MRI);
2401 TII->get(TargetOpcode::PHI), NewDestReg);
2408 MIB.
addReg(RegionSourceReg);
2409 MIB.
addMBB(RegionSourceMBB);
2416 LinearizedRegion *LRegion) {
2420 for (
auto *PHII : PHIs) {
2421 splitLoopPHI(*PHII, Entry, EntrySucc, LRegion);
2427AMDGPUMachineCFGStructurizer::splitExit(LinearizedRegion *LRegion) {
2428 auto MRTRegion = LRegion->getRegionMRT();
2429 auto Exit = LRegion->getExit();
2430 auto MF =
Exit->getParent();
2431 auto Succ = MRTRegion->getSucc();
2434 auto AfterExitIter =
Exit->getIterator();
2436 MF->
insert(AfterExitIter, NewExit);
2437 Exit->removeSuccessor(Succ);
2438 Exit->addSuccessor(NewExit);
2439 NewExit->addSuccessor(Succ);
2440 insertUnconditionalBranch(NewExit, Succ);
2441 LRegion->addMBB(NewExit);
2442 LRegion->setExit(NewExit);
2444 LLVM_DEBUG(
dbgs() <<
"Created new exit block: " << NewExit->getNumber()
2448 for (
auto &
II : *Succ) {
2456 for (
int i = 0; i < numPreds; ++i) {
2473 MF->
insert(MBBIter, SuccMBB);
2488AMDGPUMachineCFGStructurizer::splitEntry(LinearizedRegion *LRegion) {
2496 LRegion->addMBB(EntrySucc);
2499 if (
Exit->isSuccessor(Entry)) {
2500 Exit->removeSuccessor(Entry);
2502 Exit->addSuccessor(EntrySucc);
2504 for (
auto &UI :
Branch.uses()) {
2505 if (UI.isMBB() && UI.getMBB() ==
Entry) {
2506 UI.setMBB(EntrySucc);
2510 splitLoopPHIs(Entry, EntrySucc, LRegion);
2516AMDGPUMachineCFGStructurizer::initLinearizedRegion(RegionMRT *
Region) {
2517 LinearizedRegion *LRegion =
Region->getLinearizedRegion();
2525 if (Exit ==
nullptr) {
2529 E = Exit->pred_end();
2532 (*PI)->removeSuccessor(Exit);
2548 if (Tree ==
nullptr)
2551 if (Tree->isMBB()) {
2558 RegionMRT *
Region = Tree->getRegionMRT();
2571bool AMDGPUMachineCFGStructurizer::structurizeComplexRegion(RegionMRT *
Region) {
2572 auto *LRegion = initLinearizedRegion(
Region);
2576 LRegion->addMBB(LastMerge);
2577 LRegion->setExit(LastMerge);
2579 rewriteRegionExitPHIs(
Region, LastMerge, LRegion);
2585 LLVM_DEBUG(
dbgs() <<
"===========If Region Start===============\n");
2586 if (LRegion->getHasLoop()) {
2592 unsigned BBSelectRegIn;
2593 unsigned BBSelectRegOut;
2594 for (MRT *Child : *Children) {
2598 if (Child->isRegion()) {
2600 LinearizedRegion *InnerLRegion =
2601 Child->getRegionMRT()->getLinearizedRegion();
2612 unsigned OuterSelect = InnerLRegion->getBBSelectRegOut();
2613 unsigned InnerSelectReg =
2614 InnerLRegion->getRegionMRT()->getInnerOutputRegister();
2615 replaceRegisterWith(InnerSelectReg, OuterSelect),
2616 resolvePHIInfos(InnerEntry);
2617 if (!InnerLRegion->getExit()->isSuccessor(CurrentMerge))
2618 InnerLRegion->getExit()->addSuccessor(CurrentMerge);
2622 BBSelectRegOut = Child->getBBSelectRegOut();
2623 BBSelectRegIn = Child->getBBSelectRegIn();
2631 CurrentMerge = createIfRegion(CurrentMerge, InnerLRegion, LRegion,
2632 Child->getRegionMRT()->getEntry(),
2633 BBSelectRegIn, BBSelectRegOut);
2634 TII->convertNonUniformIfRegion(CurrentMerge, IfEnd);
2646 BBSelectRegOut = Child->getBBSelectRegOut();
2647 BBSelectRegIn = Child->getBBSelectRegIn();
2657 CurrentMerge = createIfRegion(CurrentMerge,
MBB, LRegion, BBSelectRegIn,
2660 TII->convertNonUniformIfRegion(CurrentMerge, IfEnd);
2667 LRegion->removeFalseRegisterKills(
MRI);
2669 if (LRegion->getHasLoop()) {
2672 resolvePHIInfos(LRegion->getEntry());
2675 unsigned InReg = LRegion->getBBSelectRegIn();
2677 MRI->createVirtualRegister(
MRI->getRegClass(InReg));
2678 Register NewInReg =
MRI->createVirtualRegister(
MRI->getRegClass(InReg));
2679 TII->materializeImmediate(*(LRegion->getEntry()),
2680 LRegion->getEntry()->getFirstTerminator(),
DL,
2683 LRegion->replaceRegisterInsideRegion(InReg, InnerSelectReg,
false,
MRI);
2685 insertMergePHI(LRegion->getEntry(), LRegion->getExit(), NewSucc,
2686 InnerSelectReg, NewInReg,
2687 LRegion->getRegionMRT()->getInnerOutputRegister());
2689 TII->convertNonUniformLoopRegion(NewSucc, LastMerge);
2693 TII->insertReturn(*LastMerge);
2700 LLVM_DEBUG(
dbgs() <<
"===========If Region End===============\n");
2702 Region->setLinearizedRegion(LRegion);
2706bool AMDGPUMachineCFGStructurizer::structurizeRegion(RegionMRT *
Region) {
2707 if (
false && regionIsSimpleIf(
Region)) {
2708 transformSimpleIfRegion(
Region);
2714 structurizeComplexRegion(
Region);
2720bool AMDGPUMachineCFGStructurizer::structurizeRegions(RegionMRT *
Region,
2722 bool Changed =
false;
2724 auto Children =
Region->getChildren();
2725 for (
auto *CI : *Children) {
2726 if (CI->isRegion()) {
2727 Changed |= structurizeRegions(CI->getRegionMRT(),
false);
2732 Changed |= structurizeRegion(
Region);
2738void AMDGPUMachineCFGStructurizer::initFallthroughMap(
MachineFunction &MF) {
2740 for (
auto &
MBBI : MF) {
2742 if (
MBB !=
nullptr) {
2750void AMDGPUMachineCFGStructurizer::createLinearizedRegion(RegionMRT *
Region,
2751 unsigned SelectOut) {
2752 LinearizedRegion *LRegion =
new LinearizedRegion();
2754 LRegion->addLiveOut(SelectOut);
2758 LRegion->setRegionMRT(
Region);
2759 Region->setLinearizedRegion(LRegion);
2766AMDGPUMachineCFGStructurizer::initializeSelectRegisters(MRT *MRT,
unsigned SelectOut,
2769 if (MRT->isRegion()) {
2770 RegionMRT *
Region = MRT->getRegionMRT();
2771 Region->setBBSelectRegOut(SelectOut);
2775 createLinearizedRegion(
Region, SelectOut);
2777 for (
auto *CI : *
Region->getChildren())
2778 InnerSelectOut = initializeSelectRegisters(CI, InnerSelectOut,
MRI,
TII);
2779 MRT->setBBSelectRegIn(InnerSelectOut);
2780 return InnerSelectOut;
2782 MRT->setBBSelectRegOut(SelectOut);
2784 MRT->setBBSelectRegIn(NewSelectIn);
2789 for (
auto &
MBBI : MF) {
2791 if (Instr.isPHI()) {
2793 for (
int i = 0; i < numPreds; ++i) {
2794 assert(Instr.getOperand(i * 2 + 1).isReg() &&
2795 "PHI Operand not a register");
2802bool AMDGPUMachineCFGStructurizer::runOnMachineFunction(
MachineFunction &MF) {
2805 TRI =
ST.getRegisterInfo();
2807 initFallthroughMap(MF);
2813 Regions = &(getAnalysis<MachineRegionInfoPass>().getRegionInfo());
2816 RegionMRT *RTree = MRT::buildMRT(MF, Regions,
TII,
MRI);
2817 setRegionMRT(RTree);
2818 initializeSelectRegisters(RTree, 0,
MRI,
TII);
2820 bool result = structurizeRegions(RTree,
true);
2823 initFallthroughMap(MF);
2830 "AMDGPU Machine CFG Structurizer",
false,
false)
2836 return new AMDGPUMachineCFGStructurizer();
unsigned const MachineRegisterInfo * MRI
static bool containsNewBackedge(MRT *Tree, SmallPtrSet< MachineBasicBlock *, 8 > &MBBs)
static MachineBasicBlock * split(MachineBasicBlock::iterator I)
static unsigned getPHISourceReg(MachineInstr &PHI, unsigned Index)
bool regionIsSequence(RegionMRT *Region)
static unsigned getPHIDestReg(MachineInstr &PHI)
amdgpu machine cfg structurizer
static void collectPHIs(MachineBasicBlock *MBB, SmallVector< MachineInstr *, 2 > &PHIs)
static void setPhiPred(MachineInstr &PHI, unsigned Index, MachineBasicBlock *NewPred)
static bool isFunctionEntryBlock(MachineBasicBlock *MBB)
static void removeOldExitPreds(RegionMRT *Region)
static bool isPHIRegionIndex(SmallVector< unsigned, 2 > PHIRegionIndices, unsigned Index)
static void checkRegOnlyPHIInputs(MachineFunction &MF)
static void fixMBBTerminator(MachineBasicBlock *MBB)
static bool hasOneExitNode(MachineFunction &MF)
static void removeExternalCFGEdges(MachineBasicBlock *StartMBB, MachineBasicBlock *EndMBB)
static void removeExternalCFGSuccessors(MachineBasicBlock *MBB)
static MachineBasicBlock * getSingleExitNode(MachineFunction &MF)
static unsigned createBBSelectReg(const SIInstrInfo *TII, MachineRegisterInfo *MRI)
void fixupRegionExits(RegionMRT *Region)
static int structurize_once
static MachineBasicBlock * getPHIPred(MachineInstr &PHI, unsigned Index)
char AMDGPUMachineCFGStructurizerID
amdgpu machine cfg AMDGPU Machine CFG Structurizer
static unsigned getPHINumInputs(MachineInstr &PHI)
static void fixRegionTerminator(RegionMRT *Region)
static bool mbbHasBackEdge(MachineBasicBlock *MBB, SmallPtrSet< MachineBasicBlock *, 8 > &MBBs)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static const Function * getParent(const Value *V)
COFF::MachineTypes Machine
Analysis containing CSE Info
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static void clear(coro::Shape &Shape)
This file defines the DenseSet and SmallDenseSet classes.
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
static bool isReg(const MCInst &MI, unsigned OpNo)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isLiveOut(const MachineBasicBlock &MBB, unsigned Reg)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
unsigned pred_size() const
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator instr_begin()
MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
succ_iterator succ_begin()
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
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 '...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineBasicBlock & front() const
void splice(iterator InsertPt, iterator MBBI)
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
void setIsKill(bool Val=true)
void print(raw_ostream &os, const TargetRegisterInfo *TRI=nullptr, const TargetIntrinsicInfo *IntrinsicInfo=nullptr) const
Print the MachineOperand to os.
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)
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
BlockT * getExit() const
Get the exit BasicBlock of the Region.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
RegionT * getParent() const
Get the parent of the Region.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
RegionT * getTopLevelRegion() const
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A vector that has set insertion semantics.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ Undef
Value of the register doesn't matter.
Reg
All possible values of the reg field in the ModR/M byte.
NodeAddr< InstrNode * > Instr
NodeAddr< DefNode * > Def
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.
APInt operator*(APInt a, uint64_t RHS)
bool operator!=(uint64_t V1, const APInt &V2)
iterator_range< po_iterator< T > > post_order(const T &G)
void initializeAMDGPUMachineCFGStructurizerPass(PassRegistry &)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createAMDGPUMachineCFGStructurizerPass()
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
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.