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<MachineLoopInfo>();
389 MDT = &getAnalysis<MachineDominatorTree>();
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) {
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!");
584 if (
L->contains(Incoming)) {
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 };
1009 auto CheckRegs = IsInnerHWLoop ?
ArrayRef(Regs01, std::size(Regs01))
1012 if (
MI->modifiesRegister(R,
TRI))
1020bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
1021 bool IsInnerHWLoop)
const {
1026 if (isInvalidLoopOperation(&
MI, IsInnerHWLoop)) {
1048 if (
MRI->use_nodbg_empty(Reg))
1056 use_nodbg_iterator
I =
MRI->use_nodbg_begin(Reg);
1057 use_nodbg_iterator
End =
MRI->use_nodbg_end();
1058 if (std::next(
I) !=
End || !
I->getParent()->isPHI())
1063 if (!OPO.isReg() || !OPO.isDef())
1067 use_nodbg_iterator nextJ;
1068 for (use_nodbg_iterator J =
MRI->use_nodbg_begin(OPReg);
1069 J !=
End; J = nextJ) {
1070 nextJ = std::next(J);
1090 if (isDead(
MI, DeadPhis)) {
1112 MI->eraseFromParent();
1113 for (
unsigned i = 0; i < DeadPhis.
size(); ++i)
1114 DeadPhis[i]->eraseFromParent();
1126bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1130 assert(
L->getHeader() &&
"Loop without a header?");
1132 bool Changed =
false;
1133 bool L0Used =
false;
1134 bool L1Used =
false;
1138 Changed |= convertToHardwareLoop(
I, RecL0used, RecL1used);
1139 L0Used |= RecL0used;
1140 L1Used |= RecL1used;
1144 if (Changed && L0Used && L1Used)
1154 unsigned IsInnerHWLoop = 1;
1157 LOOP_i = Hexagon::J2_loop1i;
1158 LOOP_r = Hexagon::J2_loop1r;
1159 ENDLOOP = Hexagon::ENDLOOP1;
1162 LOOP_i = Hexagon::J2_loop0i;
1163 LOOP_r = Hexagon::J2_loop0r;
1164 ENDLOOP = Hexagon::ENDLOOP0;
1178 if (containsInvalidInstruction(L, IsInnerHWLoop))
1187 if (LastI == LastMBB->
end())
1191 if (!fixupInductionVariable(L))
1198 Preheader = createPreheaderForLoop(L);
1207 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1212 if (TripCount->isReg()) {
1225 if (ExitingBlock !=
L->getLoopLatch()) {
1232 if (
L->contains(TB))
1234 else if (
L->contains(FB))
1240 LoopStart = TopBlock;
1245 if (InsertPos != Preheader->
end())
1246 DL = InsertPos->getDebugLoc();
1248 if (TripCount->isReg()) {
1250 Register CountReg =
MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1251 BuildMI(*Preheader, InsertPos,
DL,
TII->get(TargetOpcode::COPY), CountReg)
1252 .
addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1257 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1261 int64_t CountImm = TripCount->getImm();
1263 Register CountReg =
MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
1264 BuildMI(*Preheader, InsertPos,
DL,
TII->get(Hexagon::A2_tfrsi), CountReg)
1277 DebugLoc LastIDL = LastI->getDebugLoc();
1283 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1284 LastI->getOpcode() == Hexagon::J2_jumpf) {
1287 LastI = LastMBB->
erase(LastI);
1288 if (!
L->contains(BranchTarget)) {
1289 if (LastI != LastMBB->
end())
1290 LastI = LastMBB->
erase(LastI);
1296 LastMBB->
erase(LastI);
1302 for (
unsigned i = 0; i < OldInsts.
size(); ++i)
1303 removeIfDead(OldInsts[i]);
1318bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1320 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1335 bool FoundBump =
false;
1336 instr_iterator CmpIt = CmpI->
getIterator(), NextIt = std::next(CmpIt);
1337 for (instr_iterator
I = NextIt,
E = BB->
instr_end();
I !=
E; ++
I) {
1339 for (
unsigned i = 0, n =
In->getNumOperands(); i < n; ++i) {
1342 if (MO.
getReg() == PredR)
1353 assert (FoundBump &&
"Cannot determine instruction order");
1365 LoopFeederMap &LoopFeederPhi)
const {
1366 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1373 LoopFeederPhi.insert(std::make_pair(MO->
getReg(), Def));
1382bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1384 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1389 if (isLoopFeeder(L,
MBB, Phi, &(Phi->
getOperand(i)), LoopFeederPhi))
1390 if (loopCountMayWrapOrUnderFlow(&(Phi->
getOperand(i)), EndVal,
1410bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1413 LoopFeederMap &LoopFeederPhi)
const {
1415 if (!InitVal->
isReg())
1418 if (!EndVal->
isImm())
1424 if (checkForImmediate(*InitVal, Imm))
1425 return (EndVal->
getImm() == Imm);
1430 if (!
Reg.isVirtual())
1439 if (
Def->isPHI() && !phiMayWrapOrUnderflow(Def, EndVal,
Def->getParent(),
1442 if (
Def->isCopy() && !loopCountMayWrapOrUnderFlow(&(
Def->getOperand(1)),
1443 EndVal,
Def->getParent(),
1451 E =
MRI->use_instr_nodbg_end();
I !=
E; ++
I) {
1454 int64_t CmpMask = 0, CmpValue = 0;
1464 Comparison::Kind
Cmp =
1465 getComparisonKind(
MI->getOpcode(),
nullptr,
nullptr, 0);
1469 Cmp = Comparison::getNegatedComparison(Cmp);
1470 if (CmpReg2 != 0 && CmpReg2 == Reg)
1471 Cmp = Comparison::getSwappedComparison(Cmp);
1474 if (Comparison::isSigned(Cmp))
1480 if ((Cmp & Comparison::G) || Cmp == Comparison::NE)
1487 if (!
Def->isCopy() && !
Def->isPHI())
1493bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1494 int64_t &Val)
const {
1513 case TargetOpcode::COPY:
1514 case Hexagon::A2_tfrsi:
1515 case Hexagon::A2_tfrpi:
1516 case Hexagon::CONST32:
1517 case Hexagon::CONST64:
1521 if (!checkForImmediate(DI->
getOperand(1), TV))
1524 case Hexagon::A2_combineii:
1525 case Hexagon::A4_combineir:
1526 case Hexagon::A4_combineii:
1527 case Hexagon::A4_combineri:
1528 case Hexagon::A2_combinew: {
1532 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2, V2))
1537 case TargetOpcode::REG_SEQUENCE: {
1541 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1545 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1546 TV = V1 | (V3 << 32);
1547 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1548 TV = V3 | (V1 << 32);
1561 case Hexagon::isub_lo:
1562 Val = TV & 0xFFFFFFFFULL;
1564 case Hexagon::isub_hi:
1565 Val = (TV >> 32) & 0xFFFFFFFFULL;
1574void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1592bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1597 if (!(Header && Latch && ExitingBlock))
1602 using RegisterBump = std::pair<Register, int64_t>;
1603 using RegisterInduction = std::pair<Register, RegisterBump>;
1604 using RegisterInductionSet = std::set<RegisterInduction>;
1607 RegisterInductionSet IndRegs;
1614 for (instr_iterator
I = Header->instr_begin(),
E = Header->instr_end();
1615 I !=
E &&
I->isPHI(); ++
I) {
1632 if (
MRI->getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1634 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1640 if (IndRegs.empty())
1647 if (NotAnalyzed ||
Cond.empty())
1650 if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) {
1660 TB = (LTB == Header) ? LTB : LFB;
1662 FB = (LTB == Header) ? LTB : LFB;
1684 unsigned CSz =
Cond.size();
1685 if (CSz != 1 && CSz != 2)
1711 if (!isImmediate(MO)) {
1720 }
else if (MO.
isImm()) {
1727 if (CmpRegs.
empty())
1731 for (RegisterInductionSet::iterator
I = IndRegs.begin(),
E = IndRegs.end();
1736 if (CmpRegs.
count(
I->first))
1742 const RegisterBump &RB =
I->second;
1743 if (CmpRegs.
count(RB.first)) {
1752 for (
unsigned i = 1, n = PredDef->
getNumOperands(); i < n; ++i) {
1756 <<
") = " << *(
MRI->getVRegDef(
I->first)));
1760 IndI =
MRI->getVRegDef(
I->first);
1762 }
else if (MO.
isReg()) {
1764 <<
") = " << *(
MRI->getVRegDef(MO.
getReg())));
1772 if (IndI && nonIndI &&
1773 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1776 bool Order = orderBumpCompare(IndI, PredDef);
1788 Comparison::Kind
Cmp =
1789 getComparisonKind(PredDef->
getOpcode(),
nullptr,
nullptr, 0);
1790 if (!Cmp || Comparison::isUnsigned(Cmp))
1796 int64_t CmpImm = getImmediate(*CmpImmOp);
1797 int64_t
V = RB.second;
1799 if (((V > 0) && (CmpImm >
INT64_MAX - V)) ||
1813 bool Order = orderBumpCompare(BumpI, PredDef);
1818 setImmediate(*CmpImmOp, CmpImm);
1850 if (!Latch || !ExitingBlock || Header->hasAddressTaken())
1857 using MBBVector = std::vector<MachineBasicBlock *>;
1859 MBBVector Preds(Header->pred_begin(), Header->pred_end());
1873 MF->
insert(Header->getIterator(), NewPH);
1875 if (Header->pred_size() > 2) {
1881 for (instr_iterator
I = Header->instr_begin(),
E = Header->instr_end();
1882 I !=
E &&
I->isPHI(); ++
I) {
1913 if (PredB != Latch) {
1922 assert(Header->pred_size() == 2);
1929 for (instr_iterator
I = Header->instr_begin(),
E = Header->instr_end();
1930 I !=
E &&
I->isPHI(); ++
I) {
1934 if (MO.
getMBB() != Latch)
1953 assert (!NotAnalyzed &&
"Should be analyzable!");
1954 if (TB != Header && (Tmp2.
empty() || FB != Header))
1956 PB->ReplaceUsesOfBlockWith(Header, NewPH);
1964 (void)LatchNotAnalyzed;
1965 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)
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
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.
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...
std::vector< MachineBasicBlock * >::iterator pred_iterator
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...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
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.
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.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
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.