66#define DEBUG_TYPE "hwloops"
79 cl::desc(
"Add a preheader to a hardware loop if one doesn't exist"));
85 cl::desc(
"Allow speculation of preheader "
88STATISTIC(NumHWLoops,
"Number of loops converted to hardware loops");
127 using LoopFeederMap = std::map<Register, 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))
158 return (Kind)(
Cmp ^ (
EQ |
NE));
163 return (Cmp & (L | G) && !(Cmp & U));
166 static bool isUnsigned(Kind Cmp) {
187 Comparison::Kind getComparisonKind(
unsigned CondOpc,
190 int64_t IVBump)
const;
207 int64_t IVBump, Comparison::Kind Cmp)
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))
305 char HexagonHardwareLoops::ID = 0;
307 int HexagonHardwareLoops::Counter = 0;
315 enum CountValueType {
324 Values(
const Values&) =
default;
333 explicit CountValue(CountValueType t,
Register v,
unsigned u = 0) {
335 if (Kind == CV_Register) {
343 bool isReg()
const {
return Kind == CV_Register; }
344 bool isImm()
const {
return Kind == CV_Immediate; }
348 return Contents.R.Reg;
351 unsigned getSubReg()
const {
353 return Contents.R.Sub;
356 unsigned getImm()
const {
358 return Contents.ImmVal;
363 if (
isImm()) {
OS << Contents.ImmVal; }
370 "Hexagon Hardware Loops",
false,
false)
377 return new HexagonHardwareLoops();
381 LLVM_DEBUG(
dbgs() <<
"********* Hexagon Hardware Loops *********\n");
385 bool Changed =
false;
387 MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
389 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
395 if (L->isOutermost()) {
398 Changed |= convertToHardwareLoop(L, L0Used, L1Used);
404bool HexagonHardwareLoops::findInductionRegister(
MachineLoop *L,
413 if (!Header || !Preheader || !Latch || !ExitingBlock)
418 using RegisterBump = std::pair<Register, int64_t>;
424 using InductionMap = std::map<Register, RegisterBump>;
430 for (instr_iterator
I = Header->instr_begin(), E = Header->instr_end();
431 I != E &&
I->isPHI(); ++
I) {
437 for (
unsigned i = 1, n =
Phi->getNumOperands(); i < n; i += 2) {
438 if (
Phi->getOperand(i+1).getMBB() != Latch)
450 if (
MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
452 IndMap.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
465 unsigned PredPos, PredRegFlags;
474 int64_t CmpImm = 0, CmpMask = 0;
485 InductionMap::iterator IndMapEnd = IndMap.end();
486 InductionMap::iterator
F = IndMapEnd;
488 InductionMap::iterator F1 = IndMap.find(CmpReg1);
493 InductionMap::iterator F2 = IndMap.find(CmpReg2);
494 if (F2 != IndMapEnd) {
503 Reg =
F->second.first;
504 IVBump =
F->second.second;
505 IVOp =
MRI->getVRegDef(
F->first);
510HexagonHardwareLoops::Comparison::Kind
511HexagonHardwareLoops::getComparisonKind(
unsigned CondOpc,
514 int64_t IVBump)
const {
515 Comparison::Kind
Cmp = (Comparison::Kind)0;
517 case Hexagon::C2_cmpeq:
518 case Hexagon::C2_cmpeqi:
519 case Hexagon::C2_cmpeqp:
520 Cmp = Comparison::EQ;
522 case Hexagon::C4_cmpneq:
523 case Hexagon::C4_cmpneqi:
524 Cmp = Comparison::NE;
526 case Hexagon::C2_cmplt:
527 Cmp = Comparison::LTs;
529 case Hexagon::C2_cmpltu:
530 Cmp = Comparison::LTu;
532 case Hexagon::C4_cmplte:
533 case Hexagon::C4_cmpltei:
534 Cmp = Comparison::LEs;
536 case Hexagon::C4_cmplteu:
537 case Hexagon::C4_cmplteui:
538 Cmp = Comparison::LEu;
540 case Hexagon::C2_cmpgt:
541 case Hexagon::C2_cmpgti:
542 case Hexagon::C2_cmpgtp:
543 Cmp = Comparison::GTs;
545 case Hexagon::C2_cmpgtu:
546 case Hexagon::C2_cmpgtui:
547 case Hexagon::C2_cmpgtup:
548 Cmp = Comparison::GTu;
550 case Hexagon::C2_cmpgei:
551 Cmp = Comparison::GEs;
553 case Hexagon::C2_cmpgeui:
554 Cmp = Comparison::GEs;
557 return (Comparison::Kind)0;
569CountValue *HexagonHardwareLoops::getLoopTripCount(
MachineLoop *L,
574 "Loop must have more than one incoming edge!");
585 if (
L->contains(Backedge))
588 }
else if (!
L->contains(Backedge))
601 bool FoundIV = findInductionRegister(L, IVReg, IVBump, IVOp);
610 for (
unsigned i = 1, n = IV_Phi->
getNumOperands(); i < n; i += 2) {
612 if (
MBB == Preheader)
614 else if (
MBB == Latch)
630 assert (TB &&
"Exit block without a branch?");
631 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
638 TB = (LTB == Header) ? LTB : LFB;
640 FB = (LTB == Header) ? LTB: LFB;
642 assert ((!FB || TB == Header || FB == Header) &&
"Branches not to header?");
643 if (!TB || (FB && TB != Header && FB != Header))
652 unsigned PredPos, PredRegFlags;
659 int64_t
Mask = 0, ImmValue = 0;
675 Comparison::Kind
Cmp;
676 bool isSwapped =
false;
693 Cmp = getComparisonKind(CondOpc, InitialValue, EndValue, IVBump);
697 Cmp = Comparison::getNegatedComparison(Cmp);
699 Cmp = Comparison::getSwappedComparison(Cmp);
701 if (InitialValue->
isReg()) {
706 if (!checkForImmediate(*InitialValue, V))
711 if (EndValue->
isReg()) {
716 if (!checkForImmediate(*EndValue, V))
722 return computeCount(L, InitialValue, EndValue, IVReg, IVBump, Cmp);
734 Comparison::Kind Cmp)
const {
736 if (Cmp == Comparison::EQ)
741 if (Start->isReg()) {
743 if (StartValInstr && (StartValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
744 StartValInstr->
getOpcode() == Hexagon::A2_tfrpi))
749 if (EndValInstr && (EndValInstr->
getOpcode() == Hexagon::A2_tfrsi ||
750 EndValInstr->
getOpcode() == Hexagon::A2_tfrpi))
754 if (!Start->isReg() && !Start->isImm())
756 if (!
End->isReg() && !
End->isImm())
759 bool CmpLess =
Cmp & Comparison::L;
760 bool CmpGreater =
Cmp & Comparison::G;
761 bool CmpHasEqual =
Cmp & Comparison::EQ;
764 if (CmpLess && IVBump < 0)
768 if (CmpGreater && IVBump > 0)
773 LoopFeederMap LoopFeederPhi;
782 if (Start->isImm() &&
End->isImm()) {
784 int64_t StartV = Start->getImm();
785 int64_t EndV =
End->getImm();
786 int64_t Dist = EndV - StartV;
790 bool Exact = (Dist % IVBump) == 0;
792 if (Cmp == Comparison::NE) {
795 if ((Dist < 0) ^ (IVBump < 0))
802 Dist = Dist > 0 ? Dist+1 : Dist-1;
808 if ((CmpLess && Dist < 0) || (CmpGreater && Dist > 0))
812 int64_t Dist1 = (IVBump > 0) ? (Dist + (IVBump - 1)) / IVBump
813 : (-Dist + (-IVBump - 1)) / (-IVBump);
814 assert (Dist1 > 0 &&
"Fishy thing. Both operands have the same sign.");
818 if (Count > 0xFFFFFFFFULL)
821 return new CountValue(CountValue::CV_Immediate, Count);
834 assert (PH &&
"Should have a preheader by now");
837 if (InsertPos != PH->
end())
838 DL = InsertPos->getDebugLoc();
854 bool RegToImm = Start->isReg() &&
End->isImm();
855 bool RegToReg = Start->isReg() &&
End->isReg();
857 int64_t StartV = 0, EndV = 0;
859 StartV = Start->getImm();
861 EndV =
End->getImm();
876 else if (
End->isImm())
882 if (Cmp != Comparison::NE) {
884 StartV -= (IVBump-1);
885 else if (
End->isImm())
893 if (Start->isReg()) {
895 SR = Start->getSubReg();
898 SR =
End->getSubReg();
903 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
912 if (Start->isImm() && StartV == 0) {
913 DistR =
End->getReg();
914 DistSR =
End->getSubReg();
917 (RegToImm ?
TII->get(Hexagon::A2_subri) :
918 TII->get(Hexagon::A2_addi));
919 if (RegToReg || RegToImm) {
926 .
addReg(Start->getReg(), 0, Start->getSubReg());
929 .
addReg(Start->getReg(), 0, Start->getSubReg());
936 if (EndValInstr->
getOpcode() == Hexagon::A2_addi &&
980 unsigned Shift =
Log2_32(IVBump);
993 return new CountValue(CountValue::CV_Register, CountR, CountSR);
997bool HexagonHardwareLoops::isInvalidLoopOperation(
const MachineInstr *
MI,
998 bool IsInnerHWLoop)
const {
1001 if (
MI->getDesc().isCall())
1005 using namespace Hexagon;
1007 static const Register Regs01[] = { LC0, SA0, LC1, SA1 };
1008 static const Register Regs1[] = { LC1, SA1 };
1011 if (
MI->modifiesRegister(R,
TRI))
1019bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
1020 bool IsInnerHWLoop)
const {
1025 if (isInvalidLoopOperation(&
MI, IsInnerHWLoop)) {
1047 if (
MRI->use_nodbg_empty(Reg))
1055 use_nodbg_iterator
I =
MRI->use_nodbg_begin(Reg);
1056 use_nodbg_iterator
End =
MRI->use_nodbg_end();
1057 if (std::next(
I) !=
End || !
I->getParent()->isPHI())
1062 if (!OPO.isReg() || !OPO.isDef())
1066 use_nodbg_iterator nextJ;
1067 for (use_nodbg_iterator J =
MRI->use_nodbg_begin(OPReg);
1068 J !=
End; J = nextJ) {
1069 nextJ = std::next(J);
1089 if (isDead(
MI, DeadPhis)) {
1111 MI->eraseFromParent();
1112 for (
unsigned i = 0; i < DeadPhis.
size(); ++i)
1113 DeadPhis[i]->eraseFromParent();
1125bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1129 assert(
L->getHeader() &&
"Loop without a header?");
1131 bool Changed =
false;
1132 bool L0Used =
false;
1133 bool L1Used =
false;
1137 Changed |= convertToHardwareLoop(
I, RecL0used, RecL1used);
1138 L0Used |= RecL0used;
1139 L1Used |= RecL1used;
1143 if (Changed && L0Used && L1Used)
1153 unsigned IsInnerHWLoop = 1;
1156 LOOP_i = Hexagon::J2_loop1i;
1157 LOOP_r = Hexagon::J2_loop1r;
1158 ENDLOOP = Hexagon::ENDLOOP1;
1161 LOOP_i = Hexagon::J2_loop0i;
1162 LOOP_r = Hexagon::J2_loop0r;
1163 ENDLOOP = Hexagon::ENDLOOP0;
1177 if (containsInvalidInstruction(L, IsInnerHWLoop))
1186 if (LastI == LastMBB->
end())
1190 if (!fixupInductionVariable(L))
1197 Preheader = createPreheaderForLoop(L);
1206 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1211 if (TripCount->isReg()) {
1224 if (ExitingBlock !=
L->getLoopLatch()) {
1231 if (
L->contains(TB))
1233 else if (
L->contains(FB))
1239 LoopStart = TopBlock;
1244 if (InsertPos != Preheader->
end())
1245 DL = InsertPos->getDebugLoc();
1247 if (TripCount->isReg()) {
1249 Register CountReg =
MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1250 BuildMI(*Preheader, InsertPos,
DL,
TII->get(TargetOpcode::COPY), CountReg)
1251 .
addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1256 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1260 int64_t CountImm = TripCount->getImm();
1262 Register CountReg =
MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1263 BuildMI(*Preheader, InsertPos,
DL,
TII->get(Hexagon::A2_tfrsi), CountReg)
1276 DebugLoc LastIDL = LastI->getDebugLoc();
1282 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1283 LastI->getOpcode() == Hexagon::J2_jumpf) {
1286 LastI = LastMBB->
erase(LastI);
1287 if (!
L->contains(BranchTarget)) {
1288 if (LastI != LastMBB->
end())
1289 LastI = LastMBB->
erase(LastI);
1295 LastMBB->
erase(LastI);
1301 for (
unsigned i = 0; i < OldInsts.
size(); ++i)
1302 removeIfDead(OldInsts[i]);
1317bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1319 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1328 for (instr_iterator
I(BumpI), E = BB->
instr_end();
I != E; ++
I)
1334 bool FoundBump =
false;
1335 instr_iterator CmpIt = CmpI->
getIterator(), NextIt = std::next(CmpIt);
1336 for (instr_iterator
I = NextIt, E = BB->
instr_end();
I != E; ++
I) {
1338 for (
unsigned i = 0, n =
In->getNumOperands(); i < n; ++i) {
1341 if (MO.
getReg() == PredR)
1352 assert (FoundBump &&
"Cannot determine instruction order");
1364 LoopFeederMap &LoopFeederPhi)
const {
1365 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1372 LoopFeederPhi.insert(std::make_pair(MO->
getReg(), Def));
1381bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1383 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1384 assert(
Phi->isPHI() &&
"Expecting a Phi.");
1387 for (
int i = 1, n =
Phi->getNumOperands(); i < n; i += 2)
1388 if (isLoopFeeder(L,
MBB, Phi, &(
Phi->getOperand(i)), LoopFeederPhi))
1389 if (loopCountMayWrapOrUnderFlow(&(
Phi->getOperand(i)), EndVal,
1390 Phi->getParent(), L, LoopFeederPhi))
1409bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1412 LoopFeederMap &LoopFeederPhi)
const {
1414 if (!InitVal->
isReg())
1417 if (!EndVal->
isImm())
1423 if (checkForImmediate(*InitVal, Imm))
1424 return (EndVal->
getImm() == Imm);
1429 if (!
Reg.isVirtual())
1438 if (
Def->isPHI() && !phiMayWrapOrUnderflow(Def, EndVal,
Def->getParent(),
1441 if (
Def->isCopy() && !loopCountMayWrapOrUnderFlow(&(
Def->getOperand(1)),
1442 EndVal,
Def->getParent(),
1450 E =
MRI->use_instr_nodbg_end();
I != E; ++
I) {
1453 int64_t CmpMask = 0, CmpValue = 0;
1463 Comparison::Kind
Cmp =
1464 getComparisonKind(
MI->getOpcode(),
nullptr,
nullptr, 0);
1468 Cmp = Comparison::getNegatedComparison(Cmp);
1469 if (CmpReg2 != 0 && CmpReg2 == Reg)
1470 Cmp = Comparison::getSwappedComparison(Cmp);
1473 if (Comparison::isSigned(Cmp))
1479 if ((Cmp & Comparison::G) || Cmp == Comparison::NE)
1486 if (!
Def->isCopy() && !
Def->isPHI())
1492bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1493 int64_t &Val)
const {
1512 case TargetOpcode::COPY:
1513 case Hexagon::A2_tfrsi:
1514 case Hexagon::A2_tfrpi:
1515 case Hexagon::CONST32:
1516 case Hexagon::CONST64:
1520 if (!checkForImmediate(DI->
getOperand(1), TV))
1523 case Hexagon::A2_combineii:
1524 case Hexagon::A4_combineir:
1525 case Hexagon::A4_combineii:
1526 case Hexagon::A4_combineri:
1527 case Hexagon::A2_combinew: {
1531 if (!checkForImmediate(
S1, V1) || !checkForImmediate(S2, V2))
1536 case TargetOpcode::REG_SEQUENCE: {
1540 if (!checkForImmediate(
S1, V1) || !checkForImmediate(S3, V3))
1544 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1545 TV = V1 | (V3 << 32);
1546 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1547 TV = V3 | (V1 << 32);
1560 case Hexagon::isub_lo:
1561 Val = TV & 0xFFFFFFFFULL;
1563 case Hexagon::isub_hi:
1564 Val = (TV >> 32) & 0xFFFFFFFFULL;
1573void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1591bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1596 if (!(Header && Latch && ExitingBlock))
1601 using RegisterBump = std::pair<Register, int64_t>;
1602 using RegisterInduction = std::pair<Register, RegisterBump>;
1603 using RegisterInductionSet = std::set<RegisterInduction>;
1606 RegisterInductionSet IndRegs;
1613 for (instr_iterator
I = Header->instr_begin(), E = Header->instr_end();
1614 I != E &&
I->isPHI(); ++
I) {
1618 for (
unsigned i = 1, n =
Phi->getNumOperands(); i < n; i += 2) {
1619 if (
Phi->getOperand(i+1).getMBB() != Latch)
1631 if (
MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1633 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1639 if (IndRegs.empty())
1646 if (NotAnalyzed ||
Cond.empty())
1649 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1659 TB = (LTB == Header) ? LTB : LFB;
1661 FB = (LTB == Header) ? LTB : LFB;
1683 unsigned CSz =
Cond.size();
1684 if (CSz != 1 && CSz != 2)
1710 if (!isImmediate(MO)) {
1719 }
else if (MO.
isImm()) {
1726 if (CmpRegs.
empty())
1730 for (RegisterInductionSet::iterator
I = IndRegs.begin(), E = IndRegs.end();
1735 if (CmpRegs.
count(
I->first))
1741 const RegisterBump &RB =
I->second;
1742 if (CmpRegs.
count(RB.first)) {
1751 for (
unsigned i = 1, n = PredDef->
getNumOperands(); i < n; ++i) {
1755 <<
") = " << *(
MRI->getVRegDef(
I->first)));
1759 IndI =
MRI->getVRegDef(
I->first);
1761 }
else if (MO.
isReg()) {
1763 <<
") = " << *(
MRI->getVRegDef(MO.
getReg())));
1771 if (IndI && nonIndI &&
1772 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1775 bool Order = orderBumpCompare(IndI, PredDef);
1787 Comparison::Kind
Cmp =
1788 getComparisonKind(PredDef->
getOpcode(),
nullptr,
nullptr, 0);
1789 if (!Cmp || Comparison::isUnsigned(Cmp))
1795 int64_t CmpImm = getImmediate(*CmpImmOp);
1796 int64_t
V = RB.second;
1798 if (((V > 0) && (CmpImm >
INT64_MAX - V)) ||
1812 bool Order = orderBumpCompare(BumpI, PredDef);
1817 setImmediate(*CmpImmOp, CmpImm);
1849 if (!Latch || !ExitingBlock || Header->hasAddressTaken())
1856 using MBBVector = std::vector<MachineBasicBlock *>;
1858 MBBVector Preds(Header->pred_begin(), Header->pred_end());
1872 MF->
insert(Header->getIterator(), NewPH);
1874 if (Header->pred_size() > 2) {
1880 for (instr_iterator
I = Header->instr_begin(), E = Header->instr_end();
1881 I != E &&
I->isPHI(); ++
I) {
1912 if (PredB != Latch) {
1921 assert(Header->pred_size() == 2);
1928 for (instr_iterator
I = Header->instr_begin(), E = Header->instr_end();
1929 I != E &&
I->isPHI(); ++
I) {
1933 if (MO.
getMBB() != Latch)
1952 assert (!NotAnalyzed &&
"Should be analyzable!");
1953 if (TB != Header && (Tmp2.
empty() || FB != Header))
1955 PB->ReplaceUsesOfBlockWith(Header, NewPH);
1963 (void)LatchNotAnalyzed;
1964 assert (!LatchNotAnalyzed &&
"Should be analyzable!");
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool isSigned(unsigned int Opcode)
const HexagonInstrInfo * TII
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"))
static cl::opt< bool > SpecPreheader("hwloop-spec-preheader", cl::Hidden, cl::desc("Allow speculation of preheader " "instructions"))
static cl::opt< std::string > PHFn("hexagon-hwloop-phfn", cl::Hidden, cl::init(""))
static cl::opt< int > HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1))
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Base class for the actual dominator tree node.
DomTreeNodeBase * getIDom() const
FunctionPass class - This class is used to implement most global optimizations.
bool doesNotReturn(const MachineInstr &CallMI) const
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....
bool getPredReg(ArrayRef< MachineOperand > Cond, Register &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const
bool isValidOffset(unsigned Opcode, int Offset, const TargetRegisterInfo *TRI, bool Extend=true) const
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
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.
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
bool isExtendable(const MachineInstr &MI) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
Represents a single loop in the control flow graph.
Describe properties that are true of each instruction in the target description file.
bool isAdd() const
Return true if the instruction is an add instruction.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
Instructions::iterator instr_iterator
pred_iterator pred_begin()
instr_iterator instr_end()
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
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 '...
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineDomTreeNode * addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB)
addNewBlock - Add a new node to the dominator tree information.
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
void changeImmediateDominator(MachineBasicBlock *N, MachineBasicBlock *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
iterator_range< mop_iterator > operands()
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setMBB(MachineBasicBlock *MBB)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register 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)
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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,...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A Use represents the edge between a Value definition and its users.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ PD
PD - Prefix code for packed double precision vector floating point operations performed in the SSE re...
initializer< Ty > init(const Ty &Val)
NodeAddr< PhiNode * > Phi
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
FunctionPass * createHexagonHardwareLoops()
void initializeHexagonHardwareLoopsPass(PassRegistry &)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...