63 #define DEBUG_TYPE "hwloops"
76 cl::desc(
"Add a preheader to a hardware loop if one doesn't exist"));
85 STATISTIC(NumHWLoops,
"Number of loops converted to hardware loops");
116 StringRef getPassName()
const override {
return "Hexagon Hardware Loops"; }
125 typedef std::map<unsigned, MachineInstr *> LoopFeederMap;
145 static Kind getSwappedComparison(
Kind Cmp) {
146 assert ((!((Cmp &
L) && (Cmp &
G))) &&
"Malformed comparison operator");
147 if ((Cmp & L) || (Cmp &
G))
148 return (
Kind)(Cmp ^ (L|
G));
152 static Kind getNegatedComparison(
Kind Cmp) {
153 if ((Cmp & L) || (Cmp & G))
154 return (
Kind)((Cmp ^ (L |
G)) ^
EQ);
155 if ((Cmp &
NE) || (Cmp &
EQ))
160 static bool isSigned(
Kind Cmp) {
161 return (Cmp & (L | G) && !(Cmp & U));
164 static bool isUnsigned(
Kind Cmp) {
188 int64_t IVBump)
const;
210 bool IsInnerHWLoop)
const;
214 bool containsInvalidInstruction(
MachineLoop *L,
bool IsInnerHWLoop)
const;
218 bool convertToHardwareLoop(
MachineLoop *L,
bool &L0used,
bool &L1used);
238 LoopFeederMap &LoopFeederPhi)
const;
244 LoopFeederMap &LoopFeederPhi)
const;
251 LoopFeederMap &LoopFeederPhi)
const;
256 bool checkForImmediate(
const MachineOperand &MO, int64_t &Val)
const;
261 return checkForImmediate(MO, V);
267 if (!checkForImmediate(MO, V))
313 enum CountValueType {
329 explicit CountValue(CountValueType
t,
unsigned v,
unsigned u = 0) {
331 if (
Kind == CV_Register) {
339 bool isReg()
const {
return Kind == CV_Register; }
340 bool isImm()
const {
return Kind == CV_Immediate; }
344 return Contents.R.Reg;
346 unsigned getSubReg()
const {
348 return Contents.R.Sub;
350 unsigned getImm()
const {
351 assert(isImm() &&
"Wrong CountValue accessor");
352 return Contents.ImmVal;
356 if (
isReg()) { OS <<
PrintReg(Contents.R.Reg, TRI, Contents.R.Sub); }
357 if (isImm()) { OS << Contents.ImmVal; }
364 "Hexagon Hardware Loops",
false,
false)
371 return new HexagonHardwareLoops();
375 DEBUG(
dbgs() <<
"********* Hexagon Hardware Loops *********\n");
379 bool Changed =
false;
381 MLI = &getAnalysis<MachineLoopInfo>();
383 MDT = &getAnalysis<MachineDominatorTree>();
387 if (!L->getParentLoop()) {
390 Changed |= convertToHardwareLoop(L, L0Used, L1Used);
396 bool HexagonHardwareLoops::findInductionRegister(
MachineLoop *L,
405 if (!Header || !Preheader || !Latch || !ExitingBlock)
410 typedef std::pair<unsigned,int64_t> RegisterBump;
416 typedef std::map<unsigned,RegisterBump> InductionMap;
422 I !=
E &&
I->isPHI(); ++
I) {
441 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
443 IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
451 bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
455 unsigned PredR, PredPos, PredRegFlags;
456 if (!TII->getPredReg(Cond, PredR, PredPos, PredRegFlags))
463 unsigned CmpReg1 = 0, CmpReg2 = 0;
464 int CmpImm = 0, CmpMask = 0;
466 TII->analyzeCompare(*PredI, CmpReg1, CmpReg2, CmpMask, CmpImm);
475 InductionMap::iterator IndMapEnd = IndMap.end();
476 InductionMap::iterator
F = IndMapEnd;
478 InductionMap::iterator F1 = IndMap.find(CmpReg1);
483 InductionMap::iterator F2 = IndMap.find(CmpReg2);
484 if (F2 != IndMapEnd) {
493 Reg = F->second.first;
494 IVBump = F->second.second;
495 IVOp = MRI->getVRegDef(F->first);
500 HexagonHardwareLoops::Comparison::Kind
501 HexagonHardwareLoops::getComparisonKind(
unsigned CondOpc,
504 int64_t IVBump)
const {
507 case Hexagon::C2_cmpeqi:
508 case Hexagon::C2_cmpeq:
509 case Hexagon::C2_cmpeqp:
512 case Hexagon::C4_cmpneq:
513 case Hexagon::C4_cmpneqi:
516 case Hexagon::C4_cmplte:
517 Cmp = Comparison::LEs;
519 case Hexagon::C4_cmplteu:
520 Cmp = Comparison::LEu;
522 case Hexagon::C2_cmpgtui:
523 case Hexagon::C2_cmpgtu:
524 case Hexagon::C2_cmpgtup:
525 Cmp = Comparison::GTu;
527 case Hexagon::C2_cmpgti:
528 case Hexagon::C2_cmpgt:
529 case Hexagon::C2_cmpgtp:
530 Cmp = Comparison::GTs;
545 CountValue *HexagonHardwareLoops::getLoopTripCount(
MachineLoop *L,
550 "Loop must have more than one incoming edge!");
577 bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
588 if (MBB == Preheader)
590 else if (MBB == Latch)
598 bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
606 assert (TB &&
"Exit block without a branch?");
607 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
610 bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond,
false);
614 TB = (LTB == Header) ? LTB : LFB;
616 FB = (LTB == Header) ? LTB: LFB;
618 assert ((!FB || TB == Header || FB == Header) &&
"Branches not to header?");
619 if (!TB || (FB && TB != Header && FB != Header))
626 bool Negated = TII->predOpcodeHasNot(Cond) ^ (TB != Header);
627 unsigned PredReg, PredPos, PredRegFlags;
628 if (!TII->getPredReg(Cond, PredReg, PredPos, PredRegFlags))
633 unsigned CmpReg1 = 0, CmpReg2 = 0;
634 int Mask = 0, ImmValue = 0;
636 TII->analyzeCompare(*CondI, CmpReg1, CmpReg2, Mask, ImmValue);
651 bool isSwapped =
false;
668 Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
672 Cmp = Comparison::getNegatedComparison(Cmp);
674 Cmp = Comparison::getSwappedComparison(Cmp);
676 if (InitialValue->
isReg()) {
677 unsigned R = InitialValue->
getReg();
679 if (!MDT->properlyDominates(DefBB, Header))
683 if (EndValue->
isReg()) {
684 unsigned R = EndValue->
getReg();
686 if (!MDT->properlyDominates(DefBB, Header))
691 return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
710 if (Start->
isReg()) {
712 if (StartValInstr && (StartValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
713 StartValInstr->
getOpcode() == Hexagon::A2_tfrpi))
718 if (EndValInstr && (EndValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
719 EndValInstr->
getOpcode() == Hexagon::A2_tfrpi))
733 if (CmpLess && IVBump < 0)
737 if (CmpGreater && IVBump > 0)
742 LoopFeederMap LoopFeederPhi;
753 int64_t StartV = Start->
getImm();
754 int64_t EndV = End->
getImm();
755 int64_t Dist = EndV - StartV;
759 bool Exact = (Dist % IVBump) == 0;
764 if ((Dist < 0) ^ (IVBump < 0))
771 Dist = Dist > 0 ? Dist+1 : Dist-1;
777 if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
781 int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
782 : (-Dist + (-IVBump - 1)) / (-IVBump);
783 assert (Dist1 > 0 &&
"Fishy thing. Both operands have the same sign.");
785 uint64_t Count = Dist1;
787 if (Count > 0xFFFFFFFFULL)
790 return new CountValue(CountValue::CV_Immediate, Count);
803 assert (PH &&
"Should have a preheader by now");
806 if (InsertPos != PH->
end())
807 DL = InsertPos->getDebugLoc();
823 bool RegToImm = Start->
isReg() && End->
isImm();
824 bool RegToReg = Start->
isReg() && End->
isReg();
826 int64_t StartV = 0, EndV = 0;
845 else if (End->
isImm())
853 StartV -= (IVBump-1);
854 else if (End->
isImm())
860 unsigned R = 0, SR = 0;
861 if (Start->
isReg()) {
871 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
876 unsigned DistR, DistSR;
879 if (Start->
isImm() && StartV == 0) {
883 const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
884 (RegToImm ? TII->get(Hexagon::A2_subri) :
885 TII->get(Hexagon::A2_addi));
886 if (RegToReg || RegToImm) {
887 unsigned SubR = MRI->createVirtualRegister(IntRC);
889 BuildMI(*PH, InsertPos, DL, SubD, SubR);
903 if (EndValInstr->
getOpcode() == Hexagon::A2_addi &&
907 unsigned SubR = MRI->createVirtualRegister(IntRC);
909 BuildMI(*PH, InsertPos, DL, SubD, SubR);
919 unsigned AdjR, AdjSR;
926 unsigned AddR = MRI->createVirtualRegister(IntRC);
927 MCInstrDesc const &AddD = TII->get(Hexagon::A2_addi);
928 BuildMI(*PH, InsertPos, DL, AddD, AddR)
937 unsigned CountR, CountSR;
944 unsigned Shift =
Log2_32(IVBump);
947 unsigned LsrR = MRI->createVirtualRegister(IntRC);
948 const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
949 BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
957 return new CountValue(CountValue::CV_Register, CountR, CountSR);
961 bool HexagonHardwareLoops::isInvalidLoopOperation(
const MachineInstr *
MI,
962 bool IsInnerHWLoop)
const {
967 return !TII->doesNotReturn(*MI);
975 if (IsInnerHWLoop && (R == Hexagon::LC0 || R == Hexagon::SA0 ||
976 R == Hexagon::LC1 || R == Hexagon::SA1))
978 if (!IsInnerHWLoop && (R == Hexagon::LC1 || R == Hexagon::SA1))
986 bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
987 bool IsInnerHWLoop)
const {
988 const std::vector<MachineBasicBlock *> &Blocks = L->
getBlocks();
989 DEBUG(
dbgs() <<
"\nhw_loop head, BB#" << Blocks[0]->getNumber(););
990 for (
unsigned i = 0, e = Blocks.size();
i != e; ++
i) {
993 MII = MBB->
begin(),
E = MBB->
end(); MII !=
E; ++MII) {
995 if (isInvalidLoopOperation(MI, IsInnerHWLoop)) {
996 DEBUG(
dbgs()<<
"\nCannot convert to hw_loop due to:"; MI->
dump(););
1008 bool HexagonHardwareLoops::isDead(
const MachineInstr *MI,
1016 unsigned Reg = MO.
getReg();
1017 if (MRI->use_nodbg_empty(Reg))
1025 use_nodbg_iterator
I = MRI->use_nodbg_begin(Reg);
1026 use_nodbg_iterator End = MRI->use_nodbg_end();
1027 if (std::next(I) != End || !I->getParent()->isPHI())
1031 for (
unsigned j = 0, f = OnePhi->
getNumOperands(); j != f; ++j) {
1036 unsigned OPReg = OPO.
getReg();
1037 use_nodbg_iterator nextJ;
1038 for (use_nodbg_iterator J = MRI->use_nodbg_begin(OPReg);
1039 J !=
End; J = nextJ) {
1040 nextJ = std::next(J);
1056 void HexagonHardwareLoops::removeIfDead(
MachineInstr *MI) {
1060 if (isDead(MI, DeadPhis)) {
1061 DEBUG(
dbgs() <<
"HW looping will remove: " << *MI);
1070 unsigned Reg = MO.
getReg();
1073 E = MRI->use_end(); I !=
E; I = nextI) {
1074 nextI = std::next(I);
1085 for (
unsigned i = 0;
i < DeadPhis.
size(); ++
i)
1086 DeadPhis[
i]->eraseFromParent();
1098 bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1104 bool Changed =
false;
1105 bool L0Used =
false;
1106 bool L1Used =
false;
1110 Changed |= convertToHardwareLoop(*I, RecL0used, RecL1used);
1111 L0Used |= RecL0used;
1112 L1Used |= RecL1used;
1116 if (Changed && L0Used && L1Used)
1126 unsigned IsInnerHWLoop = 1;
1129 LOOP_i = Hexagon::J2_loop1i;
1130 LOOP_r = Hexagon::J2_loop1r;
1131 ENDLOOP = Hexagon::ENDLOOP1;
1134 LOOP_i = Hexagon::J2_loop0i;
1135 LOOP_r = Hexagon::J2_loop0r;
1136 ENDLOOP = Hexagon::ENDLOOP0;
1150 if (containsInvalidInstruction(L, IsInnerHWLoop))
1159 if (LastI == LastMBB->
end())
1163 if (!fixupInductionVariable(L))
1170 Preheader = createPreheaderForLoop(L);
1179 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1184 if (TripCount->isReg()) {
1187 MachineInstr *TCDef = MRI->getVRegDef(TripCount->getReg());
1189 if (!MDT->dominates(BBDef, Preheader))
1201 if (TII->analyzeBranch(*ExitingBlock, TB, FB, Cond,
false))
1212 LoopStart = TopBlock;
1217 if (InsertPos != Preheader->
end())
1218 DL = InsertPos->getDebugLoc();
1220 if (TripCount->isReg()) {
1222 unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1223 BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg)
1224 .addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1226 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r)).addMBB(LoopStart)
1229 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1233 int64_t CountImm = TripCount->getImm();
1234 if (!TII->isValidOffset(LOOP_i, CountImm)) {
1235 unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1236 BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
1238 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r))
1239 .addMBB(LoopStart).
addReg(CountReg);
1241 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_i))
1242 .addMBB(LoopStart).
addImm(CountImm);
1254 DebugLoc LastIDL = LastI->getDebugLoc();
1255 BuildMI(*LastMBB, LastI, LastIDL, TII->
get(ENDLOOP)).addMBB(LoopStart);
1260 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1261 LastI->getOpcode() == Hexagon::J2_jumpf) {
1264 LastI = LastMBB->
erase(LastI);
1266 if (LastI != LastMBB->
end())
1267 LastI = LastMBB->
erase(LastI);
1269 TII->insertBranch(*LastMBB, BranchTarget,
nullptr, Cond, LastIDL);
1273 LastMBB->
erase(LastI);
1279 for (
unsigned i = 0;
i < OldInsts.
size(); ++
i)
1280 removeIfDead(OldInsts[
i]);
1295 bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1297 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1305 for (instr_iterator
I(BumpI),
E = BB->
instr_end(); I !=
E; ++
I)
1311 bool FoundBump =
false;
1312 instr_iterator CmpIt = CmpI->
getIterator(), NextIt = std::next(CmpIt);
1313 for (instr_iterator I = NextIt,
E = BB->
instr_end(); I !=
E; ++
I) {
1318 if (MO.
getReg() == PredR)
1329 assert (FoundBump &&
"Cannot determine instruction order");
1341 LoopFeederMap &LoopFeederPhi)
const {
1342 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1343 const std::vector<MachineBasicBlock *> &Blocks = L->
getBlocks();
1344 DEBUG(
dbgs() <<
"\nhw_loop head, BB#" << Blocks[0]->getNumber(););
1346 for (
unsigned i = 0, e = Blocks.size(); i != e; ++
i) {
1352 LoopFeederPhi.insert(std::make_pair(MO->
getReg(),
Def));
1361 bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1363 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1368 if (isLoopFeeder(L, MBB, Phi, &(Phi->
getOperand(i)), LoopFeederPhi))
1369 if (loopCountMayWrapOrUnderFlow(&(Phi->
getOperand(i)), EndVal,
1389 bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1392 LoopFeederMap &LoopFeederPhi)
const {
1394 if (!InitVal->
isReg())
1397 if (!EndVal->
isImm())
1403 if (checkForImmediate(*InitVal, Imm))
1404 return (EndVal->
getImm() == Imm);
1406 unsigned Reg = InitVal->
getReg();
1418 if (Def->
isPHI() && !phiMayWrapOrUnderflow(Def, EndVal, Def->
getParent(),
1430 E = MRI->use_instr_nodbg_end(); I !=
E; ++
I) {
1432 unsigned CmpReg1 = 0, CmpReg2 = 0;
1433 int CmpMask = 0, CmpValue = 0;
1435 if (!TII->analyzeCompare(*MI, CmpReg1, CmpReg2, CmpMask, CmpValue))
1440 if (TII->analyzeBranch(*MI->
getParent(), TBB, FBB, Cond,
false))
1444 getComparisonKind(MI->
getOpcode(),
nullptr,
nullptr, 0);
1447 if (TII->predOpcodeHasNot(Cond) ^ (TBB !=
MBB))
1448 Cmp = Comparison::getNegatedComparison(Cmp);
1449 if (CmpReg2 != 0 && CmpReg2 == Reg)
1450 Cmp = Comparison::getSwappedComparison(Cmp);
1453 if (Comparison::isSigned(Cmp))
1472 bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1473 int64_t &Val)
const {
1486 unsigned R = MO.
getReg();
1492 case TargetOpcode::COPY:
1493 case Hexagon::A2_tfrsi:
1494 case Hexagon::A2_tfrpi:
1496 case Hexagon::CONST64: {
1500 if (!checkForImmediate(DI->
getOperand(1), TV))
1504 case Hexagon::A2_combineii:
1505 case Hexagon::A4_combineir:
1506 case Hexagon::A4_combineii:
1507 case Hexagon::A4_combineri:
1508 case Hexagon::A2_combinew: {
1512 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1514 TV = V2 | (V1 << 32);
1517 case TargetOpcode::REG_SEQUENCE: {
1521 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1525 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1526 TV = V1 | (V3 << 32);
1527 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1528 TV = V3 | (V1 << 32);
1541 case Hexagon::isub_lo:
1542 Val = TV & 0xFFFFFFFFULL;
1544 case Hexagon::isub_hi:
1545 Val = (TV >> 32) & 0xFFFFFFFFULL;
1554 void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1561 unsigned R = MO.
getReg();
1565 unsigned NewR = MRI->createVirtualRegister(RC);
1574 if (CmpOpc == Hexagon::A4_cmpbeqi)
1576 if (CmpOpc == Hexagon::A4_cmpbgti)
1582 bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1587 if (!(Header && Latch && ExitingBlock))
1592 typedef std::pair<unsigned,int64_t> RegisterBump;
1593 typedef std::pair<unsigned,RegisterBump> RegisterInduction;
1594 typedef std::set<RegisterInduction> RegisterInductionSet;
1597 RegisterInductionSet IndRegs;
1604 I !=
E && I->isPHI(); ++
I) {
1621 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1623 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1629 if (IndRegs.empty())
1635 bool NotAnalyzed = TII->analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
1636 if (NotAnalyzed || Cond.
empty())
1639 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1642 bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond,
false);
1649 TB = (LTB == Header) ? LTB : LFB;
1651 FB = (LTB == Header) ? LTB : LFB;
1664 if (MDT->dominates(TB, FB))
1673 unsigned CSz = Cond.
size();
1674 if (CSz != 1 && CSz != 2)
1677 if (!Cond[CSz-1].
isReg())
1680 unsigned P = Cond[CSz-1].getReg();
1701 if (!isImmediate(MO)) {
1710 }
else if (MO.
isImm()) {
1717 if (CmpRegs.
empty())
1721 for (RegisterInductionSet::iterator I = IndRegs.begin(),
E = IndRegs.end();
1726 if (CmpRegs.
count(I->first))
1732 const RegisterBump &RB = I->second;
1733 if (CmpRegs.
count(RB.first)) {
1745 DEBUG(
dbgs() <<
"\n DefMI(" << i <<
") = "
1746 << *(MRI->getVRegDef(I->first)));
1750 IndI = MRI->getVRegDef(I->first);
1752 }
else if (MO.
isReg()) {
1753 DEBUG(
dbgs() <<
"\n DefMI(" << i <<
") = "
1754 << *(MRI->getVRegDef(MO.
getReg())));
1758 nonIndI = MRI->getVRegDef(MO.
getReg());
1762 if (IndI && nonIndI &&
1763 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1766 bool Order = orderBumpCompare(IndI, PredDef);
1779 getComparisonKind(PredDef->
getOpcode(),
nullptr,
nullptr, 0);
1780 if (!Cmp || Comparison::isUnsigned(Cmp))
1786 int64_t CmpImm = getImmediate(*CmpImmOp);
1787 int64_t V = RB.second;
1789 if (((V > 0) && (CmpImm > INT64_MAX - V)) ||
1790 ((V < 0) && (CmpImm < INT64_MIN - V)))
1796 if (CmpImmOp->
isImm())
1803 bool Order = orderBumpCompare(BumpI, PredDef);
1808 setImmediate(*CmpImmOp, CmpImm);
1848 typedef std::vector<MachineBasicBlock*>
MBBVector;
1853 if (TII->analyzeBranch(*ExitingBlock, TB, FB, Tmp1,
false))
1858 bool NotAnalyzed = TII->analyzeBranch(*PB, TB, FB, Tmp1,
false);
1873 I !=
E && I->isPHI(); ++
I) {
1882 unsigned NewPR = MRI->createVirtualRegister(RC);
1904 if (PredB != Latch) {
1921 I !=
E && I->isPHI(); ++
I) {
1925 if (MO.
getMBB() != Latch)
1943 bool NotAnalyzed = TII->analyzeBranch(*PB, TB, FB, Tmp2,
false);
1945 assert (!NotAnalyzed &&
"Should be analyzable!");
1946 if (TB != Header && (Tmp2.
empty() || FB != Header))
1947 TII->insertBranch(*PB, NewPH,
nullptr, EmptyCond, DL);
1955 bool LatchNotAnalyzed = TII->analyzeBranch(*Latch, TB, FB, Tmp2,
false);
1956 (void)LatchNotAnalyzed;
1957 assert (!LatchNotAnalyzed &&
"Should be analyzable!");
1959 TII->insertBranch(*Latch, Header,
nullptr, EmptyCond, DL);
1962 TII->insertBranch(*NewPH, Header,
nullptr, EmptyCond, DL);
1973 MDT->addNewBlock(NewPH, DHN->getBlock());
1974 MDT->changeImmediateDominator(Header, NewPH);
static bool isReg(const MCInst &MI, unsigned OpNo)
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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()
instr_iterator instr_end()
static cl::opt< bool > SpecPreheader("hwloop-spec-preheader", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Allow speculation of preheader ""instructions"))
STATISTIC(NumFunctions,"Total number of functions")
MachineBasicBlock * getMBB() const
void initializeHexagonHardwareLoopsPass(PassRegistry &)
static cl::opt< bool > HWCreatePreheader("hexagon-hwloop-preheader", cl::Hidden, cl::init(true), cl::desc("Add a preheader to a hardware loop if one doesn't exist"))
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Describe properties that are true of each instruction in the target description file.
static bool isImmValidForOpcode(unsigned CmpOpc, int64_t Imm)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
constexpr bool isInt< 8 >(int64_t x)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static cl::opt< std::string > PHFn("hexagon-hwloop-phfn", cl::Hidden, cl::init(""))
LoopT * getParentLoop() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
SmallVector< MachineBasicBlock *, 4 > MBBVector
FunctionPass * createHexagonHardwareLoops()
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImp=false)
CreateMachineInstr - Allocate a new MachineInstr.
const std::vector< BlockT * > & getBlocks() const
Get a list of the basic blocks which make up this loop.
BlockT * getHeader() const
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
INITIALIZE_PASS_BEGIN(HexagonHardwareLoops,"hwloops","Hexagon Hardware Loops", false, false) INITIALIZE_PASS_END(HexagonHardwareLoops
DomTreeNodeBase< NodeT > * getIDom() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...
LLVM_NODISCARD bool empty() const
MachineBasicBlock * getTopBlock()
Return the "top" block in the loop, which is the first block in the linear layout, ignoring any parts of the loop not contiguous with the part that contains the header.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
A Use represents the edge between a Value definition and its users.
bool isCall() const
Return true if the instruction is a call.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
LLVM_NODISCARD bool empty() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
MachineBasicBlock * findLoopControlBlock()
Find the block that contains the loop control variable and the loop test.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
Base class for the actual dominator tree node.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
std::vector< MachineBasicBlock * >::iterator pred_iterator
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static cl::opt< int > HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1))
initializer< Ty > init(const Ty &Val)
constexpr bool isUInt< 8 >(uint64_t x)
unsigned const MachineRegisterInfo * MRI
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
MachineInstrBuilder & UseMI
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
constexpr bool isPowerOf2_64(uint64_t Value)
isPowerOf2_64 - This function returns true if the argument is a power of two 0 (64 bit edition...
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isAdd() const
Return true if the instruction is an add instruction.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void dump(const TargetInstrInfo *TII=nullptr) const
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
void setHasAddressTaken()
Set this block to reflect that it potentially is the target of an indirect branch.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Representation of each machine instruction.
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0)
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.
Represents a single loop in the control flow graph.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
APFloat abs(APFloat X)
Returns the absolute value of the argument.
void setSubReg(unsigned subReg)
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
std::vector< LoopT * >::const_iterator iterator
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned pred_size() const