49 #define DEBUG_TYPE "structcfg" 51 #define DEFAULT_VEC_SLOTS 8 61 STATISTIC(numSerialPatternMatch,
"CFGStructurizer number of serial pattern " 63 STATISTIC(numIfPatternMatch,
"CFGStructurizer number of if pattern " 65 STATISTIC(numClonedBlock,
"CFGStructurizer cloned blocks");
66 STATISTIC(numClonedInstr,
"CFGStructurizer cloned instructions");
82 #define SHOWNEWINSTR(i) LLVM_DEBUG(dbgs() << "New instr: " << *i << "\n"); 84 #define SHOWNEWBLK(b, msg) \ 85 LLVM_DEBUG(dbgs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 88 #define SHOWBLK_DETAIL(b, msg) \ 90 dbgs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 95 #define INVALIDSCCNUM -1 103 class BlockInformation {
105 bool IsRetired =
false;
108 BlockInformation() =
default;
120 using MBBInfoMap = std::map<MachineBasicBlock *, BlockInformation *>;
121 using LoopLandInfoMap = std::map<MachineLoop *, MachineBasicBlock *>;
125 SinglePath_InPath = 1,
126 SinglePath_NotInPath = 2
136 return "AMDGPU Control Flow Graph structurizer Pass";
156 TRI = &
TII->getRegisterInfo();
161 MLI = &getAnalysis<MachineLoopInfo>();
163 MDT = &getAnalysis<MachineDominatorTree>();
165 PDT = &getAnalysis<MachinePostDominatorTree>();
182 void printOrderedBlocks()
const {
185 iterBlkEnd = OrderedBlks.end(); iterBlk != iterBlkEnd; ++iterBlk, ++i) {
186 dbgs() <<
"BB" << (*iterBlk)->getNumber();
187 dbgs() <<
"(" <<
getSCCNum(*iterBlk) <<
"," << (*iterBlk)->size() <<
")";
188 if (i != 0 && i % 10 == 0) {
198 iterEnd = LoopInfo.
end(); iter != iterEnd; ++iter) {
199 (*iter)->print(
dbgs(), 0);
210 bool AllowSideEntry =
true)
const;
233 static int getBranchNzeroOpcode(
int OldOpcode);
234 static int getBranchZeroOpcode(
int OldOpcode);
235 static int getContinueNzeroOpcode(
int OldOpcode);
236 static int getContinueZeroOpcode(
int OldOpcode);
270 int loopendPatternMatch();
334 MBBInfoMap BlockInfoMap;
335 LoopLandInfoMap LLInfoMap;
336 std::map<MachineLoop *, bool> Visited;
346 MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB);
347 if (It == BlockInfoMap.end())
349 return (*It).second->SccNum;
354 LoopLandInfoMap::const_iterator It = LLInfoMap.find(LoopRep);
355 if (It == LLInfoMap.end())
369 MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB);
370 if (It == BlockInfoMap.end())
372 return (*It).second->IsRetired;
377 while (LoopRep && LoopRep->
getHeader() == MBB) {
381 if (!isRetiredBlock(LoopLand))
388 AMDGPUCFGStructurizer::PathToKind AMDGPUCFGStructurizer::singlePathTo(
390 bool AllowSideEntry)
const {
392 if (SrcMBB == DstMBB)
393 return SinglePath_InPath;
394 while (SrcMBB && SrcMBB->
succ_size() == 1) {
396 if (SrcMBB == DstMBB)
397 return SinglePath_InPath;
398 if (!AllowSideEntry && SrcMBB->
pred_size() > 1)
399 return Not_SinglePath;
402 return SinglePath_NotInPath;
403 return Not_SinglePath;
410 if (!isRetiredBlock(*It))
418 unsigned BlockSizeThreshold = 30;
419 unsigned CloneInstrThreshold = 100;
420 bool MultiplePreds = MBB && (MBB->
pred_size() > 1);
424 unsigned BlkSize = MBB->
size();
425 return ((BlkSize > BlockSizeThreshold) &&
426 (BlkSize * (MBB->
pred_size() - 1) > CloneInstrThreshold));
429 void AMDGPUCFGStructurizer::reversePredicateSetter(
435 if (I->getOpcode() == R600::PRED_X) {
436 switch (I->getOperand(2).getImm()) {
437 case R600::PRED_SETE_INT:
438 I->getOperand(2).setImm(R600::PRED_SETNE_INT);
440 case R600::PRED_SETNE_INT:
441 I->getOperand(2).setImm(R600::PRED_SETE_INT);
443 case R600::PRED_SETE:
444 I->getOperand(2).setImm(R600::PRED_SETNE);
446 case R600::PRED_SETNE:
447 I->getOperand(2).setImm(R600::PRED_SETE);
457 int NewOpcode,
const DebugLoc &DL) {
490 void AMDGPUCFGStructurizer::insertCondBranchBefore(
503 void AMDGPUCFGStructurizer::insertCondBranchBefore(
514 int AMDGPUCFGStructurizer::getBranchNzeroOpcode(
int OldOpcode) {
516 case R600::JUMP_COND:
517 case R600::JUMP:
return R600::IF_PREDICATE_SET;
518 case R600::BRANCH_COND_i32:
519 case R600::BRANCH_COND_f32:
return R600::IF_LOGICALNZ_f32;
525 int AMDGPUCFGStructurizer::getBranchZeroOpcode(
int OldOpcode) {
527 case R600::JUMP_COND:
528 case R600::JUMP:
return R600::IF_PREDICATE_SET;
529 case R600::BRANCH_COND_i32:
530 case R600::BRANCH_COND_f32:
return R600::IF_LOGICALZ_f32;
536 int AMDGPUCFGStructurizer::getContinueNzeroOpcode(
int OldOpcode) {
538 case R600::JUMP_COND:
539 case R600::JUMP:
return R600::CONTINUE_LOGICALNZ_i32;
545 int AMDGPUCFGStructurizer::getContinueZeroOpcode(
int OldOpcode) {
547 case R600::JUMP_COND:
548 case R600::JUMP:
return R600::CONTINUE_LOGICALZ_i32;
558 void AMDGPUCFGStructurizer::setTrueBranch(
MachineInstr *MI,
571 return (*It == TrueBranch) ? *Next : *It;
574 bool AMDGPUCFGStructurizer::isCondBranch(
MachineInstr *MI) {
576 case R600::JUMP_COND:
577 case R600::BRANCH_COND_i32:
578 case R600::BRANCH_COND_f32:
return true;
585 bool AMDGPUCFGStructurizer::isUncondBranch(
MachineInstr *MI) {
608 MachineInstr *AMDGPUCFGStructurizer::getNormalBlockBranchInstr(
612 if (MI && (isCondBranch(MI) || isUncondBranch(MI)))
617 MachineInstr *AMDGPUCFGStructurizer::getLoopendBlockBranchInstr(
624 if (isCondBranch(MI) || isUncondBranch(MI))
635 if (It != MBB->
rend()) {
650 <<
" is return block without RETURN instr\n";);
657 iterEnd = SrcMBB->
succ_end(); It != iterEnd; ++It)
670 void AMDGPUCFGStructurizer::replaceInstrUseOfBlockWith(
673 MachineInstr *BranchMI = getLoopendBlockBranchInstr(SrcMBB);
674 if (BranchMI && isCondBranch(BranchMI) &&
675 getTrueBranch(BranchMI) == OldMBB)
676 setTrueBranch(BranchMI, NewBlk);
682 &&
"found a jump table");
690 if (Pre->getOpcode() == R600::CONTINUE
691 && It->getOpcode() == R600::ENDLOOP)
698 for (
unsigned i = 0; i < ContInstr.
size(); ++i)
699 ContInstr[i]->eraseFromParent();
707 bool AMDGPUCFGStructurizer::prepare() {
708 bool Changed =
false;
714 orderBlocks(FuncRep);
720 E = MLI->end(); It !=
E; ++It) {
725 if (ExitingMBBs.
size() == 0) {
735 It = OrderedBlks.begin(),
E = OrderedBlks.end(); It !=
E; ++It) {
737 removeUnconditionalBranch(MBB);
738 removeRedundantConditionalBranch(MBB);
739 if (isReturnBlock(MBB)) {
745 if (RetBlks.
size() >= 2) {
746 addDummyExitBlock(RetBlks);
753 bool AMDGPUCFGStructurizer::run() {
759 ReverseVector(orderedBlks);
766 bool MakeProgress =
false;
767 int NumRemainedBlk = countActiveBlock(OrderedBlks.begin(),
773 <<
", numRemaintedBlk = " << NumRemainedBlk <<
"\n";);
794 SccNumBlk = NumRemainedBlk;
799 if (!isRetiredBlock(MBB))
804 bool ContNextScc =
true;
809 int sccRemainedNumBlk = countActiveBlock(SccBeginIter, It);
810 if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= SccNumBlk) {
812 <<
", sccNumIter = " << SccNumIter;
813 dbgs() <<
"doesn't make any progress\n";);
815 }
else if (sccRemainedNumBlk != 1 && sccRemainedNumBlk < SccNumBlk) {
816 SccNumBlk = sccRemainedNumBlk;
820 <<
"sccNumIter = " << SccNumIter <<
'\n';);
831 SccBeginMBB =
nullptr;
840 int NewnumRemainedBlk
841 = countActiveBlock(OrderedBlks.begin(), OrderedBlks.end());
843 if (NewnumRemainedBlk == 1 || NewnumRemainedBlk < NumRemainedBlk) {
845 NumRemainedBlk = NewnumRemainedBlk;
847 MakeProgress =
false;
851 }
while (!Finish && MakeProgress);
857 for (MBBInfoMap::iterator It = BlockInfoMap.begin(),
E = BlockInfoMap.end();
859 if ((*It).second && (*It).second->IsRetired) {
860 assert(((*It).first)->getNumber() != -1);
861 LLVM_DEBUG(
dbgs() <<
"Erase BB" << ((*It).first)->getNumber() <<
"\n";);
862 (*It).first->eraseFromParent();
866 BlockInfoMap.clear();
882 const std::vector<MachineBasicBlock *> &SccNext = *It;
883 for (std::vector<MachineBasicBlock *>::const_iterator
884 blockIter = SccNext.begin(), blockEnd = SccNext.end();
885 blockIter != blockEnd; ++blockIter) {
888 recordSccnum(MBB, SccNum);
893 for (
auto *MBB :
nodes(MF)) {
896 dbgs() <<
"unreachable block BB" << MBB->
getNumber() <<
"\n";
906 while ((CurMatch = patternMatchGroup(MBB)) > 0)
907 NumMatch += CurMatch;
910 <<
", numMatch = " << NumMatch <<
"\n";);
917 NumMatch += loopendPatternMatch();
918 NumMatch += serialPatternMatch(MBB);
919 NumMatch += ifPatternMatch(MBB);
928 if (childBlk->
pred_size() != 1 || isActiveLoophead(childBlk))
931 mergeSerialBlock(MBB, childBlk);
932 ++numSerialPatternMatch;
940 if (hasBackEdge(MBB))
942 MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB);
946 assert(isCondBranch(BranchMI));
950 NumMatch += serialPatternMatch(TrueMBB);
951 NumMatch += ifPatternMatch(TrueMBB);
953 NumMatch += serialPatternMatch(FalseMBB);
954 NumMatch += ifPatternMatch(FalseMBB);
973 reversePredicateSetter(MBB->
end(), *MBB);
977 && isSameloopDetachedContbreak(TrueMBB, FalseMBB)) {
980 && isSameloopDetachedContbreak(FalseMBB, TrueMBB)) {
983 return NumMatch + handleJumpintoIf(MBB, TrueMBB, FalseMBB);
991 || (FalseMBB && FalseMBB->
pred_size() > 1))) {
992 Cloned += improveSimpleJumpintoIf(MBB, TrueMBB, FalseMBB, &LandBlk);
995 if (TrueMBB && TrueMBB->
pred_size() > 1) {
996 TrueMBB = cloneBlockForPredecessor(TrueMBB, MBB);
1000 if (FalseMBB && FalseMBB->
pred_size() > 1) {
1001 FalseMBB = cloneBlockForPredecessor(FalseMBB, MBB);
1005 mergeIfthenelseBlock(BranchMI, MBB, TrueMBB, FalseMBB, LandBlk);
1007 ++numIfPatternMatch;
1009 numClonedBlock += Cloned;
1011 return 1 + Cloned + NumMatch;
1014 int AMDGPUCFGStructurizer::loopendPatternMatch() {
1015 std::deque<MachineLoop *> NestedLoops;
1016 for (
auto &It: *MLI)
1018 NestedLoops.push_front(ML);
1020 if (NestedLoops.empty())
1028 if (ExaminedLoop->getNumBlocks() == 0 || Visited[ExaminedLoop])
1031 int NumBreak = mergeLoop(ExaminedLoop);
1039 int AMDGPUCFGStructurizer::mergeLoop(
MachineLoop *LoopRep) {
1043 assert(!ExitingMBBs.
empty() &&
"Infinite Loop not supported");
1045 <<
" exiting blocks\n";);
1050 for (
unsigned i = 0, e = ExitBlks.size(); i < e; ++i)
1051 ExitBlkSet.
insert(ExitBlks[i]);
1054 assert(ExitBlk &&
"Loop has several exit block");
1056 for (
auto *LB : inverse_children<MachineBasicBlock*>(LoopHeader))
1060 for (
unsigned i = 0, e = ExitingMBBs.
size(); i < e; ++i)
1061 mergeLoopbreakBlock(ExitingMBBs[i], ExitBlk);
1062 for (
unsigned i = 0, e = LatchBlks.
size(); i < e; ++i)
1063 settleLoopcontBlock(LatchBlks[i], LoopHeader);
1067 Match += serialPatternMatch(LoopHeader);
1068 Match += ifPatternMatch(LoopHeader);
1069 }
while (Match > 0);
1070 mergeLooplandBlock(LoopHeader, ExitBlk);
1073 MLI->changeLoopFor(LoopHeader, ParentLoop);
1075 MLI->removeBlock(LoopHeader);
1076 Visited[LoopRep] =
true;
1080 bool AMDGPUCFGStructurizer::isSameloopDetachedContbreak(
1084 if (LoopRep&& LoopRep == MLI->getLoopFor(Src2MBB)) {
1099 int Num = handleJumpintoIfImp(HeadMBB, TrueMBB, FalseMBB);
1101 LLVM_DEBUG(
dbgs() <<
"handleJumpintoIf swap trueBlk and FalseBlk" 1103 Num = handleJumpintoIfImp(HeadMBB, FalseMBB, TrueMBB);
1118 <<
", numSucc=" << TrueMBB->
succ_size() <<
" false = BB" 1124 if (singlePathTo(FalseMBB, DownBlk) == SinglePath_InPath) {
1127 Num += cloneOnSideEntryTo(HeadMBB, TrueMBB, DownBlk);
1128 Num += cloneOnSideEntryTo(HeadMBB, FalseMBB, DownBlk);
1130 numClonedBlock += Num;
1131 Num += serialPatternMatch(*HeadMBB->
succ_begin());
1132 Num += serialPatternMatch(*std::next(HeadMBB->
succ_begin()));
1133 Num += ifPatternMatch(HeadMBB);
1139 DownBlk = (DownBlk->succ_size() == 1) ? (*DownBlk->succ_begin()) :
nullptr;
1146 void AMDGPUCFGStructurizer::showImproveSimpleJumpintoIf(
1150 <<
" size = " << HeadMBB->
size();
1158 dbgs() <<
", true = BB" << TrueMBB->
getNumber() <<
" size = " 1159 << TrueMBB->
size() <<
" numPred = " << TrueMBB->
pred_size();
1167 dbgs() <<
", false = BB" << FalseMBB->
getNumber() <<
" size = " 1168 << FalseMBB->
size() <<
" numPred = " << FalseMBB->
pred_size();
1176 dbgs() <<
", land = BB" << LandMBB->
getNumber() <<
" size = " 1177 << LandMBB->
size() <<
" numPred = " << LandMBB->
pred_size();
1192 bool MigrateTrue =
false;
1193 bool MigrateFalse =
false;
1198 && (!FalseMBB || FalseMBB->
succ_size() <= 1));
1200 if (TrueMBB == FalseMBB)
1203 MigrateTrue = needMigrateBlock(TrueMBB);
1204 MigrateFalse = needMigrateBlock(FalseMBB);
1206 if (!MigrateTrue && !MigrateFalse)
1212 if (!MigrateTrue && TrueMBB && TrueMBB->
pred_size() > 1)
1214 if (!MigrateFalse && FalseMBB && FalseMBB->
pred_size() > 1)
1215 MigrateFalse =
true;
1218 dbgs() <<
"before improveSimpleJumpintoIf: ";
1219 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););
1233 if (!MigrateTrue || !MigrateFalse) {
1304 bool LandBlkHasOtherPred = (LandBlk->
pred_size() > 2);
1309 if (LandBlkHasOtherPred) {
1311 unsigned CmpResReg =
1314 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET,
1322 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET, InitReg,
1326 migrateInstruction(TrueMBB, LandBlk, I);
1335 migrateInstruction(FalseMBB, LandBlk, I);
1342 if (LandBlkHasOtherPred) {
1344 insertInstrBefore(I, R600::ENDIF);
1348 PE = LandBlk->
pred_end(); PI != PE; ++PI) {
1350 if (MBB != TrueMBB && MBB != FalseMBB)
1355 dbgs() <<
"result from improveSimpleJumpintoIf: ";
1356 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););
1359 *LandMBBPtr = LandBlk;
1371 cloneSuccessorList(DstMBB, SrcMBB);
1373 removeSuccessor(SrcMBB);
1374 MLI->removeBlock(SrcMBB);
1375 retireBlock(SrcMBB);
1378 void AMDGPUCFGStructurizer::mergeIfthenelseBlock(
MachineInstr *BranchMI,
1385 dbgs() <<
"{ ";
if (FalseMBB) {
1387 }
dbgs() <<
" }\n ";
1388 dbgs() <<
"landBlock: ";
if (!LandMBB) {
dbgs() <<
"NULL"; }
else {
1404 insertCondBranchBefore(I, getBranchNzeroOpcode(OldOpcode),
1412 retireBlock(TrueMBB);
1413 MLI->removeBlock(TrueMBB);
1421 if (LandMBB && FalseMBB->
succ_size() != 0)
1423 retireBlock(FalseMBB);
1424 MLI->removeBlock(FalseMBB);
1426 insertInstrBefore(I, R600::ENDIF);
1430 if (LandMBB && TrueMBB && FalseMBB)
1437 <<
" land = BB" << LandMBB->
getNumber() <<
"\n";);
1439 insertInstrBefore(DstBlk, R600::WHILELOOP,
DebugLoc());
1440 insertInstrEnd(DstBlk, R600::ENDLOOP,
DebugLoc());
1447 << ExitingMBB->
getNumber() <<
" land = BB" 1449 MachineInstr *BranchMI = getLoopendBlockBranchInstr(ExitingMBB);
1450 assert(BranchMI && isCondBranch(BranchMI));
1451 DebugLoc DL = BranchMI->getDebugLoc();
1454 if (TrueBranch != LandMBB)
1455 reversePredicateSetter(I, *I->getParent());
1456 insertCondBranchBefore(ExitingMBB, I, R600::IF_PREDICATE_SET, R600::PREDICATE_BIT, DL);
1457 insertInstrBefore(I, R600::BREAK);
1458 insertInstrBefore(I, R600::ENDIF);
1460 BranchMI->eraseFromParent();
1468 << ContingMBB->
getNumber() <<
", cont = BB" 1471 MachineInstr *MI = getLoopendBlockBranchInstr(ContingMBB);
1473 assert(isCondBranch(MI));
1476 int OldOpcode = MI->getOpcode();
1479 bool UseContinueLogical = ((&*ContingMBB->
rbegin()) == MI);
1481 if (!UseContinueLogical) {
1483 TrueBranch == ContMBB ? getBranchNzeroOpcode(OldOpcode) :
1484 getBranchZeroOpcode(OldOpcode);
1485 insertCondBranchBefore(I, BranchOpcode, DL);
1487 insertInstrEnd(ContingMBB, R600::CONTINUE, DL);
1488 insertInstrEnd(ContingMBB, R600::ENDIF, DL);
1491 TrueBranch == ContMBB ? getContinueNzeroOpcode(OldOpcode) :
1492 getContinueZeroOpcode(OldOpcode);
1493 insertCondBranchBefore(I, BranchOpcode, DL);
1496 MI->eraseFromParent();
1503 insertInstrEnd(ContingMBB, R600::CONTINUE,
1504 getLastDebugLocInBB(ContingMBB));
1512 while (SrcMBB && SrcMBB != DstMBB) {
1515 SrcMBB = cloneBlockForPredecessor(SrcMBB, PreMBB);
1530 "succBlk is not a prececessor of curBlk");
1533 replaceInstrUseOfBlockWith(PredMBB, MBB, CloneMBB);
1539 cloneSuccessorList(CloneMBB, MBB);
1541 numClonedInstr += MBB->
size();
1547 SHOWNEWBLK(CloneMBB,
"result of Cloned block: ");
1556 MachineInstr *BranchMI = getNormalBlockBranchInstr(SrcMBB);
1558 LLVM_DEBUG(
dbgs() <<
"migrateInstruction don't see branch instr\n";);
1559 SpliceEnd = SrcMBB->
end();
1561 LLVM_DEBUG(
dbgs() <<
"migrateInstruction see branch instr: " << *BranchMI);
1562 SpliceEnd = BranchMI;
1564 LLVM_DEBUG(
dbgs() <<
"migrateInstruction before splice dstSize = " 1565 << DstMBB->
size() <<
"srcSize = " << SrcMBB->
size()
1569 DstMBB->
splice(I, SrcMBB, SrcMBB->
begin(), SpliceEnd);
1571 LLVM_DEBUG(
dbgs() <<
"migrateInstruction after splice dstSize = " 1572 << DstMBB->
size() <<
"srcSize = " << SrcMBB->
size()
1577 AMDGPUCFGStructurizer::normalizeInfiniteLoopExit(
MachineLoop* LoopRep) {
1581 if (!LoopHeader || !LoopLatch)
1583 MachineInstr *BranchMI = getLoopendBlockBranchInstr(LoopLatch);
1585 if (!BranchMI || !isUncondBranch(BranchMI))
1590 SHOWNEWBLK(DummyExitBlk,
"DummyExitBlock to normalize infiniteLoop: ");
1591 LLVM_DEBUG(
dbgs() <<
"Old branch instr: " << *BranchMI <<
"\n";);
1593 Ctx.
emitError(
"Extra register needed to handle CFG");
1602 while ((BranchMI = getLoopendBlockBranchInstr(MBB))
1603 && isUncondBranch(BranchMI)) {
1604 LLVM_DEBUG(
dbgs() <<
"Removing uncond branch instr: " << *BranchMI);
1609 void AMDGPUCFGStructurizer::removeRedundantConditionalBranch(
1618 MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB);
1619 assert(BranchMI && isCondBranch(BranchMI));
1620 LLVM_DEBUG(
dbgs() <<
"Removing unneeded cond branch instr: " << *BranchMI);
1622 SHOWNEWBLK(MBB1,
"Removing redundant successor");
1626 void AMDGPUCFGStructurizer::addDummyExitBlock(
1633 E = RetMBB.
end(); It !=
E; ++It) {
1640 <<
" successors\n";);
1642 SHOWNEWBLK(DummyExitBlk,
"DummyExitBlock: ");
1652 BlockInformation *&srcBlkInfo = BlockInfoMap[MBB];
1654 srcBlkInfo =
new BlockInformation();
1655 srcBlkInfo->SccNum = SccNum;
1661 BlockInformation *&SrcBlkInfo = BlockInfoMap[MBB];
1664 SrcBlkInfo =
new BlockInformation();
1666 SrcBlkInfo->IsRetired =
true;
1668 &&
"can't retire block yet");
1672 "AMDGPU CFG Structurizer",
false,
false)
1680 return new AMDGPUCFGStructurizer();
void print(raw_ostream &OS, const SlotIndexes *=nullptr, bool IsStandalone=true) const
INITIALIZE_PASS_BEGIN(AMDGPUCFGStructurizer, "amdgpustructurizer", "AMDGPU CFG Structurizer", false, false) INITIALIZE_PASS_END(AMDGPUCFGStructurizer
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AMDGPU specific subclass of TargetSubtarget.
typename SuperClass::const_iterator const_iterator
MachineBasicBlock * getMBB() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
Interface definition for R600InstrInfo.
A Module instance is used to store all the information related to an LLVM module. ...
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
FunctionPass * createAMDGPUCFGStructurizerPass()
Interface definition for R600RegisterInfo.
void dump() const
dump - Print the current MachineFunction to cerr, useful for debugger use.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImp=false)
CreateMachineInstr - Allocate a new MachineInstr.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void initializeAMDGPUCFGStructurizerPass(PassRegistry &)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static int getSCCNum(const BasicBlock *BB, const BranchProbabilityInfo::SccInfo &SccI)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
BlockT * getHeader() const
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
void getExitBlocks(SmallVectorImpl< BlockT *> &ExitBlocks) const
Return all of the successor blocks of this loop.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
std::vector< MachineLoop *>::const_iterator iterator
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.
reverse_iterator rbegin()
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.
This is an important class for using LLVM in a threaded context.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
#define SHOWNEWBLK(b, msg)
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
bool isValid() const
Check for null.
std::vector< MachineBasicBlock * >::iterator pred_iterator
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
succ_iterator succ_begin()
void getExitingBlocks(SmallVectorImpl< BlockT *> &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
pred_iterator pred_begin()
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.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
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.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned pred_size() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
typename SuperClass::iterator iterator
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
unsigned succ_size() const
const MachineBasicBlock * getParent() const
LoopT * getParentLoop() const
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
iterator_range< typename GraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
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.
LLVM_NODISCARD bool empty() const
void push_back(MachineInstr *MI)
LoopInfoBase< MachineBasicBlock, MachineLoop >::iterator iterator
The iterator interface to the top-level loops in the current function.
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.
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
iterator_range< df_iterator< T > > depth_first(const T &G)
bool isEmpty() const
isEmpty - Return true if there are no jump tables.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void push_back(MachineBasicBlock *MBB)
StringRef - Represent a constant reference to a string, i.e.
static uint32_t blk(uint32_t *Buf, int I)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineOperand & getOperand(unsigned i) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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...
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.