66 #define DEBUG_TYPE "hwloops" 79 cl::desc(
"Add a preheader to a hardware loop if one doesn't exist"));
88 STATISTIC(NumHWLoops,
"Number of loops converted to hardware loops");
118 StringRef getPassName()
const override {
return "Hexagon Hardware Loops"; }
127 using LoopFeederMap = std::map<unsigned, MachineInstr *>;
147 static Kind getSwappedComparison(
Kind Cmp) {
148 assert ((!((Cmp & L) && (Cmp &
G))) &&
"Malformed comparison operator");
149 if ((Cmp & L) || (Cmp &
G))
150 return (
Kind)(Cmp ^ (L|
G));
154 static Kind getNegatedComparison(
Kind Cmp) {
155 if ((Cmp & L) || (Cmp & G))
156 return (
Kind)((Cmp ^ (L |
G)) ^
EQ);
157 if ((Cmp &
NE) || (Cmp &
EQ))
162 static bool isSigned(
Kind Cmp) {
163 return (Cmp & (L | G) && !(Cmp & U));
166 static bool isUnsigned(
Kind Cmp) {
190 int64_t IVBump)
const;
212 bool IsInnerHWLoop)
const;
216 bool containsInvalidInstruction(
MachineLoop *L,
bool IsInnerHWLoop)
const;
220 bool convertToHardwareLoop(
MachineLoop *L,
bool &L0used,
bool &L1used);
240 LoopFeederMap &LoopFeederPhi)
const;
246 LoopFeederMap &LoopFeederPhi)
const;
253 LoopFeederMap &LoopFeederPhi)
const;
258 bool checkForImmediate(
const MachineOperand &MO, int64_t &Val)
const;
263 return checkForImmediate(MO, V);
269 if (!checkForImmediate(MO, V))
307 int HexagonHardwareLoops::Counter = 0;
315 enum CountValueType {
331 explicit CountValue(CountValueType t,
unsigned v,
unsigned u = 0) {
333 if (Kind == CV_Register) {
341 bool isReg()
const {
return Kind == CV_Register; }
342 bool isImm()
const {
return Kind == CV_Immediate; }
346 return Contents.R.Reg;
349 unsigned getSubReg()
const {
351 return Contents.R.Sub;
354 unsigned getImm()
const {
355 assert(isImm() &&
"Wrong CountValue accessor");
356 return Contents.ImmVal;
360 if (
isReg()) { OS <<
printReg(Contents.R.Reg, TRI, Contents.R.Sub); }
361 if (isImm()) { OS << Contents.ImmVal; }
368 "Hexagon Hardware Loops",
false,
false)
375 return new HexagonHardwareLoops();
379 LLVM_DEBUG(
dbgs() <<
"********* Hexagon Hardware Loops *********\n");
383 bool Changed =
false;
385 MLI = &getAnalysis<MachineLoopInfo>();
387 MDT = &getAnalysis<MachineDominatorTree>();
389 TII = HST.getInstrInfo();
390 TRI = HST.getRegisterInfo();
393 if (!L->getParentLoop()) {
396 Changed |= convertToHardwareLoop(L, L0Used, L1Used);
402 bool HexagonHardwareLoops::findInductionRegister(
MachineLoop *L,
411 if (!Header || !Preheader || !Latch || !ExitingBlock)
416 using RegisterBump = std::pair<unsigned, int64_t>;
422 using InductionMap = std::map<unsigned, RegisterBump>;
429 I !=
E &&
I->isPHI(); ++
I) {
448 if (MRI->
getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
450 IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
458 bool NotAnalyzed = TII->
analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
462 unsigned PredR, PredPos, PredRegFlags;
463 if (!TII->
getPredReg(Cond, PredR, PredPos, PredRegFlags))
470 unsigned CmpReg1 = 0, CmpReg2 = 0;
471 int CmpImm = 0, CmpMask = 0;
482 InductionMap::iterator IndMapEnd = IndMap.end();
483 InductionMap::iterator
F = IndMapEnd;
485 InductionMap::iterator F1 = IndMap.find(CmpReg1);
490 InductionMap::iterator F2 = IndMap.find(CmpReg2);
491 if (F2 != IndMapEnd) {
500 Reg = F->second.first;
501 IVBump = F->second.second;
507 HexagonHardwareLoops::Comparison::Kind
508 HexagonHardwareLoops::getComparisonKind(
unsigned CondOpc,
511 int64_t IVBump)
const {
514 case Hexagon::C2_cmpeq:
515 case Hexagon::C2_cmpeqi:
516 case Hexagon::C2_cmpeqp:
519 case Hexagon::C4_cmpneq:
520 case Hexagon::C4_cmpneqi:
523 case Hexagon::C2_cmplt:
524 Cmp = Comparison::LTs;
526 case Hexagon::C2_cmpltu:
527 Cmp = Comparison::LTu;
529 case Hexagon::C4_cmplte:
530 case Hexagon::C4_cmpltei:
531 Cmp = Comparison::LEs;
533 case Hexagon::C4_cmplteu:
534 case Hexagon::C4_cmplteui:
535 Cmp = Comparison::LEu;
537 case Hexagon::C2_cmpgt:
538 case Hexagon::C2_cmpgti:
539 case Hexagon::C2_cmpgtp:
540 Cmp = Comparison::GTs;
542 case Hexagon::C2_cmpgtu:
543 case Hexagon::C2_cmpgtui:
544 case Hexagon::C2_cmpgtup:
545 Cmp = Comparison::GTu;
547 case Hexagon::C2_cmpgei:
548 Cmp = Comparison::GEs;
550 case Hexagon::C2_cmpgeui:
551 Cmp = Comparison::GEs;
566 CountValue *HexagonHardwareLoops::getLoopTripCount(
MachineLoop *L,
571 "Loop must have more than one incoming edge!");
598 bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
607 for (
unsigned i = 1, n = IV_Phi->
getNumOperands(); i < n; i += 2) {
609 if (MBB == Preheader)
611 else if (MBB == Latch)
619 bool NotAnalyzed = TII->
analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
627 assert (TB &&
"Exit block without a branch?");
628 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
631 bool NotAnalyzed = TII->
analyzeBranch(*Latch, LTB, LFB, LCond,
false);
635 TB = (LTB == Header) ? LTB : LFB;
637 FB = (LTB == Header) ? LTB: LFB;
639 assert ((!FB || TB == Header || FB == Header) &&
"Branches not to header?");
640 if (!TB || (FB && TB != Header && FB != Header))
648 unsigned PredReg, PredPos, PredRegFlags;
649 if (!TII->
getPredReg(Cond, PredReg, PredPos, PredRegFlags))
654 unsigned CmpReg1 = 0, CmpReg2 = 0;
655 int Mask = 0, ImmValue = 0;
672 bool isSwapped =
false;
689 Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
693 Cmp = Comparison::getNegatedComparison(Cmp);
695 Cmp = Comparison::getSwappedComparison(Cmp);
697 if (InitialValue->
isReg()) {
698 unsigned R = InitialValue->
getReg();
702 if (!checkForImmediate(*InitialValue, V))
707 if (EndValue->
isReg()) {
708 unsigned R = EndValue->
getReg();
712 if (!checkForImmediate(*EndValue, V))
718 return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
737 if (Start->
isReg()) {
739 if (StartValInstr && (StartValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
740 StartValInstr->
getOpcode() == Hexagon::A2_tfrpi))
745 if (EndValInstr && (EndValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
746 EndValInstr->
getOpcode() == Hexagon::A2_tfrpi))
755 bool CmpLess = Cmp & Comparison::L;
760 if (CmpLess && IVBump < 0)
764 if (CmpGreater && IVBump > 0)
769 LoopFeederMap LoopFeederPhi;
780 int64_t StartV = Start->
getImm();
781 int64_t EndV = End->
getImm();
782 int64_t Dist = EndV - StartV;
786 bool Exact = (Dist % IVBump) == 0;
791 if ((Dist < 0) ^ (IVBump < 0))
798 Dist = Dist > 0 ? Dist+1 : Dist-1;
804 if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
808 int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
809 : (-Dist + (-IVBump - 1)) / (-IVBump);
810 assert (Dist1 > 0 &&
"Fishy thing. Both operands have the same sign.");
812 uint64_t Count = Dist1;
814 if (Count > 0xFFFFFFFFULL)
817 return new CountValue(CountValue::CV_Immediate, Count);
830 assert (PH &&
"Should have a preheader by now");
833 if (InsertPos != PH->
end())
834 DL = InsertPos->getDebugLoc();
850 bool RegToImm = Start->
isReg() && End->
isImm();
851 bool RegToReg = Start->
isReg() && End->
isReg();
853 int64_t StartV = 0, EndV = 0;
872 else if (End->
isImm())
880 StartV -= (IVBump-1);
881 else if (End->
isImm())
887 unsigned R = 0, SR = 0;
888 if (Start->
isReg()) {
898 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
903 unsigned DistR, DistSR;
906 if (Start->
isImm() && StartV == 0) {
910 const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
911 (RegToImm ? TII->get(Hexagon::A2_subri) :
912 TII->get(Hexagon::A2_addi));
913 if (RegToReg || RegToImm) {
916 BuildMI(*PH, InsertPos, DL, SubD, SubR);
930 if (EndValInstr->
getOpcode() == Hexagon::A2_addi &&
937 BuildMI(*PH, InsertPos, DL, SubD, SubR);
947 unsigned AdjR, AdjSR;
955 MCInstrDesc const &AddD = TII->get(Hexagon::A2_addi);
956 BuildMI(*PH, InsertPos, DL, AddD, AddR)
965 unsigned CountR, CountSR;
972 unsigned Shift =
Log2_32(IVBump);
976 const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
977 BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
985 return new CountValue(CountValue::CV_Register, CountR, CountSR);
989 bool HexagonHardwareLoops::isInvalidLoopOperation(
const MachineInstr *
MI,
990 bool IsInnerHWLoop)
const {
997 using namespace Hexagon;
999 static const unsigned Regs01[] = { LC0, SA0, LC1, SA1 };
1000 static const unsigned Regs1[] = { LC1, SA1 };
1003 for (
unsigned R : CheckRegs)
1012 bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
1013 bool IsInnerHWLoop)
const {
1018 MII = MBB->begin(),
E = MBB->end(); MII !=
E; ++MII) {
1020 if (isInvalidLoopOperation(MI, IsInnerHWLoop)) {
1034 bool HexagonHardwareLoops::isDead(
const MachineInstr *MI,
1042 unsigned Reg = MO.
getReg();
1053 if (std::next(I) != End || !I->getParent()->isPHI())
1057 for (
unsigned j = 0, f = OnePhi->
getNumOperands(); j != f; ++j) {
1062 unsigned OPReg = OPO.
getReg();
1063 use_nodbg_iterator nextJ;
1065 J != End; J = nextJ) {
1066 nextJ = std::next(J);
1082 void HexagonHardwareLoops::removeIfDead(
MachineInstr *MI) {
1086 if (isDead(MI, DeadPhis)) {
1096 unsigned Reg = MO.
getReg();
1100 nextI = std::next(
I);
1111 for (
unsigned i = 0; i < DeadPhis.
size(); ++i)
1112 DeadPhis[i]->eraseFromParent();
1124 bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1130 bool Changed =
false;
1131 bool L0Used =
false;
1132 bool L1Used =
false;
1136 Changed |= convertToHardwareLoop(*
I, RecL0used, RecL1used);
1137 L0Used |= RecL0used;
1138 L1Used |= RecL1used;
1142 if (Changed && L0Used && L1Used)
1152 unsigned IsInnerHWLoop = 1;
1155 LOOP_i = Hexagon::J2_loop1i;
1156 LOOP_r = Hexagon::J2_loop1r;
1157 ENDLOOP = Hexagon::ENDLOOP1;
1160 LOOP_i = Hexagon::J2_loop0i;
1161 LOOP_r = Hexagon::J2_loop0r;
1162 ENDLOOP = Hexagon::ENDLOOP0;
1176 if (containsInvalidInstruction(L, IsInnerHWLoop))
1185 if (LastI == LastMBB->
end())
1189 if (!fixupInductionVariable(L))
1196 Preheader = createPreheaderForLoop(L);
1205 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1210 if (TripCount->isReg()) {
1238 LoopStart = TopBlock;
1243 if (InsertPos != Preheader->
end())
1244 DL = InsertPos->getDebugLoc();
1246 if (TripCount->isReg()) {
1249 BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg)
1250 .addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1252 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r)).addMBB(LoopStart)
1255 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1259 int64_t CountImm = TripCount->getImm();
1262 BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
1264 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_r))
1265 .addMBB(LoopStart).
addReg(CountReg);
1267 BuildMI(*Preheader, InsertPos, DL, TII->get(LOOP_i))
1268 .addMBB(LoopStart).
addImm(CountImm);
1280 DebugLoc LastIDL = LastI->getDebugLoc();
1281 BuildMI(*LastMBB, LastI, LastIDL, TII->get(ENDLOOP)).addMBB(LoopStart);
1286 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1287 LastI->getOpcode() == Hexagon::J2_jumpf) {
1290 LastI = LastMBB->
erase(LastI);
1292 if (LastI != LastMBB->
end())
1293 LastI = LastMBB->
erase(LastI);
1295 TII->
insertBranch(*LastMBB, BranchTarget,
nullptr, Cond, LastIDL);
1299 LastMBB->
erase(LastI);
1305 for (
unsigned i = 0; i < OldInsts.
size(); ++i)
1306 removeIfDead(OldInsts[i]);
1321 bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1323 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1338 bool FoundBump =
false;
1339 instr_iterator CmpIt = CmpI->
getIterator(), NextIt = std::next(CmpIt);
1340 for (instr_iterator
I = NextIt,
E = BB->
instr_end();
I !=
E; ++
I) {
1345 if (MO.
getReg() == PredR)
1356 assert (FoundBump &&
"Cannot determine instruction order");
1368 LoopFeederMap &LoopFeederPhi)
const {
1369 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1378 LoopFeederPhi.insert(std::make_pair(MO->
getReg(),
Def));
1387 bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1389 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1394 if (isLoopFeeder(L, MBB, Phi, &(Phi->
getOperand(i)), LoopFeederPhi))
1395 if (loopCountMayWrapOrUnderFlow(&(Phi->
getOperand(i)), EndVal,
1415 bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1418 LoopFeederMap &LoopFeederPhi)
const {
1420 if (!InitVal->
isReg())
1423 if (!EndVal->
isImm())
1429 if (checkForImmediate(*InitVal, Imm))
1430 return (EndVal->
getImm() == Imm);
1432 unsigned Reg = InitVal->
getReg();
1444 if (Def->
isPHI() && !phiMayWrapOrUnderflow(Def, EndVal, Def->
getParent(),
1458 unsigned CmpReg1 = 0, CmpReg2 = 0;
1459 int CmpMask = 0, CmpValue = 0;
1461 if (!TII->
analyzeCompare(*MI, CmpReg1, CmpReg2, CmpMask, CmpValue))
1470 getComparisonKind(MI->
getOpcode(),
nullptr,
nullptr, 0);
1474 Cmp = Comparison::getNegatedComparison(Cmp);
1475 if (CmpReg2 != 0 && CmpReg2 == Reg)
1476 Cmp = Comparison::getSwappedComparison(Cmp);
1479 if (Comparison::isSigned(Cmp))
1498 bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1499 int64_t &Val)
const {
1512 unsigned R = MO.
getReg();
1518 case TargetOpcode::COPY:
1519 case Hexagon::A2_tfrsi:
1520 case Hexagon::A2_tfrpi:
1522 case Hexagon::CONST64:
1526 if (!checkForImmediate(DI->
getOperand(1), TV))
1529 case Hexagon::A2_combineii:
1530 case Hexagon::A4_combineir:
1531 case Hexagon::A4_combineii:
1532 case Hexagon::A4_combineri:
1533 case Hexagon::A2_combinew: {
1537 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1539 TV = V2 | (
static_cast<uint64_t
>(V1) << 32);
1542 case TargetOpcode::REG_SEQUENCE: {
1546 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1550 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1551 TV = V1 | (V3 << 32);
1552 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1553 TV = V3 | (V1 << 32);
1566 case Hexagon::isub_lo:
1567 Val = TV & 0xFFFFFFFFULL;
1569 case Hexagon::isub_hi:
1570 Val = (TV >> 32) & 0xFFFFFFFFULL;
1579 void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1586 unsigned R = MO.
getReg();
1599 if (CmpOpc == Hexagon::A4_cmpbeqi)
1601 if (CmpOpc == Hexagon::A4_cmpbgti)
1607 bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1612 if (!(Header && Latch && ExitingBlock))
1617 using RegisterBump = std::pair<unsigned, int64_t>;
1618 using RegisterInduction = std::pair<unsigned, RegisterBump>;
1619 using RegisterInductionSet = std::set<RegisterInduction>;
1622 RegisterInductionSet IndRegs;
1630 I !=
E &&
I->isPHI(); ++
I) {
1647 if (MRI->
getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1649 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1655 if (IndRegs.empty())
1661 bool NotAnalyzed = TII->
analyzeBranch(*ExitingBlock, TB, FB, Cond,
false);
1662 if (NotAnalyzed || Cond.
empty())
1665 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1668 bool NotAnalyzed = TII->
analyzeBranch(*Latch, LTB, LFB, LCond,
false);
1675 TB = (LTB == Header) ? LTB : LFB;
1677 FB = (LTB == Header) ? LTB : LFB;
1699 unsigned CSz = Cond.
size();
1700 if (CSz != 1 && CSz != 2)
1703 if (!Cond[CSz-1].
isReg())
1706 unsigned P = Cond[CSz-1].getReg();
1719 for (
unsigned i = 0, n = PredDef->
getNumOperands(); i < n; ++i) {
1727 if (!isImmediate(MO)) {
1736 }
else if (MO.
isImm()) {
1743 if (CmpRegs.
empty())
1747 for (RegisterInductionSet::iterator
I = IndRegs.begin(),
E = IndRegs.end();
1752 if (CmpRegs.
count(
I->first))
1758 const RegisterBump &RB =
I->second;
1759 if (CmpRegs.
count(RB.first)) {
1768 for (
unsigned i = 1, n = PredDef->
getNumOperands(); i < n; ++i) {
1778 }
else if (MO.
isReg()) {
1788 if (IndI && nonIndI &&
1789 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1792 bool Order = orderBumpCompare(IndI, PredDef);
1805 getComparisonKind(PredDef->
getOpcode(),
nullptr,
nullptr, 0);
1806 if (!Cmp || Comparison::isUnsigned(Cmp))
1812 int64_t CmpImm = getImmediate(*CmpImmOp);
1813 int64_t V = RB.second;
1815 if (((V > 0) && (CmpImm >
INT64_MAX - V)) ||
1822 if (CmpImmOp->
isImm())
1829 bool Order = orderBumpCompare(BumpI, PredDef);
1834 setImmediate(*CmpImmOp, CmpImm);
1835 for (
unsigned i = 0, n = PredDef->
getNumOperands(); i < n; ++i) {
1874 using MBBVector = std::vector<MachineBasicBlock *>;
1885 bool NotAnalyzed = TII->
analyzeBranch(*PB, TB, FB, Tmp1,
false);
1900 I !=
E &&
I->isPHI(); ++
I) {
1931 if (PredB != Latch) {
1948 I !=
E &&
I->isPHI(); ++
I) {
1952 if (MO.
getMBB() != Latch)
1970 bool NotAnalyzed = TII->
analyzeBranch(*PB, TB, FB, Tmp2,
false);
1972 assert (!NotAnalyzed &&
"Should be analyzable!");
1973 if (TB != Header && (Tmp2.
empty() || FB != Header))
1982 bool LatchNotAnalyzed = TII->
analyzeBranch(*Latch, TB, FB, Tmp2,
false);
1983 (void)LatchNotAnalyzed;
1984 assert (!LatchNotAnalyzed &&
"Should be analyzable!");
1986 TII->
insertBranch(*Latch, Header,
nullptr, EmptyCond, DL);
1989 TII->
insertBranch(*NewPH, Header,
nullptr, EmptyCond, DL);
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
instr_iterator instr_begin()
bool use_nodbg_empty(unsigned RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register...
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
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"))
void push_back(const T &Elt)
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.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
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.
unsigned getSubReg() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
constexpr bool isInt< 8 >(int64_t x)
static cl::opt< std::string > PHFn("hexagon-hwloop-phfn", cl::Hidden, cl::init(""))
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
FunctionPass * createHexagonHardwareLoops()
use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, const DebugLoc &DL, bool NoImp=false)
CreateMachineInstr - Allocate a new MachineInstr.
static use_nodbg_iterator use_nodbg_end()
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 analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e...
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
static use_iterator use_end()
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.
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
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
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.
A Use represents the edge between a Value definition and its users.
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
BlockT * getHeader() const
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
defusechain_iterator - This class provides iterator support for machine operands in the function that...
std::vector< MachineLoop *>::const_iterator iterator
bool doesNotReturn(const MachineInstr &CallMI) const
MachineBasicBlock * findLoopControlBlock()
Find the block that contains the loop control variable and the loop test.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
defusechain_iterator< true, false, true, true, false, false > use_nodbg_iterator
use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the specified register...
Base class for the actual dominator tree node.
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.
bool getPredReg(ArrayRef< MachineOperand > Cond, unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
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)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr bool isUInt< 8 >(uint64_t x)
unsigned const MachineRegisterInfo * MRI
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.
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
MachineInstrBuilder & UseMI
DomTreeNodeBase * getIDom() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
std::vector< MachineBasicBlock * >::iterator pred_iterator
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
bool isAdd() const
Return true if the instruction is an add instruction.
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.
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...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
unsigned pred_size() const
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.
unsigned Log2_32(uint32_t Value)
Return 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)
typename SuperClass::iterator iterator
void setHasAddressTaken()
Set this block to reflect that it potentially is the target of an indirect branch.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
LoopT * getParentLoop() const
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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.
use_iterator use_begin(unsigned RegNo) const
LLVM_NODISCARD bool empty() const
Represents a single loop in the control flow graph.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
bool isValidOffset(unsigned Opcode, int Offset, const TargetRegisterInfo *TRI, bool Extend=true) const
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)
bool isCall() const
Return true if the instruction is a call.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
void changeImmediateDominator(MachineBasicBlock *N, MachineBasicBlock *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * findLoopPreheader(MachineLoop *L, bool SpeculativePreheader=false) const
Find the block that either is the loop preheader, or could speculatively be used as the preheader...
Instructions::iterator instr_iterator
static use_instr_nodbg_iterator use_instr_nodbg_end()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const
INITIALIZE_PASS_BEGIN(HexagonHardwareLoops, "hwloops", "Hexagon Hardware Loops", false, false) INITIALIZE_PASS_END(HexagonHardwareLoops
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...
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const MachineOperand & getOperand(unsigned i) const
MachineDomTreeNode * addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB)
addNewBlock - Add a new node to the dominator tree information.
static cl::opt< bool > SpecPreheader("hwloop-spec-preheader", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Allow speculation of preheader " "instructions"))
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
block_iterator block_begin() const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LoopInfoBase< MachineBasicBlock, MachineLoop > & getBase()
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.