47#define DEBUG_TYPE "ppc-instr-info"
49#define GET_INSTRMAP_INFO
50#define GET_INSTRINFO_CTOR_DTOR
51#include "PPCGenInstrInfo.inc"
54 "Number of spillvsrrc spilled to stack as vec");
56 "Number of spillvsrrc spilled to stack as gpr");
57STATISTIC(NumGPRtoVSRSpill,
"Number of gpr spills to spillvsrrc");
59 "Number of ISELs that depend on comparison of constants converted");
61 "Number of compare-immediate instructions fed by constants");
63 "Number of record-form rotates converted to record-form andi");
67 cl::desc(
"Disable analysis for CTR loops"));
73cl::desc(
"Causes the backend to crash instead of generating a nop VSX copy"),
78 cl::desc(
"Use the old (incorrect) instruction latency calculation"));
82 cl::desc(
"register pressure factor for the transformations."));
86 cl::desc(
"enable register pressure reduce in machine combiner pass."));
89void PPCInstrInfo::anchor() {}
94 STI.isPPC64() ?
PPC::BLR8 :
PPC::BLR),
95 Subtarget(STI), RI(STI.getTargetMachine()) {}
99 return Subtarget.isPPC64() ? &PPC::G8RC_NOX0RegClass
100 : &PPC::GPRC_NOR0RegClass;
109 static_cast<const PPCSubtarget *
>(STI)->getCPUDirective();
113 static_cast<const PPCSubtarget *
>(STI)->getInstrItineraryData();
145 unsigned *PredCost)
const {
147 return PPCGenInstrInfo::getInstrLatency(ItinData,
MI, PredCost);
157 unsigned DefClass =
MI.getDesc().getSchedClass();
158 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
163 std::optional<unsigned> Cycle = ItinData->
getOperandCycle(DefClass, i);
176 std::optional<unsigned>
Latency = PPCGenInstrInfo::getOperandLatency(
179 if (!
DefMI.getParent())
186 if (Reg.isVirtual()) {
188 &
DefMI.getParent()->getParent()->getRegInfo();
192 IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
193 PPC::CRBITRCRegClass.contains(Reg);
196 if (
UseMI.isBranch() && IsRegCR) {
202 unsigned Directive = Subtarget.getCPUDirective();
276#define InfoArrayIdxFMAInst 0
277#define InfoArrayIdxFAddInst 1
278#define InfoArrayIdxFMULInst 2
279#define InfoArrayIdxAddOpIdx 3
280#define InfoArrayIdxMULOpIdx 4
281#define InfoArrayIdxFSubInst 5
292 {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
293 {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
294 {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
295 {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
296 {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
297 {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
301int16_t PPCInstrInfo::getFMAOpIdxInfo(
unsigned Opcode)
const {
358 bool DoRegPressureReduce)
const {
362 auto IsAllOpsVirtualReg = [](
const MachineInstr &Instr) {
363 for (
const auto &MO : Instr.explicit_operands())
364 if (!(MO.isReg() && MO.getReg().isVirtual()))
369 auto IsReassociableAddOrSub = [&](
const MachineInstr &Instr,
371 if (Instr.getOpcode() !=
382 if (!IsAllOpsVirtualReg(Instr))
394 auto IsReassociableFMA = [&](
const MachineInstr &Instr, int16_t &AddOpIdx,
395 int16_t &MulOpIdx,
bool IsLeaf) {
396 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
407 if (!IsAllOpsVirtualReg(Instr))
427 int16_t AddOpIdx = -1;
428 int16_t MulOpIdx = -1;
430 bool IsUsedOnceL =
false;
431 bool IsUsedOnceR =
false;
435 auto IsRPReductionCandidate = [&]() {
439 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
444 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
true)) {
445 assert((MulOpIdx >= 0) &&
"mul operand index not right!");
446 Register MULRegL = RI.lookThruSingleUseCopyChain(
448 Register MULRegR = RI.lookThruSingleUseCopyChain(
450 if (!MULRegL && !MULRegR)
453 if (MULRegL && !MULRegR) {
457 }
else if (!MULRegL && MULRegR) {
470 return MULInstrL && MULInstrR;
476 if (DoRegPressureReduce && IsRPReductionCandidate()) {
477 assert((MULInstrL && MULInstrR) &&
"wrong register preduction candidate!");
498 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
false))
501 assert((AddOpIdx >= 0) &&
"add operand index not right!");
508 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx,
false))
511 assert((AddOpIdx >= 0) &&
"add operand index not right!");
516 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx,
true)) {
532 assert(!InsInstrs.
empty() &&
"Instructions set to be inserted is empty!");
538 int16_t Idx = getFMAOpIdxInfo(Root.
getOpcode());
577 for (
auto *Inst : InsInstrs) {
579 assert(Operand.isReg() &&
"Invalid instruction in InsInstrs!");
580 if (Operand.getReg() == PPC::ZERO8) {
581 Placeholder = &Operand;
587 assert(Placeholder &&
"Placeholder does not exist!");
592 generateLoadForNewConst(ConstPoolIdx, &Root,
C->getType(), InsInstrs);
595 Placeholder->setReg(LoadNewConst);
616 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
623 auto GetMBBPressure =
629 RPTracker.
init(
MBB->getParent(), RegClassInfo,
nullptr,
MBB,
MBB->end(),
633 if (
MI.isDebugValue() ||
MI.isDebugLabel())
636 RegOpers.
collect(
MI, RI, *MRI,
false,
false);
639 RPTracker.
recede(RegOpers);
649 unsigned VSSRCLimit =
653 return GetMBBPressure(
MBB)[PPC::RegisterPressureSets::VSSRC] >
659 if (!
I->hasOneMemOperand())
663 return Op->isLoad() &&
Op->getPseudoValue() &&
667Register PPCInstrInfo::generateLoadForNewConst(
673 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
675 "Target not supported!\n");
683 BuildMI(*MF,
MI->getDebugLoc(),
get(PPC::ADDIStocHA8), VReg1)
687 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
688 "Only float and double are supported!");
693 LoadOpcode = PPC::DFLOADf32;
695 LoadOpcode = PPC::DFLOADf64;
725 assert(
I->mayLoad() &&
"Should be a load instruction.\n");
726 for (
auto MO :
I->uses()) {
730 if (Reg == 0 || !Reg.isVirtual())
734 for (
auto MO2 :
DefMI->uses())
736 return (MCP->
getConstants())[MO2.getIndex()].Val.ConstVal;
756 bool DoRegPressureReduce)
const {
766 DoRegPressureReduce);
779 reassociateFMA(Root,
Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
784 DelInstrs, InstrIdxForVirtReg);
789void PPCInstrInfo::reassociateFMA(
802 int16_t Idx = getFMAOpIdxInfo(FmaOp);
803 assert(Idx >= 0 &&
"Root must be a FMA instruction");
805 bool IsILPReassociate =
836 uint32_t IntersectedFlags = 0;
837 if (IsILPReassociate)
842 auto GetOperandInfo = [&](
const MachineOperand &Operand,
Register &
Reg,
846 KillFlag = Operand.
isKill();
849 auto GetFMAInstrInfo = [&](
const MachineInstr &
Instr,
Register &MulOp1,
851 bool &MulOp1KillFlag,
bool &MulOp2KillFlag,
852 bool &AddOpKillFlag) {
853 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
854 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
855 GetOperandInfo(
Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
858 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
860 bool KillX =
false, KillY =
false, KillM11 =
false, KillM12 =
false,
861 KillM21 =
false, KillM22 =
false, KillM31 =
false, KillM32 =
false,
862 KillA11 =
false, KillA21 =
false, KillB =
false;
864 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
866 if (IsILPReassociate)
867 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
870 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
871 GetOperandInfo(Leaf->
getOperand(AddOpIdx), RegX, KillX);
873 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
874 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
877 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
878 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
888 InstrIdxForVirtReg.
insert(std::make_pair(NewVRA, 0));
891 if (IsILPReassociate) {
893 InstrIdxForVirtReg.
insert(std::make_pair(NewVRB, 1));
899 InstrIdxForVirtReg.
insert(std::make_pair(NewVRD, 2));
902 auto AdjustOperandOrder = [&](MachineInstr *
MI,
Register RegAdd,
bool KillAdd,
904 Register RegMul2,
bool KillRegMul2) {
905 MI->getOperand(AddOpIdx).setReg(RegAdd);
906 MI->getOperand(AddOpIdx).setIsKill(KillAdd);
907 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
908 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
909 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
910 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
913 MachineInstrBuilder NewARegPressure, NewCRegPressure;
919 MachineInstrBuilder MINewB =
924 MachineInstrBuilder MINewA =
931 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
932 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
935 MachineInstrBuilder MINewC =
953 assert(NewVRD &&
"new FMA register not created!");
955 MachineInstrBuilder MINewA =
960 MachineInstrBuilder MINewB =
965 MachineInstrBuilder MINewD =
972 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
973 AdjustOperandOrder(MINewD, NewVRA,
true, RegM31, KillM31, RegM32,
977 MachineInstrBuilder MINewC =
999 bool KillVarReg =
false;
1002 KillVarReg = KillM31;
1005 KillVarReg = KillM32;
1029 if (!IsILPReassociate) {
1038 "Insertion instructions set should not be empty!");
1042 if (IsILPReassociate)
1050 unsigned &SubIdx)
const {
1051 switch (
MI.getOpcode()) {
1052 default:
return false;
1055 case PPC::EXTSW_32_64:
1056 SrcReg =
MI.getOperand(1).getReg();
1057 DstReg =
MI.getOperand(0).getReg();
1058 SubIdx = PPC::sub_32;
1064 int &FrameIndex)
const {
1068 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1069 MI.getOperand(2).isFI()) {
1070 FrameIndex =
MI.getOperand(2).getIndex();
1071 return MI.getOperand(0).getReg();
1081 switch (
MI.getOpcode()) {
1091 case PPC::ADDIStocHA:
1092 case PPC::ADDIStocHA8:
1094 case PPC::ADDItocL8:
1095 case PPC::LOAD_STACK_GUARD:
1096 case PPC::PPCLdFixedAddr:
1098 case PPC::XXLXORspz:
1099 case PPC::XXLXORdpz:
1100 case PPC::XXLEQVOnes:
1101 case PPC::XXSPLTI32DX:
1103 case PPC::XXSPLTIDP:
1107 case PPC::V_SETALLONESB:
1108 case PPC::V_SETALLONESH:
1109 case PPC::V_SETALLONES:
1112 case PPC::XXSETACCZ:
1113 case PPC::DMXXSETACCZ:
1120 int &FrameIndex)
const {
1122 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1123 MI.getOperand(2).isFI()) {
1124 FrameIndex =
MI.getOperand(2).getIndex();
1125 return MI.getOperand(0).getReg();
1133 unsigned OpIdx2)
const {
1137 if (
MI.getOpcode() != PPC::RLWIMI &&
MI.getOpcode() != PPC::RLWIMI_rec)
1145 if (
MI.getOperand(3).getImm() != 0)
1156 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1157 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1161 unsigned SubReg1 =
MI.getOperand(1).getSubReg();
1162 unsigned SubReg2 =
MI.getOperand(2).getSubReg();
1163 bool Reg1IsKill =
MI.getOperand(1).isKill();
1164 bool Reg2IsKill =
MI.getOperand(2).isKill();
1165 bool ChangeReg0 =
false;
1171 "Expecting a two-address instruction!");
1172 assert(
MI.getOperand(0).getSubReg() == SubReg1 &&
"Tied subreg mismatch");
1178 unsigned MB =
MI.getOperand(4).getImm();
1179 unsigned ME =
MI.getOperand(5).getImm();
1183 if (MB == 0 && ME == 31)
1188 Register Reg0 = ChangeReg0 ? Reg2 :
MI.getOperand(0).getReg();
1189 bool Reg0IsDead =
MI.getOperand(0).isDead();
1190 return BuildMI(MF,
MI.getDebugLoc(),
MI.getDesc())
1199 MI.getOperand(0).setReg(Reg2);
1200 MI.getOperand(0).setSubReg(SubReg2);
1202 MI.getOperand(2).setReg(Reg1);
1203 MI.getOperand(1).setReg(Reg2);
1204 MI.getOperand(2).setSubReg(SubReg1);
1205 MI.getOperand(1).setSubReg(SubReg2);
1206 MI.getOperand(2).setIsKill(Reg1IsKill);
1207 MI.getOperand(1).setIsKill(Reg2IsKill);
1210 MI.getOperand(4).setImm((ME + 1) & 31);
1211 MI.getOperand(5).setImm((MB - 1) & 31);
1216 unsigned &SrcOpIdx1,
1217 unsigned &SrcOpIdx2)
const {
1228 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1235 unsigned Directive = Subtarget.getCPUDirective();
1238 default: Opcode = PPC::NOP;
break;
1264 bool AllowModify)
const {
1265 bool isPPC64 = Subtarget.isPPC64();
1272 if (!isUnpredicatedTerminator(*
I))
1278 if (
I->getOpcode() == PPC::B &&
1279 MBB.isLayoutSuccessor(
I->getOperand(0).getMBB())) {
1280 I->eraseFromParent();
1283 I =
MBB.getLastNonDebugInstr();
1284 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1293 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
1299 }
else if (LastInst.
getOpcode() == PPC::BCC) {
1307 }
else if (LastInst.
getOpcode() == PPC::BC) {
1315 }
else if (LastInst.
getOpcode() == PPC::BCn) {
1323 }
else if (LastInst.
getOpcode() == PPC::BDNZ8 ||
1334 }
else if (LastInst.
getOpcode() == PPC::BDZ8 ||
1355 if (
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
1359 if (SecondLastInst.
getOpcode() == PPC::BCC &&
1369 }
else if (SecondLastInst.
getOpcode() == PPC::BC &&
1379 }
else if (SecondLastInst.
getOpcode() == PPC::BCn &&
1389 }
else if ((SecondLastInst.
getOpcode() == PPC::BDNZ8 ||
1390 SecondLastInst.
getOpcode() == PPC::BDNZ) &&
1403 }
else if ((SecondLastInst.
getOpcode() == PPC::BDZ8 ||
1404 SecondLastInst.
getOpcode() == PPC::BDZ) &&
1427 I->eraseFromParent();
1436 int *BytesRemoved)
const {
1437 assert(!BytesRemoved &&
"code size not handled");
1443 if (
I->getOpcode() != PPC::B &&
I->getOpcode() != PPC::BCC &&
1444 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1445 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1446 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1450 I->eraseFromParent();
1454 if (
I ==
MBB.begin())
return 1;
1456 if (
I->getOpcode() != PPC::BCC &&
1457 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1458 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1459 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1463 I->eraseFromParent();
1472 int *BytesAdded)
const {
1474 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1476 "PPC branch conditions have two components!");
1477 assert(!BytesAdded &&
"code size not handled");
1479 bool isPPC64 = Subtarget.isPPC64();
1487 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1488 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1504 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1505 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1523 Register FalseReg,
int &CondCycles,
1524 int &TrueCycles,
int &FalseCycles)
const {
1525 if (!Subtarget.hasISEL())
1528 if (
Cond.size() != 2)
1549 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1550 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1551 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1552 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1572 "PPC branch conditions have two components!");
1578 assert(RC &&
"TrueReg and FalseReg must have overlapping register classes");
1580 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1581 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1583 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1584 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1585 "isel is for regular integer GPRs only");
1587 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1590 unsigned SubIdx = 0;
1591 bool SwapOps =
false;
1592 switch (SelectPred) {
1596 SubIdx = PPC::sub_eq; SwapOps =
false;
break;
1600 SubIdx = PPC::sub_eq; SwapOps =
true;
break;
1604 SubIdx = PPC::sub_lt; SwapOps =
false;
break;
1608 SubIdx = PPC::sub_lt; SwapOps =
true;
break;
1612 SubIdx = PPC::sub_gt; SwapOps =
false;
break;
1616 SubIdx = PPC::sub_gt; SwapOps =
true;
break;
1620 SubIdx = PPC::sub_un; SwapOps =
false;
break;
1624 SubIdx = PPC::sub_un; SwapOps =
true;
break;
1629 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1630 SecondReg = SwapOps ? TrueReg : FalseReg;
1639 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1654 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1655 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1656 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1657 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1659 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1660 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1661 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1662 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1664 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1665 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1666 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1667 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1669 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1670 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1671 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1672 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1675 assert(Ret != 4 &&
"Invalid CR bit register");
1683 bool RenamableDest,
bool RenamableSrc)
const {
1686 if (PPC::F8RCRegClass.
contains(DestReg) &&
1687 PPC::VSRCRegClass.
contains(SrcReg)) {
1689 RI.getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1695 }
else if (PPC::F8RCRegClass.
contains(SrcReg) &&
1696 PPC::VSRCRegClass.
contains(DestReg)) {
1698 RI.getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1707 if (PPC::CRBITRCRegClass.
contains(SrcReg) &&
1708 PPC::GPRCRegClass.
contains(DestReg)) {
1720 }
else if (PPC::CRRCRegClass.
contains(SrcReg) &&
1721 (PPC::G8RCRegClass.
contains(DestReg) ||
1722 PPC::GPRCRegClass.
contains(DestReg))) {
1723 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1724 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1725 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1726 unsigned CRNum = RI.getEncodingValue(SrcReg);
1738 }
else if (PPC::G8RCRegClass.
contains(SrcReg) &&
1739 PPC::VSFRCRegClass.
contains(DestReg)) {
1740 assert(Subtarget.hasDirectMove() &&
1741 "Subtarget doesn't support directmove, don't know how to copy.");
1746 }
else if (PPC::VSFRCRegClass.
contains(SrcReg) &&
1747 PPC::G8RCRegClass.
contains(DestReg)) {
1748 assert(Subtarget.hasDirectMove() &&
1749 "Subtarget doesn't support directmove, don't know how to copy.");
1753 }
else if (PPC::SPERCRegClass.
contains(SrcReg) &&
1754 PPC::GPRCRegClass.
contains(DestReg)) {
1758 }
else if (PPC::GPRCRegClass.
contains(SrcReg) &&
1759 PPC::SPERCRegClass.
contains(DestReg)) {
1763 }
else if ((PPC::G8RCRegClass.
contains(DestReg) ||
1764 PPC::GPRCRegClass.
contains(DestReg)) &&
1765 SrcReg == PPC::CARRY) {
1766 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1771 }
else if ((PPC::G8RCRegClass.
contains(SrcReg) ||
1772 PPC::GPRCRegClass.
contains(SrcReg)) &&
1773 DestReg == PPC::CARRY) {
1774 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1783 if (PPC::GPRCRegClass.
contains(DestReg, SrcReg))
1785 else if (PPC::G8RCRegClass.
contains(DestReg, SrcReg))
1787 else if (PPC::F4RCRegClass.
contains(DestReg, SrcReg))
1789 else if (PPC::CRRCRegClass.
contains(DestReg, SrcReg))
1791 else if (PPC::VRRCRegClass.
contains(DestReg, SrcReg))
1793 else if (PPC::VSRCRegClass.
contains(DestReg, SrcReg))
1803 else if (PPC::VSFRCRegClass.
contains(DestReg, SrcReg) ||
1804 PPC::VSSRCRegClass.
contains(DestReg, SrcReg))
1805 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1806 else if (Subtarget.pairedVectorMemops() &&
1807 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1808 if (SrcReg > PPC::VSRp15)
1809 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1811 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1812 if (DestReg > PPC::VSRp15)
1813 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1815 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1822 else if (PPC::CRBITRCRegClass.
contains(DestReg, SrcReg))
1824 else if (PPC::SPERCRegClass.
contains(DestReg, SrcReg))
1826 else if ((PPC::ACCRCRegClass.
contains(DestReg) ||
1827 PPC::UACCRCRegClass.
contains(DestReg)) &&
1828 (PPC::ACCRCRegClass.
contains(SrcReg) ||
1829 PPC::UACCRCRegClass.
contains(SrcReg))) {
1835 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1836 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1838 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1840 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1843 for (
unsigned Idx = 0; Idx < 4; Idx++)
1849 if (SrcPrimed && !KillSrc)
1852 }
else if (PPC::G8pRCRegClass.
contains(DestReg) &&
1853 PPC::G8pRCRegClass.
contains(SrcReg)) {
1855 unsigned DestRegIdx = DestReg - PPC::G8p0;
1856 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1857 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1858 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1859 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1860 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1868 }
else if ((PPC::WACCRCRegClass.
contains(DestReg) ||
1869 PPC::WACC_HIRCRegClass.
contains(DestReg)) &&
1870 (PPC::WACCRCRegClass.
contains(SrcReg) ||
1871 PPC::WACC_HIRCRegClass.
contains(SrcReg))) {
1873 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1874 : PPC::DMXXEXTFDMR512_HI;
1877 RS.enterBasicBlockEnd(
MBB);
1878 RS.backward(std::next(
I));
1880 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1884 RS.setRegUsed(TmpReg1);
1885 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1894 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1895 : PPC::DMXXINSTDMR512_HI;
1902 }
else if (PPC::DMRRCRegClass.
contains(DestReg) &&
1903 PPC::DMRRCRegClass.
contains(SrcReg)) {
1914 if (
MCID.getNumOperands() == 3)
1924 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1925 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1927 }
else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1928 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1930 }
else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1932 }
else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1934 }
else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1936 }
else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1938 }
else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1940 }
else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1942 }
else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1944 }
else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1946 }
else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1948 }
else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1950 }
else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1951 assert(Subtarget.pairedVectorMemops() &&
1952 "Register unexpected when paired memops are disabled.");
1954 }
else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1955 assert(Subtarget.pairedVectorMemops() &&
1956 "Register unexpected when paired memops are disabled.");
1958 }
else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1959 assert(Subtarget.pairedVectorMemops() &&
1960 "Register unexpected when paired memops are disabled.");
1962 }
else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1963 assert(Subtarget.pairedVectorMemops() &&
1964 "Register unexpected when paired memops are disabled.");
1966 }
else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1968 }
else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1970 }
else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1972 }
else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1974 }
else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1985 return OpcodesForSpill[getSpillIndex(RC)];
1991 return OpcodesForSpill[getSpillIndex(RC)];
1994void PPCInstrInfo::StoreRegToStackSlot(
2008 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
2009 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2022 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2025 MBB.insert(
MI, NewMI);
2032 NewMIs.
back()->addMemOperand(MF, MMO);
2051 unsigned DestReg,
int FrameIdx,
2066 if (
MI !=
MBB.end())
DL =
MI->getDebugLoc();
2068 LoadRegFromStackSlot(MF,
DL, DestReg, FrameIdx, RC, NewMIs);
2071 MBB.insert(
MI, NewMI);
2078 NewMIs.
back()->addMemOperand(MF, MMO);
2101 assert(
Cond.size() == 2 &&
"Invalid PPC branch opcode!");
2116 unsigned DefOpc =
DefMI.getOpcode();
2117 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2119 if (!
DefMI.getOperand(1).isImm())
2121 if (
DefMI.getOperand(1).getImm() != 0)
2137 for (UseIdx = 0; UseIdx <
UseMI.getNumOperands(); ++UseIdx)
2138 if (
UseMI.getOperand(UseIdx).isReg() &&
2139 UseMI.getOperand(UseIdx).getReg() == Reg)
2142 assert(UseIdx <
UseMI.getNumOperands() &&
"Cannot find Reg in UseMI");
2149 int16_t RegClass = getOpRegClassID(UseInfo);
2150 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2151 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2157 if (UseInfo.Constraints != 0)
2161 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2165 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2178 DefMI.eraseFromParent();
2184 if (
MI.definesRegister(PPC::CTR,
nullptr) ||
2185 MI.definesRegister(PPC::CTR8,
nullptr))
2197 unsigned NumT,
unsigned ExtraT,
2199 unsigned NumF,
unsigned ExtraF,
2219 switch (
MI.getOpcode()) {
2235 unsigned OpC =
MI.getOpcode();
2236 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2237 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2238 bool isPPC64 = Subtarget.isPPC64();
2239 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2240 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2246 MI.setDesc(
get(PPC::BCLR));
2249 MI.setDesc(
get(PPC::BCLRn));
2252 MI.setDesc(
get(PPC::BCCLR));
2259 }
else if (OpC == PPC::B) {
2260 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2261 bool isPPC64 = Subtarget.isPPC64();
2262 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2263 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2270 MI.removeOperand(0);
2272 MI.setDesc(
get(PPC::BC));
2278 MI.removeOperand(0);
2280 MI.setDesc(
get(PPC::BCn));
2286 MI.removeOperand(0);
2288 MI.setDesc(
get(PPC::BCC));
2296 }
else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2297 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2298 OpC == PPC::BCTRL8_RM) {
2299 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR)
2302 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2303 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2304 bool isPPC64 = Subtarget.isPPC64();
2307 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2308 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2311 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2312 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2315 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2316 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2327 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2339 assert(Pred1.
size() == 2 &&
"Invalid PPC first predicate");
2340 assert(Pred2.
size() == 2 &&
"Invalid PPC second predicate");
2342 if (Pred1[1].
getReg() == PPC::CTR8 || Pred1[1].
getReg() == PPC::CTR)
2344 if (Pred2[1].
getReg() == PPC::CTR8 || Pred2[1].
getReg() == PPC::CTR)
2369 std::vector<MachineOperand> &Pred,
2370 bool SkipDead)
const {
2378 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2379 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2383 for (
unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2386 if (MO.isDef() && RC->
contains(MO.getReg())) {
2390 }
else if (MO.isRegMask()) {
2392 if (MO.clobbersPhysReg(R)) {
2405 int64_t &
Value)
const {
2406 unsigned Opc =
MI.getOpcode();
2409 default:
return false;
2414 SrcReg =
MI.getOperand(1).getReg();
2416 Value =
MI.getOperand(2).getImm();
2425 SrcReg =
MI.getOperand(1).getReg();
2426 SrcReg2 =
MI.getOperand(2).getReg();
2445 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2456 bool isPPC64 = Subtarget.isPPC64();
2457 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2458 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2459 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2462 Register ActualSrc = RI.lookThruCopyLike(SrcReg, MRI);
2468 if (!
MI)
return false;
2470 bool equalityOnly =
false;
2473 if (is32BitSignedCompare) {
2479 }
else if (is32BitUnsignedCompare) {
2484 equalityOnly =
true;
2488 equalityOnly = is64BitUnsignedCompare;
2490 equalityOnly = is32BitUnsignedCompare;
2499 if (
UseMI->getOpcode() == PPC::BCC) {
2505 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2506 UseMI->getOpcode() == PPC::ISEL8) {
2507 unsigned SubIdx =
UseMI->getOperand(3).getSubReg();
2508 if (SubIdx != PPC::sub_eq)
2520 bool FoundUse =
false;
2549 else if (
Value != 0) {
2558 if (equalityOnly || !MRI->
hasOneUse(CRReg))
2562 if (
UseMI->getOpcode() != PPC::BCC)
2568 int16_t Immed = (int16_t)
Value;
2592 UseMI->getOperand(0).setImm(Pred);
2602 for (;
I != E && !noSub; --
I) {
2604 unsigned IOpC = Instr.getOpcode();
2606 if (&*
I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, &RI) ||
2607 Instr.readsRegister(PPC::CR0, &RI)))
2616 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2617 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2618 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2619 ((Instr.getOperand(1).getReg() == SrcReg &&
2620 Instr.getOperand(2).getReg() == SrcReg2) ||
2621 (Instr.getOperand(1).getReg() == SrcReg2 &&
2622 Instr.getOperand(2).getReg() == SrcReg))) {
2640 int MIOpC =
MI->getOpcode();
2641 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2642 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2645 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2663 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2673 bool ShouldSwap =
false;
2675 ShouldSwap = SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
2676 Sub->getOperand(2).getReg() == SrcReg;
2680 ShouldSwap = !ShouldSwap;
2688 if (
UseMI->getOpcode() == PPC::BCC) {
2693 "Invalid predicate for equality-only optimization");
2697 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2698 UseMI->getOpcode() == PPC::ISEL8) {
2699 unsigned NewSubReg =
UseMI->getOperand(3).getSubReg();
2700 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2701 "Invalid CR bit for equality-only optimization");
2703 if (NewSubReg == PPC::sub_lt)
2704 NewSubReg = PPC::sub_gt;
2705 else if (NewSubReg == PPC::sub_gt)
2706 NewSubReg = PPC::sub_lt;
2708 SubRegsToUpdate.
push_back(std::make_pair(&(
UseMI->getOperand(3)),
2714 "Non-zero immediate support and ShouldSwap"
2715 "may conflict in updating predicate");
2723 BuildMI(*
MI->getParent(), std::next(MII),
MI->getDebugLoc(),
2724 get(TargetOpcode::COPY), CRReg)
2729 MI->clearRegisterDeads(PPC::CR0);
2731 if (MIOpC != NewOpC) {
2741 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2742 Register GPRRes =
MI->getOperand(0).getReg();
2743 int64_t SH =
MI->getOperand(2).getImm();
2744 int64_t MB =
MI->getOperand(3).getImm();
2745 int64_t ME =
MI->getOperand(4).getImm();
2748 bool MBInLoHWord = MB >= 16;
2749 bool MEInLoHWord = ME >= 16;
2750 uint64_t Mask = ~0LLU;
2752 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2753 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2755 Mask >>= MBInLoHWord ? 0 : 16;
2756 NewOpC = MIOpC == PPC::RLWINM
2757 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2758 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2759 }
else if (MRI->
use_empty(GPRRes) && (ME == 31) &&
2760 (ME - MB + 1 == SH) && (MB >= 16)) {
2764 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2766 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2769 if (Mask != ~0LLU) {
2770 MI->removeOperand(4);
2771 MI->removeOperand(3);
2772 MI->getOperand(2).setImm(Mask);
2773 NumRcRotatesConvertedToRcAnd++;
2775 }
else if (MIOpC == PPC::RLDICL &&
MI->getOperand(2).getImm() == 0) {
2776 int64_t MB =
MI->getOperand(3).getImm();
2778 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2779 NewOpC = PPC::ANDI8_rec;
2780 MI->removeOperand(3);
2781 MI->getOperand(2).setImm(Mask);
2782 NumRcRotatesConvertedToRcAnd++;
2787 MI->setDesc(NewDesc);
2790 if (!
MI->definesRegister(ImpDef,
nullptr)) {
2791 MI->addOperand(*
MI->getParent()->getParent(),
2796 if (!
MI->readsRegister(ImpUse,
nullptr)) {
2797 MI->addOperand(*
MI->getParent()->getParent(),
2802 assert(
MI->definesRegister(PPC::CR0,
nullptr) &&
2803 "Record-form instruction does not define cr0?");
2808 for (
unsigned i = 0, e = PredsToUpdate.
size(); i < e; i++)
2809 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2811 for (
unsigned i = 0, e = SubRegsToUpdate.
size(); i < e; i++)
2812 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2823 int64_t CmpMask, CmpValue;
2828 if (CmpValue || !CmpMask || SrcReg2)
2836 if (
Opc == PPC::CMPLWI ||
Opc == PPC::CMPLDI)
2843 if (Subtarget.isPPC64() &&
Opc == PPC::CMPWI)
2850 bool SrcRegHasOtherUse =
false;
2857 if (CRReg != PPC::CR0)
2861 bool SeenUseOfCRReg =
false;
2862 bool IsCRRegKilled =
false;
2863 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI,
false, IsCRRegKilled,
2869 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2883 "Record-form instruction does not define cr0?");
2897 OffsetIsScalable =
false;
2932 case PPC::DFSTOREf64:
2933 return FirstOpc == SecondOpc;
2939 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2946 int64_t OpOffset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2947 unsigned NumBytes)
const {
2953 "Only base registers and frame indices are supported.");
2958 if (ClusterSize > 2)
2972 unsigned FirstOpc = FirstLdSt.
getOpcode();
2973 unsigned SecondOpc = SecondLdSt.
getOpcode();
2984 int64_t Offset1 = 0, Offset2 = 0;
2993 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2994 "getMemOperandWithOffsetWidth return incorrect base op");
2996 assert(Offset1 <= Offset2 &&
"Caller should have ordered offsets.");
2997 return Offset1 + (int64_t)Width1.
getValue() == Offset2;
3004 unsigned Opcode =
MI.getOpcode();
3007 case PPC::INLINEASM:
3008 case PPC::INLINEASM_BR: {
3010 const char *AsmStr =
MI.getOperand(0).getSymbolName();
3013 case TargetOpcode::STACKMAP: {
3017 case TargetOpcode::PATCHPOINT: {
3021 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
3024 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
3031 case TargetOpcode::PATCHABLE_RET: {
3033 unsigned RetOpcode =
MI.getOperand(0).getImm();
3034 bool IsConditional = RetOpcode == PPC::BCCLR;
3035 return (8 + IsConditional) * 4;
3037 case TargetOpcode::BUNDLE:
3038 return getInstBundleSize(
MI);
3040 return get(Opcode).getSize();
3047 return MI.getOpcode() == TargetOpcode::STACKMAP
3048 ? InstSizeVerifyMode::AllowOverEstimate
3049 : InstSizeVerifyMode::ExactSize;
3052std::pair<unsigned, unsigned>
3055 return std::make_pair(TF, 0u);
3060 using namespace PPCII;
3061 static const std::pair<unsigned, const char *> TargetFlags[] = {
3062 {MO_PLT,
"ppc-plt"},
3063 {MO_PIC_FLAG,
"ppc-pic"},
3064 {MO_PCREL_FLAG,
"ppc-pcrel"},
3065 {MO_GOT_FLAG,
"ppc-got"},
3066 {MO_PCREL_OPT_FLAG,
"ppc-opt-pcrel"},
3067 {MO_TLSGD_FLAG,
"ppc-tlsgd"},
3068 {MO_TPREL_FLAG,
"ppc-tprel"},
3069 {MO_TLSLDM_FLAG,
"ppc-tlsldm"},
3070 {MO_TLSLD_FLAG,
"ppc-tlsld"},
3071 {MO_TLSGDM_FLAG,
"ppc-tlsgdm"},
3072 {MO_GOT_TLSGD_PCREL_FLAG,
"ppc-got-tlsgd-pcrel"},
3073 {MO_GOT_TLSLD_PCREL_FLAG,
"ppc-got-tlsld-pcrel"},
3074 {MO_GOT_TPREL_PCREL_FLAG,
"ppc-got-tprel-pcrel"},
3077 {MO_TPREL_LO,
"ppc-tprel-lo"},
3078 {MO_TPREL_HA,
"ppc-tprel-ha"},
3079 {MO_DTPREL_LO,
"ppc-dtprel-lo"},
3080 {MO_TLSLD_LO,
"ppc-tlsld-lo"},
3081 {MO_TOC_LO,
"ppc-toc-lo"},
3082 {MO_TLS,
"ppc-tls"},
3083 {MO_PIC_HA_FLAG,
"ppc-ha-pic"},
3084 {MO_PIC_LO_FLAG,
"ppc-lo-pic"},
3085 {MO_TPREL_PCREL_FLAG,
"ppc-tprel-pcrel"},
3086 {MO_TLS_PCREL_FLAG,
"ppc-tls-pcrel"},
3087 {MO_GOT_PCREL_FLAG,
"ppc-got-pcrel"},
3099 unsigned UpperOpcode, LowerOpcode;
3100 switch (
MI.getOpcode()) {
3101 case PPC::DFLOADf32:
3102 UpperOpcode = PPC::LXSSP;
3103 LowerOpcode = PPC::LFS;
3105 case PPC::DFLOADf64:
3106 UpperOpcode = PPC::LXSD;
3107 LowerOpcode = PPC::LFD;
3109 case PPC::DFSTOREf32:
3110 UpperOpcode = PPC::STXSSP;
3111 LowerOpcode = PPC::STFS;
3113 case PPC::DFSTOREf64:
3114 UpperOpcode = PPC::STXSD;
3115 LowerOpcode = PPC::STFD;
3117 case PPC::XFLOADf32:
3118 UpperOpcode = PPC::LXSSPX;
3119 LowerOpcode = PPC::LFSX;
3121 case PPC::XFLOADf64:
3122 UpperOpcode = PPC::LXSDX;
3123 LowerOpcode = PPC::LFDX;
3125 case PPC::XFSTOREf32:
3126 UpperOpcode = PPC::STXSSPX;
3127 LowerOpcode = PPC::STFSX;
3129 case PPC::XFSTOREf64:
3130 UpperOpcode = PPC::STXSDX;
3131 LowerOpcode = PPC::STFDX;
3134 UpperOpcode = PPC::LXSIWAX;
3135 LowerOpcode = PPC::LFIWAX;
3138 UpperOpcode = PPC::LXSIWZX;
3139 LowerOpcode = PPC::LFIWZX;
3142 UpperOpcode = PPC::STXSIWX;
3143 LowerOpcode = PPC::STFIWX;
3149 Register TargetReg =
MI.getOperand(0).getReg();
3151 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3152 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3153 Opcode = LowerOpcode;
3155 Opcode = UpperOpcode;
3156 MI.setDesc(
get(Opcode));
3165 auto &
MBB = *
MI.getParent();
3166 auto DL =
MI.getDebugLoc();
3168 switch (
MI.getOpcode()) {
3169 case PPC::BUILD_UACC: {
3172 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3173 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3174 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3178 for (
int VecNo = 0; VecNo < 4; VecNo++)
3188 case PPC::KILL_PAIR: {
3189 MI.setDesc(
get(PPC::UNENCODED_NOP));
3190 MI.removeOperand(1);
3191 MI.removeOperand(0);
3194 case TargetOpcode::LOAD_STACK_GUARD: {
3195 auto M =
MBB.getParent()->getFunction().getParent();
3197 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() ==
"tls") &&
3198 "Only Linux target or tls mode are expected to contain "
3199 "LOAD_STACK_GUARD");
3201 if (M->getStackProtectorGuard() ==
"tls")
3202 Offset = M->getStackProtectorGuardOffset();
3204 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3205 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3206 MI.setDesc(
get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3212 case PPC::PPCLdFixedAddr: {
3213 assert((Subtarget.getTargetTriple().isOSGlibc() ||
3214 Subtarget.getTargetTriple().isMusl()) &&
3215 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3217 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3218 MI.setDesc(
get(PPC::LWZ));
3219 uint64_t FAType =
MI.getOperand(1).getImm();
3220#undef PPC_LNX_FEATURE
3222#define PPC_LNX_DEFINE_OFFSETS
3223#include "llvm/TargetParser/PPCTargetParser.def"
3224 bool IsLE = Subtarget.isLittleEndian();
3225 bool Is64 = Subtarget.isPPC64();
3226 if (FAType == PPC_FAWORD_HWCAP) {
3228 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3230 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3231 }
else if (FAType == PPC_FAWORD_HWCAP2) {
3233 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3235 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3236 }
else if (FAType == PPC_FAWORD_CPUID) {
3238 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3240 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3242 assert(
Offset &&
"Do not know the offset for this fixed addr load");
3243 MI.removeOperand(1);
3244 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3249#define PPC_TGT_PARSER_UNDEF_MACROS
3250#include "llvm/TargetParser/PPCTargetParser.def"
3251#undef PPC_TGT_PARSER_UNDEF_MACROS
3253 case PPC::DFLOADf32:
3254 case PPC::DFLOADf64:
3255 case PPC::DFSTOREf32:
3256 case PPC::DFSTOREf64: {
3257 assert(Subtarget.hasP9Vector() &&
3258 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3261 "D-form op must have register and immediate operands");
3264 case PPC::XFLOADf32:
3265 case PPC::XFSTOREf32:
3269 assert(Subtarget.hasP8Vector() &&
3270 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3271 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3272 "X-form op must have register and register operands");
3275 case PPC::XFLOADf64:
3276 case PPC::XFSTOREf64: {
3277 assert(Subtarget.hasVSX() &&
3278 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3279 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3280 "X-form op must have register and register operands");
3283 case PPC::SPILLTOVSR_LD: {
3284 Register TargetReg =
MI.getOperand(0).getReg();
3285 if (PPC::VSFRCRegClass.
contains(TargetReg)) {
3286 MI.setDesc(
get(PPC::DFLOADf64));
3290 MI.setDesc(
get(PPC::LD));
3293 case PPC::SPILLTOVSR_ST: {
3295 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3296 NumStoreSPILLVSRRCAsVec++;
3297 MI.setDesc(
get(PPC::DFSTOREf64));
3300 NumStoreSPILLVSRRCAsGpr++;
3301 MI.setDesc(
get(PPC::STD));
3305 case PPC::SPILLTOVSR_LDX: {
3306 Register TargetReg =
MI.getOperand(0).getReg();
3307 if (PPC::VSFRCRegClass.
contains(TargetReg))
3308 MI.setDesc(
get(PPC::LXSDX));
3310 MI.setDesc(
get(PPC::LDX));
3313 case PPC::SPILLTOVSR_STX: {
3315 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3316 NumStoreSPILLVSRRCAsVec++;
3317 MI.setDesc(
get(PPC::STXSDX));
3319 NumStoreSPILLVSRRCAsGpr++;
3320 MI.setDesc(
get(PPC::STDX));
3327 case PPC::CFENCE8: {
3328 auto Val =
MI.getOperand(0).getReg();
3329 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3335 MI.setDesc(
get(PPC::ISYNC));
3336 MI.removeOperand(0);
3339 case PPC::LWAT_CSNE_PSEUDO:
3340 case PPC::LDAT_CSNE_PSEUDO:
3350static unsigned selectReg(int64_t Imm1, int64_t Imm2,
unsigned CompareOpc,
3351 unsigned TrueReg,
unsigned FalseReg,
3352 unsigned CRSubReg) {
3354 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3358 return Imm1 < Imm2 ? TrueReg : FalseReg;
3360 return Imm1 > Imm2 ? TrueReg : FalseReg;
3362 return Imm1 == Imm2 ? TrueReg : FalseReg;
3366 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3374 return Imm1 == Imm2 ? TrueReg : FalseReg;
3377 return PPC::NoRegister;
3382 int64_t
Imm)
const {
3383 assert(
MI.getOperand(OpNo).isReg() &&
"Operand must be a REG");
3385 Register InUseReg =
MI.getOperand(OpNo).getReg();
3386 MI.getOperand(OpNo).ChangeToImmediate(
Imm);
3393 int UseOpIdx =
MI.findRegisterUseOperandIdx(InUseReg, &RI,
false);
3394 if (UseOpIdx >= 0) {
3404 MI.removeOperand(UseOpIdx);
3413 int OperandToKeep = LII.
SetCR ? 1 : 0;
3414 for (
int i =
MI.getNumOperands() - 1; i > OperandToKeep; i--)
3415 MI.removeOperand(i);
3419 MI.setDesc(
get(LII.
Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3434 bool &SeenIntermediateUse)
const {
3435 assert(!
MI.getParent()->getParent()->getRegInfo().isSSA() &&
3436 "Should be called after register allocation.");
3439 SeenIntermediateUse =
false;
3440 for (; It != E; ++It) {
3441 if (It->modifiesRegister(Reg, &RI))
3443 if (It->readsRegister(Reg, &RI))
3444 SeenIntermediateUse =
true;
3452 int64_t
Imm)
const {
3453 assert(!
MBB.getParent()->getRegInfo().isSSA() &&
3454 "Register should be in non-SSA form after RA");
3455 bool isPPC64 = Subtarget.isPPC64();
3469 assert(isPPC64 &&
"Materializing 64-bit immediate to single register is "
3470 "only supported in PPC64");
3472 if ((
Imm >> 32) & 0xFFFF)
3492 unsigned &OpNoForForwarding,
3493 bool &SeenIntermediateUse)
const {
3494 OpNoForForwarding = ~0U;
3501 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3502 if (!
MI.getOperand(i).isReg())
3505 if (!Reg.isVirtual())
3507 Register TrueReg = RI.lookThruCopyLike(Reg, MRI);
3510 if (!DefMIForTrueReg)
3512 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3513 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3514 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3515 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3516 OpNoForForwarding = i;
3517 DefMI = DefMIForTrueReg;
3522 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3532 unsigned Opc =
MI.getOpcode();
3533 bool ConvertibleImmForm =
3534 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3535 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3536 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3537 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3538 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3539 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3540 Opc == PPC::RLWINM8_rec;
3541 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3548 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3549 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3551 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3552 MachineOperand &MO =
MI.getOperand(i);
3553 SeenIntermediateUse =
false;
3567 case PPC::ADDItocL8:
3570 OpNoForForwarding = i;
3577 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3580unsigned PPCInstrInfo::getSpillTarget()
const {
3583 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3585 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3586 2 : Subtarget.hasP9Vector() ?
3625 bool PostRA = !MRI->
isSSA();
3631 unsigned ToBeDeletedReg = 0;
3632 int64_t OffsetImm = 0;
3633 unsigned XFormOpcode = 0;
3641 bool OtherIntermediateUse =
false;
3645 if (OtherIntermediateUse || !ADDMI)
3652 unsigned ScaleRegIdx = 0;
3653 int64_t OffsetAddi = 0;
3667 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3672 for (
auto It = ++Start; It != End; It++)
3681 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3686 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3702 MI.setDesc(
get(XFormOpcode));
3704 .ChangeToRegister(ScaleReg,
false,
false,
3708 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3720 int64_t &
Imm)
const {
3724 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3740 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3744 unsigned &ToBeDeletedReg,
3745 unsigned &XFormOpcode,
3749 if (!
MI.mayLoadOrStore())
3752 unsigned Opc =
MI.getOpcode();
3754 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3757 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3771 if (!ImmOperand.
isImm())
3774 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3777 if (!RegOperand.
isKill())
3780 ToBeDeletedReg = RegOperand.
getReg();
3781 OffsetImm = ImmOperand.
getImm();
3788 int64_t &OffsetAddi,
3789 int64_t OffsetImm)
const {
3790 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3796 bool OtherIntermediateUse =
false;
3817 if (OtherIntermediateUse || !ADDIMI)
3836 bool PostRA = !MRI->
isSSA();
3837 bool SeenIntermediateUse =
true;
3838 unsigned ForwardingOperand = ~0U;
3840 SeenIntermediateUse);
3843 assert(ForwardingOperand <
MI.getNumOperands() &&
3844 "The forwarding operand needs to be valid at this point");
3845 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3846 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3847 if (KilledDef && KillFwdDefMI)
3861 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3862 PPC::INSTRUCTION_LIST_END &&
3863 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3867 bool IsVFReg =
MI.getOperand(0).isReg() &&
3868 MI.getOperand(0).getReg().isPhysical() &&
3875 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3882 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3888 simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef, &RegsToUpdate))
3897 Register FoldingReg =
MI.getOperand(1).getReg();
3903 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3904 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3908 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3911 "Invalid PPC::RLWINM Instruction!");
3913 uint64_t SHMI =
MI.getOperand(2).getImm();
3915 uint64_t MBMI =
MI.getOperand(3).getImm();
3917 uint64_t MEMI =
MI.getOperand(4).getImm();
3919 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3920 "Invalid PPC::RLWINM Instruction!");
3942 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3945 if ((MBMI > MEMI) && !SrcMaskFull)
3955 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3956 APInt FinalMask = RotatedSrcMask & MaskMI;
3958 bool Simplified =
false;
3961 if (FinalMask.
isZero()) {
3963 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3968 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3970 MI.removeOperand(4);
3971 MI.removeOperand(3);
3972 MI.removeOperand(2);
3973 MI.getOperand(1).ChangeToImmediate(0);
3974 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
3977 MI.removeOperand(4);
3978 MI.removeOperand(3);
3979 MI.getOperand(2).setImm(0);
3980 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3983 MI.getOperand(1).setIsKill(
true);
3987 MI.getOperand(1).setIsKill(
false);
4003 uint16_t NewSH = (SHSrc + SHMI) % 32;
4004 MI.getOperand(2).setImm(NewSH);
4007 MI.getOperand(3).setImm(NewMB);
4008 MI.getOperand(4).setImm(NewME);
4012 MI.getOperand(1).setIsKill(
true);
4016 MI.getOperand(1).setIsKill(
false);
4046 default:
return false;
4054 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4063 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4079 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4087 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4095 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4115 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4116 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4117 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4118 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4123 case PPC::RLWNM_rec:
4124 case PPC::RLWNM8_rec:
4144 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4145 Opc == PPC::RLWNM8_rec)
4151 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4152 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4153 case PPC::RLWNM_rec:
4156 case PPC::RLWNM8_rec:
4159 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4160 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4167 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4168 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4188 case PPC::RLDCL_rec:
4190 case PPC::RLDCR_rec:
4206 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4207 Opc == PPC::RLDCR_rec)
4213 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4214 case PPC::RLDCL_rec:
4217 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4218 case PPC::RLDCR_rec:
4221 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4225 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4272 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4273 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4274 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4275 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4276 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4277 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4278 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4279 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4285 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4286 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4287 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4288 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4289 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4290 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4291 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4292 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4297 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4298 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4330 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4331 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4332 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4333 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4334 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4335 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4336 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4337 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4342 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4343 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4344 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4345 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4346 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4347 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4348 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4349 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4354 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4355 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4368 case PPC::XFLOADf32:
4369 case PPC::XFLOADf64:
4370 case PPC::XFSTOREf32:
4371 case PPC::XFSTOREf64:
4372 if (!Subtarget.hasP9Vector())
4399 case PPC::XFLOADf32:
4413 case PPC::XFLOADf64:
4431 case PPC::XFSTOREf32:
4445 case PPC::XFSTOREf64:
4456 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4458 unsigned MaxOp = std::max(Op1, Op2);
4459 unsigned MinOp = std::min(Op1, Op2);
4462 MI.removeOperand(std::max(Op1, Op2));
4463 MI.removeOperand(std::min(Op1, Op2));
4467 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4468 MI.addOperand(MOp2);
4469 MI.addOperand(MOp1);
4474 unsigned TotalOps =
MI.getNumOperands() + 2;
4475 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4477 MI.removeOperand(i);
4480 MI.addOperand(MOp2);
4482 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4484 MI.addOperand(MOp1);
4486 MI.addOperand(MOps.
back());
4497 unsigned OpNoForForwarding
4501 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4538 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4544 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4548 "Add inst must have at least three operands");
4549 RegMO = &
DefMI.getOperand(1);
4550 ImmMO = &
DefMI.getOperand(2);
4553 if (!RegMO->
isReg())
4562bool PPCInstrInfo::isRegElgibleForForwarding(
4565 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4572 const MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4582 for (; It !=
E; ++It) {
4586 IsFwdFeederRegKilled =
true;
4588 SeenIntermediateUse =
true;
4590 if ((&*It) == &
DefMI)
4603bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4607 int64_t BaseImm)
const {
4609 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4630 if (ImmMO.
isImm()) {
4635 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4656 unsigned OpNoForForwarding,
4659 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4660 !
DefMI.getOperand(1).isImm())
4664 MachineRegisterInfo *MRI = &MF->
getRegInfo();
4667 int64_t Immediate =
DefMI.getOperand(1).getImm();
4671 bool ReplaceWithLI =
false;
4672 bool Is64BitLI =
false;
4675 unsigned Opc =
MI.getOpcode();
4698 int64_t Comparand =
MI.getOperand(2).getImm();
4699 int64_t SExtComparand = ((
uint64_t)Comparand & ~0x7FFFuLL) != 0
4700 ? (Comparand | 0xFFFFFFFFFFFF0000)
4704 unsigned UseOpc = CompareUseMI.getOpcode();
4705 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4707 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4708 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4709 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4710 unsigned RegToCopy =
4711 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4712 if (RegToCopy == PPC::NoRegister)
4715 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4716 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4718 CompareUseMI.removeOperand(3);
4719 CompareUseMI.removeOperand(2);
4723 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4727 for (
const MachineOperand &MO : CompareUseMI.operands())
4732 CompareUseMI.setDesc(
get(PPC::COPY));
4733 CompareUseMI.removeOperand(3);
4734 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4735 CmpIselsConverted++;
4744 MissedConvertibleImmediateInstrs++;
4752 int64_t Addend =
MI.getOperand(2).getImm();
4754 ReplaceWithLI =
true;
4755 Is64BitLI =
Opc == PPC::ADDI8;
4756 NewImm = Addend + SExtImm;
4762 case PPC::SUBFIC8: {
4764 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4766 int64_t Minuend =
MI.getOperand(2).getImm();
4768 ReplaceWithLI =
true;
4769 Is64BitLI =
Opc == PPC::SUBFIC8;
4770 NewImm = Minuend - SExtImm;
4776 case PPC::RLDICL_rec:
4777 case PPC::RLDICL_32:
4778 case PPC::RLDICL_32_64: {
4780 int64_t SH =
MI.getOperand(2).getImm();
4781 int64_t MB =
MI.getOperand(3).getImm();
4782 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4784 InVal = InVal.rotl(SH);
4791 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4792 ReplaceWithLI =
true;
4793 Is64BitLI =
Opc != PPC::RLDICL_32;
4794 NewImm = InVal.getSExtValue();
4795 SetCR =
Opc == PPC::RLDICL_rec;
4802 case PPC::RLWINM_rec:
4803 case PPC::RLWINM8_rec: {
4804 int64_t SH =
MI.getOperand(2).getImm();
4805 int64_t MB =
MI.getOperand(3).getImm();
4806 int64_t ME =
MI.getOperand(4).getImm();
4807 APInt InVal(32, SExtImm,
true);
4808 InVal = InVal.rotl(SH);
4814 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4815 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4818 ReplaceWithLI =
true;
4819 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4820 NewImm = InVal.getSExtValue();
4821 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4830 int64_t LogicalImm =
MI.getOperand(2).getImm();
4832 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4833 Result = LogicalImm | SExtImm;
4835 Result = LogicalImm ^ SExtImm;
4837 ReplaceWithLI =
true;
4838 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4846 if (ReplaceWithLI) {
4851 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4852 if (PostRA && ImmChanged)
4859 DefMI.getOperand(1).setImm(NewImm);
4863 else if (MRI->
use_empty(
MI.getOperand(0).getReg())) {
4865 assert(Immediate &&
"Transformation converted zero to non-zero?");
4868 }
else if (ImmChanged)
4877 LoadImmediateInfo LII;
4883 if (KilledDef && SetCR)
4884 *KilledDef =
nullptr;
4897bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4899 MachineRegisterInfo *MRI = &
MI.getParent()->getParent()->getRegInfo();
4907 if (!
MI.mayLoadOrStore())
4910 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4912 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4913 "MI must have x-form opcode");
4917 bool IsVFReg =
MI.getOperand(0).isReg() &&
4918 MI.getOperand(0).getReg().isPhysical() &&
4930 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4931 if (!ImmOperandMI.
isImm())
4935 MachineOperand *ImmMO =
nullptr;
4936 MachineOperand *RegMO =
nullptr;
4937 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4939 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4944 int64_t ImmBase = ImmOperandMI.
getImm();
4946 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm, ImmBase))
4950 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4967bool PPCInstrInfo::transformToImmFormFedByAdd(
4977 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
4982 MachineOperand *ImmMO =
nullptr;
4983 MachineOperand *RegMO =
nullptr;
4984 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4986 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4991 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm))
4994 bool IsFwdFeederRegKilled =
false;
4995 bool SeenIntermediateUse =
false;
4997 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
4998 IsFwdFeederRegKilled, SeenIntermediateUse))
5001 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5018 if (ImmMO->
isImm()) {
5029 if (
DefMI.getOpcode() == PPC::ADDItocL8)
5039 MI.removeOperand(i);
5045 MI.addOperand(*ImmMO);
5047 for (
auto &MO : MOps)
5064 unsigned ConstantOpNo,
5067 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5068 !
DefMI.getOperand(1).isImm())
5074 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5084 APInt ActualValue(64,
Imm,
true);
5085 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5099 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5103 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5106 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5107 ConstantOpNo != PosForOrigZero)
5111 unsigned Opc =
MI.getOpcode();
5112 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5113 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5114 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5115 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5116 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5117 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5118 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5119 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5121 Opc == PPC::SRD_rec;
5135 if (SpecialShift32 || SpecialShift64) {
5136 LoadImmediateInfo LII;
5140 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5141 if (
Imm & (SpecialShift32 ? 0x20 : 0x40))
5146 else if (!SetCR && ShAmt == 0 && !PostRA) {
5147 MI.removeOperand(2);
5148 MI.setDesc(
get(PPC::COPY));
5151 if (SpecialShift32) {
5159 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5168 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5198 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5215 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5216 return &PPC::VSRCRegClass;
5221 return PPC::getRecordFormOpcode(Opcode);
5225 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5226 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5227 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5228 Opcode == PPC::LHZUX8);
5242 int Opcode =
MI->getOpcode();
5243 if (
TII.isSExt32To64(Opcode))
5252 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5258 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5259 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5260 MI->getOperand(3).getImm() > 0 &&
5261 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5266 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5268 if ((
Imm & 0x8000) == 0)
5288 int Opcode =
MI->getOpcode();
5289 if (
TII.isZExt32To64(Opcode))
5294 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5295 MI->getOperand(0).getReg() ==
Reg)
5300 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5301 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5302 int64_t
Imm =
MI->getOperand(1).getImm();
5309 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5310 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5311 Opcode == PPC::RLDICL_32_64) &&
5312 MI->getOperand(3).getImm() >= 32)
5315 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5316 MI->getOperand(3).getImm() >= 32 &&
5317 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5320 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5321 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5322 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5323 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5332 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5334 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5336 Register StackReg =
MI.getOperand(2).getReg();
5359 unsigned BinOpDepth,
5361 if (!Reg.isVirtual())
5368 unsigned Opcode =
MI->getOpcode();
5377 unsigned OperandEnd = 3, OperandStride = 1;
5378 if (Opcode == PPC::PHI) {
5379 OperandEnd =
MI->getNumOperands();
5383 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5384 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5386 BinOpDepth + 1, LV);
5395 Register SrcReg =
MI->getOperand(1).getReg();
5409 if (SrcReg != PPC::X3)
5432 BinOpDepth + 1, LV);
5434 BinOpDepth + 1, LV);
5439 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5446 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5447 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5448 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5449 {PPC::AND, PPC::AND8}};
5452 auto It = OpcodeMap.
find(Opcode);
5453 if (It != OpcodeMap.
end()) {
5455 NewOpcode = It->second;
5463 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5466 assert(NewOpcode != -1 &&
5467 "Must have a 64-bit opcode to map the 32-bit opcode!");
5471 RI.getRegClass(
MCID.operands()[0].RegClass);
5473 Register SrcReg =
MI->getOperand(0).getReg();
5483 auto MBB =
MI->getParent();
5491 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5493 if (!Operand.
isReg())
5501 RI.getRegClass(
MCID.operands()[i].RegClass);
5503 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5504 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5513 PromoteRegs[i] = DstTmpReg;
5523 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5530 for (
unsigned i = 1; i < Iter->getNumOperands(); i++) {
5532 if (!Operand.
isReg())
5540 MI->eraseFromParent();
5556std::pair<bool, bool>
5558 const unsigned BinOpDepth,
5561 return std::pair<bool, bool>(
false,
false);
5565 return std::pair<bool, bool>(
false,
false);
5572 if (IsSExt && IsZExt)
5573 return std::pair<bool, bool>(IsSExt, IsZExt);
5575 switch (
MI->getOpcode()) {
5577 Register SrcReg =
MI->getOperand(1).getReg();
5586 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5587 SrcExt.second || IsZExt);
5593 if (
MI->getParent()->getBasicBlock() ==
5599 return std::pair<bool, bool>(IsSExt, IsZExt);
5603 if (SrcReg != PPC::X3) {
5606 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5607 SrcExt.second || IsZExt);
5617 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5620 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5621 return IsExtendPair;
5625 return IsExtendPair;
5630 return IsExtendPair;
5632 if (IntTy && IntTy->getBitWidth() <= 32) {
5634 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5635 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5636 return std::pair<bool, bool>(IsSExt, IsZExt);
5639 return IsExtendPair;
5648 Register SrcReg =
MI->getOperand(1).getReg();
5650 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5651 SrcExt.second || IsZExt);
5662 Register SrcReg =
MI->getOperand(1).getReg();
5664 uint16_t
Imm =
MI->getOperand(2).getImm();
5666 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5668 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5669 SrcExt.second || IsZExt);
5679 return std::pair<bool, bool>(
false,
false);
5683 unsigned OperandEnd = 3, OperandStride = 1;
5684 if (
MI->getOpcode() == PPC::PHI) {
5685 OperandEnd =
MI->getNumOperands();
5691 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5692 if (!
MI->getOperand(
I).isReg())
5693 return std::pair<bool, bool>(
false,
false);
5697 IsSExt &= SrcExt.first;
5698 IsZExt &= SrcExt.second;
5700 return std::pair<bool, bool>(IsSExt, IsZExt);
5709 return std::pair<bool, bool>(
false,
false);
5711 Register SrcReg1 =
MI->getOperand(1).getReg();
5712 Register SrcReg2 =
MI->getOperand(2).getReg();
5715 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5716 Src1Ext.second || Src2Ext.second);
5722 return std::pair<bool, bool>(IsSExt, IsZExt);
5726 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5739 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5741 TII(MF->getSubtarget().getInstrInfo()) {
5750 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5752 return MI == EndLoop;
5755 std::optional<bool> createTripCountGreaterCondition(
5756 int TC, MachineBasicBlock &
MBB,
5757 SmallVectorImpl<MachineOperand> &
Cond)
override {
5758 if (TripCount == -1) {
5763 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5768 return TripCount > TC;
5771 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5776 void adjustTripCount(
int TripCountAdjust)
override {
5779 if (LoopCount->
getOpcode() == PPC::LI8 ||
5790 void disposed(LiveIntervals *LIS)
override {
5795 Loop->eraseFromParent();
5802std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5807 if (Preheader == LoopBB)
5808 Preheader = *std::next(LoopBB->
pred_begin());
5811 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5814 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5817 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5827 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5830 for (
auto &
I : PreHeader.
instrs())
5831 if (
I.getOpcode() == LOOPi)
5873 int64_t OffsetA = 0, OffsetB = 0;
5879 int LowOffset = std::min(OffsetA, OffsetB);
5880 int HighOffset = std::max(OffsetA, OffsetB);
5881 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5883 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
5897 bool IsLDAT =
MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
5903 if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
5907 Register DstReg64 = IsLDAT ? DstReg
5909 DstReg, PPC::sub_32, &PPC::G8RCRegClass));
5911 ScratchReg = DstReg64;
5919 if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
5921 .
addReg(IsLDAT ? PPC::X8 : PPC::R8)
5922 .
addReg(IsLDAT ? PPC::X8 : PPC::R8);
5924 MI.eraseFromParent();
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
static bool isOpZeroOfSubwordPreincLoad(int Opcode)
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
static cl::opt< float > FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5), cl::desc("register pressure factor for the transformations."))
#define InfoArrayIdxMULOpIdx
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, unsigned TrueReg, unsigned FalseReg, unsigned CRSubReg)
static unsigned getCRBitValue(unsigned CRBit)
static bool isAnImmediateOperand(const MachineOperand &MO)
static const uint16_t FMAOpIdxInfo[][6]
static cl::opt< bool > DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops"))
#define InfoArrayIdxAddOpIdx
static cl::opt< bool > UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation"))
static bool definedBySignExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMAInst
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc, const PPCSubtarget &Subtarget)
static cl::opt< bool > EnableFMARegPressureReduction("ppc-fma-rp-reduction", cl::Hidden, cl::init(true), cl::desc("enable register pressure reduce in machine combiner pass."))
static bool isLdStSafeToCluster(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
const unsigned MAX_BINOP_DEPTH
static cl::opt< bool > DisableCmpOpt("disable-ppc-cmp-opt", cl::desc("Disable compare instruction optimization"), cl::Hidden)
#define InfoArrayIdxFSubInst
#define InfoArrayIdxFAddInst
static bool definedByZeroExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMULInst
static cl::opt< bool > VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool isPhysical(const MachineOperand &MO)
This file declares the machine register scavenger class.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
LLVM_ABI APInt rotl(unsigned rotateAmt) const
Rotate left by rotateAmt.
static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit, unsigned hiBit)
Wrap version of getBitsSet.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
Get the array size.
This class holds the attributes for a particular argument, parameter, function, or return value.
This is an important base class in LLVM.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const BasicBlock & getEntryBlock() const
AttributeList getAttributes() const
Return the attribute list for this Function.
Type * getReturnType() const
Returns the type of the ret val.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Itinerary data supplied by a subtarget to be used by a target.
std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
Class to represent integer types.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
Represents a single loop in the control flow graph.
Instances of this class represent a single low-level machine instruction.
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
ArrayRef< MCPhysReg > implicit_uses() const
Return a list of registers that are potentially read by any instance of this machine instruction.
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
This holds information about one operand of a machine instruction, indicating the register class for ...
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasImplicitDef() const
Returns true if the instruction has implicit definition.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
LLVM_ABI void clearRegisterDeads(Register Reg)
Clear all dead flags on operands defining register Reg.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
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)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI bool isLiveIn(Register Reg) const
static use_instr_iterator use_instr_end()
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based hazard recognizer for P...
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isLiveInSExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and sign-extended.
bool isLiveInZExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and zero-extended.
PPCHazardRecognizer970 - This class defines a finite state automata that models the dispatch logic on...
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for a fma chain ending in Root.
bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase=nullptr) const
bool isReMaterializableImpl(const MachineInstr &MI) const override
PPCInstrInfo(const PPCSubtarget &STI)
const TargetRegisterClass * updatedRC(const TargetRegisterClass *RC) const
bool isPredicated(const MachineInstr &MI) const override
bool expandVSXMemPseudo(MachineInstr &MI) const
bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
Fixup the placeholders we put in genAlternativeCodeSequence() for MachineCombiner.
MCInst getNop() const override
Return the noop instruction to use for a noop.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static int getRecordFormOpcode(unsigned Opcode)
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
bool isXFormMemOp(unsigned Opcode) const
const PPCRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
CombinerObjective getCombinerObjective(unsigned Pattern) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const
unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const
bool expandAMOCSNEPseudo(MachineInstr &MI) const
void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth, LiveVariables *LV) const
bool isTOCSaveMI(const MachineInstr &MI) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer to use for this target when ...
bool isSExt32To64(unsigned Opcode) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool isBDNZ(unsigned Opcode) const
Check Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isZeroExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
std::pair< bool, bool > isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, const MachineRegisterInfo *MRI) const
bool expandPostRAPseudo(MachineInstr &MI) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index, MachineInstr *&ADDIMI, int64_t &OffsetAddi, int64_t OffsetImm) const
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
void materializeImmPostRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register Reg, int64_t Imm) const
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
Return true if two MIs access different memory addresses and false otherwise.
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
CreateTargetHazardRecognizer - Return the hazard recognizer to use for this target when scheduling th...
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
Get the base operand and byte offset of an instruction that reads/writes memory.
void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const
void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const
bool foldFrameOffset(MachineInstr &MI) const
bool isLoadFromConstantPool(MachineInstr *I) const
MachineInstr * findLoopInstr(MachineBasicBlock &PreHeader, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
bool convertToImmediateForm(MachineInstr &MI, SmallSet< Register, 4 > &RegsToUpdate, MachineInstr **KilledDef=nullptr) const
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
Return true if get the base operand, byte offset of an instruction and the memory width.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool shouldReduceRegisterPressure(const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const override
On PowerPC, we leverage machine combiner pass to reduce register pressure when the register pressure ...
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
InstSizeVerifyMode getInstSizeVerifyMode(const MachineInstr &MI) const override
bool isSignExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, int64_t Imm) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
Returns true if the two given memory operations should be scheduled adjacent.
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...
bool optimizeCmpPostRA(MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
const Constant * getConstantFromConstantPool(MachineInstr *I) const
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, bool PostRA) const
MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const
static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg)
const PPCTargetMachine & getTargetMachine() const
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void closeRegion()
Finalize the region boundaries and recored live ins and live outs.
LLVM_ABI void recede(SmallVectorImpl< VRegMaskOrUnit > *LiveUses=nullptr)
Recede across the previous instruction.
RegisterPressure & getPressure()
Get the resulting register pressure over the traversed region.
LLVM_ABI void recedeSkipDebugValues()
Recede until we find an instruction which is not a DebugValue.
LLVM_ABI void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)
Setup the RegPressureTracker.
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
List of registers defined and used by a machine instruction.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const TargetInstrInfo * TII
Target instruction information.
MachineFunction & MF
Machine function.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
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...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
StackOffset holds a fixed and a scalable offset in bytes.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const Triple & getTargetTriple() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
bool isOSAIX() const
Tests whether the OS is AIX.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
#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.
PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.
Define some predicates that are used for node matching.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
int32_t getNonRecordFormOpcode(uint32_t)
int32_t getAltVSXFMAOpcode(uint32_t Opcode)
static bool isVFRegister(MCRegister Reg)
template class LLVM_TEMPLATE_ABI opt< bool >
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static unsigned getCRFromCRBit(unsigned SrcReg)
constexpr RegState getDeadRegState(bool B)
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
@ MustReduceRegisterPressure
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t IsSummingOperands
uint64_t OpNoForForwarding
uint64_t ImmMustBeMultipleOf
uint64_t ZeroIsSpecialNew
uint64_t ZeroIsSpecialOrig
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.