34 #include "llvm/Config/llvm-config.h" 47 #define DEBUG_TYPE "amdgpucfgstructurizer" 51 class PHILinearizeDestIterator;
54 friend class PHILinearizeDestIterator;
57 using PHISourceT = std::pair<unsigned, MachineBasicBlock *>;
61 using PHIInfoElementT =
struct {
69 static unsigned phiInfoElementGetDest(PHIInfoElementT *
Info);
70 static void phiInfoElementSetDef(PHIInfoElementT *Info,
unsigned NewDef);
71 static PHISourcesT &phiInfoElementGetSources(PHIInfoElementT *Info);
72 static void phiInfoElementAddSource(PHIInfoElementT *Info,
unsigned SourceReg,
74 static void phiInfoElementRemoveSource(PHIInfoElementT *Info,
77 PHIInfoElementT *findPHIInfoElement(
unsigned DestReg);
78 PHIInfoElementT *findPHIInfoElementFromSource(
unsigned SourceReg,
84 void addDest(
unsigned DestReg,
const DebugLoc &DL);
85 void replaceDef(
unsigned OldDestReg,
unsigned NewDestReg);
86 void deleteDef(
unsigned DestReg);
87 void addSource(
unsigned DestReg,
unsigned SourceReg,
89 void removeSource(
unsigned DestReg,
unsigned SourceReg,
94 unsigned getNumSources(
unsigned DestReg);
98 using source_iterator = PHISourcesT::iterator;
99 using dest_iterator = PHILinearizeDestIterator;
101 dest_iterator dests_begin();
102 dest_iterator dests_end();
104 source_iterator sources_begin(
unsigned Reg);
105 source_iterator sources_end(
unsigned Reg);
108 class PHILinearizeDestIterator {
115 unsigned operator*() {
return PHILinearize::phiInfoElementGetDest(*Iter); }
116 PHILinearizeDestIterator &operator++() {
120 bool operator==(
const PHILinearizeDestIterator &I)
const {
121 return I.Iter == Iter;
123 bool operator!=(
const PHILinearizeDestIterator &I)
const {
124 return I.Iter != Iter;
130 unsigned PHILinearize::phiInfoElementGetDest(PHIInfoElementT *
Info) {
131 return Info->DestReg;
134 void PHILinearize::phiInfoElementSetDef(PHIInfoElementT *
Info,
136 Info->DestReg = NewDef;
140 PHILinearize::phiInfoElementGetSources(PHIInfoElementT *
Info) {
141 return Info->Sources;
144 void PHILinearize::phiInfoElementAddSource(PHIInfoElementT *
Info,
152 for (
auto SI : phiInfoElementGetSources(
Info)) {
153 assert((
SI.second != SourceMBB || SourceReg ==
SI.first));
157 phiInfoElementGetSources(
Info).insert(PHISourceT(SourceReg, SourceMBB));
160 void PHILinearize::phiInfoElementRemoveSource(PHIInfoElementT *
Info,
163 auto &Sources = phiInfoElementGetSources(
Info);
165 for (
auto SI : Sources) {
166 if (
SI.first == SourceReg &&
167 (
SI.second ==
nullptr ||
SI.second == SourceMBB)) {
172 for (
auto &
Source : ElimiatedSources) {
177 PHILinearize::PHIInfoElementT *
178 PHILinearize::findPHIInfoElement(
unsigned DestReg) {
179 for (
auto I : PHIInfo) {
180 if (phiInfoElementGetDest(
I) == DestReg) {
187 PHILinearize::PHIInfoElementT *
188 PHILinearize::findPHIInfoElementFromSource(
unsigned SourceReg,
190 for (
auto I : PHIInfo) {
191 for (
auto SI : phiInfoElementGetSources(
I)) {
192 if (
SI.first == SourceReg &&
193 (
SI.second ==
nullptr ||
SI.second == SourceMBB)) {
203 bool FoundSource =
false;
204 for (
auto I : PHIInfo) {
205 for (
auto SI : phiInfoElementGetSources(
I)) {
206 if (
SI.second == SourceMBB) {
215 void PHILinearize::addDest(
unsigned DestReg,
const DebugLoc &DL) {
216 assert(findPHIInfoElement(DestReg) ==
nullptr &&
"Dest already exsists");
217 PHISourcesT EmptySet;
218 PHIInfoElementT *NewElement =
new PHIInfoElementT();
219 NewElement->DestReg = DestReg;
221 NewElement->Sources = EmptySet;
222 PHIInfo.insert(NewElement);
225 void PHILinearize::replaceDef(
unsigned OldDestReg,
unsigned NewDestReg) {
226 phiInfoElementSetDef(findPHIInfoElement(OldDestReg), NewDestReg);
229 void PHILinearize::deleteDef(
unsigned DestReg) {
230 PHIInfoElementT *InfoElement = findPHIInfoElement(DestReg);
231 PHIInfo.erase(InfoElement);
235 void PHILinearize::addSource(
unsigned DestReg,
unsigned SourceReg,
237 phiInfoElementAddSource(findPHIInfoElement(DestReg), SourceReg, SourceMBB);
240 void PHILinearize::removeSource(
unsigned DestReg,
unsigned SourceReg,
242 phiInfoElementRemoveSource(findPHIInfoElement(DestReg), SourceReg, SourceMBB);
247 PHIInfoElementT *InfoElement =
248 findPHIInfoElementFromSource(SourceReg, SourceMBB);
249 if (InfoElement !=
nullptr) {
250 DestReg = phiInfoElementGetDest(InfoElement);
258 return findDest(Reg, SourceMBB, DestReg);
261 unsigned PHILinearize::getNumSources(
unsigned DestReg) {
262 return phiInfoElementGetSources(findPHIInfoElement(DestReg)).size();
265 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 268 dbgs() <<
"=PHIInfo Start=\n";
269 for (
auto PII : this->PHIInfo) {
270 PHIInfoElementT &Element = *PII;
273 for (
auto &
SI : Element.Sources) {
279 dbgs() <<
"=PHIInfo End=\n";
285 PHILinearize::dest_iterator PHILinearize::dests_begin() {
286 return PHILinearizeDestIterator(PHIInfo.begin());
289 PHILinearize::dest_iterator PHILinearize::dests_end() {
290 return PHILinearizeDestIterator(PHIInfo.end());
293 PHILinearize::source_iterator PHILinearize::sources_begin(
unsigned Reg) {
294 auto InfoElement = findPHIInfoElement(Reg);
295 return phiInfoElementGetSources(InfoElement).begin();
298 PHILinearize::source_iterator PHILinearize::sources_end(
unsigned Reg) {
299 auto InfoElement = findPHIInfoElement(Reg);
300 return phiInfoElementGetSources(InfoElement).end();
333 class LinearizedRegion {
342 LinearizedRegion *Parent;
349 void storeLiveOutRegRegion(RegionMRT *
Region,
unsigned Reg,
353 PHILinearize &PHIInfo);
357 RegionMRT *TopRegion);
364 RegionMRT *TopRegion =
nullptr);
370 ~LinearizedRegion() =
default;
372 void setRegionMRT(RegionMRT *Region) { RMRT = Region; }
374 RegionMRT *getRegionMRT() {
return RMRT; }
376 void setParent(LinearizedRegion *
P) { Parent =
P; }
378 LinearizedRegion *
getParent() {
return Parent; }
382 void setBBSelectRegIn(
unsigned Reg);
384 unsigned getBBSelectRegIn();
386 void setBBSelectRegOut(
unsigned Reg,
bool IsLiveOut);
388 unsigned getBBSelectRegOut();
390 void setHasLoop(
bool Value);
394 void addLiveOut(
unsigned VReg);
396 void removeLiveOut(
unsigned Reg);
398 void replaceLiveOut(
unsigned OldReg,
unsigned NewReg);
400 void replaceRegister(
unsigned Register,
unsigned NewRegister,
402 bool ReplaceOutside,
bool IncludeLoopPHIs);
404 void replaceRegisterInsideRegion(
unsigned Register,
unsigned NewRegister,
405 bool IncludeLoopPHIs,
408 void replaceRegisterOutsideRegion(
unsigned Register,
unsigned NewRegister,
409 bool IncludeLoopPHIs,
424 void addMBBs(LinearizedRegion *InnerRegion);
441 unsigned BBSelectRegIn;
442 unsigned BBSelectRegOut;
445 virtual ~MRT() =
default;
447 unsigned getBBSelectRegIn() {
return BBSelectRegIn; }
449 unsigned getBBSelectRegOut() {
return BBSelectRegOut; }
451 void setBBSelectRegIn(
unsigned Reg) { BBSelectRegIn =
Reg; }
453 void setBBSelectRegOut(
unsigned Reg) { BBSelectRegOut =
Reg; }
455 virtual RegionMRT *getRegionMRT() {
return nullptr; }
457 virtual MBBMRT *getMBBMRT() {
return nullptr; }
459 bool isRegion() {
return getRegionMRT() !=
nullptr; }
461 bool isMBB() {
return getMBBMRT() !=
nullptr; }
463 bool isRoot() {
return Parent ==
nullptr; }
465 void setParent(RegionMRT *
Region) { Parent = Region; }
467 RegionMRT *
getParent() {
return Parent; }
480 void dumpDepth(
int depth) {
481 for (
int i = depth; i > 0; --i) {
487 class MBBMRT :
public MRT {
493 setBBSelectRegOut(0);
497 MBBMRT *getMBBMRT()
override {
return this; }
503 dbgs() <<
"MBB: " << getMBB()->getNumber();
505 dbgs() <<
", Out: " <<
printReg(getBBSelectRegOut(), TRI) <<
"\n";
509 class RegionMRT :
public MRT {
512 LinearizedRegion *LRegion =
nullptr;
519 setBBSelectRegOut(0);
523 ~RegionMRT()
override {
528 for (
auto CI : Children) {
533 RegionMRT *getRegionMRT()
override {
return this; }
535 void setLinearizedRegion(LinearizedRegion *LinearizeRegion) {
536 LRegion = LinearizeRegion;
539 LinearizedRegion *getLinearizedRegion() {
return LRegion; }
541 MachineRegion *getMachineRegion() {
return Region; }
543 unsigned getInnerOutputRegister() {
544 return (*(Children.
begin()))->getBBSelectRegOut();
547 void addChild(MRT *Tree) { Children.
insert(Tree); }
553 dbgs() <<
"Region: " << (
void *)Region;
555 dbgs() <<
", Out: " <<
printReg(getBBSelectRegOut(), TRI) <<
"\n";
559 dbgs() <<
"Succ: " << getSucc()->getNumber() <<
"\n";
561 dbgs() <<
"Succ: none \n";
562 for (
auto MRTI : Children) {
563 MRTI->dump(TRI, depth + 1);
567 MRT *getEntryTree() {
return Children.
back(); }
569 MRT *getExitTree() {
return Children.
front(); }
572 MRT *Tree = Children.
back();
573 return (Tree->isRegion()) ? Tree->getRegionMRT()->getEntry()
574 : Tree->getMBBMRT()->getMBB();
578 MRT *Tree = Children.
front();
579 return (Tree->isRegion()) ? Tree->getRegionMRT()->getExit()
580 : Tree->getMBBMRT()->getMBB();
588 for (
auto CI : Children) {
590 if (MBB == CI->getMBBMRT()->getMBB()) {
594 if (CI->getRegionMRT()->contains(MBB)) {
596 }
else if (CI->getRegionMRT()->getLinearizedRegion() !=
nullptr &&
597 CI->getRegionMRT()->getLinearizedRegion()->contains(MBB)) {
605 void replaceLiveOutReg(
unsigned Register,
unsigned NewRegister) {
606 LinearizedRegion *LRegion = getLinearizedRegion();
607 LRegion->replaceLiveOut(Register, NewRegister);
608 for (
auto &CI : Children) {
609 if (CI->isRegion()) {
610 CI->getRegionMRT()->replaceLiveOutReg(Register, NewRegister);
626 for (
auto &MFI : MF) {
642 RegionMRT *Result =
new RegionMRT(TopLevelRegion);
643 RegionMap[TopLevelRegion] = Result;
650 MBBMRT *ExitMRT =
new MBBMRT(Exit);
651 RegionMap[RegionInfo->
getRegionFor(Exit)]->addChild(ExitMRT);
652 ExitMRT->setBBSelectRegIn(BBSelectRegIn);
663 MBBMRT *NewMBB =
new MBBMRT(MBB);
667 if (RegionMap.
count(Region) == 0) {
668 RegionMRT *NewMRTRegion =
new RegionMRT(Region);
669 RegionMap[Region] = NewMRTRegion;
673 while (RegionMap.
count(Parent) == 0) {
674 RegionMRT *NewMRTParent =
new RegionMRT(Parent);
675 NewMRTParent->addChild(NewMRTRegion);
676 NewMRTRegion->setParent(NewMRTParent);
677 RegionMap[Parent] = NewMRTParent;
678 NewMRTRegion = NewMRTParent;
681 RegionMap[Parent]->addChild(NewMRTRegion);
682 NewMRTRegion->setParent(RegionMap[Parent]);
686 RegionMap[Region]->addChild(NewMBB);
687 NewMBB->setParent(RegionMap[Region]);
688 RegionMap[Region]->setSucc(Region->getExit());
697 PHILinearize &PHIInfo) {
703 if (PHIInfo.isSource(Reg)) {
709 if (UI.getParent()->getParent() != MBB) {
711 <<
"): " <<
printReg(Reg, TRI) <<
"\n");
721 if ((&(*MII)) == DefInstr) {
733 void LinearizedRegion::storeLiveOutRegRegion(RegionMRT *
Region,
unsigned Reg,
737 PHILinearize &PHIInfo) {
742 if (!Region->contains(UI.getParent()->getParent())) {
744 <<
"): " <<
printReg(Reg, TRI) <<
"\n");
754 PHILinearize &PHIInfo) {
757 for (
auto &II : *MBB) {
758 for (
auto &RI : II.defs()) {
759 storeLiveOutReg(MBB, RI.getReg(), RI.getParent(),
MRI,
TRI, PHIInfo);
761 for (
auto &IRI : II.implicit_operands()) {
763 storeLiveOutReg(MBB, IRI.getReg(), IRI.getParent(),
MRI,
TRI, PHIInfo);
773 for (
auto &II : *(*
SI)) {
777 for (
int i = 0; i < numPreds; ++i) {
783 <<
"): " <<
printReg(PHIReg, TRI) <<
"\n");
797 PHILinearize &PHIInfo,
798 RegionMRT *TopRegion) {
799 for (
auto &II : *MBB) {
800 for (
auto &RI : II.defs()) {
801 storeLiveOutRegRegion(TopRegion, RI.getReg(), RI.getParent(),
MRI,
TRI,
804 for (
auto &IRI : II.implicit_operands()) {
806 storeLiveOutRegRegion(TopRegion, IRI.getReg(), IRI.getParent(),
MRI,
813 void LinearizedRegion::storeLiveOuts(RegionMRT *Region,
816 PHILinearize &PHIInfo,
817 RegionMRT *CurrentTopRegion) {
820 RegionMRT *TopRegion =
821 CurrentTopRegion ==
nullptr ? Region : CurrentTopRegion;
827 auto Children = Region->getChildren();
828 for (
auto CI : *Children) {
830 auto MBB = CI->getMBBMRT()->getMBB();
831 storeMBBLiveOuts(MBB, MRI, TRI, PHIInfo, TopRegion);
833 LinearizedRegion *SubRegion = CI->getRegionMRT()->getLinearizedRegion();
836 for (
auto MBBI : SubRegion->MBBs) {
837 storeMBBLiveOuts(MBBI, MRI, TRI, PHIInfo, TopRegion);
842 if (CurrentTopRegion ==
nullptr) {
843 auto Succ = Region->getSucc();
844 for (
auto &II : *Succ) {
848 for (
int i = 0; i < numPreds; ++i) {
852 <<
"): " <<
printReg(PHIReg, TRI) <<
"\n");
863 OS <<
"Linearized Region {";
865 for (
const auto &MBB : MBBs) {
873 OS <<
"} (" << Entry->getNumber() <<
", " 874 << (Exit ==
nullptr ? -1 : Exit->getNumber())
876 <<
" Out:" <<
printReg(getBBSelectRegOut(),
TRI) <<
" {";
877 for (
auto &LI : LiveOuts) {
884 unsigned LinearizedRegion::getBBSelectRegIn() {
885 return getRegionMRT()->getBBSelectRegIn();
888 unsigned LinearizedRegion::getBBSelectRegOut() {
889 return getRegionMRT()->getBBSelectRegOut();
892 void LinearizedRegion::setHasLoop(
bool Value) { HasLoop = Value; }
894 bool LinearizedRegion::getHasLoop() {
return HasLoop; }
896 void LinearizedRegion::addLiveOut(
unsigned VReg) { LiveOuts.insert(VReg); }
898 void LinearizedRegion::removeLiveOut(
unsigned Reg) {
903 void LinearizedRegion::replaceLiveOut(
unsigned OldReg,
unsigned NewReg) {
905 removeLiveOut(OldReg);
910 void LinearizedRegion::replaceRegister(
unsigned Register,
unsigned NewRegister,
912 bool ReplaceInside,
bool ReplaceOutside,
913 bool IncludeLoopPHI) {
914 assert(Register != NewRegister &&
"Cannot replace a reg with itself");
917 dbgs() <<
"Pepareing to replace register (region): " 922 if (ReplaceOutside &&
924 LinearizedRegion *Current =
this;
925 while (Current !=
nullptr && Current->getEntry() !=
nullptr) {
928 Current->replaceLiveOut(Register, NewRegister);
931 Current = Current->getParent();
948 bool ShouldReplace = (IsInside && ReplaceInside) ||
949 (!IsInside && ReplaceOutside) ||
950 (IncludeLoopPHI && IsLoopPHI);
970 void LinearizedRegion::replaceRegisterInsideRegion(
unsigned Register,
971 unsigned NewRegister,
972 bool IncludeLoopPHIs,
974 replaceRegister(Register, NewRegister, MRI,
true,
false, IncludeLoopPHIs);
977 void LinearizedRegion::replaceRegisterOutsideRegion(
unsigned Register,
978 unsigned NewRegister,
979 bool IncludeLoopPHIs,
981 replaceRegister(Register, NewRegister, MRI,
false,
true, IncludeLoopPHIs);
998 void LinearizedRegion::addMBBs(LinearizedRegion *InnerRegion) {
999 for (
const auto &MBB : InnerRegion->MBBs) {
1005 return MBBs.count(MBB) == 1;
1009 return LiveOuts.count(Reg) == 1;
1020 for (
auto MBBI : MBBs) {
1022 for (
auto &II : *MBB) {
1023 for (
auto &RI : II.uses()) {
1025 unsigned Reg = RI.getReg();
1027 if (hasNoDef(Reg, MRI))
1037 <<
" has NO defs\n");
1041 <<
" has multiple defs\n");
1048 if (UseIsOutsideDefMBB && UseOperand->
isKill()) {
1060 void LinearizedRegion::initLiveOut(RegionMRT *Region,
1063 PHILinearize &PHIInfo) {
1064 storeLiveOuts(Region, MRI, TRI, PHIInfo);
1070 PHILinearize &PHIInfo) {
1073 storeLiveOuts(MBB, MRI, TRI, PHIInfo);
1078 LinearizedRegion::LinearizedRegion() {
1092 unsigned BBSelectRegister;
1093 PHILinearize PHIInfo;
1097 void getPHIRegionIndices(RegionMRT *Region,
MachineInstr &PHI,
1099 void getPHIRegionIndices(LinearizedRegion *Region,
MachineInstr &PHI,
1101 void getPHINonRegionIndices(LinearizedRegion *Region,
MachineInstr &PHI,
1104 void storePHILinearizationInfoDest(
1114 unsigned *ReplaceReg);
1116 bool shrinkPHI(
MachineInstr &PHI,
unsigned CombinedSourceReg,
1120 void replacePHI(
MachineInstr &PHI,
unsigned CombinedSourceReg,
1123 void replaceEntryPHI(
MachineInstr &PHI,
unsigned CombinedSourceReg,
1128 unsigned CombinedSourceReg,
1129 LinearizedRegion *LRegion);
1134 LinearizedRegion *LRegion);
1137 void rewriteRegionEntryPHIs(LinearizedRegion *Region,
1140 bool regionIsSimpleIf(RegionMRT *Region);
1142 void transformSimpleIfRegion(RegionMRT *Region);
1154 unsigned IfSourceRegister,
unsigned CodeSourceRegister,
1155 bool IsUndefIfSource =
false);
1164 void createEntryPHI(LinearizedRegion *CurrentRegion,
unsigned DestReg);
1166 void createEntryPHIs(LinearizedRegion *CurrentRegion);
1169 void replaceRegisterWith(
unsigned Register,
unsigned NewRegister);
1173 LinearizedRegion *LRegion,
1174 unsigned BBSelectRegIn,
1175 unsigned BBSelectRegOut);
1180 unsigned BBSelectRegIn,
unsigned BBSelectRegOut);
1185 unsigned BBSelectReg);
1190 LinearizedRegion *InnerRegion,
unsigned DestReg,
1191 unsigned SourceReg);
1196 LinearizedRegion *InnerRegion,
1197 LinearizedRegion *LRegion);
1202 LinearizedRegion *LRegion);
1208 LinearizedRegion *initLinearizedRegion(RegionMRT *Region);
1210 bool structurizeComplexRegion(RegionMRT *Region);
1212 bool structurizeRegion(RegionMRT *Region);
1214 bool structurizeRegions(RegionMRT *Region,
bool isTopRegion);
1230 void createLinearizedRegion(RegionMRT *Region,
unsigned SelectOut);
1232 unsigned initializeSelectRegisters(MRT *MRT,
unsigned ExistingExitReg,
1236 void setRegionMRT(RegionMRT *RegionTree) { RMRT = RegionTree; }
1238 RegionMRT *getRegionMRT() {
return RMRT; }
1247 bool AMDGPUMachineCFGStructurizer::regionIsSimpleIf(RegionMRT *Region) {
1250 bool FoundBypass =
false;
1251 bool FoundIf =
false;
1262 if (Current == Succ) {
1264 }
else if ((Current->
succ_size() == 1) &&
1270 return FoundIf && FoundBypass;
1273 void AMDGPUMachineCFGStructurizer::transformSimpleIfRegion(RegionMRT *Region) {
1283 for (
auto &UI : TI.uses()) {
1284 if (UI.isMBB() && UI.getMBB() != Succ) {
1295 LinearizedRegion *LRegion = Region->getLinearizedRegion();
1296 auto Exit = LRegion->getExit();
1300 SE = Exit->succ_end();
1303 if (LRegion->contains(Succ)) {
1305 assert(InternalSucc ==
nullptr);
1306 InternalSucc = Succ;
1309 assert(ExternalSucc ==
nullptr);
1310 ExternalSucc = Succ;
1314 for (
auto &TI : Exit->terminators()) {
1315 for (
auto &UI : TI.uses()) {
1317 auto Target = UI.getMBB();
1318 if (
Target != InternalSucc &&
Target != ExternalSucc) {
1319 UI.setMBB(ExternalSucc);
1330 auto Children = Region->getChildren();
1331 for (
auto CI : *Children) {
1332 if (!CI->isRegion()) {
1333 if (CI->getMBBMRT()->getMBB()->succ_size() > 1) {
1342 auto Children = Region->getChildren();
1343 for (
auto CI : *Children) {
1344 if (!CI->isRegion()) {
1352 void AMDGPUMachineCFGStructurizer::getPHIRegionIndices(
1356 for (
unsigned i = 0; i < NumInputs; ++i) {
1358 if (Region->contains(Pred)) {
1364 void AMDGPUMachineCFGStructurizer::getPHIRegionIndices(
1368 for (
unsigned i = 0; i < NumInputs; ++i) {
1370 if (Region->contains(Pred)) {
1376 void AMDGPUMachineCFGStructurizer::getPHINonRegionIndices(
1380 for (
unsigned i = 0; i < NumInputs; ++i) {
1382 if (!Region->contains(Pred)) {
1388 void AMDGPUMachineCFGStructurizer::storePHILinearizationInfoDest(
1391 if (RegionIndices) {
1392 for (
auto i : *RegionIndices) {
1397 for (
unsigned i = 0; i < NumInputs; ++i) {
1403 unsigned AMDGPUMachineCFGStructurizer::storePHILinearizationInfo(
1406 unsigned LinearizeDestReg =
1408 PHIInfo.addDest(LinearizeDestReg, PHI.
getDebugLoc());
1409 storePHILinearizationInfoDest(LinearizeDestReg, PHI, RegionIndices);
1410 return LinearizeDestReg;
1421 if (Instr.
isPHI()) {
1427 storePHILinearizationInfoDest(PHIDestReg, Instr);
1431 for (
auto PI : PHIs) {
1432 PI->eraseFromParent();
1438 for (
auto i : PHIRegionIndices) {
1445 bool AMDGPUMachineCFGStructurizer::shrinkPHI(
MachineInstr &PHI,
1447 unsigned *ReplaceReg) {
1448 return shrinkPHI(PHI, 0,
nullptr, PHIIndices, ReplaceReg);
1451 bool AMDGPUMachineCFGStructurizer::shrinkPHI(
MachineInstr &PHI,
1452 unsigned CombinedSourceReg,
1455 unsigned *ReplaceReg) {
1461 bool Replaced =
false;
1463 int SingleExternalEntryIndex = -1;
1464 for (
unsigned i = 0; i < NumInputs; ++i) {
1466 if (SingleExternalEntryIndex == -1) {
1468 SingleExternalEntryIndex = i;
1471 SingleExternalEntryIndex = -2;
1476 if (SingleExternalEntryIndex > -1) {
1487 MIB.
addReg(CombinedSourceReg);
1493 for (
unsigned i = 0; i < NumInputs; ++i) {
1510 void AMDGPUMachineCFGStructurizer::replacePHI(
1518 bool HasExternalEdge =
false;
1520 for (
unsigned i = 0; i < NumInputs; ++i) {
1522 HasExternalEdge =
true;
1526 if (HasExternalEdge) {
1531 MIB.
addReg(CombinedSourceReg);
1535 for (
unsigned i = 0; i < NumInputs; ++i) {
1553 void AMDGPUMachineCFGStructurizer::replaceEntryPHI(
1561 unsigned NumNonRegionInputs = NumInputs;
1562 for (
unsigned i = 0; i < NumInputs; ++i) {
1564 NumNonRegionInputs--;
1568 if (NumNonRegionInputs == 0) {
1570 replaceRegisterWith(DestReg, CombinedSourceReg);
1580 MIB.
addReg(CombinedSourceReg);
1585 for (
unsigned i = 0; i < NumInputs; ++i) {
1601 void AMDGPUMachineCFGStructurizer::replaceLiveOutRegs(
1603 unsigned CombinedSourceReg, LinearizedRegion *LRegion) {
1604 bool WasLiveOut =
false;
1605 for (
auto PII : PHIRegionIndices) {
1607 if (LRegion->isLiveOut(Reg)) {
1613 if ((*UI).getParent()->getParent() != DefMBB) {
1619 << (IsDead ?
"dead" :
"alive")
1620 <<
" after PHI replace\n");
1622 LRegion->removeLiveOut(Reg);
1629 LRegion->addLiveOut(CombinedSourceReg);
1632 void AMDGPUMachineCFGStructurizer::rewriteRegionExitPHI(RegionMRT *Region,
1635 LinearizedRegion *LRegion) {
1637 getPHIRegionIndices(Region, PHI, PHIRegionIndices);
1638 unsigned LinearizedSourceReg =
1639 storePHILinearizationInfo(PHI, &PHIRegionIndices);
1641 replacePHI(PHI, LinearizedSourceReg, LastMerge, PHIRegionIndices);
1642 replaceLiveOutRegs(PHI, PHIRegionIndices, LinearizedSourceReg, LRegion);
1645 void AMDGPUMachineCFGStructurizer::rewriteRegionEntryPHI(LinearizedRegion *Region,
1649 getPHINonRegionIndices(Region, PHI, PHINonRegionIndices);
1650 unsigned LinearizedSourceReg =
1651 storePHILinearizationInfo(PHI, &PHINonRegionIndices);
1652 replaceEntryPHI(PHI, LinearizedSourceReg, IfMBB, PHINonRegionIndices);
1657 for (
auto &BBI : *MBB) {
1664 void AMDGPUMachineCFGStructurizer::rewriteRegionExitPHIs(RegionMRT *Region,
1666 LinearizedRegion *LRegion) {
1668 auto Exit = Region->getSucc();
1669 if (Exit ==
nullptr)
1674 for (
auto PHII : PHIs) {
1675 rewriteRegionExitPHI(Region, LastMerge, *PHII, LRegion);
1679 void AMDGPUMachineCFGStructurizer::rewriteRegionEntryPHIs(LinearizedRegion *Region,
1682 auto Entry = Region->getEntry();
1686 for (
auto PHII : PHIs) {
1687 rewriteRegionEntryPHI(Region, IfMBB, *PHII);
1691 void AMDGPUMachineCFGStructurizer::insertUnconditionalBranch(
MachineBasicBlock *MBB,
1695 <<
" -> " << Dest->
getNumber() <<
"\n");
1697 bool HasTerminator = Terminator != MBB->
instr_end();
1698 if (HasTerminator) {
1699 TII->ReplaceTailWithBranchTo(Terminator, Dest);
1702 TII->insertUnconditionalBranch(*MBB, Dest, DL);
1708 for (
auto &MFI : MF) {
1709 if (MFI.succ_size() == 0) {
1710 if (result ==
nullptr) {
1726 AMDGPUMachineCFGStructurizer::createLinearizedExitBlock(RegionMRT *Region) {
1727 auto Exit = Region->getSucc();
1732 return &(*(--(Region->getEntry()->getParent()->end())));
1736 if (Exit ==
nullptr) {
1738 MF->
insert(ExitIter, LastMerge);
1741 MF->
insert(ExitIter, LastMerge);
1743 insertUnconditionalBranch(LastMerge, Exit);
1753 unsigned DestRegister,
1754 unsigned IfSourceRegister,
1755 unsigned CodeSourceRegister,
1756 bool IsUndefIfSource) {
1762 <<
"): " <<
printReg(DestRegister, TRI) <<
" = PHI(" 1763 <<
printReg(IfSourceRegister, TRI) <<
", " 1765 <<
printReg(CodeSourceRegister, TRI) <<
", " 1769 TII->get(TargetOpcode::PHI), DestRegister);
1770 if (IsUndefIfSource &&
false) {
1773 MIB.
addReg(IfSourceRegister);
1776 MIB.
addReg(CodeSourceRegister);
1785 (MBB)->removeSuccessor(*PI);
1797 unsigned SuccSize = StartMBB->
succ_size();
1805 if ((*PI) != StartMBB &&
1806 !((*PI) == StartMBBSucc && StartMBB != EndMBB && SuccSize == 1)) {
1808 std::pair<MachineBasicBlock *, MachineBasicBlock *>(EndMBB, *PI));
1816 if ((*PI) != EndMBB) {
1818 std::pair<MachineBasicBlock *, MachineBasicBlock *>(*PI, StartMBB));
1822 for (
auto SI : Succs) {
1823 std::pair<MachineBasicBlock *, MachineBasicBlock *> Edge =
SI;
1826 Edge.first->removeSuccessor(Edge.second);
1833 bool InheritPreds) {
1841 if ((*PI) != CodeBBEnd) {
1853 MF->
insert(MergeIter, IfBB);
1854 MF->
splice(MergeIter, CodeBBStartI, ++CodeBBEndI);
1882 TII->
insertBranch(*IfBB, MergeBB, CodeBBStart, Cond, DL);
1887 void AMDGPUMachineCFGStructurizer::ensureCondIsNotKilled(
1889 if (Cond.
size() != 1)
1891 if (!Cond[0].
isReg())
1894 unsigned CondReg = Cond[0].getReg();
1896 (*UI).setIsKill(
false);
1900 void AMDGPUMachineCFGStructurizer::rewriteCodeBBTerminator(
MachineBasicBlock *CodeBB,
1902 unsigned BBSelectReg) {
1911 if (FalseBB ==
nullptr && TrueBB ==
nullptr && FallthroughBB ==
nullptr) {
1917 insertUnconditionalBranch(CodeBB, MergeBB, DL);
1921 if (FalseBB ==
nullptr && TrueBB ==
nullptr) {
1922 TrueBB = FallthroughBB;
1923 }
else if (TrueBB !=
nullptr) {
1925 (FallthroughBB && (FallthroughBB != TrueBB)) ? FallthroughBB : FalseBB;
1928 if ((TrueBB !=
nullptr && FalseBB ==
nullptr) || (TrueBB == FalseBB)) {
1939 ensureCondIsNotKilled(Cond);
1941 BBSelectReg, Cond, TrueBBReg, FalseBBReg);
1944 insertUnconditionalBranch(CodeBB, MergeBB, DL);
1947 MachineInstr *AMDGPUMachineCFGStructurizer::getDefInstr(
unsigned Reg) {
1951 <<
" has NO defs\n");
1955 <<
" has multiple defs\n");
1964 return (*(MRI->
def_begin(Reg))).getParent();
1970 LinearizedRegion *InnerRegion,
1972 unsigned SourceReg) {
1976 bool IsSingleBB = InnerRegion->getEntry() == InnerRegion->getExit();
1978 if (DefInstr->
isPHI() && DefInstr->
getParent() == CodeBB && IsSingleBB) {
1983 InnerRegion->replaceRegisterInsideRegion(SourceReg, DestReg,
true, MRI);
1987 storePHILinearizationInfoDest(DestReg, *DefInstr);
1990 PHIInfo.removeSource(DestReg, SourceReg, CodeBB);
1994 if (IsSingleBB && DefInstr->
getParent() == InnerRegion->getEntry()) {
1997 InnerRegion->replaceRegisterOutsideRegion(SourceReg, DestReg,
false, MRI);
2001 bool IsLastDef = PHIInfo.getNumSources(DestReg) == 1;
2003 insertMergePHI(IfBB, InnerRegion->getExit(), MergeBB, DestReg, NextDestReg,
2004 SourceReg, IsLastDef);
2006 PHIInfo.removeSource(DestReg, SourceReg, CodeBB);
2011 PHIInfo.deleteDef(DestReg);
2013 PHIInfo.replaceDef(DestReg, NextDestReg);
2019 LinearizedRegion *InnerRegion,
2020 unsigned Register) {
2021 return getDefInstr(Register)->getParent() == MBB ||
2022 InnerRegion->contains(getDefInstr(Register)->
getParent());
2028 LinearizedRegion *InnerRegion,
2029 LinearizedRegion *LRegion) {
2032 bool IsSingleBB = InnerRegion->getEntry() == InnerRegion->getExit();
2033 for (
auto OLI : *LiveOuts) {
2037 for (
auto LI : OldLiveOuts) {
2039 if (!containsDef(CodeBB, InnerRegion, LI) ||
2040 (!IsSingleBB && (getDefInstr(LI)->
getParent() == LRegion->getExit()))) {
2049 if ( Reg != InnerRegion->getBBSelectRegOut()) {
2068 InnerRegion->replaceRegisterOutsideRegion(Reg, PHIDestReg,
true, MRI);
2070 insertMergePHI(IfBB, InnerRegion->getExit(), MergeBB, PHIDestReg,
2071 IfSourceReg,
Reg,
true);
2078 if (PHIInfo.findSourcesFromMBB(CodeBB, Sources)) {
2081 for (
auto SI : Sources) {
2083 PHIInfo.findDest(
SI, CodeBB, DestReg);
2084 insertChainedPHI(IfBB, CodeBB, MergeBB, InnerRegion, DestReg,
SI);
2097 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2100 unsigned DestReg = *DRI;
2101 auto SE = PHIInfo.sources_end(DestReg);
2103 bool MBBContainsPHISource =
false;
2105 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2106 unsigned SourceReg = (*SRI).first;
2109 MBBContainsPHISource =
true;
2115 if (MBBContainsPHISource) {
2116 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2117 PHILinearize::PHISourceT
Source = *SRI;
2118 unsigned SourceReg = Source.first;
2122 ElimiatedSources.push_back(
2123 std::make_tuple(DestReg, SourceReg, SourceMBB));
2130 for (
auto &SourceInfo : ElimiatedSources) {
2131 PHIInfo.removeSource(std::get<0>(SourceInfo), std::get<1>(SourceInfo),
2132 std::get<2>(SourceInfo));
2138 void AMDGPUMachineCFGStructurizer::createEntryPHI(LinearizedRegion *CurrentRegion,
2144 << (*(Entry->
pred_begin()))->getNumber() <<
"\n");
2147 auto SE = PHIInfo.sources_end(DestReg);
2149 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2153 if (NumSources == 1) {
2154 auto SRI = PHIInfo.sources_begin(DestReg);
2155 unsigned SourceReg = (*SRI).first;
2156 replaceRegisterWith(DestReg, SourceReg);
2160 TII->get(TargetOpcode::PHI), DestReg);
2163 unsigned CurrentBackedgeReg = 0;
2165 for (
auto SRI = PHIInfo.sources_begin(DestReg); SRI != SE; ++SRI) {
2166 unsigned SourceReg = (*SRI).first;
2168 if (CurrentRegion->contains((*SRI).second)) {
2169 if (CurrentBackedgeReg == 0) {
2170 CurrentBackedgeReg = SourceReg;
2179 TII->get(TargetOpcode::PHI), NewBackedgeReg);
2180 BackedgePHI.
addReg(CurrentBackedgeReg);
2183 BackedgePHI.
addMBB((*SRI).second);
2184 CurrentBackedgeReg = NewBackedgeReg;
2186 <<
"Inserting backedge PHI: " 2187 <<
printReg(NewBackedgeReg, TRI) <<
" = PHI(" 2188 <<
printReg(CurrentBackedgeReg, TRI) <<
", " 2195 MIB.
addMBB((*SRI).second);
2202 if (CurrentBackedgeReg != 0) {
2203 MIB.
addReg(CurrentBackedgeReg);
2213 void AMDGPUMachineCFGStructurizer::createEntryPHIs(LinearizedRegion *CurrentRegion) {
2216 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2219 unsigned DestReg = *DRI;
2220 createEntryPHI(CurrentRegion, DestReg);
2225 void AMDGPUMachineCFGStructurizer::replaceRegisterWith(
unsigned Register,
2226 unsigned NewRegister) {
2227 assert(Register != NewRegister &&
"Cannot replace a reg with itself");
2251 PHIInfo.deleteDef(Register);
2253 getRegionMRT()->replaceLiveOutReg(Register, NewRegister);
2258 void AMDGPUMachineCFGStructurizer::resolvePHIInfos(
MachineBasicBlock *FunctionEntry) {
2261 for (
auto DRI = PHIInfo.dests_begin(), DE = PHIInfo.dests_end(); DRI != DE;
2263 unsigned DestReg = *DRI;
2265 auto SRI = PHIInfo.sources_begin(DestReg);
2266 unsigned SourceReg = (*SRI).first;
2268 <<
" SourceReg: " <<
printReg(SourceReg, TRI) <<
"\n");
2270 assert(PHIInfo.sources_end(DestReg) == ++SRI &&
2271 "More than one phi source in entry node");
2272 replaceRegisterWith(DestReg, SourceReg);
2282 LinearizedRegion *CurrentRegion,
unsigned BBSelectRegIn,
2283 unsigned BBSelectRegOut) {
2287 rewriteCodeBBTerminator(CodeBB, MergeBB, BBSelectRegOut);
2288 resolvePHIInfos(CodeBB);
2291 CurrentRegion->addMBB(CodeBB);
2294 if (CurrentRegion->getEntry() == CodeBB && !CurrentRegion->getHasLoop()) {
2300 if (CodeBBEndIter != MergeIter) {
2301 MF->
splice(MergeIter, CodeBBStartIter, CodeBBEndIter);
2303 rewriteCodeBBTerminator(CodeBB, MergeBB, BBSelectRegOut);
2304 prunePHIInfo(CodeBB);
2305 createEntryPHIs(CurrentRegion);
2308 CurrentRegion->addMBB(CodeBB);
2314 rewriteCodeBBTerminator(CodeBB, MergeBB, CodeBBSelectReg);
2315 bool IsRegionEntryBB = CurrentRegion->getEntry() == CodeBB;
2317 BBSelectRegIn, IsRegionEntryBB);
2318 CurrentRegion->addMBB(IfBB);
2321 if (IsRegionEntryBB) {
2322 CurrentRegion->setEntry(IfBB);
2324 if (CurrentRegion->getHasLoop()) {
2336 RegionExit, RegionExit->
instr_end(), DL,
2337 CurrentRegion->getRegionMRT()->getInnerOutputRegister(),
2338 CurrentRegion->getRegionMRT()->getEntry()->getNumber());
2345 TII->
insertBranch(*RegionExit, CurrentRegion->getEntry(), RegionExit,
2350 CurrentRegion->addMBB(CodeBB);
2351 LinearizedRegion InnerRegion(CodeBB, MRI, TRI, PHIInfo);
2353 InnerRegion.setParent(CurrentRegion);
2355 insertMergePHI(IfBB, CodeBB, MergeBB, BBSelectRegOut, BBSelectRegIn,
2357 InnerRegion.addMBB(MergeBB);
2360 rewriteLiveOutRegs(IfBB, CodeBB, MergeBB, &InnerRegion, CurrentRegion);
2361 extractKilledPHIs(CodeBB);
2362 if (IsRegionEntryBB) {
2363 createEntryPHIs(CurrentRegion);
2372 unsigned BBSelectRegIn,
unsigned BBSelectRegOut) {
2373 unsigned CodeBBSelectReg =
2374 InnerRegion->getRegionMRT()->getInnerOutputRegister();
2378 SelectBB, BBSelectRegIn,
true);
2379 CurrentRegion->addMBB(IfBB);
2380 bool isEntry = CurrentRegion->getEntry() == InnerRegion->getEntry();
2383 if (CurrentRegion->getHasLoop()) {
2396 CurrentRegion->getRegionMRT()->getInnerOutputRegister(),
2397 CurrentRegion->getRegionMRT()->getEntry()->getNumber());
2403 TII->
insertBranch(*RegionExit, CurrentRegion->getEntry(), RegionExit,
2408 CurrentRegion->addMBBs(InnerRegion);
2410 insertMergePHI(IfBB, CodeExitBB, MergeBB, BBSelectRegOut, BBSelectRegIn,
2413 rewriteLiveOutRegs(IfBB, CodeExitBB, MergeBB, InnerRegion,
2416 rewriteRegionEntryPHIs(InnerRegion, IfBB);
2419 CurrentRegion->setEntry(IfBB);
2423 createEntryPHIs(CurrentRegion);
2429 void AMDGPUMachineCFGStructurizer::splitLoopPHI(
MachineInstr &PHI,
2432 LinearizedRegion *LRegion) {
2434 getPHIRegionIndices(LRegion, PHI, PHIRegionIndices);
2438 unsigned RegionIndex = PHIRegionIndices[0];
2442 unsigned PHISource = PHIDest;
2443 unsigned ReplaceReg;
2445 if (shrinkPHI(PHI, PHIRegionIndices, &ReplaceReg)) {
2446 PHISource = ReplaceReg;
2451 LRegion->replaceRegisterInsideRegion(PHIDest, NewDestReg,
false, MRI);
2454 TII->get(TargetOpcode::PHI), NewDestReg);
2461 MIB.
addReg(RegionSourceReg);
2462 MIB.
addMBB(RegionSourceMBB);
2469 LinearizedRegion *LRegion) {
2473 for (
auto PHII : PHIs) {
2474 splitLoopPHI(*PHII, Entry, EntrySucc, LRegion);
2480 AMDGPUMachineCFGStructurizer::splitExit(LinearizedRegion *LRegion) {
2481 auto MRTRegion = LRegion->getRegionMRT();
2482 auto Exit = LRegion->getExit();
2483 auto MF = Exit->getParent();
2484 auto Succ = MRTRegion->getSucc();
2489 MF->
insert(AfterExitIter, NewExit);
2490 Exit->removeSuccessor(Succ);
2491 Exit->addSuccessor(NewExit);
2493 insertUnconditionalBranch(NewExit, Succ);
2494 LRegion->addMBB(NewExit);
2495 LRegion->setExit(NewExit);
2501 for (
auto &II : *Succ) {
2509 for (
int i = 0; i < numPreds; ++i) {
2526 MF->
insert(MBBIter, SuccMBB);
2541 AMDGPUMachineCFGStructurizer::splitEntry(LinearizedRegion *LRegion) {
2549 LRegion->addMBB(EntrySucc);
2552 if (Exit->isSuccessor(Entry)) {
2553 Exit->removeSuccessor(Entry);
2555 Exit->addSuccessor(EntrySucc);
2557 for (
auto &UI : Branch.
uses()) {
2558 if (UI.isMBB() && UI.getMBB() == Entry) {
2559 UI.setMBB(EntrySucc);
2563 splitLoopPHIs(Entry, EntrySucc, LRegion);
2569 AMDGPUMachineCFGStructurizer::initLinearizedRegion(RegionMRT *Region) {
2570 LinearizedRegion *LRegion = Region->getLinearizedRegion();
2571 LRegion->initLiveOut(Region, MRI, TRI, PHIInfo);
2572 LRegion->setEntry(Region->getEntry());
2578 if (Exit ==
nullptr) {
2584 if (Region->contains(*PI)) {
2585 (*PI)->removeSuccessor(Exit);
2603 if (Tree ==
nullptr)
2606 if (Tree->isMBB()) {
2613 RegionMRT *Region = Tree->getRegionMRT();
2615 for (
auto CI = Children->
rbegin(), CE = Children->
rend(); CI != CE; ++CI) {
2628 bool AMDGPUMachineCFGStructurizer::structurizeComplexRegion(RegionMRT *Region) {
2629 auto *LRegion = initLinearizedRegion(Region);
2633 LRegion->addMBB(LastMerge);
2634 LRegion->setExit(LastMerge);
2636 rewriteRegionExitPHIs(Region, LastMerge, LRegion);
2642 LLVM_DEBUG(
dbgs() <<
"===========If Region Start===============\n");
2643 if (LRegion->getHasLoop()) {
2649 unsigned BBSelectRegIn;
2650 unsigned BBSelectRegOut;
2651 for (
auto CI = Children->begin(), CE = Children->end(); CI != CE; ++CI) {
2660 if (Child->isRegion()) {
2662 LinearizedRegion *InnerLRegion =
2663 Child->getRegionMRT()->getLinearizedRegion();
2674 unsigned OuterSelect = InnerLRegion->getBBSelectRegOut();
2675 unsigned InnerSelectReg =
2676 InnerLRegion->getRegionMRT()->getInnerOutputRegister();
2677 replaceRegisterWith(InnerSelectReg, OuterSelect),
2678 resolvePHIInfos(InnerEntry);
2679 if (!InnerLRegion->getExit()->isSuccessor(CurrentMerge))
2680 InnerLRegion->getExit()->addSuccessor(CurrentMerge);
2684 BBSelectRegOut = Child->getBBSelectRegOut();
2685 BBSelectRegIn = Child->getBBSelectRegIn();
2693 CurrentMerge = createIfRegion(CurrentMerge, InnerLRegion, LRegion,
2694 Child->getRegionMRT()->getEntry(),
2695 BBSelectRegIn, BBSelectRegOut);
2708 BBSelectRegOut = Child->getBBSelectRegOut();
2709 BBSelectRegIn = Child->getBBSelectRegIn();
2719 CurrentMerge = createIfRegion(CurrentMerge, MBB, LRegion, BBSelectRegIn,
2729 LRegion->removeFalseRegisterKills(MRI);
2731 if (LRegion->getHasLoop()) {
2734 resolvePHIInfos(LRegion->getEntry());
2737 unsigned InReg = LRegion->getBBSelectRegIn();
2738 unsigned InnerSelectReg =
2742 LRegion->getEntry()->getFirstTerminator(), DL,
2743 NewInReg, Region->getEntry()->getNumber());
2745 LRegion->replaceRegisterInsideRegion(InReg, InnerSelectReg,
false, MRI);
2747 insertMergePHI(LRegion->getEntry(), LRegion->getExit(), NewSucc,
2748 InnerSelectReg, NewInReg,
2749 LRegion->getRegionMRT()->getInnerOutputRegister());
2754 if (Region->isRoot()) {
2758 LLVM_DEBUG(Region->getEntry()->getParent()->dump());
2762 LLVM_DEBUG(
dbgs() <<
"===========If Region End===============\n");
2764 Region->setLinearizedRegion(LRegion);
2768 bool AMDGPUMachineCFGStructurizer::structurizeRegion(RegionMRT *Region) {
2769 if (
false && regionIsSimpleIf(Region)) {
2770 transformSimpleIfRegion(Region);
2776 structurizeComplexRegion(Region);
2783 bool AMDGPUMachineCFGStructurizer::structurizeRegions(RegionMRT *Region,
2785 bool Changed =
false;
2787 auto Children = Region->getChildren();
2788 for (
auto CI : *Children) {
2789 if (CI->isRegion()) {
2790 Changed |= structurizeRegions(CI->getRegionMRT(),
false);
2795 Changed |= structurizeRegion(Region);
2801 void AMDGPUMachineCFGStructurizer::initFallthroughMap(
MachineFunction &MF) {
2803 for (
auto &MBBI : MF) {
2805 if (MBB !=
nullptr) {
2806 LLVM_DEBUG(
dbgs() <<
"Fallthrough: " << MBBI.getNumber() <<
" -> " 2809 FallthroughMap[&MBBI] = MBB;
2813 void AMDGPUMachineCFGStructurizer::createLinearizedRegion(RegionMRT *Region,
2814 unsigned SelectOut) {
2815 LinearizedRegion *LRegion =
new LinearizedRegion();
2817 LRegion->addLiveOut(SelectOut);
2821 LRegion->setRegionMRT(Region);
2822 Region->setLinearizedRegion(LRegion);
2823 LRegion->setParent(Region->getParent()
2824 ? Region->getParent()->getLinearizedRegion()
2829 AMDGPUMachineCFGStructurizer::initializeSelectRegisters(MRT *MRT,
unsigned SelectOut,
2832 if (MRT->isRegion()) {
2833 RegionMRT *Region = MRT->getRegionMRT();
2834 Region->setBBSelectRegOut(SelectOut);
2838 createLinearizedRegion(Region, SelectOut);
2840 for (
auto CI = Region->getChildren()->begin(),
2841 CE = Region->getChildren()->end();
2844 initializeSelectRegisters((*CI), InnerSelectOut, MRI, TII);
2846 MRT->setBBSelectRegIn(InnerSelectOut);
2847 return InnerSelectOut;
2849 MRT->setBBSelectRegOut(SelectOut);
2851 MRT->setBBSelectRegIn(NewSelectIn);
2857 for (
auto &MBBI : MF) {
2859 E = MBBI.instr_end();
2862 if (Instr.
isPHI()) {
2864 for (
int i = 0; i < numPreds; ++i) {
2866 "PHI Operand not a register");
2873 bool AMDGPUMachineCFGStructurizer::runOnMachineFunction(
MachineFunction &MF) {
2878 initFallthroughMap(MF);
2884 Regions = &(getAnalysis<MachineRegionInfoPass>().getRegionInfo());
2887 RegionMRT *RTree = MRT::buildMRT(MF, Regions, TII, MRI);
2888 setRegionMRT(RTree);
2889 initializeSelectRegisters(RTree, 0, MRI, TII);
2891 bool result = structurizeRegions(RTree,
true);
2894 initFallthroughMap(MF);
2901 "AMDGPU Machine CFG Structurizer",
false,
false)
2907 return new AMDGPUMachineCFGStructurizer();
static bool isReg(const MCInst &MI, unsigned OpNo)
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...
instr_iterator instr_begin()
AMDGPU specific subclass of TargetSubtarget.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
const T & front() const
Return the first element of the SetVector.
This class represents lattice values for constants.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
static void fixRegionTerminator(RegionMRT *Region)
Implements a dense probed hash-table based set.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
void push_back(const T &Elt)
static int structurize_once
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned getReg() const
getReg - Returns the register number.
unsigned insertNE(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned SrcReg, int Value) const
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
static bool mbbHasBackEdge(MachineBasicBlock *MBB, SmallPtrSet< MachineBasicBlock *, 8 > &MBBs)
const SIInstrInfo * getInstrInfo() const override
static void dump(StringRef Title, SpillInfo const &Spills)
unsigned const TargetRegisterInfo * TRI
bool hasOneDef(unsigned RegNo) const
Return true if there is exactly one operand defining the specified register.
static void checkRegOnlyPHIInputs(MachineFunction &MF)
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
const T & back() const
Return the last element of the SetVector.
amdgpu machine cfg structurizer
static void removeExternalCFGSuccessors(MachineBasicBlock *MBB)
FunctionPass * createAMDGPUMachineCFGStructurizerPass()
static MachineBasicBlock * getPHIPred(MachineInstr &PHI, unsigned Index)
return AArch64::GPR64RegClass contains(Reg)
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
bool regionIsSequence(RegionMRT *Region)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static use_iterator use_end()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
MachineBasicBlock * getFallThrough()
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
iterator_range< iterator > terminators()
def_iterator def_begin(unsigned RegNo) const
reverse_iterator rbegin()
Get an reverse_iterator to the end of the SetVector.
APInt operator*(APInt a, uint64_t RHS)
void fixupRegionExits(RegionMRT *Region)
RegionT * getTopLevelRegion() const
amdgpu machine cfg AMDGPU Machine CFG Structurizer
static bool isSource(Value *V)
Return true if the given value is a source in the use-def chain, producing a narrow 'TypeSize' value...
bool insert(const value_type &X)
Insert a new element into the SetVector.
static bool isPHIRegionIndex(SmallVector< unsigned, 2 > PHIRegionIndices, unsigned Index)
iterator begin()
Get an iterator to the beginning of the SetVector.
void convertNonUniformLoopRegion(MachineBasicBlock *LoopEntry, MachineBasicBlock *LoopEnd) const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static void removeOldExitPreds(RegionMRT *Region)
COFF::MachineTypes Machine
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Analysis containing CSE Info
static MachineBasicBlock * getSingleExitNode(MachineFunction &MF)
static bool hasOneExitNode(MachineFunction &MF)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetRegisterInfo * getTargetRegisterInfo() const
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
unsigned const MachineRegisterInfo * MRI
const TargetRegisterClass * getPreferredSelectRegClass(unsigned Size) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
std::pair< iterator, bool > insert(const ValueT &V)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void insertVectorSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DstReg, ArrayRef< MachineOperand > Cond, unsigned TrueReg, unsigned FalseReg) const
void setMBB(MachineBasicBlock *MBB)
static bool containsNewBackedge(MRT *Tree, SmallPtrSet< MachineBasicBlock *, 8 > &MBBs)
void insertReturn(MachineBasicBlock &MBB) const
Represent the analysis usage information of a pass.
static unsigned getPHISourceReg(MachineInstr &PHI, unsigned Index)
unsigned insertEQ(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned SrcReg, int Value) const
FunctionPass class - This class is used to implement most global optimizations.
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
iterator_range< po_iterator< T > > post_order(const T &G)
static unsigned createBBSelectReg(const SIInstrInfo *TII, MachineRegisterInfo *MRI)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
void materializeImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DestReg, int64_t Value) const
std::vector< MachineBasicBlock * >::iterator pred_iterator
succ_iterator succ_begin()
static void fixMBBTerminator(MachineBasicBlock *MBB)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
pred_iterator pred_begin()
static bool isFunctionEntryBlock(MachineBasicBlock *MBB)
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
static void removeExternalCFGEdges(MachineBasicBlock *StartMBB, MachineBasicBlock *EndMBB)
SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
Iterator for intrusive lists based on ilist_node.
void initializeAMDGPUMachineCFGStructurizerPass(PassRegistry &)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void splice(iterator InsertPt, iterator MBBI)
iterator_range< use_iterator > use_operands(unsigned Reg) const
MachineOperand class - Representation of each machine instruction operand.
static MachineBasicBlock * split(MachineBasicBlock::iterator I)
Promote Memory to Register
static unsigned getPHINumInputs(MachineInstr &PHI)
reg_iterator reg_begin(unsigned RegNo) const
unsigned pred_size() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target - Wrapper for Target specific information.
static void clear(coro::Shape &Shape)
static void collectPHIs(MachineBasicBlock *MBB, SmallVector< MachineInstr *, 2 > &PHIs)
unsigned succ_size() const
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static unsigned getPHIDestReg(MachineInstr &PHI)
bool operator!=(uint64_t V1, const APInt &V2)
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Interface definition for SIInstrInfo.
reverse_iterator rend()
Get a reverse_iterator to the beginning of the SetVector.
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 '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
use_iterator use_begin(unsigned RegNo) const
void setReg(unsigned Reg)
Change the register this operand corresponds to.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
char & AMDGPUMachineCFGStructurizerID
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
RegionT * getParent() const
Get the parent of the Region.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
static def_iterator def_end()
LLVM Value Representation.
static void setPhiPred(MachineInstr &PHI, unsigned Index, MachineBasicBlock *NewPred)
A vector that has set insertion semantics.
static const Function * getParent(const Value *V)
This class implements an extremely fast bulk output stream that can only output to a stream...
static bool isLiveOut(const MachineBasicBlock &MBB, unsigned Reg)
bool operator==(uint64_t V1, const APInt &V2)
INITIALIZE_PASS_BEGIN(AMDGPUMachineCFGStructurizer, "amdgpu-machine-cfg-structurizer", "AMDGPU Machine CFG Structurizer", false, false) INITIALIZE_PASS_END(AMDGPUMachineCFGStructurizer
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
static reg_iterator reg_end()
const MachineOperand & getOperand(unsigned i) const
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
void convertNonUniformIfRegion(MachineBasicBlock *IfEntry, MachineBasicBlock *IfEnd) const
std::vector< MachineBasicBlock * >::iterator succ_iterator
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
const SIRegisterInfo * getRegisterInfo() const override