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");
72 cl::desc(
"Enable compare instruction optimization"),
76 "ppc-crash-on-vsx-self-copy",
78 "Causes the backend to crash instead of generating a nop VSX copy"),
83 cl::desc(
"Use the old (incorrect) instruction latency calculation"));
87 cl::desc(
"register pressure factor for the transformations."));
91 cl::desc(
"enable register pressure reduce in machine combiner pass."));
94void PPCInstrInfo::anchor() {}
99 STI.isPPC64() ?
PPC::BLR8 :
PPC::BLR),
100 Subtarget(STI), RI(STI.getTargetMachine()) {}
104 return Subtarget.isPPC64() ? &PPC::G8RC_NOX0RegClass
105 : &PPC::GPRC_NOR0RegClass;
114 static_cast<const PPCSubtarget *
>(STI)->getCPUDirective();
118 static_cast<const PPCSubtarget *
>(STI)->getInstrItineraryData();
150 unsigned *PredCost)
const {
152 return PPCGenInstrInfo::getInstrLatency(ItinData,
MI, PredCost);
162 unsigned DefClass =
MI.getDesc().getSchedClass();
163 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
168 std::optional<unsigned> Cycle = ItinData->
getOperandCycle(DefClass, i);
181 std::optional<unsigned>
Latency = PPCGenInstrInfo::getOperandLatency(
184 if (!
DefMI.getParent())
191 if (Reg.isVirtual()) {
193 &
DefMI.getParent()->getParent()->getRegInfo();
197 IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
198 PPC::CRBITRCRegClass.contains(Reg);
201 if (
UseMI.isBranch() && IsRegCR) {
207 unsigned Directive = Subtarget.getCPUDirective();
281#define InfoArrayIdxFMAInst 0
282#define InfoArrayIdxFAddInst 1
283#define InfoArrayIdxFMULInst 2
284#define InfoArrayIdxAddOpIdx 3
285#define InfoArrayIdxMULOpIdx 4
286#define InfoArrayIdxFSubInst 5
297 {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
298 {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
299 {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
300 {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
301 {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
302 {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
306int16_t PPCInstrInfo::getFMAOpIdxInfo(
unsigned Opcode)
const {
363 bool DoRegPressureReduce)
const {
367 auto IsAllOpsVirtualReg = [](
const MachineInstr &Instr) {
368 for (
const auto &MO : Instr.explicit_operands())
369 if (!(MO.isReg() && MO.getReg().isVirtual()))
374 auto IsReassociableAddOrSub = [&](
const MachineInstr &Instr,
376 if (Instr.getOpcode() !=
387 if (!IsAllOpsVirtualReg(Instr))
399 auto IsReassociableFMA = [&](
const MachineInstr &Instr, int16_t &AddOpIdx,
400 int16_t &MulOpIdx,
bool IsLeaf) {
401 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
412 if (!IsAllOpsVirtualReg(Instr))
432 int16_t AddOpIdx = -1;
433 int16_t MulOpIdx = -1;
435 bool IsUsedOnceL =
false;
436 bool IsUsedOnceR =
false;
440 auto IsRPReductionCandidate = [&]() {
444 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
449 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
true)) {
450 assert((MulOpIdx >= 0) &&
"mul operand index not right!");
451 Register MULRegL = RI.lookThruSingleUseCopyChain(
453 Register MULRegR = RI.lookThruSingleUseCopyChain(
455 if (!MULRegL && !MULRegR)
458 if (MULRegL && !MULRegR) {
462 }
else if (!MULRegL && MULRegR) {
475 return MULInstrL && MULInstrR;
481 if (DoRegPressureReduce && IsRPReductionCandidate()) {
482 assert((MULInstrL && MULInstrR) &&
"wrong register preduction candidate!");
503 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
false))
506 assert((AddOpIdx >= 0) &&
"add operand index not right!");
513 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx,
false))
516 assert((AddOpIdx >= 0) &&
"add operand index not right!");
521 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx,
true)) {
537 assert(!InsInstrs.
empty() &&
"Instructions set to be inserted is empty!");
543 int16_t Idx = getFMAOpIdxInfo(Root.
getOpcode());
582 for (
auto *Inst : InsInstrs) {
584 assert(Operand.isReg() &&
"Invalid instruction in InsInstrs!");
585 if (Operand.getReg() == PPC::ZERO8) {
586 Placeholder = &Operand;
592 assert(Placeholder &&
"Placeholder does not exist!");
597 generateLoadForNewConst(ConstPoolIdx, &Root,
C->getType(), InsInstrs);
600 Placeholder->setReg(LoadNewConst);
621 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
628 auto GetMBBPressure =
634 RPTracker.
init(
MBB->getParent(), RegClassInfo,
nullptr,
MBB,
MBB->end(),
638 if (
MI.isDebugValue() ||
MI.isDebugLabel())
641 RegOpers.
collect(
MI, RI, *MRI,
false,
false);
644 RPTracker.
recede(RegOpers);
654 unsigned VSSRCLimit =
658 return GetMBBPressure(
MBB)[PPC::RegisterPressureSets::VSSRC] >
664 if (!
I->hasOneMemOperand())
668 return Op->isLoad() &&
Op->getPseudoValue() &&
672Register PPCInstrInfo::generateLoadForNewConst(
678 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
680 "Target not supported!\n");
688 BuildMI(*MF,
MI->getDebugLoc(),
get(PPC::ADDIStocHA8), VReg1)
692 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
693 "Only float and double are supported!");
698 LoadOpcode = PPC::DFLOADf32;
700 LoadOpcode = PPC::DFLOADf64;
730 assert(
I->mayLoad() &&
"Should be a load instruction.\n");
731 for (
auto MO :
I->uses()) {
735 if (Reg == 0 || !Reg.isVirtual())
739 for (
auto MO2 :
DefMI->uses())
741 return (MCP->
getConstants())[MO2.getIndex()].Val.ConstVal;
761 bool DoRegPressureReduce)
const {
771 DoRegPressureReduce);
784 reassociateFMA(Root,
Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
789 DelInstrs, InstrIdxForVirtReg);
794void PPCInstrInfo::reassociateFMA(
807 int16_t Idx = getFMAOpIdxInfo(FmaOp);
808 assert(Idx >= 0 &&
"Root must be a FMA instruction");
810 bool IsILPReassociate =
841 uint32_t IntersectedFlags = 0;
842 if (IsILPReassociate)
847 auto GetOperandInfo = [&](
const MachineOperand &Operand,
Register &
Reg,
851 KillFlag = Operand.
isKill();
854 auto GetFMAInstrInfo = [&](
const MachineInstr &
Instr,
Register &MulOp1,
856 bool &MulOp1KillFlag,
bool &MulOp2KillFlag,
857 bool &AddOpKillFlag) {
858 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
859 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
860 GetOperandInfo(
Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
863 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
865 bool KillX =
false, KillY =
false, KillM11 =
false, KillM12 =
false,
866 KillM21 =
false, KillM22 =
false, KillM31 =
false, KillM32 =
false,
867 KillA11 =
false, KillA21 =
false, KillB =
false;
869 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
871 if (IsILPReassociate)
872 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
875 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
876 GetOperandInfo(Leaf->
getOperand(AddOpIdx), RegX, KillX);
878 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
879 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
882 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
883 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
893 InstrIdxForVirtReg.
insert(std::make_pair(NewVRA, 0));
896 if (IsILPReassociate) {
898 InstrIdxForVirtReg.
insert(std::make_pair(NewVRB, 1));
904 InstrIdxForVirtReg.
insert(std::make_pair(NewVRD, 2));
907 auto AdjustOperandOrder = [&](MachineInstr *
MI,
Register RegAdd,
bool KillAdd,
909 Register RegMul2,
bool KillRegMul2) {
910 MI->getOperand(AddOpIdx).setReg(RegAdd);
911 MI->getOperand(AddOpIdx).setIsKill(KillAdd);
912 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
913 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
914 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
915 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
918 MachineInstrBuilder NewARegPressure, NewCRegPressure;
924 MachineInstrBuilder MINewB =
929 MachineInstrBuilder MINewA =
936 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
937 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
940 MachineInstrBuilder MINewC =
958 assert(NewVRD &&
"new FMA register not created!");
960 MachineInstrBuilder MINewA =
965 MachineInstrBuilder MINewB =
970 MachineInstrBuilder MINewD =
977 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
978 AdjustOperandOrder(MINewD, NewVRA,
true, RegM31, KillM31, RegM32,
982 MachineInstrBuilder MINewC =
1004 bool KillVarReg =
false;
1007 KillVarReg = KillM31;
1010 KillVarReg = KillM32;
1034 if (!IsILPReassociate) {
1043 "Insertion instructions set should not be empty!");
1047 if (IsILPReassociate)
1055 unsigned &SubIdx)
const {
1056 switch (
MI.getOpcode()) {
1057 default:
return false;
1060 case PPC::EXTSW_32_64:
1061 SrcReg =
MI.getOperand(1).getReg();
1062 DstReg =
MI.getOperand(0).getReg();
1063 SubIdx = PPC::sub_32;
1069 int &FrameIndex)
const {
1073 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1074 MI.getOperand(2).isFI()) {
1075 FrameIndex =
MI.getOperand(2).getIndex();
1076 return MI.getOperand(0).getReg();
1086 switch (
MI.getOpcode()) {
1096 case PPC::ADDIStocHA:
1097 case PPC::ADDIStocHA8:
1099 case PPC::ADDItocL8:
1100 case PPC::LOAD_STACK_GUARD:
1101 case PPC::PPCLdFixedAddr:
1103 case PPC::XXLXORspz:
1104 case PPC::XXLXORdpz:
1105 case PPC::XXLEQVOnes:
1106 case PPC::XXSPLTI32DX:
1108 case PPC::XXSPLTIDP:
1112 case PPC::V_SETALLONESB:
1113 case PPC::V_SETALLONESH:
1114 case PPC::V_SETALLONES:
1117 case PPC::XXSETACCZ:
1118 case PPC::DMXXSETACCZ:
1125 int &FrameIndex)
const {
1127 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1128 MI.getOperand(2).isFI()) {
1129 FrameIndex =
MI.getOperand(2).getIndex();
1130 return MI.getOperand(0).getReg();
1138 unsigned OpIdx2)
const {
1142 if (
MI.getOpcode() != PPC::RLWIMI &&
MI.getOpcode() != PPC::RLWIMI_rec)
1150 if (
MI.getOperand(3).getImm() != 0)
1161 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1162 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1166 unsigned SubReg1 =
MI.getOperand(1).getSubReg();
1167 unsigned SubReg2 =
MI.getOperand(2).getSubReg();
1168 bool Reg1IsKill =
MI.getOperand(1).isKill();
1169 bool Reg2IsKill =
MI.getOperand(2).isKill();
1170 bool ChangeReg0 =
false;
1176 "Expecting a two-address instruction!");
1177 assert(
MI.getOperand(0).getSubReg() == SubReg1 &&
"Tied subreg mismatch");
1183 unsigned MB =
MI.getOperand(4).getImm();
1184 unsigned ME =
MI.getOperand(5).getImm();
1188 if (MB == 0 && ME == 31)
1193 Register Reg0 = ChangeReg0 ? Reg2 :
MI.getOperand(0).getReg();
1194 bool Reg0IsDead =
MI.getOperand(0).isDead();
1195 return BuildMI(MF,
MI.getDebugLoc(),
MI.getDesc())
1204 MI.getOperand(0).setReg(Reg2);
1205 MI.getOperand(0).setSubReg(SubReg2);
1207 MI.getOperand(2).setReg(Reg1);
1208 MI.getOperand(1).setReg(Reg2);
1209 MI.getOperand(2).setSubReg(SubReg1);
1210 MI.getOperand(1).setSubReg(SubReg2);
1211 MI.getOperand(2).setIsKill(Reg1IsKill);
1212 MI.getOperand(1).setIsKill(Reg2IsKill);
1215 MI.getOperand(4).setImm((ME + 1) & 31);
1216 MI.getOperand(5).setImm((MB - 1) & 31);
1221 unsigned &SrcOpIdx1,
1222 unsigned &SrcOpIdx2)
const {
1233 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1240 unsigned Directive = Subtarget.getCPUDirective();
1243 default: Opcode = PPC::NOP;
break;
1269 bool AllowModify)
const {
1270 bool isPPC64 = Subtarget.isPPC64();
1277 if (!isUnpredicatedTerminator(*
I))
1283 if (
I->getOpcode() == PPC::B &&
1284 MBB.isLayoutSuccessor(
I->getOperand(0).getMBB())) {
1285 I->eraseFromParent();
1288 I =
MBB.getLastNonDebugInstr();
1289 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1298 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
1304 }
else if (LastInst.
getOpcode() == PPC::BCC) {
1312 }
else if (LastInst.
getOpcode() == PPC::BC) {
1320 }
else if (LastInst.
getOpcode() == PPC::BCn) {
1328 }
else if (LastInst.
getOpcode() == PPC::BDNZ8 ||
1339 }
else if (LastInst.
getOpcode() == PPC::BDZ8 ||
1360 if (
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
1364 if (SecondLastInst.
getOpcode() == PPC::BCC &&
1374 }
else if (SecondLastInst.
getOpcode() == PPC::BC &&
1384 }
else if (SecondLastInst.
getOpcode() == PPC::BCn &&
1394 }
else if ((SecondLastInst.
getOpcode() == PPC::BDNZ8 ||
1395 SecondLastInst.
getOpcode() == PPC::BDNZ) &&
1408 }
else if ((SecondLastInst.
getOpcode() == PPC::BDZ8 ||
1409 SecondLastInst.
getOpcode() == PPC::BDZ) &&
1432 I->eraseFromParent();
1441 int *BytesRemoved)
const {
1442 assert(!BytesRemoved &&
"code size not handled");
1448 if (
I->getOpcode() != PPC::B &&
I->getOpcode() != PPC::BCC &&
1449 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1450 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1451 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1455 I->eraseFromParent();
1459 if (
I ==
MBB.begin())
return 1;
1461 if (
I->getOpcode() != PPC::BCC &&
1462 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1463 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1464 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1468 I->eraseFromParent();
1477 int *BytesAdded)
const {
1479 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1481 "PPC branch conditions have two components!");
1482 assert(!BytesAdded &&
"code size not handled");
1484 bool isPPC64 = Subtarget.isPPC64();
1492 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1493 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1509 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1510 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1529 SelectExpansion &Exp)
const {
1530 if (!Subtarget.hasISEL())
1533 if (
Cond.size() != 2)
1554 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1555 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1556 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1557 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1566 Exp.FalseCycles = 1;
1577 "PPC branch conditions have two components!");
1583 assert(RC &&
"TrueReg and FalseReg must have overlapping register classes");
1585 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1586 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1588 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1589 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1590 "isel is for regular integer GPRs only");
1592 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1595 unsigned SubIdx = 0;
1596 bool SwapOps =
false;
1597 switch (SelectPred) {
1601 SubIdx = PPC::sub_eq; SwapOps =
false;
break;
1605 SubIdx = PPC::sub_eq; SwapOps =
true;
break;
1609 SubIdx = PPC::sub_lt; SwapOps =
false;
break;
1613 SubIdx = PPC::sub_lt; SwapOps =
true;
break;
1617 SubIdx = PPC::sub_gt; SwapOps =
false;
break;
1621 SubIdx = PPC::sub_gt; SwapOps =
true;
break;
1625 SubIdx = PPC::sub_un; SwapOps =
false;
break;
1629 SubIdx = PPC::sub_un; SwapOps =
true;
break;
1634 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1635 SecondReg = SwapOps ? TrueReg : FalseReg;
1644 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1659 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1660 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1661 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1662 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1664 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1665 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1666 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1667 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1669 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1670 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1671 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1672 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1674 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1675 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1676 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1677 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1680 assert(Ret != 4 &&
"Invalid CR bit register");
1688 bool RenamableDest,
bool RenamableSrc)
const {
1691 if (PPC::F8RCRegClass.
contains(DestReg) &&
1692 PPC::VSRCRegClass.
contains(SrcReg)) {
1694 RI.getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1700 }
else if (PPC::F8RCRegClass.
contains(SrcReg) &&
1701 PPC::VSRCRegClass.
contains(DestReg)) {
1703 RI.getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1712 if (PPC::CRBITRCRegClass.
contains(SrcReg) &&
1713 PPC::GPRCRegClass.
contains(DestReg)) {
1725 }
else if (PPC::CRRCRegClass.
contains(SrcReg) &&
1726 (PPC::G8RCRegClass.
contains(DestReg) ||
1727 PPC::GPRCRegClass.
contains(DestReg))) {
1728 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1729 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1730 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1731 unsigned CRNum = RI.getEncodingValue(SrcReg);
1743 }
else if (PPC::G8RCRegClass.
contains(SrcReg) &&
1744 PPC::VSFRCRegClass.
contains(DestReg)) {
1745 assert(Subtarget.hasDirectMove() &&
1746 "Subtarget doesn't support directmove, don't know how to copy.");
1751 }
else if (PPC::VSFRCRegClass.
contains(SrcReg) &&
1752 PPC::G8RCRegClass.
contains(DestReg)) {
1753 assert(Subtarget.hasDirectMove() &&
1754 "Subtarget doesn't support directmove, don't know how to copy.");
1758 }
else if (PPC::SPERCRegClass.
contains(SrcReg) &&
1759 PPC::GPRCRegClass.
contains(DestReg)) {
1763 }
else if (PPC::GPRCRegClass.
contains(SrcReg) &&
1764 PPC::SPERCRegClass.
contains(DestReg)) {
1768 }
else if ((PPC::G8RCRegClass.
contains(DestReg) ||
1769 PPC::GPRCRegClass.
contains(DestReg)) &&
1770 SrcReg == PPC::CARRY) {
1771 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1776 }
else if ((PPC::G8RCRegClass.
contains(SrcReg) ||
1777 PPC::GPRCRegClass.
contains(SrcReg)) &&
1778 DestReg == PPC::CARRY) {
1779 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1788 if (PPC::GPRCRegClass.
contains(DestReg, SrcReg))
1790 else if (PPC::G8RCRegClass.
contains(DestReg, SrcReg))
1792 else if (PPC::F4RCRegClass.
contains(DestReg, SrcReg))
1794 else if (PPC::CRRCRegClass.
contains(DestReg, SrcReg))
1796 else if (PPC::VRRCRegClass.
contains(DestReg, SrcReg))
1798 else if (PPC::VSRCRegClass.
contains(DestReg, SrcReg))
1808 else if (PPC::VSFRCRegClass.
contains(DestReg, SrcReg) ||
1809 PPC::VSSRCRegClass.
contains(DestReg, SrcReg))
1810 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1811 else if (Subtarget.pairedVectorMemops() &&
1812 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1813 if (SrcReg > PPC::VSRp15)
1814 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1816 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1817 if (DestReg > PPC::VSRp15)
1818 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1820 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1827 else if (PPC::CRBITRCRegClass.
contains(DestReg, SrcReg))
1829 else if (PPC::SPERCRegClass.
contains(DestReg, SrcReg))
1831 else if ((PPC::ACCRCRegClass.
contains(DestReg) ||
1832 PPC::UACCRCRegClass.
contains(DestReg)) &&
1833 (PPC::ACCRCRegClass.
contains(SrcReg) ||
1834 PPC::UACCRCRegClass.
contains(SrcReg))) {
1840 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1841 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1843 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1845 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1848 for (
unsigned Idx = 0; Idx < 4; Idx++)
1854 if (SrcPrimed && !KillSrc)
1857 }
else if (PPC::G8pRCRegClass.
contains(DestReg) &&
1858 PPC::G8pRCRegClass.
contains(SrcReg)) {
1860 unsigned DestRegIdx = DestReg - PPC::G8p0;
1861 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1862 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1863 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1864 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1865 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1873 }
else if ((PPC::WACCRCRegClass.
contains(DestReg) ||
1874 PPC::WACC_HIRCRegClass.
contains(DestReg)) &&
1875 (PPC::WACCRCRegClass.
contains(SrcReg) ||
1876 PPC::WACC_HIRCRegClass.
contains(SrcReg))) {
1878 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1879 : PPC::DMXXEXTFDMR512_HI;
1882 RS.enterBasicBlockEnd(
MBB);
1883 RS.backward(std::next(
I));
1885 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1889 RS.setRegUsed(TmpReg1);
1890 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1899 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1900 : PPC::DMXXINSTDMR512_HI;
1907 }
else if (PPC::DMRRCRegClass.
contains(DestReg) &&
1908 PPC::DMRRCRegClass.
contains(SrcReg)) {
1919 if (
MCID.getNumOperands() == 3)
1929 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1930 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1932 }
else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1933 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1935 }
else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1937 }
else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1939 }
else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1941 }
else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1943 }
else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1945 }
else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1947 }
else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1949 }
else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1951 }
else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1953 }
else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1955 }
else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1956 assert(Subtarget.pairedVectorMemops() &&
1957 "Register unexpected when paired memops are disabled.");
1959 }
else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1960 assert(Subtarget.pairedVectorMemops() &&
1961 "Register unexpected when paired memops are disabled.");
1963 }
else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1964 assert(Subtarget.pairedVectorMemops() &&
1965 "Register unexpected when paired memops are disabled.");
1967 }
else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1968 assert(Subtarget.pairedVectorMemops() &&
1969 "Register unexpected when paired memops are disabled.");
1971 }
else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1973 }
else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1975 }
else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1977 }
else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1979 }
else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1990 return OpcodesForSpill[getSpillIndex(RC)];
1996 return OpcodesForSpill[getSpillIndex(RC)];
1999void PPCInstrInfo::StoreRegToStackSlot(
2013 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
2014 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2027 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2030 MBB.insert(
MI, NewMI);
2037 NewMIs.
back()->addMemOperand(MF, MMO);
2056 unsigned DestReg,
int FrameIdx,
2071 if (
MI !=
MBB.end())
DL =
MI->getDebugLoc();
2073 LoadRegFromStackSlot(MF,
DL, DestReg, FrameIdx, RC, NewMIs);
2076 MBB.insert(
MI, NewMI);
2083 NewMIs.
back()->addMemOperand(MF, MMO);
2106 assert(
Cond.size() == 2 &&
"Invalid PPC branch opcode!");
2121 unsigned DefOpc =
DefMI.getOpcode();
2122 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2124 if (!
DefMI.getOperand(1).isImm())
2126 if (
DefMI.getOperand(1).getImm() != 0)
2142 for (UseIdx = 0; UseIdx <
UseMI.getNumOperands(); ++UseIdx)
2143 if (
UseMI.getOperand(UseIdx).isReg() &&
2144 UseMI.getOperand(UseIdx).getReg() == Reg)
2147 assert(UseIdx <
UseMI.getNumOperands() &&
"Cannot find Reg in UseMI");
2154 int16_t RegClass = getOpRegClassID(UseInfo);
2155 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2156 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2162 if (UseInfo.Constraints != 0)
2166 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2170 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2183 DefMI.eraseFromParent();
2189 if (
MI.definesRegister(PPC::CTR,
nullptr) ||
2190 MI.definesRegister(PPC::CTR8,
nullptr))
2202 unsigned NumT,
unsigned ExtraT,
2204 unsigned NumF,
unsigned ExtraF,
2224 switch (
MI.getOpcode()) {
2240 unsigned OpC =
MI.getOpcode();
2241 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2242 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2243 bool isPPC64 = Subtarget.isPPC64();
2244 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2245 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2251 MI.setDesc(
get(PPC::BCLR));
2254 MI.setDesc(
get(PPC::BCLRn));
2257 MI.setDesc(
get(PPC::BCCLR));
2264 }
else if (OpC == PPC::B) {
2265 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2266 bool isPPC64 = Subtarget.isPPC64();
2267 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2268 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2275 MI.removeOperand(0);
2277 MI.setDesc(
get(PPC::BC));
2283 MI.removeOperand(0);
2285 MI.setDesc(
get(PPC::BCn));
2291 MI.removeOperand(0);
2293 MI.setDesc(
get(PPC::BCC));
2301 }
else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2302 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2303 OpC == PPC::BCTRL8_RM) {
2304 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR)
2307 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2308 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2309 bool isPPC64 = Subtarget.isPPC64();
2312 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2313 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2316 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2317 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2320 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2321 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2332 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2344 assert(Pred1.
size() == 2 &&
"Invalid PPC first predicate");
2345 assert(Pred2.
size() == 2 &&
"Invalid PPC second predicate");
2347 if (Pred1[1].
getReg() == PPC::CTR8 || Pred1[1].
getReg() == PPC::CTR)
2349 if (Pred2[1].
getReg() == PPC::CTR8 || Pred2[1].
getReg() == PPC::CTR)
2374 std::vector<MachineOperand> &Pred,
2375 bool SkipDead)
const {
2383 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2384 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2388 for (
unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2391 if (MO.isDef() && RC->
contains(MO.getReg())) {
2395 }
else if (MO.isRegMask()) {
2397 if (MO.clobbersPhysReg(R)) {
2410 int64_t &
Value)
const {
2411 unsigned Opc =
MI.getOpcode();
2414 default:
return false;
2419 SrcReg =
MI.getOperand(1).getReg();
2421 Value =
MI.getOperand(2).getImm();
2430 SrcReg =
MI.getOperand(1).getReg();
2431 SrcReg2 =
MI.getOperand(2).getReg();
2450 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2461 bool isPPC64 = Subtarget.isPPC64();
2462 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2463 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2464 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2467 Register ActualSrc = RI.lookThruCopyLike(SrcReg, MRI);
2473 if (!
MI)
return false;
2475 bool equalityOnly =
false;
2478 if (is32BitSignedCompare) {
2484 }
else if (is32BitUnsignedCompare) {
2489 equalityOnly =
true;
2493 equalityOnly = is64BitUnsignedCompare;
2495 equalityOnly = is32BitUnsignedCompare;
2504 if (
UseMI->getOpcode() == PPC::BCC) {
2510 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2511 UseMI->getOpcode() == PPC::ISEL8) {
2512 unsigned SubIdx =
UseMI->getOperand(3).getSubReg();
2513 if (SubIdx != PPC::sub_eq)
2525 bool FoundUse =
false;
2554 else if (
Value != 0) {
2563 if (equalityOnly || !MRI->
hasOneUse(CRReg))
2567 if (
UseMI->getOpcode() != PPC::BCC)
2573 int16_t Immed = (int16_t)
Value;
2597 UseMI->getOperand(0).setImm(Pred);
2607 for (;
I != E && !noSub; --
I) {
2609 unsigned IOpC = Instr.getOpcode();
2611 if (&*
I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, &RI) ||
2612 Instr.readsRegister(PPC::CR0, &RI)))
2621 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2622 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2623 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2624 ((Instr.getOperand(1).getReg() == SrcReg &&
2625 Instr.getOperand(2).getReg() == SrcReg2) ||
2626 (Instr.getOperand(1).getReg() == SrcReg2 &&
2627 Instr.getOperand(2).getReg() == SrcReg))) {
2645 int MIOpC =
MI->getOpcode();
2646 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2647 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2650 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2674 const bool IntroducesRecFormInstr = MIOpC != NewOpC;
2675 if (IntroducesRecFormInstr) {
2677 if (
MBB->computeRegisterLiveness(
2687 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2697 bool ShouldSwap =
false;
2699 ShouldSwap = SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
2700 Sub->getOperand(2).getReg() == SrcReg;
2704 ShouldSwap = !ShouldSwap;
2712 if (
UseMI->getOpcode() == PPC::BCC) {
2717 "Invalid predicate for equality-only optimization");
2721 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2722 UseMI->getOpcode() == PPC::ISEL8) {
2723 unsigned NewSubReg =
UseMI->getOperand(3).getSubReg();
2724 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2725 "Invalid CR bit for equality-only optimization");
2727 if (NewSubReg == PPC::sub_lt)
2728 NewSubReg = PPC::sub_gt;
2729 else if (NewSubReg == PPC::sub_gt)
2730 NewSubReg = PPC::sub_lt;
2732 SubRegsToUpdate.
push_back(std::make_pair(&(
UseMI->getOperand(3)),
2738 "Non-zero immediate support and ShouldSwap"
2739 "may conflict in updating predicate");
2747 BuildMI(*
MI->getParent(), std::next(MII),
MI->getDebugLoc(),
2748 get(TargetOpcode::COPY), CRReg)
2753 MI->clearRegisterDeads(PPC::CR0);
2755 if (MIOpC != NewOpC) {
2765 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2766 Register GPRRes =
MI->getOperand(0).getReg();
2767 int64_t SH =
MI->getOperand(2).getImm();
2768 int64_t MB =
MI->getOperand(3).getImm();
2769 int64_t ME =
MI->getOperand(4).getImm();
2772 bool MBInLoHWord = MB >= 16;
2773 bool MEInLoHWord = ME >= 16;
2774 uint64_t Mask = ~0LLU;
2776 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2777 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2779 Mask >>= MBInLoHWord ? 0 : 16;
2780 NewOpC = MIOpC == PPC::RLWINM
2781 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2782 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2783 }
else if (MRI->
use_empty(GPRRes) && (ME == 31) &&
2784 (ME - MB + 1 == SH) && (MB >= 16)) {
2788 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2790 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2793 if (Mask != ~0LLU) {
2794 MI->removeOperand(4);
2795 MI->removeOperand(3);
2796 MI->getOperand(2).setImm(Mask);
2797 NumRcRotatesConvertedToRcAnd++;
2799 }
else if (MIOpC == PPC::RLDICL &&
MI->getOperand(2).getImm() == 0) {
2800 int64_t MB =
MI->getOperand(3).getImm();
2802 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2803 NewOpC = PPC::ANDI8_rec;
2804 MI->removeOperand(3);
2805 MI->getOperand(2).setImm(Mask);
2806 NumRcRotatesConvertedToRcAnd++;
2811 MI->setDesc(NewDesc);
2814 if (!
MI->definesRegister(ImpDef,
nullptr)) {
2815 MI->addOperand(*
MI->getParent()->getParent(),
2820 if (!
MI->readsRegister(ImpUse,
nullptr)) {
2821 MI->addOperand(*
MI->getParent()->getParent(),
2826 assert(
MI->definesRegister(PPC::CR0,
nullptr) &&
2827 "Record-form instruction does not define cr0?");
2832 for (
unsigned i = 0, e = PredsToUpdate.
size(); i < e; i++)
2833 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2835 for (
unsigned i = 0, e = SubRegsToUpdate.
size(); i < e; i++)
2836 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2847 int64_t CmpMask, CmpValue;
2852 if (CmpValue || !CmpMask || SrcReg2)
2860 if (
Opc == PPC::CMPLWI ||
Opc == PPC::CMPLDI)
2867 if (Subtarget.isPPC64() &&
Opc == PPC::CMPWI)
2874 bool SrcRegHasOtherUse =
false;
2881 if (CRReg != PPC::CR0)
2885 bool SeenUseOfCRReg =
false;
2886 bool IsCRRegKilled =
false;
2887 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI,
false, IsCRRegKilled,
2893 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2907 "Record-form instruction does not define cr0?");
2920 OffsetIsScalable =
false;
2955 case PPC::DFSTOREf64:
2956 return FirstOpc == SecondOpc;
2962 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2969 int64_t OpOffset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2970 unsigned NumBytes)
const {
2976 "Only base registers and frame indices are supported.");
2981 if (ClusterSize > 2)
2995 unsigned FirstOpc = FirstLdSt.
getOpcode();
2996 unsigned SecondOpc = SecondLdSt.
getOpcode();
3007 int64_t Offset1 = 0, Offset2 = 0;
3016 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
3017 "getMemOperandWithOffsetWidth return incorrect base op");
3019 assert(Offset1 <= Offset2 &&
"Caller should have ordered offsets.");
3020 return Offset1 + (int64_t)Width1.
getValue() == Offset2;
3027 unsigned Opcode =
MI.getOpcode();
3030 case PPC::INLINEASM:
3031 case PPC::INLINEASM_BR: {
3033 const char *AsmStr =
MI.getOperand(0).getSymbolName();
3036 case TargetOpcode::STACKMAP: {
3040 case TargetOpcode::PATCHPOINT: {
3044 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
3047 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
3054 case TargetOpcode::PATCHABLE_RET: {
3056 unsigned RetOpcode =
MI.getOperand(0).getImm();
3057 bool IsConditional = RetOpcode == PPC::BCCLR;
3058 return (8 + IsConditional) * 4;
3060 case TargetOpcode::BUNDLE:
3061 return getInstBundleSize(
MI);
3063 return get(Opcode).getSize();
3070 return MI.getOpcode() == TargetOpcode::STACKMAP
3071 ? InstSizeVerifyMode::AllowOverEstimate
3072 : InstSizeVerifyMode::ExactSize;
3075std::pair<unsigned, unsigned>
3078 return std::make_pair(TF, 0u);
3083 using namespace PPCII;
3084 static const std::pair<unsigned, const char *> TargetFlags[] = {
3085 {MO_PLT,
"ppc-plt"},
3086 {MO_PIC_FLAG,
"ppc-pic"},
3087 {MO_PCREL_FLAG,
"ppc-pcrel"},
3088 {MO_GOT_FLAG,
"ppc-got"},
3089 {MO_PCREL_OPT_FLAG,
"ppc-opt-pcrel"},
3090 {MO_TLSGD_FLAG,
"ppc-tlsgd"},
3091 {MO_TPREL_FLAG,
"ppc-tprel"},
3092 {MO_TLSLDM_FLAG,
"ppc-tlsldm"},
3093 {MO_TLSLD_FLAG,
"ppc-tlsld"},
3094 {MO_TLSGDM_FLAG,
"ppc-tlsgdm"},
3095 {MO_GOT_TLSGD_PCREL_FLAG,
"ppc-got-tlsgd-pcrel"},
3096 {MO_GOT_TLSLD_PCREL_FLAG,
"ppc-got-tlsld-pcrel"},
3097 {MO_GOT_TPREL_PCREL_FLAG,
"ppc-got-tprel-pcrel"},
3100 {MO_TPREL_LO,
"ppc-tprel-lo"},
3101 {MO_TPREL_HA,
"ppc-tprel-ha"},
3102 {MO_DTPREL_LO,
"ppc-dtprel-lo"},
3103 {MO_TLSLD_LO,
"ppc-tlsld-lo"},
3104 {MO_TOC_LO,
"ppc-toc-lo"},
3105 {MO_TLS,
"ppc-tls"},
3106 {MO_PIC_HA_FLAG,
"ppc-ha-pic"},
3107 {MO_PIC_LO_FLAG,
"ppc-lo-pic"},
3108 {MO_TPREL_PCREL_FLAG,
"ppc-tprel-pcrel"},
3109 {MO_TLS_PCREL_FLAG,
"ppc-tls-pcrel"},
3110 {MO_GOT_PCREL_FLAG,
"ppc-got-pcrel"},
3122 unsigned UpperOpcode, LowerOpcode;
3123 switch (
MI.getOpcode()) {
3124 case PPC::DFLOADf32:
3125 UpperOpcode = PPC::LXSSP;
3126 LowerOpcode = PPC::LFS;
3128 case PPC::DFLOADf64:
3129 UpperOpcode = PPC::LXSD;
3130 LowerOpcode = PPC::LFD;
3132 case PPC::DFSTOREf32:
3133 UpperOpcode = PPC::STXSSP;
3134 LowerOpcode = PPC::STFS;
3136 case PPC::DFSTOREf64:
3137 UpperOpcode = PPC::STXSD;
3138 LowerOpcode = PPC::STFD;
3140 case PPC::XFLOADf32:
3141 UpperOpcode = PPC::LXSSPX;
3142 LowerOpcode = PPC::LFSX;
3144 case PPC::XFLOADf64:
3145 UpperOpcode = PPC::LXSDX;
3146 LowerOpcode = PPC::LFDX;
3148 case PPC::XFSTOREf32:
3149 UpperOpcode = PPC::STXSSPX;
3150 LowerOpcode = PPC::STFSX;
3152 case PPC::XFSTOREf64:
3153 UpperOpcode = PPC::STXSDX;
3154 LowerOpcode = PPC::STFDX;
3157 UpperOpcode = PPC::LXSIWAX;
3158 LowerOpcode = PPC::LFIWAX;
3161 UpperOpcode = PPC::LXSIWZX;
3162 LowerOpcode = PPC::LFIWZX;
3165 UpperOpcode = PPC::STXSIWX;
3166 LowerOpcode = PPC::STFIWX;
3172 Register TargetReg =
MI.getOperand(0).getReg();
3174 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3175 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3176 Opcode = LowerOpcode;
3178 Opcode = UpperOpcode;
3179 MI.setDesc(
get(Opcode));
3188 auto &
MBB = *
MI.getParent();
3189 auto DL =
MI.getDebugLoc();
3191 switch (
MI.getOpcode()) {
3192 case PPC::BUILD_UACC: {
3195 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3196 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3197 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3201 for (
int VecNo = 0; VecNo < 4; VecNo++)
3211 case PPC::KILL_PAIR: {
3212 MI.setDesc(
get(PPC::UNENCODED_NOP));
3213 MI.removeOperand(1);
3214 MI.removeOperand(0);
3217 case TargetOpcode::LOAD_STACK_GUARD: {
3218 auto M =
MBB.getParent()->getFunction().getParent();
3220 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() ==
"tls") &&
3221 "Only Linux target or tls mode are expected to contain "
3222 "LOAD_STACK_GUARD");
3224 if (M->getStackProtectorGuard() ==
"tls")
3225 Offset = M->getStackProtectorGuardOffset();
3227 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3228 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3229 MI.setDesc(
get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3235 case PPC::PPCLdFixedAddr: {
3236 assert((Subtarget.getTargetTriple().isOSGlibc() ||
3237 Subtarget.getTargetTriple().isMusl()) &&
3238 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3240 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3241 MI.setDesc(
get(PPC::LWZ));
3242 uint64_t FAType =
MI.getOperand(1).getImm();
3243#undef PPC_LNX_FEATURE
3245#define PPC_LNX_DEFINE_OFFSETS
3246#include "llvm/TargetParser/PPCTargetParser.def"
3247 bool IsLE = Subtarget.isLittleEndian();
3248 bool Is64 = Subtarget.isPPC64();
3249 if (FAType == PPC_FAWORD_HWCAP) {
3251 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3253 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3254 }
else if (FAType == PPC_FAWORD_HWCAP2) {
3256 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3258 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3259 }
else if (FAType == PPC_FAWORD_CPUID) {
3261 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3263 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3265 assert(
Offset &&
"Do not know the offset for this fixed addr load");
3266 MI.removeOperand(1);
3267 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3272#define PPC_TGT_PARSER_UNDEF_MACROS
3273#include "llvm/TargetParser/PPCTargetParser.def"
3274#undef PPC_TGT_PARSER_UNDEF_MACROS
3276 case PPC::DFLOADf32:
3277 case PPC::DFLOADf64:
3278 case PPC::DFSTOREf32:
3279 case PPC::DFSTOREf64: {
3280 assert(Subtarget.hasP9Vector() &&
3281 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3284 "D-form op must have register and immediate operands");
3287 case PPC::XFLOADf32:
3288 case PPC::XFSTOREf32:
3292 assert(Subtarget.hasP8Vector() &&
3293 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3294 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3295 "X-form op must have register and register operands");
3298 case PPC::XFLOADf64:
3299 case PPC::XFSTOREf64: {
3300 assert(Subtarget.hasVSX() &&
3301 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3302 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3303 "X-form op must have register and register operands");
3306 case PPC::SPILLTOVSR_LD: {
3307 Register TargetReg =
MI.getOperand(0).getReg();
3308 if (PPC::VSFRCRegClass.
contains(TargetReg)) {
3309 MI.setDesc(
get(PPC::DFLOADf64));
3313 MI.setDesc(
get(PPC::LD));
3316 case PPC::SPILLTOVSR_ST: {
3318 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3319 NumStoreSPILLVSRRCAsVec++;
3320 MI.setDesc(
get(PPC::DFSTOREf64));
3323 NumStoreSPILLVSRRCAsGpr++;
3324 MI.setDesc(
get(PPC::STD));
3328 case PPC::SPILLTOVSR_LDX: {
3329 Register TargetReg =
MI.getOperand(0).getReg();
3330 if (PPC::VSFRCRegClass.
contains(TargetReg))
3331 MI.setDesc(
get(PPC::LXSDX));
3333 MI.setDesc(
get(PPC::LDX));
3336 case PPC::SPILLTOVSR_STX: {
3338 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3339 NumStoreSPILLVSRRCAsVec++;
3340 MI.setDesc(
get(PPC::STXSDX));
3342 NumStoreSPILLVSRRCAsGpr++;
3343 MI.setDesc(
get(PPC::STDX));
3350 case PPC::CFENCE8: {
3351 auto Val =
MI.getOperand(0).getReg();
3352 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3358 MI.setDesc(
get(PPC::ISYNC));
3359 MI.removeOperand(0);
3362 case PPC::LWAT_CSNE_PSEUDO:
3363 case PPC::LDAT_CSNE_PSEUDO:
3373static unsigned selectReg(int64_t Imm1, int64_t Imm2,
unsigned CompareOpc,
3374 unsigned TrueReg,
unsigned FalseReg,
3375 unsigned CRSubReg) {
3377 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3381 return Imm1 < Imm2 ? TrueReg : FalseReg;
3383 return Imm1 > Imm2 ? TrueReg : FalseReg;
3385 return Imm1 == Imm2 ? TrueReg : FalseReg;
3389 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3397 return Imm1 == Imm2 ? TrueReg : FalseReg;
3400 return PPC::NoRegister;
3405 int64_t
Imm)
const {
3406 assert(
MI.getOperand(OpNo).isReg() &&
"Operand must be a REG");
3408 Register InUseReg =
MI.getOperand(OpNo).getReg();
3409 MI.getOperand(OpNo).ChangeToImmediate(
Imm);
3416 int UseOpIdx =
MI.findRegisterUseOperandIdx(InUseReg, &RI,
false);
3417 if (UseOpIdx >= 0) {
3427 MI.removeOperand(UseOpIdx);
3436 int OperandToKeep = LII.
SetCR ? 1 : 0;
3437 for (
int i =
MI.getNumOperands() - 1; i > OperandToKeep; i--)
3438 MI.removeOperand(i);
3442 MI.setDesc(
get(LII.
Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3457 bool &SeenIntermediateUse)
const {
3458 assert(!
MI.getParent()->getParent()->getRegInfo().isSSA() &&
3459 "Should be called after register allocation.");
3462 SeenIntermediateUse =
false;
3463 for (; It != E; ++It) {
3464 if (It->modifiesRegister(Reg, &RI))
3466 if (It->readsRegister(Reg, &RI))
3467 SeenIntermediateUse =
true;
3475 int64_t
Imm)
const {
3476 assert(!
MBB.getParent()->getRegInfo().isSSA() &&
3477 "Register should be in non-SSA form after RA");
3478 bool isPPC64 = Subtarget.isPPC64();
3492 assert(isPPC64 &&
"Materializing 64-bit immediate to single register is "
3493 "only supported in PPC64");
3495 if ((
Imm >> 32) & 0xFFFF)
3515 unsigned &OpNoForForwarding,
3516 bool &SeenIntermediateUse)
const {
3517 OpNoForForwarding = ~0U;
3524 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3525 if (!
MI.getOperand(i).isReg())
3528 if (!Reg.isVirtual())
3530 Register TrueReg = RI.lookThruCopyLike(Reg, MRI);
3533 if (!DefMIForTrueReg)
3535 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3536 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3537 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3538 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3539 OpNoForForwarding = i;
3540 DefMI = DefMIForTrueReg;
3545 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3555 unsigned Opc =
MI.getOpcode();
3556 bool ConvertibleImmForm =
3557 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3558 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3559 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3560 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3561 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3562 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3563 Opc == PPC::RLWINM8_rec;
3564 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3571 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3572 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3574 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3575 MachineOperand &MO =
MI.getOperand(i);
3576 SeenIntermediateUse =
false;
3590 case PPC::ADDItocL8:
3593 OpNoForForwarding = i;
3600 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3603unsigned PPCInstrInfo::getSpillTarget()
const {
3606 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3608 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3609 2 : Subtarget.hasP9Vector() ?
3648 bool PostRA = !MRI->
isSSA();
3654 unsigned ToBeDeletedReg = 0;
3655 int64_t OffsetImm = 0;
3656 unsigned XFormOpcode = 0;
3664 bool OtherIntermediateUse =
false;
3668 if (OtherIntermediateUse || !ADDMI)
3675 unsigned ScaleRegIdx = 0;
3676 int64_t OffsetAddi = 0;
3690 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3695 for (
auto It = ++Start; It !=
End; It++)
3704 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3709 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3725 MI.setDesc(
get(XFormOpcode));
3727 .ChangeToRegister(ScaleReg,
false,
false,
3731 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3743 int64_t &
Imm)
const {
3747 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3763 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3767 unsigned &ToBeDeletedReg,
3768 unsigned &XFormOpcode,
3772 if (!
MI.mayLoadOrStore())
3775 unsigned Opc =
MI.getOpcode();
3777 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3780 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3794 if (!ImmOperand.
isImm())
3797 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3800 if (!RegOperand.
isKill())
3803 ToBeDeletedReg = RegOperand.
getReg();
3804 OffsetImm = ImmOperand.
getImm();
3811 int64_t &OffsetAddi,
3812 int64_t OffsetImm)
const {
3813 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3819 bool OtherIntermediateUse =
false;
3840 if (OtherIntermediateUse || !ADDIMI)
3859 bool PostRA = !MRI->
isSSA();
3860 bool SeenIntermediateUse =
true;
3861 unsigned ForwardingOperand = ~0U;
3863 SeenIntermediateUse);
3866 assert(ForwardingOperand <
MI.getNumOperands() &&
3867 "The forwarding operand needs to be valid at this point");
3868 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3869 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3870 if (KilledDef && KillFwdDefMI)
3884 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3885 PPC::INSTRUCTION_LIST_END &&
3886 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3890 bool IsVFReg =
MI.getOperand(0).isReg() &&
3891 MI.getOperand(0).getReg().isPhysical() &&
3898 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3905 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3911 simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef, &RegsToUpdate))
3920 Register FoldingReg =
MI.getOperand(1).getReg();
3926 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3927 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3931 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3934 "Invalid PPC::RLWINM Instruction!");
3936 uint64_t SHMI =
MI.getOperand(2).getImm();
3938 uint64_t MBMI =
MI.getOperand(3).getImm();
3940 uint64_t MEMI =
MI.getOperand(4).getImm();
3942 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3943 "Invalid PPC::RLWINM Instruction!");
3965 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3968 if ((MBMI > MEMI) && !SrcMaskFull)
3978 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3979 APInt FinalMask = RotatedSrcMask & MaskMI;
3981 bool Simplified =
false;
3984 if (FinalMask.
isZero()) {
3986 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3991 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3993 MI.removeOperand(4);
3994 MI.removeOperand(3);
3995 MI.removeOperand(2);
3996 MI.getOperand(1).ChangeToImmediate(0);
3997 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
4000 MI.removeOperand(4);
4001 MI.removeOperand(3);
4002 MI.getOperand(2).setImm(0);
4003 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
4006 MI.getOperand(1).setIsKill(
true);
4010 MI.getOperand(1).setIsKill(
false);
4026 uint16_t NewSH = (SHSrc + SHMI) % 32;
4027 MI.getOperand(2).setImm(NewSH);
4030 MI.getOperand(3).setImm(NewMB);
4031 MI.getOperand(4).setImm(NewME);
4035 MI.getOperand(1).setIsKill(
true);
4039 MI.getOperand(1).setIsKill(
false);
4069 default:
return false;
4077 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4086 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4102 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4110 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4118 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4138 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4139 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4140 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4141 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4146 case PPC::RLWNM_rec:
4147 case PPC::RLWNM8_rec:
4167 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4168 Opc == PPC::RLWNM8_rec)
4174 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4175 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4176 case PPC::RLWNM_rec:
4179 case PPC::RLWNM8_rec:
4182 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4183 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4190 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4191 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4211 case PPC::RLDCL_rec:
4213 case PPC::RLDCR_rec:
4229 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4230 Opc == PPC::RLDCR_rec)
4236 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4237 case PPC::RLDCL_rec:
4240 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4241 case PPC::RLDCR_rec:
4244 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4248 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4295 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4296 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4297 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4298 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4299 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4300 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4301 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4302 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4308 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4309 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4310 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4311 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4312 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4313 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4314 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4315 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4320 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4321 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4353 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4354 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4355 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4356 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4357 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4358 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4359 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4360 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4365 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4366 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4367 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4368 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4369 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4370 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4371 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4372 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4377 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4378 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4391 case PPC::XFLOADf32:
4392 case PPC::XFLOADf64:
4393 case PPC::XFSTOREf32:
4394 case PPC::XFSTOREf64:
4395 if (!Subtarget.hasP9Vector())
4422 case PPC::XFLOADf32:
4436 case PPC::XFLOADf64:
4454 case PPC::XFSTOREf32:
4468 case PPC::XFSTOREf64:
4479 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4481 unsigned MaxOp = std::max(Op1, Op2);
4482 unsigned MinOp = std::min(Op1, Op2);
4485 MI.removeOperand(std::max(Op1, Op2));
4486 MI.removeOperand(std::min(Op1, Op2));
4490 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4491 MI.addOperand(MOp2);
4492 MI.addOperand(MOp1);
4497 unsigned TotalOps =
MI.getNumOperands() + 2;
4498 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4500 MI.removeOperand(i);
4503 MI.addOperand(MOp2);
4505 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4507 MI.addOperand(MOp1);
4509 MI.addOperand(MOps.
back());
4520 unsigned OpNoForForwarding
4524 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4561 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4567 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4571 "Add inst must have at least three operands");
4572 RegMO = &
DefMI.getOperand(1);
4573 ImmMO = &
DefMI.getOperand(2);
4576 if (!RegMO->
isReg())
4585bool PPCInstrInfo::isRegElgibleForForwarding(
4588 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4595 const MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4605 for (; It !=
E; ++It) {
4609 IsFwdFeederRegKilled =
true;
4611 SeenIntermediateUse =
true;
4613 if ((&*It) == &
DefMI)
4626bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4630 int64_t BaseImm)
const {
4632 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4653 if (ImmMO.
isImm()) {
4658 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4679 unsigned OpNoForForwarding,
4682 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4683 !
DefMI.getOperand(1).isImm())
4687 MachineRegisterInfo *MRI = &MF->
getRegInfo();
4690 int64_t Immediate =
DefMI.getOperand(1).getImm();
4694 bool ReplaceWithLI =
false;
4695 bool Is64BitLI =
false;
4698 unsigned Opc =
MI.getOpcode();
4721 int64_t Comparand =
MI.getOperand(2).getImm();
4722 int64_t SExtComparand = ((
uint64_t)Comparand & ~0x7FFFuLL) != 0
4723 ? (Comparand | 0xFFFFFFFFFFFF0000)
4727 unsigned UseOpc = CompareUseMI.getOpcode();
4728 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4730 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4731 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4732 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4733 unsigned RegToCopy =
4734 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4735 if (RegToCopy == PPC::NoRegister)
4738 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4739 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4741 CompareUseMI.removeOperand(3);
4742 CompareUseMI.removeOperand(2);
4746 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4750 for (
const MachineOperand &MO : CompareUseMI.operands())
4755 CompareUseMI.setDesc(
get(PPC::COPY));
4756 CompareUseMI.removeOperand(3);
4757 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4758 CmpIselsConverted++;
4767 MissedConvertibleImmediateInstrs++;
4775 int64_t Addend =
MI.getOperand(2).getImm();
4777 ReplaceWithLI =
true;
4778 Is64BitLI =
Opc == PPC::ADDI8;
4779 NewImm = Addend + SExtImm;
4785 case PPC::SUBFIC8: {
4787 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4789 int64_t Minuend =
MI.getOperand(2).getImm();
4791 ReplaceWithLI =
true;
4792 Is64BitLI =
Opc == PPC::SUBFIC8;
4793 NewImm = Minuend - SExtImm;
4799 case PPC::RLDICL_rec:
4800 case PPC::RLDICL_32:
4801 case PPC::RLDICL_32_64: {
4803 int64_t SH =
MI.getOperand(2).getImm();
4804 int64_t MB =
MI.getOperand(3).getImm();
4805 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4807 InVal = InVal.rotl(SH);
4814 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4815 ReplaceWithLI =
true;
4816 Is64BitLI =
Opc != PPC::RLDICL_32;
4817 NewImm = InVal.getSExtValue();
4818 SetCR =
Opc == PPC::RLDICL_rec;
4825 case PPC::RLWINM_rec:
4826 case PPC::RLWINM8_rec: {
4827 int64_t SH =
MI.getOperand(2).getImm();
4828 int64_t MB =
MI.getOperand(3).getImm();
4829 int64_t ME =
MI.getOperand(4).getImm();
4830 APInt InVal(32, SExtImm,
true);
4831 InVal = InVal.rotl(SH);
4837 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4838 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4841 ReplaceWithLI =
true;
4842 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4843 NewImm = InVal.getSExtValue();
4844 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4853 int64_t LogicalImm =
MI.getOperand(2).getImm();
4855 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4856 Result = LogicalImm | SExtImm;
4858 Result = LogicalImm ^ SExtImm;
4860 ReplaceWithLI =
true;
4861 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4869 if (ReplaceWithLI) {
4874 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4875 if (PostRA && ImmChanged)
4882 DefMI.getOperand(1).setImm(NewImm);
4886 else if (MRI->
use_empty(
MI.getOperand(0).getReg())) {
4888 assert(Immediate &&
"Transformation converted zero to non-zero?");
4891 }
else if (ImmChanged)
4900 LoadImmediateInfo LII;
4906 if (KilledDef && SetCR)
4907 *KilledDef =
nullptr;
4920bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4922 MachineRegisterInfo *MRI = &
MI.getParent()->getParent()->getRegInfo();
4930 if (!
MI.mayLoadOrStore())
4933 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4935 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4936 "MI must have x-form opcode");
4940 bool IsVFReg =
MI.getOperand(0).isReg() &&
4941 MI.getOperand(0).getReg().isPhysical() &&
4953 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4954 if (!ImmOperandMI.
isImm())
4958 MachineOperand *ImmMO =
nullptr;
4959 MachineOperand *RegMO =
nullptr;
4960 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4962 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4967 int64_t ImmBase = ImmOperandMI.
getImm();
4969 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm, ImmBase))
4973 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4990bool PPCInstrInfo::transformToImmFormFedByAdd(
5000 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
5005 MachineOperand *ImmMO =
nullptr;
5006 MachineOperand *RegMO =
nullptr;
5007 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
5009 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
5014 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm))
5017 bool IsFwdFeederRegKilled =
false;
5018 bool SeenIntermediateUse =
false;
5020 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
5021 IsFwdFeederRegKilled, SeenIntermediateUse))
5024 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5041 if (ImmMO->
isImm()) {
5052 if (
DefMI.getOpcode() == PPC::ADDItocL8)
5062 MI.removeOperand(i);
5068 MI.addOperand(*ImmMO);
5070 for (
auto &MO : MOps)
5087 unsigned ConstantOpNo,
5090 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5091 !
DefMI.getOperand(1).isImm())
5097 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5107 APInt ActualValue(64,
Imm,
true);
5108 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5122 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5126 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5129 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5130 ConstantOpNo != PosForOrigZero)
5134 unsigned Opc =
MI.getOpcode();
5135 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5136 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5137 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5138 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5139 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5140 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5141 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5142 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5144 Opc == PPC::SRD_rec;
5158 if (SpecialShift32 || SpecialShift64) {
5159 LoadImmediateInfo LII;
5163 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5164 if (
Imm & (SpecialShift32 ? 0x20 : 0x40))
5169 else if (!SetCR && ShAmt == 0 && !PostRA) {
5170 MI.removeOperand(2);
5171 MI.setDesc(
get(PPC::COPY));
5174 if (SpecialShift32) {
5182 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5191 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5221 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5238 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5239 return &PPC::VSRCRegClass;
5244 return PPC::getRecordFormOpcode(Opcode);
5248 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5249 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5250 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5251 Opcode == PPC::LHZUX8);
5265 int Opcode =
MI->getOpcode();
5266 if (
TII.isSExt32To64(Opcode))
5275 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5281 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5282 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5283 MI->getOperand(3).getImm() > 0 &&
5284 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5289 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5291 if ((
Imm & 0x8000) == 0)
5311 int Opcode =
MI->getOpcode();
5312 if (
TII.isZExt32To64(Opcode))
5317 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5318 MI->getOperand(0).getReg() ==
Reg)
5323 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5324 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5325 int64_t
Imm =
MI->getOperand(1).getImm();
5332 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5333 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5334 Opcode == PPC::RLDICL_32_64) &&
5335 MI->getOperand(3).getImm() >= 32)
5338 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5339 MI->getOperand(3).getImm() >= 32 &&
5340 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5343 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5344 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5345 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5346 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5355 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5357 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5359 Register StackReg =
MI.getOperand(2).getReg();
5382 unsigned BinOpDepth)
const {
5383 if (!Reg.isVirtual())
5390 unsigned Opcode =
MI->getOpcode();
5399 unsigned OperandEnd = 3, OperandStride = 1;
5400 if (Opcode == PPC::PHI) {
5401 OperandEnd =
MI->getNumOperands();
5405 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5406 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5417 Register SrcReg =
MI->getOperand(1).getReg();
5431 if (SrcReg != PPC::X3)
5460 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5467 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5468 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5469 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5470 {PPC::AND, PPC::AND8}};
5473 auto It = OpcodeMap.
find(Opcode);
5474 if (It != OpcodeMap.
end()) {
5476 NewOpcode = It->second;
5484 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5487 assert(NewOpcode != -1 &&
5488 "Must have a 64-bit opcode to map the 32-bit opcode!");
5492 RI.getRegClass(
MCID.operands()[0].RegClass);
5494 Register SrcReg =
MI->getOperand(0).getReg();
5504 auto MBB =
MI->getParent();
5511 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5513 if (!Operand.
isReg())
5521 RI.getRegClass(
MCID.operands()[i].RegClass);
5527 if (Operand.
getSubReg() == PPC::sub_32) {
5529 "sub_32 source register class is incompatible with the promoted "
5530 "operand register class");
5535 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5536 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5545 Operand.
setReg(DstTmpReg);
5552 MI->getOperand(0).setReg(NewDefinedReg);
5567std::pair<bool, bool>
5569 const unsigned BinOpDepth,
5572 return std::pair<bool, bool>(
false,
false);
5576 return std::pair<bool, bool>(
false,
false);
5583 if (IsSExt && IsZExt)
5584 return std::pair<bool, bool>(IsSExt, IsZExt);
5586 switch (
MI->getOpcode()) {
5588 Register SrcReg =
MI->getOperand(1).getReg();
5597 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5598 SrcExt.second || IsZExt);
5604 if (
MI->getParent()->getBasicBlock() ==
5610 return std::pair<bool, bool>(IsSExt, IsZExt);
5614 if (SrcReg != PPC::X3) {
5617 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5618 SrcExt.second || IsZExt);
5628 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5631 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5632 return IsExtendPair;
5636 return IsExtendPair;
5641 return IsExtendPair;
5643 if (IntTy && IntTy->getBitWidth() <= 32) {
5645 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5646 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5647 return std::pair<bool, bool>(IsSExt, IsZExt);
5650 return IsExtendPair;
5659 Register SrcReg =
MI->getOperand(1).getReg();
5661 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5662 SrcExt.second || IsZExt);
5673 Register SrcReg =
MI->getOperand(1).getReg();
5675 uint16_t
Imm =
MI->getOperand(2).getImm();
5677 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5679 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5680 SrcExt.second || IsZExt);
5690 return std::pair<bool, bool>(
false,
false);
5694 unsigned OperandEnd = 3, OperandStride = 1;
5695 if (
MI->getOpcode() == PPC::PHI) {
5696 OperandEnd =
MI->getNumOperands();
5702 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5703 if (!
MI->getOperand(
I).isReg())
5704 return std::pair<bool, bool>(
false,
false);
5708 IsSExt &= SrcExt.first;
5709 IsZExt &= SrcExt.second;
5711 return std::pair<bool, bool>(IsSExt, IsZExt);
5720 return std::pair<bool, bool>(
false,
false);
5722 Register SrcReg1 =
MI->getOperand(1).getReg();
5723 Register SrcReg2 =
MI->getOperand(2).getReg();
5726 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5727 Src1Ext.second || Src2Ext.second);
5733 return std::pair<bool, bool>(IsSExt, IsZExt);
5737 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5750 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5752 TII(MF->getSubtarget().getInstrInfo()) {
5761 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5763 return MI == EndLoop;
5766 std::optional<bool> createTripCountGreaterCondition(
5767 int TC, MachineBasicBlock &
MBB,
5768 SmallVectorImpl<MachineOperand> &
Cond)
override {
5769 if (TripCount == -1) {
5774 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5779 return TripCount > TC;
5782 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5787 void adjustTripCount(
int TripCountAdjust)
override {
5790 if (LoopCount->
getOpcode() == PPC::LI8 ||
5801 void disposed(LiveIntervals *LIS)
override {
5806 Loop->eraseFromParent();
5813std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5818 if (Preheader == LoopBB)
5819 Preheader = *std::next(LoopBB->
pred_begin());
5822 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5825 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5828 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5838 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5841 for (
auto &
I : PreHeader.
instrs())
5842 if (
I.getOpcode() == LOOPi)
5885 int64_t OffsetA = 0, OffsetB = 0;
5891 int LowOffset = std::min(OffsetA, OffsetB);
5892 int HighOffset = std::max(OffsetA, OffsetB);
5893 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5895 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
5909 bool IsLDAT =
MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
5915 if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
5919 Register DstReg64 = IsLDAT ? DstReg
5921 DstReg, PPC::sub_32, &PPC::G8RCRegClass));
5923 ScratchReg = DstReg64;
5931 if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
5933 .
addReg(IsLDAT ? PPC::X8 : PPC::R8)
5934 .
addReg(IsLDAT ? PPC::X8 : PPC::R8);
5936 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 cl::opt< bool > VSXSelfCopyCrash("ppc-crash-on-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)
static const uint16_t FMAOpIdxInfo[][6]
#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)
static cl::opt< bool > EnableCmpOpt("ppc-cmp-opt", cl::desc("Enable compare instruction optimization"), cl::init(true), cl::Hidden)
const unsigned MAX_BINOP_DEPTH
#define InfoArrayIdxFSubInst
#define InfoArrayIdxFAddInst
static bool definedByZeroExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
static cl::opt< bool > EnableCTRLoopAnal("ppc-ctr-loop-analysis", cl::desc("Enable analysis for CTR loops"), cl::init(true), cl::Hidden)
#define InfoArrayIdxFMULInst
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)
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.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
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
@ LQR_Dead
Register is known to be fully dead.
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 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.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
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.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
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
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...
void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) const override
Get the base operand and byte offset of an instruction that reads/writes memory.
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 getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width) const
Return true if get the base operand, byte offset of an instruction and the memory width.
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
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
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, SelectExpansion &) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth) const
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 init(const MachineFunction *mf, const RegisterClassInfo *rci, LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)
Setup the RegPressureTracker.
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.
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)
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.
@ End
Run the machine verifier once, at the end of the pipeline.
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.