Go to the documentation of this file.
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 "
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))
154 static Kind getNegatedComparison(
Kind Cmp) {
155 if ((Cmp & L) || (Cmp &
G))
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 {
356 return Contents.ImmVal;
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>();
393 if (L->isOutermost()) {
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)));
462 unsigned PredR, PredPos, PredRegFlags;
471 int64_t 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);
609 if (
MBB == Preheader)
611 else if (
MBB == Latch)
627 assert (
TB &&
"Exit block without a branch?");
628 if (ExitingBlock != Latch && (
TB == Latch || FB == Latch)) {
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;
655 int64_t
Mask = 0, ImmValue = 0;
663 OldInsts.push_back(CondI);
664 OldInsts.push_back(IVOp);
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()) {
702 if (!checkForImmediate(*InitialValue, V))
707 if (EndValue->
isReg()) {
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))
750 if (!Start->isReg() && !Start->isImm())
752 if (!End->isReg() && !End->isImm())
755 bool CmpLess =
Cmp & Comparison::L;
760 if (CmpLess && IVBump < 0)
764 if (CmpGreater && IVBump > 0)
769 LoopFeederMap LoopFeederPhi;
778 if (Start->isImm() && End->isImm()) {
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.");
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;
855 StartV = Start->getImm();
857 EndV = End->getImm();
872 else if (End->isImm())
880 StartV -= (IVBump-1);
881 else if (End->isImm())
887 unsigned R = 0, SR = 0;
888 if (Start->isReg()) {
890 SR = Start->getSubReg();
893 SR = End->getSubReg();
898 if (!SR && RC == &Hexagon::DoubleRegsRegClass)
903 unsigned DistR, DistSR;
906 if (Start->isImm() && StartV == 0) {
907 DistR = End->getReg();
908 DistSR = End->getSubReg();
911 (RegToImm ?
TII->get(Hexagon::A2_subri) :
912 TII->get(Hexagon::A2_addi));
913 if (RegToReg || RegToImm) {
919 SubIB.
addReg(End->getReg(), 0, End->getSubReg())
920 .
addReg(Start->getReg(), 0, Start->getSubReg());
923 .
addReg(Start->getReg(), 0, Start->getSubReg());
930 if (EndValInstr->
getOpcode() == Hexagon::A2_addi &&
938 SubIB.
addReg(End->getReg(), 0, End->getSubReg())
947 unsigned AdjR, AdjSR;
965 unsigned CountR, CountSR;
985 return new CountValue(CountValue::CV_Register, CountR, CountSR);
989 bool HexagonHardwareLoops::isInvalidLoopOperation(
const MachineInstr *
MI,
990 bool IsInnerHWLoop)
const {
993 if (
MI->getDesc().isCall())
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)
1004 if (
MI->modifiesRegister(R,
TRI))
1012 bool HexagonHardwareLoops::containsInvalidInstruction(
MachineLoop *L,
1013 bool IsInnerHWLoop)
const {
1018 if (isInvalidLoopOperation(&
MI, IsInnerHWLoop)) {
1050 if (std::next(
I) != End || !
I->getParent()->isPHI())
1060 use_nodbg_iterator nextJ;
1062 J != End; J = nextJ) {
1063 nextJ = std::next(J);
1072 DeadPhis.push_back(OnePhi);
1083 if (isDead(
MI, DeadPhis)) {
1105 MI->eraseFromParent();
1106 for (
unsigned i = 0;
i < DeadPhis.size(); ++
i)
1107 DeadPhis[
i]->eraseFromParent();
1119 bool HexagonHardwareLoops::convertToHardwareLoop(
MachineLoop *L,
1125 bool Changed =
false;
1126 bool L0Used =
false;
1127 bool L1Used =
false;
1131 Changed |= convertToHardwareLoop(
I, RecL0used, RecL1used);
1132 L0Used |= RecL0used;
1133 L1Used |= RecL1used;
1137 if (Changed && L0Used && L1Used)
1147 unsigned IsInnerHWLoop = 1;
1150 LOOP_i = Hexagon::J2_loop1i;
1151 LOOP_r = Hexagon::J2_loop1r;
1152 ENDLOOP = Hexagon::ENDLOOP1;
1155 LOOP_i = Hexagon::J2_loop0i;
1156 LOOP_r = Hexagon::J2_loop0r;
1157 ENDLOOP = Hexagon::ENDLOOP0;
1171 if (containsInvalidInstruction(L, IsInnerHWLoop))
1180 if (LastI == LastMBB->
end())
1184 if (!fixupInductionVariable(L))
1191 Preheader = createPreheaderForLoop(L);
1200 CountValue *TripCount = getLoopTripCount(L, OldInsts);
1205 if (TripCount->isReg()) {
1218 if (ExitingBlock != L->getLoopLatch()) {
1225 if (L->contains(
TB))
1227 else if (L->contains(FB))
1233 LoopStart = TopBlock;
1238 if (InsertPos != Preheader->
end())
1239 DL = InsertPos->getDebugLoc();
1241 if (TripCount->isReg()) {
1244 BuildMI(*Preheader, InsertPos,
DL,
TII->get(TargetOpcode::COPY), CountReg)
1245 .
addReg(TripCount->getReg(), 0, TripCount->getSubReg());
1250 assert(TripCount->isImm() &&
"Expecting immediate value for trip count");
1254 int64_t CountImm = TripCount->getImm();
1257 BuildMI(*Preheader, InsertPos,
DL,
TII->get(Hexagon::A2_tfrsi), CountReg)
1275 DebugLoc LastIDL = LastI->getDebugLoc();
1281 if (LastI->getOpcode() == Hexagon::J2_jumpt ||
1282 LastI->getOpcode() == Hexagon::J2_jumpf) {
1285 LastI = LastMBB->
erase(LastI);
1287 if (LastI != LastMBB->
end())
1288 LastI = LastMBB->
erase(LastI);
1294 LastMBB->
erase(LastI);
1300 for (
unsigned i = 0;
i < OldInsts.size(); ++
i)
1301 removeIfDead(OldInsts[
i]);
1316 bool HexagonHardwareLoops::orderBumpCompare(
MachineInstr *BumpI,
1318 assert (BumpI != CmpI &&
"Bump and compare in the same instruction?");
1327 for (instr_iterator
I(BumpI),
E =
BB->instr_end();
I !=
E; ++
I)
1333 bool FoundBump =
false;
1334 instr_iterator CmpIt = CmpI->
getIterator(), NextIt = std::next(CmpIt);
1335 for (instr_iterator
I = NextIt,
E =
BB->instr_end();
I !=
E; ++
I) {
1337 for (
unsigned i = 0,
n =
In->getNumOperands();
i <
n; ++
i) {
1340 if (MO.
getReg() == PredR)
1351 assert (FoundBump &&
"Cannot determine instruction order");
1363 LoopFeederMap &LoopFeederPhi)
const {
1364 if (LoopFeederPhi.find(MO->
getReg()) == LoopFeederPhi.end()) {
1371 LoopFeederPhi.insert(std::make_pair(MO->
getReg(),
Def));
1380 bool HexagonHardwareLoops::phiMayWrapOrUnderflow(
1382 MachineLoop *L, LoopFeederMap &LoopFeederPhi)
const {
1387 if (isLoopFeeder(L,
MBB, Phi, &(Phi->
getOperand(
i)), LoopFeederPhi))
1388 if (loopCountMayWrapOrUnderFlow(&(Phi->
getOperand(
i)), EndVal,
1408 bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow(
1411 LoopFeederMap &LoopFeederPhi)
const {
1413 if (!InitVal->
isReg())
1416 if (!EndVal->
isImm())
1422 if (checkForImmediate(*InitVal,
Imm))
1428 if (!
Reg.isVirtual())
1437 if (
Def->isPHI() && !phiMayWrapOrUnderflow(
Def, EndVal,
Def->getParent(),
1440 if (
Def->isCopy() && !loopCountMayWrapOrUnderFlow(&(
Def->getOperand(1)),
1441 EndVal,
Def->getParent(),
1452 int64_t CmpMask = 0, CmpValue = 0;
1463 getComparisonKind(
MI->getOpcode(),
nullptr,
nullptr, 0);
1467 Cmp = Comparison::getNegatedComparison(Cmp);
1468 if (CmpReg2 != 0 && CmpReg2 ==
Reg)
1469 Cmp = Comparison::getSwappedComparison(Cmp);
1472 if (Comparison::isSigned(Cmp))
1485 if (!
Def->isCopy() && !
Def->isPHI())
1491 bool HexagonHardwareLoops::checkForImmediate(
const MachineOperand &MO,
1492 int64_t &Val)
const {
1511 case TargetOpcode::COPY:
1512 case Hexagon::A2_tfrsi:
1513 case Hexagon::A2_tfrpi:
1515 case Hexagon::CONST64:
1519 if (!checkForImmediate(DI->
getOperand(1), TV))
1522 case Hexagon::A2_combineii:
1523 case Hexagon::A4_combineir:
1524 case Hexagon::A4_combineii:
1525 case Hexagon::A4_combineri:
1526 case Hexagon::A2_combinew: {
1530 if (!checkForImmediate(S1, V1) || !checkForImmediate(S2,
V2))
1535 case TargetOpcode::REG_SEQUENCE: {
1539 if (!checkForImmediate(S1, V1) || !checkForImmediate(S3, V3))
1543 if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi)
1544 TV = V1 | (V3 << 32);
1545 else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo)
1546 TV = V3 | (V1 << 32);
1559 case Hexagon::isub_lo:
1560 Val = TV & 0xFFFFFFFFULL;
1562 case Hexagon::isub_hi:
1563 Val = (TV >> 32) & 0xFFFFFFFFULL;
1572 void HexagonHardwareLoops::setImmediate(
MachineOperand &MO, int64_t Val) {
1590 bool HexagonHardwareLoops::fixupInductionVariable(
MachineLoop *L) {
1595 if (!(Header && Latch && ExitingBlock))
1600 using RegisterBump = std::pair<unsigned, int64_t>;
1601 using RegisterInduction = std::pair<unsigned, RegisterBump>;
1602 using RegisterInductionSet = std::set<RegisterInduction>;
1605 RegisterInductionSet IndRegs;
1613 I !=
E &&
I->isPHI(); ++
I) {
1630 if (
MRI->
getVRegDef(IndReg) == Phi && checkForImmediate(Opnd2, V)) {
1632 IndRegs.insert(std::make_pair(UpdReg, std::make_pair(IndReg, V)));
1638 if (IndRegs.empty())
1645 if (NotAnalyzed ||
Cond.empty())
1648 if (ExitingBlock != Latch && (
TB == Latch || FB == Latch)) {
1658 TB = (LTB == Header) ? LTB : LFB;
1660 FB = (LTB == Header) ? LTB : LFB;
1682 unsigned CSz =
Cond.size();
1683 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)) {
1761 }
else if (MO.
isReg()) {
1771 if (IndI && nonIndI &&
1772 nonIndI->
getOpcode() == Hexagon::A2_addi &&
1775 bool Order = orderBumpCompare(IndI, PredDef);
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);
1857 using MBBVector = std::vector<MachineBasicBlock *>;
1882 I !=
E &&
I->isPHI(); ++
I) {
1913 if (PredB != Latch) {
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!");
pred_iterator pred_begin()
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
static use_instr_nodbg_iterator use_instr_nodbg_end()
MachineInstrBuilder & UseMI
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...
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)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Represents a single loop in the control flow graph.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
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 isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
bool predOpcodeHasNot(ArrayRef< MachineOperand > Cond) const
Reg
All possible values of the reg field in the ModR/M byte.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
void setImm(int64_t immVal)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImplicit=false)
CreateMachineInstr - Allocate a new MachineInstr.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
iterator_range< use_iterator > use_operands(Register Reg) const
void insert(iterator MBBI, MachineBasicBlock *MBB)
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
DomTreeNodeBase * getIDom() const
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
use_nodbg_iterator use_nodbg_begin(Register RegNo) const
LLVM Basic Block Representation.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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 pred_size() const
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineDomTreeNode * addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB)
addNewBlock - Add a new node to the dominator tree information.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
bool doesNotReturn(const MachineInstr &CallMI) const
Itanium Name Demangler i e convert the string _Z1fv into f()". You can also use the CRTP base ManglingParser to perform some simple analysis on the mangled name
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
void setSubReg(unsigned subReg)
Represent the analysis usage information of a pass.
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
void changeImmediateDominator(MachineBasicBlock *N, MachineBasicBlock *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
MachineBasicBlock * findLoopControlBlock()
Find the block that contains the loop control variable and the loop test.
const HexagonInstrInfo * TII
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Describe properties that are true of each instruction in the target description file.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
MachineOperand class - Representation of each machine instruction operand.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
STATISTIC(NumFunctions, "Total number of functions")
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
static use_nodbg_iterator use_nodbg_end()
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
block_iterator block_begin() const
PassBuilder PB(Machine, PassOpts->PTO, None, &PIC)
const HexagonInstrInfo * getInstrInfo() const override
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool isAdd() const
Return true if the instruction is an add instruction.
static cl::opt< std::string > PHFn("hexagon-hwloop-phfn", cl::Hidden, cl::init(""))
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
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,...
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
static cl::opt< bool > SpecPreheader("hwloop-spec-preheader", cl::Hidden, cl::desc("Allow speculation of preheader " "instructions"))
initializer< Ty > init(const Ty &Val)
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...
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
std::vector< MachineBasicBlock * >::iterator pred_iterator
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void setHasAddressTaken()
Set this block to reflect that it potentially is the target of an indirect branch.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
instr_iterator instr_begin()
static bool isReg(const MCInst &MI, unsigned OpNo)
instr_iterator instr_end()
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineBasicBlock * getMBB() const
SmallVector< MachineOperand, 4 > Cond
StringRef - Represent a constant reference to a string, i.e.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isExtendable(const MachineInstr &MI) const
self_iterator getIterator()
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< int > HWLoopLimit("hexagon-max-hwloop", cl::Hidden, cl::init(-1))
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const MachineBasicBlock * getParent() const
Base class for the actual dominator tree node.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
Function & getFunction()
Return the LLVM function that this machine code represents.
const HexagonRegisterInfo * getRegisterInfo() const override
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Instructions::iterator instr_iterator
BlockT * getHeader() const
into eax xorps xmm0 xmm0 eax xmm0 eax xmm0 ret esp eax movdqa LC0
bool isValidOffset(unsigned Opcode, int Offset, const TargetRegisterInfo *TRI, bool Extend=true) const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
INITIALIZE_PASS_BEGIN(HexagonHardwareLoops, "hwloops", "Hexagon Hardware Loops", false, false) INITIALIZE_PASS_END(HexagonHardwareLoops
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void removeOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with.
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"))
bool getPredReg(ArrayRef< MachineOperand > Cond, unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void setReg(Register Reg)
Change the register this operand corresponds to.
unsigned getNumOperands() const
Retuns the total number of operands.
MachineBasicBlock * getTopBlock()
Return the "top" block in the loop, which is the first block in the linear layout,...
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
void setMBB(MachineBasicBlock *MBB)
LLVM_NODISCARD bool empty() const
FunctionPass class - This class is used to implement most global optimizations.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
AnalysisUsage & addRequired()
FunctionPass * createHexagonHardwareLoops()
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
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.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
void initializeHexagonHardwareLoopsPass(PassRegistry &)
A Use represents the edge between a Value definition and its users.