48 #define DEBUG_TYPE "hwloops"
61 cl::desc(
"Add a preheader to a hardware loop if one doesn't exist"));
63 STATISTIC(NumHWLoops,
"Number of loops converted to hardware loops");
90 const char *getPassName()
const override {
return "Hexagon Hardware Loops"; }
99 typedef std::map<unsigned, MachineInstr *> LoopFeederMap;
119 static Kind getSwappedComparison(
Kind Cmp) {
120 assert ((!((Cmp & L) && (Cmp &
G))) &&
"Malformed comparison operator");
121 if ((Cmp & L) || (Cmp &
G))
122 return (
Kind)(Cmp ^ (L|
G));
126 static Kind getNegatedComparison(
Kind Cmp) {
127 if ((Cmp & L) || (Cmp & G))
128 return (
Kind)((Cmp ^ (L |
G)) ^
EQ);
129 if ((Cmp &
NE) || (Cmp &
EQ))
134 static bool isSigned(
Kind Cmp) {
135 return (Cmp & (L | G) && !(Cmp & U));
138 static bool isUnsigned(
Kind Cmp) {
163 int64_t IVBump)
const;
185 bool IsInnerHWLoop)
const;
189 bool containsInvalidInstruction(
MachineLoop *L,
bool IsInnerHWLoop)
const;
193 bool convertToHardwareLoop(
MachineLoop *L,
bool &L0used,
bool &L1used);
213 LoopFeederMap &LoopFeederPhi)
const;
219 LoopFeederMap &LoopFeederPhi)
const;
226 LoopFeederMap &LoopFeederPhi)
const;
231 bool checkForImmediate(
const MachineOperand &MO, int64_t &Val)
const;
236 return checkForImmediate(MO, V);
242 if (!checkForImmediate(MO, V))
280 int HexagonHardwareLoops::Counter = 0;
288 enum CountValueType {
303 explicit CountValue(CountValueType t,
unsigned v,
unsigned u = 0) {
305 if (
Kind == CV_Register) {
312 bool isReg()
const {
return Kind == CV_Register; }
313 bool isImm()
const {
return Kind == CV_Immediate; }
316 assert(
isReg() &&
"Wrong CountValue accessor");
317 return Contents.R.Reg;
319 unsigned getSubReg()
const {
320 assert(
isReg() &&
"Wrong CountValue accessor");
321 return Contents.R.Sub;
323 unsigned getImm()
const {
324 assert(isImm() &&
"Wrong CountValue accessor");
325 return Contents.ImmVal;
329 if (
isReg()) { OS <<
PrintReg(Contents.R.Reg, TRI, Contents.R.Sub); }
330 if (isImm()) { OS << Contents.ImmVal; }
337 "Hexagon Hardware Loops",
false,
false)
344 return new HexagonHardwareLoops();
348 DEBUG(
dbgs() <<
"********* Hexagon Hardware Loops *********\n");
350 bool Changed =
false;
352 MLI = &getAnalysis<MachineLoopInfo>();
354 MDT = &getAnalysis<MachineDominatorTree>();
358 if (!L->getParentLoop()) {
361 Changed |= convertToHardwareLoop(L, L0Used, L1Used);
380 bool HexagonHardwareLoops::findInductionRegister(
MachineLoop *L,
389 if (!Header || !Preheader || !Latch || !ExitingBlock)
394 typedef std::pair<unsigned,int64_t> RegisterBump;
400 typedef std::map<unsigned,RegisterBump> InductionMap;
406 I != E &&
I->isPHI(); ++
I) {
419 bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
427 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
429 IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
437 bool NotAnalyzed = TII->AnalyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
441 unsigned PredR, PredPos, PredRegFlags;
442 if (!TII->getPredReg(Cond, PredR, PredPos, PredRegFlags))
449 unsigned CmpReg1 = 0, CmpReg2 = 0;
450 int CmpImm = 0, CmpMask = 0;
451 bool CmpAnalyzed = TII->analyzeCompare(PredI, CmpReg1, CmpReg2,
461 InductionMap::iterator IndMapEnd = IndMap.end();
462 InductionMap::iterator
F = IndMapEnd;
464 InductionMap::iterator F1 = IndMap.find(CmpReg1);
469 InductionMap::iterator F2 = IndMap.find(CmpReg2);
470 if (F2 != IndMapEnd) {
479 Reg = F->second.first;
480 IVBump = F->second.second;
481 IVOp = MRI->getVRegDef(F->first);
486 HexagonHardwareLoops::Comparison::Kind
487 HexagonHardwareLoops::getComparisonKind(
unsigned CondOpc,
490 int64_t IVBump)
const {
493 case Hexagon::C2_cmpeqi:
494 case Hexagon::C2_cmpeq:
495 case Hexagon::C2_cmpeqp:
498 case Hexagon::C4_cmpneq:
499 case Hexagon::C4_cmpneqi:
502 case Hexagon::C4_cmplte:
503 Cmp = Comparison::LEs;
505 case Hexagon::C4_cmplteu:
506 Cmp = Comparison::LEu;
508 case Hexagon::C2_cmpgtui:
509 case Hexagon::C2_cmpgtu:
510 case Hexagon::C2_cmpgtup:
511 Cmp = Comparison::GTu;
513 case Hexagon::C2_cmpgti:
514 case Hexagon::C2_cmpgt:
515 case Hexagon::C2_cmpgtp:
516 Cmp = Comparison::GTs;
531 CountValue *HexagonHardwareLoops::getLoopTripCount(
MachineLoop *L,
536 "Loop must have more than one incoming edge!");
563 bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
572 for (
unsigned i = 1, n = IV_Phi->
getNumOperands(); i < n; i += 2) {
574 if (MBB == Preheader)
576 else if (MBB == Latch)
584 bool NotAnalyzed = TII->AnalyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
592 assert (TB &&
"Exit block without a branch?");
593 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
596 bool NotAnalyzed = TII->AnalyzeBranch(*Latch, LTB, LFB, LCond,
false);
600 TB = (LTB == Header) ? LTB : LFB;
602 FB = (LTB == Header) ? LTB: LFB;
604 assert ((!FB || TB == Header || FB == Header) &&
"Branches not to header?");
605 if (!TB || (FB && TB != Header && FB != Header))
612 bool Negated = TII->predOpcodeHasNot(Cond) ^ (TB != Header);
613 unsigned PredReg, PredPos, PredRegFlags;
614 if (!TII->getPredReg(Cond, PredReg, PredPos, PredRegFlags))
619 unsigned CmpReg1 = 0, CmpReg2 = 0;
620 int Mask = 0, ImmValue = 0;
621 bool AnalyzedCmp = TII->analyzeCompare(CondI, CmpReg1, CmpReg2,
637 bool isSwapped =
false;
654 Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
658 Cmp = Comparison::getNegatedComparison(Cmp);
660 Cmp = Comparison::getSwappedComparison(Cmp);
662 if (InitialValue->
isReg()) {
663 unsigned R = InitialValue->
getReg();
665 if (!MDT->properlyDominates(DefBB, Header))
669 if (EndValue->
isReg()) {
670 unsigned R = EndValue->
getReg();
672 if (!MDT->properlyDominates(DefBB, Header))
677 return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
696 if (Start->
isReg()) {
698 if (StartValInstr && (StartValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
699 StartValInstr->
getOpcode() == Hexagon::A2_tfrpi))
704 if (EndValInstr && (EndValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
705 EndValInstr->
getOpcode() == Hexagon::A2_tfrpi))
714 bool CmpLess = Cmp & Comparison::L;
719 if (CmpLess && IVBump < 0)
723 if (CmpGreater && IVBump > 0)
728 LoopFeederMap LoopFeederPhi;
739 int64_t StartV = Start->
getImm();
740 int64_t EndV = End->
getImm();
741 int64_t Dist = EndV - StartV;
745 bool Exact = (Dist % IVBump) == 0;
750 if ((Dist < 0) ^ (IVBump < 0))
757 Dist = Dist > 0 ? Dist+1 : Dist-1;
763 if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
767 int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
768 : (-Dist + (-IVBump - 1)) / (-IVBump);
769 assert (Dist1 > 0 &&
"Fishy thing. Both operands have the same sign.");
771 uint64_t Count = Dist1;
773 if (Count > 0xFFFFFFFFULL)
776 return new CountValue(CountValue::CV_Immediate, Count);
789 assert (PH &&
"Should have a preheader by now");
792 if (InsertPos != PH->
end())
793 DL = InsertPos->getDebugLoc();
809 bool RegToImm = Start->
isReg() && End->
isImm();
810 bool RegToReg = Start->
isReg() && End->
isReg();
812 int64_t StartV = 0, EndV = 0;
831 else if (End->
isImm())
839 StartV -= (IVBump-1);
840 else if (End->
isImm())
846 unsigned R = 0, SR = 0;
847 if (Start->
isReg()) {
857 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
862 unsigned DistR, DistSR;
865 if (Start->
isImm() && StartV == 0) {
869 const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
870 (RegToImm ? TII->get(Hexagon::A2_subri) :
871 TII->get(Hexagon::A2_addi));
872 if (RegToReg || RegToImm) {
873 unsigned SubR = MRI->createVirtualRegister(IntRC);
875 BuildMI(*PH, InsertPos, DL, SubD, SubR);
889 if (EndValInstr->
getOpcode() == Hexagon::A2_addi &&
893 unsigned SubR = MRI->createVirtualRegister(IntRC);
895 BuildMI(*PH, InsertPos, DL, SubD, SubR);
905 unsigned AdjR, AdjSR;
912 unsigned AddR = MRI->createVirtualRegister(IntRC);
913 MCInstrDesc const &AddD = TII->get(Hexagon::A2_addi);
914 BuildMI(*PH, InsertPos, DL, AddD, AddR)
923 unsigned CountR, CountSR;
930 unsigned Shift =
Log2_32(IVBump);
933 unsigned LsrR = MRI->createVirtualRegister(IntRC);
934 const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
935 BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
943 return new CountValue(CountValue::CV_Register, CountR, CountSR);
947 bool HexagonHardwareLoops::isInvalidLoopOperation(
const MachineInstr *
MI,
948 bool IsInnerHWLoop)
const {
961 if (IsInnerHWLoop && (R == Hexagon::LC0 || R == Hexagon::SA0 ||
962 R == Hexagon::LC1 || R == Hexagon::SA1))
964 if (!IsInnerHWLoop && (R == Hexagon::LC1 || R == Hexagon::SA1))
972 bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
973 bool IsInnerHWLoop)
const {
974 const std::vector<MachineBasicBlock *> &Blocks = L->
getBlocks();
975 DEBUG(
dbgs() <<
"\nhw_loop head, BB#" << Blocks[0]->getNumber(););
976 for (
unsigned i = 0, e = Blocks.size(); i != e; ++i) {
979 MII = MBB->
begin(), E = MBB->
end(); MII != E; ++MII) {
981 if (isInvalidLoopOperation(MI, IsInnerHWLoop)) {
982 DEBUG(
dbgs()<<
"\nCannot convert to hw_loop due to:"; MI->
dump(););
994 bool HexagonHardwareLoops::isDead(
const MachineInstr *MI,
1002 unsigned Reg = MO.
getReg();
1003 if (MRI->use_nodbg_empty(Reg))
1011 use_nodbg_iterator
I = MRI->use_nodbg_begin(Reg);
1012 use_nodbg_iterator End = MRI->use_nodbg_end();
1013 if (std::next(I) != End || !I->getParent()->isPHI())
1017 for (
unsigned j = 0, f = OnePhi->
getNumOperands(); j != f; ++j) {
1022 unsigned OPReg = OPO.
getReg();
1023 use_nodbg_iterator nextJ;
1024 for (use_nodbg_iterator J = MRI->use_nodbg_begin(OPReg);
1025 J != End; J = nextJ) {
1026 nextJ = std::next(J);
1042 void HexagonHardwareLoops::removeIfDead(
MachineInstr *MI) {
1046 if (isDead(MI, DeadPhis)) {
1047 DEBUG(
dbgs() <<
"HW looping will remove: " << *MI);
1056 unsigned Reg = MO.
getReg();
1059 E = MRI->use_end(); I != E; I = nextI) {
1060 nextI = std::next(I);
1071 for (
unsigned i = 0; i < DeadPhis.
size(); ++i)
1072 DeadPhis[i]->eraseFromParent();
1084 bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1088 assert(L->
getHeader() &&
"Loop without a header?");
1090 bool Changed =
false;
1091 bool L0Used =
false;
1092 bool L1Used =
false;
1096 Changed |= convertToHardwareLoop(*I, RecL0used, RecL1used);
1097 L0Used |= RecL0used;
1098 L1Used |= RecL1used;
1102 if (Changed && L0Used && L1Used)
1112 unsigned IsInnerHWLoop = 1;
1115 LOOP_i = Hexagon::J2_loop1i;
1116 LOOP_r = Hexagon::J2_loop1r;
1117 ENDLOOP = Hexagon::ENDLOOP1;
1120 LOOP_i = Hexagon::J2_loop0i;
1121 LOOP_r = Hexagon::J2_loop0r;
1122 ENDLOOP = Hexagon::ENDLOOP0;
1136 if (containsInvalidInstruction(L, IsInnerHWLoop))
1145 if (LastI == LastMBB->
end())
1149 if (!fixupInductionVariable(L))
1156 Preheader = createPreheaderForLoop(L);
1165 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1170 if (TripCount->isReg()) {
1173 MachineInstr *TCDef = MRI->getVRegDef(TripCount->getReg());
1175 if (!MDT->dominates(BBDef, Preheader))
1187 if (TII->AnalyzeBranch(*ExitingBlock, TB, FB, Cond,
false))
1198 LoopStart = TopBlock;
1203 if (InsertPos != Preheader->
end())
1204 DL = InsertPos->getDebugLoc();
1206 if (TripCount->isReg()) {
1208 unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1210 .addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1212 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r)).addMBB(LoopStart)
1215 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1219 int64_t CountImm = TripCount->getImm();
1220 if (!TII->isValidOffset(LOOP_i, CountImm)) {
1221 unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1222 BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
1224 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r))
1225 .addMBB(LoopStart).
addReg(CountReg);
1227 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_i))
1228 .addMBB(LoopStart).
addImm(CountImm);
1240 DebugLoc LastIDL = LastI->getDebugLoc();
1241 BuildMI(*LastMBB, LastI, LastIDL, TII->
get(ENDLOOP)).addMBB(LoopStart);
1246 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1247 LastI->getOpcode() == Hexagon::J2_jumpf) {
1250 LastI = LastMBB->
erase(LastI);
1252 if (LastI != LastMBB->
end())
1253 LastI = LastMBB->
erase(LastI);
1255 TII->InsertBranch(*LastMBB, BranchTarget,
nullptr, Cond, LastIDL);
1259 LastMBB->
erase(LastI);
1265 for (
unsigned i = 0; i < OldInsts.
size(); ++i)
1266 removeIfDead(OldInsts[i]);
1281 bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1283 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1291 for (instr_iterator I = BumpI, E = BB->
instr_end(); I != E; ++
I)
1297 bool FoundBump =
false;
1298 instr_iterator CmpIt = CmpI, NextIt = std::next(CmpIt);
1299 for (instr_iterator I = NextIt, E = BB->
instr_end(); I != E; ++
I) {
1304 if (MO.
getReg() == PredR)
1310 instr_iterator After = BumpI;
1311 instr_iterator From = CmpI;
1312 BB->
splice(std::next(After), BB, From);
1317 assert (FoundBump &&
"Cannot determine instruction order");
1329 LoopFeederMap &LoopFeederPhi)
const {
1330 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1331 const std::vector<MachineBasicBlock *> &Blocks = L->
getBlocks();
1332 DEBUG(
dbgs() <<
"\nhw_loop head, BB#" << Blocks[0]->getNumber(););
1334 for (
unsigned i = 0, e = Blocks.size(); i != e; ++i) {
1340 LoopFeederPhi.insert(std::make_pair(MO->
getReg(),
Def));
1349 bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1351 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1352 assert(Phi->
isPHI() &&
"Expecting a Phi.");
1356 if (isLoopFeeder(L, MBB, Phi, &(Phi->
getOperand(i)), LoopFeederPhi))
1357 if (loopCountMayWrapOrUnderFlow(&(Phi->
getOperand(i)), EndVal,
1377 bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1380 LoopFeederMap &LoopFeederPhi)
const {
1382 if (!InitVal->
isReg())
1385 if (!EndVal->
isImm())
1391 if (checkForImmediate(*InitVal, Imm))
1392 return (EndVal->
getImm() == Imm);
1394 unsigned Reg = InitVal->
getReg();
1406 if (Def->
isPHI() && !phiMayWrapOrUnderflow(Def, EndVal, Def->
getParent(),
1418 E = MRI->use_instr_nodbg_end(); I != E; ++
I) {
1420 unsigned CmpReg1 = 0, CmpReg2 = 0;
1421 int CmpMask = 0, CmpValue = 0;
1423 if (!TII->analyzeCompare(MI, CmpReg1, CmpReg2, CmpMask, CmpValue))
1428 if (TII->AnalyzeBranch(*MI->
getParent(), TBB, FBB, Cond,
false))
1434 if (TII->predOpcodeHasNot(Cond) ^ (TBB != MBB))
1435 Cmp = Comparison::getNegatedComparison(Cmp);
1436 if (CmpReg2 != 0 && CmpReg2 == Reg)
1437 Cmp = Comparison::getSwappedComparison(Cmp);
1440 if (Comparison::isSigned(Cmp))
1459 bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1460 int64_t &Val)
const {
1473 unsigned R = MO.
getReg();
1480 case Hexagon::A2_tfrsi:
1481 case Hexagon::A2_tfrpi:
1482 case Hexagon::CONST32_Int_Real:
1483 case Hexagon::CONST64_Int_Real: {
1487 if (!checkForImmediate(DI->
getOperand(1), TV))
1491 case Hexagon::A2_combineii:
1492 case Hexagon::A4_combineir:
1493 case Hexagon::A4_combineii:
1494 case Hexagon::A4_combineri:
1495 case Hexagon::A2_combinew: {
1499 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1501 TV = V2 | (V1 << 32);
1508 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1512 if (Sub2 == Hexagon::subreg_loreg && Sub4 == Hexagon::subreg_hireg)
1513 TV = V1 | (V3 << 32);
1514 else if (Sub2 == Hexagon::subreg_hireg && Sub4 == Hexagon::subreg_loreg)
1515 TV = V3 | (V1 << 32);
1528 case Hexagon::subreg_loreg:
1529 Val = TV & 0xFFFFFFFFULL;
1531 case Hexagon::subreg_hireg:
1532 Val = (TV >> 32) & 0xFFFFFFFFULL;
1541 void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1548 unsigned R = MO.
getReg();
1552 unsigned NewR = MRI->createVirtualRegister(RC);
1561 if (CmpOpc == Hexagon::A4_cmpbeqi)
1563 if (CmpOpc == Hexagon::A4_cmpbgti)
1569 bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1574 if (!(Header && Latch && ExitingBlock))
1579 typedef std::pair<unsigned,int64_t> RegisterBump;
1580 typedef std::pair<unsigned,RegisterBump> RegisterInduction;
1581 typedef std::set<RegisterInduction> RegisterInductionSet;
1584 RegisterInductionSet IndRegs;
1591 I != E && I->isPHI(); ++
I) {
1602 bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp);
1610 if (MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1612 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1618 if (IndRegs.empty())
1624 bool NotAnalyzed = TII->AnalyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
1625 if (NotAnalyzed || Cond.
empty())
1628 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1631 bool NotAnalyzed = TII->AnalyzeBranch(*Latch, LTB, LFB, LCond,
false);
1638 TB = (LTB == Header) ? LTB : LFB;
1640 FB = (LTB == Header) ? LTB : LFB;
1653 if (MDT->dominates(TB, FB))
1662 unsigned CSz = Cond.
size();
1663 if (CSz != 1 && CSz != 2)
1666 if (!Cond[CSz-1].
isReg())
1669 unsigned P = Cond[CSz-1].getReg();
1682 for (
unsigned i = 0, n = PredDef->
getNumOperands(); i < n; ++i) {
1690 if (!isImmediate(MO)) {
1699 }
else if (MO.
isImm()) {
1706 if (CmpRegs.
empty())
1710 for (RegisterInductionSet::iterator I = IndRegs.begin(), E = IndRegs.end();
1715 if (CmpRegs.
count(I->first))
1721 const RegisterBump &RB = I->second;
1722 if (CmpRegs.
count(RB.first)) {
1731 for (
unsigned i = 1, n = PredDef->
getNumOperands(); i < n; ++i) {
1734 DEBUG(
dbgs() <<
"\n DefMI(" << i <<
") = "
1735 << *(MRI->getVRegDef(I->first)));
1739 IndI = MRI->getVRegDef(I->first);
1741 }
else if (MO.
isReg()) {
1742 DEBUG(
dbgs() <<
"\n DefMI(" << i <<
") = "
1743 << *(MRI->getVRegDef(MO.
getReg())));
1747 nonIndI = MRI->getVRegDef(MO.
getReg());
1751 if (IndI && nonIndI &&
1752 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1755 bool Order = orderBumpCompare(IndI, PredDef);
1768 if (!Cmp || Comparison::isUnsigned(Cmp))
1774 int64_t CmpImm = getImmediate(*CmpImmOp);
1775 int64_t V = RB.second;
1777 if (((V > 0) && (CmpImm > INT64_MAX - V)) ||
1778 ((V < 0) && (CmpImm < INT64_MIN - V)))
1784 if (CmpImmOp->
isImm())
1791 bool Order = orderBumpCompare(BumpI, PredDef);
1796 setImmediate(*CmpImmOp, CmpImm);
1797 for (
unsigned i = 0, n = PredDef->
getNumOperands(); i < n; ++i) {
1837 typedef std::vector<MachineBasicBlock*> MBBVector;
1842 if (TII->AnalyzeBranch(*ExitingBlock, TB, FB, Tmp1,
false))
1845 for (MBBVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++
I) {
1847 bool NotAnalyzed = TII->AnalyzeBranch(*PB, TB, FB, Tmp1,
false);
1853 MF->
insert(Header, NewPH);
1862 I != E && I->isPHI(); ++
I) {
1871 unsigned NewPR = MRI->createVirtualRegister(RC);
1893 if (PredB != Latch) {
1911 I != E && I->isPHI(); ++
I) {
1915 if (MO.
getMBB() != Latch)
1929 for (MBBVector::iterator I = Preds.begin(), E = Preds.end(); I != E; ++
I) {
1933 bool NotAnalyzed = TII->AnalyzeBranch(*PB, TB, FB, Tmp2,
false);
1935 assert (!NotAnalyzed &&
"Should be analyzable!");
1936 if (TB != Header && (Tmp2.
empty() || FB != Header))
1937 TII->InsertBranch(*PB, NewPH,
nullptr, EmptyCond, DL);
1945 bool LatchNotAnalyzed = TII->AnalyzeBranch(*Latch, TB, FB, Tmp2,
false);
1946 (void)LatchNotAnalyzed;
1947 assert (!LatchNotAnalyzed &&
"Should be analyzable!");
1949 TII->InsertBranch(*Latch, Header,
nullptr, EmptyCond, DL);
1952 TII->InsertBranch(*NewPH, Header,
nullptr, EmptyCond, DL);
1963 MDT->changeImmediateDominator(Header, NewPH);
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isUInt< 8 >(uint64_t x)
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImp=false)
CreateMachineInstr - Allocate a new MachineInstr.
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()
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()
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)
isVirtualRegister - Return true if the specified register number is in the virtual register namespace...
bool isLoopExiting(const BlockT *BB) const
isLoopExiting - True if terminator in the block can branch to another block that is outside of the cu...
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
FunctionPass * createHexagonHardwareLoops()
Instructions::iterator instr_iterator
const std::vector< BlockT * > & getBlocks() const
getBlocks - Get a list of the basic blocks which make up this loop.
BlockT * getHeader() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
BlockT * getLoopLatch() const
getLoopLatch - 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
COPY - Target-independent register copy.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
ReplaceUsesOfBlockWith - Given a machine basic block that branched to 'Old', change the code and CFG ...
MachineBasicBlock * getTopBlock()
getTopBlock - Return the "top" block in the loop, which is the first block in the linear layout...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
static MachineOperand CreateReg(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A Use represents the edge between a Value definition and its users.
bool isCall() const
Return true if the instruction is a call.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isInt< 8 >(int64_t x)
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
addImm - Add a new immediate operand.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
PrintReg - Helper class for printing registers on a raw_ostream.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
addBasicBlockToLoop - This method is used by other analyses to update loop information.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Base class for the actual dominator tree node.
std::vector< MachineBasicBlock * >::iterator pred_iterator
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.
const BasicBlock * getBasicBlock() const
getBasicBlock - Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
static cl::opt< int > HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1))
initializer< Ty > init(const Ty &Val)
BlockT * getLoopPreheader() const
getLoopPreheader - 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)
get - Return a BlockAddress for the specified function and basic block.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
bool contains(const LoopT *L) const
contains - Return true if the specified loop is contained within in this loop.
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
BlockT * getExitingBlock() const
getExitingBlock - If getExitingBlocks would return exactly one block, return that block...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
REG_SEQUENCE - This variadic instruction is used to form a register that represents a consecutive seq...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
DomTreeNodeBase< NodeT > * getIDom() const
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...
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()
setHasAddressTaken - Set this block to reflect that it potentially is the target of an indirect branc...
bool isPowerOf2_64(uint64_t Value)
isPowerOf2_64 - This function returns true if the argument is a power of two 0 (64 bit edition...
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
hasAddressTaken - 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.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
void setSubReg(unsigned subReg)
unsigned getReg() const
getReg - Returns the register number.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const ARM::ArchExtKind Kind
This class implements an extremely fast bulk output stream that can only output to a stream...
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
addReg - Add a new virtual register operand...
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
void addSuccessor(MachineBasicBlock *succ, uint32_t weight=0)
addSuccessor - Add succ as a successor of this MachineBasicBlock.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned pred_size() const
static MachineBasicBlock * getExitingBlock(MachineLoop *L)
Return the latch block if it's one of the exiting blocks.