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();
194 IsRegCR =
MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
195 MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
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))
393 !
MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
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))
429 return MRI->hasOneNonDBGUse(OpAdd.
getReg());
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) {
473 MULInstrL =
MRI->getVRegDef(MULRegL);
474 MULInstrR =
MRI->getVRegDef(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())
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");
686 Register VReg1 =
MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
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(
804 MRI.constrainRegClass(RegC, RC);
807 int16_t Idx = getFMAOpIdxInfo(FmaOp);
808 assert(Idx >= 0 &&
"Root must be a FMA instruction");
810 bool IsILPReassociate =
830 Leaf =
MRI.getVRegDef(MULReg);
836 Leaf =
MRI.getVRegDef(MULReg);
841 uint32_t IntersectedFlags = 0;
842 if (IsILPReassociate)
847 auto GetOperandInfo = [&](
const MachineOperand &Operand,
Register &
Reg) {
852 auto GetFMAInstrInfo = [&](
const MachineInstr &
Instr,
Register &MulOp1,
854 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx), MulOp1);
855 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx + 1), MulOp2);
856 GetOperandInfo(
Instr.getOperand(AddOpIdx), AddOp);
859 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
862 GetFMAInstrInfo(Root, RegM31, RegM32, RegB);
864 if (IsILPReassociate)
865 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21);
868 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11);
869 GetOperandInfo(Leaf->
getOperand(AddOpIdx), RegX);
886 InstrIdxForVirtReg.
insert(std::make_pair(NewVRA, 0));
889 if (IsILPReassociate) {
891 InstrIdxForVirtReg.
insert(std::make_pair(NewVRB, 1));
897 InstrIdxForVirtReg.
insert(std::make_pair(NewVRD, 2));
900 auto AdjustOperandOrder = [&](MachineInstr *
MI,
Register RegAdd,
902 MI->getOperand(AddOpIdx).setReg(RegAdd);
903 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
904 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
907 MachineInstrBuilder NewARegPressure, NewCRegPressure;
913 MachineInstrBuilder MINewB =
918 MachineInstrBuilder MINewA =
925 AdjustOperandOrder(MINewB, RegX, RegM21, RegM22);
926 AdjustOperandOrder(MINewA, RegY, RegM31, RegM32);
929 MachineInstrBuilder MINewC =
947 assert(NewVRD &&
"new FMA register not created!");
949 MachineInstrBuilder MINewA =
954 MachineInstrBuilder MINewB =
959 MachineInstrBuilder MINewD =
966 AdjustOperandOrder(MINewB, RegX, RegM21, RegM22);
967 AdjustOperandOrder(MINewD, NewVRA, RegM31, RegM32);
970 MachineInstrBuilder MINewC =
1015 if (!IsILPReassociate) {
1024 "Insertion instructions set should not be empty!");
1028 if (IsILPReassociate)
1036 unsigned &SubIdx)
const {
1037 switch (
MI.getOpcode()) {
1038 default:
return false;
1041 case PPC::EXTSW_32_64:
1042 SrcReg =
MI.getOperand(1).getReg();
1043 DstReg =
MI.getOperand(0).getReg();
1044 SubIdx = PPC::sub_32;
1050 int &FrameIndex)
const {
1054 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1055 MI.getOperand(2).isFI()) {
1056 FrameIndex =
MI.getOperand(2).getIndex();
1057 return MI.getOperand(0).getReg();
1067 switch (
MI.getOpcode()) {
1077 case PPC::ADDIStocHA:
1078 case PPC::ADDIStocHA8:
1080 case PPC::ADDItocL8:
1081 case PPC::LOAD_STACK_GUARD:
1082 case PPC::PPCLdFixedAddr:
1084 case PPC::XXLXORspz:
1085 case PPC::XXLXORdpz:
1086 case PPC::XXLEQVOnes:
1087 case PPC::XXSPLTI32DX:
1089 case PPC::XXSPLTIDP:
1093 case PPC::V_SETALLONESB:
1094 case PPC::V_SETALLONESH:
1095 case PPC::V_SETALLONES:
1098 case PPC::XXSETACCZ:
1099 case PPC::DMXXSETACCZ:
1106 int &FrameIndex)
const {
1108 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1109 MI.getOperand(2).isFI()) {
1110 FrameIndex =
MI.getOperand(2).getIndex();
1111 return MI.getOperand(0).getReg();
1119 unsigned OpIdx2)
const {
1123 if (
MI.getOpcode() != PPC::RLWIMI &&
MI.getOpcode() != PPC::RLWIMI_rec)
1131 if (
MI.getOperand(3).getImm() != 0)
1142 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1143 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1147 unsigned SubReg1 =
MI.getOperand(1).getSubReg();
1148 unsigned SubReg2 =
MI.getOperand(2).getSubReg();
1149 bool Reg1IsKill =
MI.getOperand(1).isKill();
1150 bool Reg2IsKill =
MI.getOperand(2).isKill();
1151 bool ChangeReg0 =
false;
1157 "Expecting a two-address instruction!");
1158 assert(
MI.getOperand(0).getSubReg() == SubReg1 &&
"Tied subreg mismatch");
1164 unsigned MB =
MI.getOperand(4).getImm();
1165 unsigned ME =
MI.getOperand(5).getImm();
1169 if (MB == 0 && ME == 31)
1174 Register Reg0 = ChangeReg0 ? Reg2 :
MI.getOperand(0).getReg();
1175 bool Reg0IsDead =
MI.getOperand(0).isDead();
1176 return BuildMI(MF,
MI.getDebugLoc(),
MI.getDesc())
1185 MI.getOperand(0).setReg(Reg2);
1186 MI.getOperand(0).setSubReg(SubReg2);
1188 MI.getOperand(2).setReg(Reg1);
1189 MI.getOperand(1).setReg(Reg2);
1190 MI.getOperand(2).setSubReg(SubReg1);
1191 MI.getOperand(1).setSubReg(SubReg2);
1192 MI.getOperand(2).setIsKill(Reg1IsKill);
1193 MI.getOperand(1).setIsKill(Reg2IsKill);
1196 MI.getOperand(4).setImm((ME + 1) & 31);
1197 MI.getOperand(5).setImm((MB - 1) & 31);
1202 unsigned &SrcOpIdx1,
1203 unsigned &SrcOpIdx2)
const {
1214 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1221 unsigned Directive = Subtarget.getCPUDirective();
1224 default: Opcode = PPC::NOP;
break;
1250 bool AllowModify)
const {
1251 bool isPPC64 = Subtarget.isPPC64();
1258 if (!isUnpredicatedTerminator(*
I))
1264 if (
I->getOpcode() == PPC::B &&
1265 MBB.isLayoutSuccessor(
I->getOperand(0).getMBB())) {
1266 I->eraseFromParent();
1269 I =
MBB.getLastNonDebugInstr();
1270 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1279 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
1285 }
else if (LastInst.
getOpcode() == PPC::BCC) {
1293 }
else if (LastInst.
getOpcode() == PPC::BC) {
1301 }
else if (LastInst.
getOpcode() == PPC::BCn) {
1309 }
else if (LastInst.
getOpcode() == PPC::BDNZ8 ||
1320 }
else if (LastInst.
getOpcode() == PPC::BDZ8 ||
1341 if (
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
1345 if (SecondLastInst.
getOpcode() == PPC::BCC &&
1355 }
else if (SecondLastInst.
getOpcode() == PPC::BC &&
1365 }
else if (SecondLastInst.
getOpcode() == PPC::BCn &&
1375 }
else if ((SecondLastInst.
getOpcode() == PPC::BDNZ8 ||
1376 SecondLastInst.
getOpcode() == PPC::BDNZ) &&
1389 }
else if ((SecondLastInst.
getOpcode() == PPC::BDZ8 ||
1390 SecondLastInst.
getOpcode() == PPC::BDZ) &&
1413 I->eraseFromParent();
1422 int *BytesRemoved)
const {
1423 assert(!BytesRemoved &&
"code size not handled");
1429 if (
I->getOpcode() != PPC::B &&
I->getOpcode() != PPC::BCC &&
1430 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1431 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1432 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1436 I->eraseFromParent();
1440 if (
I ==
MBB.begin())
return 1;
1442 if (
I->getOpcode() != PPC::BCC &&
1443 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1444 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1445 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1449 I->eraseFromParent();
1458 int *BytesAdded)
const {
1460 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1462 "PPC branch conditions have two components!");
1463 assert(!BytesAdded &&
"code size not handled");
1465 bool isPPC64 = Subtarget.isPPC64();
1473 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1474 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1490 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1491 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1510 SelectExpansion &Exp)
const {
1511 if (!Subtarget.hasISEL())
1514 if (
Cond.size() != 2)
1530 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
1535 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1536 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1537 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1538 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1547 Exp.FalseCycles = 1;
1558 "PPC branch conditions have two components!");
1563 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
1564 assert(RC &&
"TrueReg and FalseReg must have overlapping register classes");
1566 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1567 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1569 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1570 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1571 "isel is for regular integer GPRs only");
1573 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1576 unsigned SubIdx = 0;
1577 bool SwapOps =
false;
1578 switch (SelectPred) {
1582 SubIdx = PPC::sub_eq; SwapOps =
false;
break;
1586 SubIdx = PPC::sub_eq; SwapOps =
true;
break;
1590 SubIdx = PPC::sub_lt; SwapOps =
false;
break;
1594 SubIdx = PPC::sub_lt; SwapOps =
true;
break;
1598 SubIdx = PPC::sub_gt; SwapOps =
false;
break;
1602 SubIdx = PPC::sub_gt; SwapOps =
true;
break;
1606 SubIdx = PPC::sub_un; SwapOps =
false;
break;
1610 SubIdx = PPC::sub_un; SwapOps =
true;
break;
1615 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1616 SecondReg = SwapOps ? TrueReg : FalseReg;
1621 if (
MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
1622 MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
1624 MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
1625 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1627 FirstReg =
MRI.createVirtualRegister(FirstRC);
1640 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1641 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1642 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1643 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1645 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1646 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1647 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1648 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1650 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1651 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1652 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1653 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1655 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1656 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1657 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1658 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1661 assert(Ret != 4 &&
"Invalid CR bit register");
1669 bool RenamableDest,
bool RenamableSrc)
const {
1672 if (PPC::F8RCRegClass.
contains(DestReg) &&
1673 PPC::VSRCRegClass.
contains(SrcReg)) {
1675 RI.getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1681 }
else if (PPC::F8RCRegClass.
contains(SrcReg) &&
1682 PPC::VSRCRegClass.
contains(DestReg)) {
1684 RI.getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1693 if (PPC::CRBITRCRegClass.
contains(SrcReg) &&
1694 PPC::GPRCRegClass.
contains(DestReg)) {
1706 }
else if (PPC::CRRCRegClass.
contains(SrcReg) &&
1707 (PPC::G8RCRegClass.
contains(DestReg) ||
1708 PPC::GPRCRegClass.
contains(DestReg))) {
1709 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1710 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1711 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1712 unsigned CRNum = RI.getEncodingValue(SrcReg);
1724 }
else if (PPC::G8RCRegClass.
contains(SrcReg) &&
1725 PPC::VSFRCRegClass.
contains(DestReg)) {
1726 assert(Subtarget.hasDirectMove() &&
1727 "Subtarget doesn't support directmove, don't know how to copy.");
1732 }
else if (PPC::VSFRCRegClass.
contains(SrcReg) &&
1733 PPC::G8RCRegClass.
contains(DestReg)) {
1734 assert(Subtarget.hasDirectMove() &&
1735 "Subtarget doesn't support directmove, don't know how to copy.");
1739 }
else if (PPC::SPERCRegClass.
contains(SrcReg) &&
1740 PPC::GPRCRegClass.
contains(DestReg)) {
1744 }
else if (PPC::GPRCRegClass.
contains(SrcReg) &&
1745 PPC::SPERCRegClass.
contains(DestReg)) {
1749 }
else if ((PPC::G8RCRegClass.
contains(DestReg) ||
1750 PPC::GPRCRegClass.
contains(DestReg)) &&
1751 SrcReg == PPC::CARRY) {
1752 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1757 }
else if ((PPC::G8RCRegClass.
contains(SrcReg) ||
1758 PPC::GPRCRegClass.
contains(SrcReg)) &&
1759 DestReg == PPC::CARRY) {
1760 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1769 if (PPC::GPRCRegClass.
contains(DestReg, SrcReg))
1771 else if (PPC::G8RCRegClass.
contains(DestReg, SrcReg))
1773 else if (PPC::F4RCRegClass.
contains(DestReg, SrcReg))
1775 else if (PPC::CRRCRegClass.
contains(DestReg, SrcReg))
1777 else if (PPC::VRRCRegClass.
contains(DestReg, SrcReg))
1779 else if (PPC::VSRCRegClass.
contains(DestReg, SrcReg))
1789 else if (PPC::VSFRCRegClass.
contains(DestReg, SrcReg) ||
1790 PPC::VSSRCRegClass.
contains(DestReg, SrcReg))
1791 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1792 else if (Subtarget.pairedVectorMemops() &&
1793 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1794 if (SrcReg > PPC::VSRp15)
1795 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1797 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1798 if (DestReg > PPC::VSRp15)
1799 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1801 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1808 else if (PPC::CRBITRCRegClass.
contains(DestReg, SrcReg))
1810 else if (PPC::SPERCRegClass.
contains(DestReg, SrcReg))
1812 else if ((PPC::ACCRCRegClass.
contains(DestReg) ||
1813 PPC::UACCRCRegClass.
contains(DestReg)) &&
1814 (PPC::ACCRCRegClass.
contains(SrcReg) ||
1815 PPC::UACCRCRegClass.
contains(SrcReg))) {
1821 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1822 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1824 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1826 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1829 for (
unsigned Idx = 0; Idx < 4; Idx++)
1835 if (SrcPrimed && !KillSrc)
1838 }
else if (PPC::G8pRCRegClass.
contains(DestReg) &&
1839 PPC::G8pRCRegClass.
contains(SrcReg)) {
1841 unsigned DestRegIdx = DestReg - PPC::G8p0;
1842 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1843 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1844 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1845 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1846 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1854 }
else if ((PPC::WACCRCRegClass.
contains(DestReg) ||
1855 PPC::WACC_HIRCRegClass.
contains(DestReg)) &&
1856 (PPC::WACCRCRegClass.
contains(SrcReg) ||
1857 PPC::WACC_HIRCRegClass.
contains(SrcReg))) {
1859 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1860 : PPC::DMXXEXTFDMR512_HI;
1863 RS.enterBasicBlockEnd(
MBB);
1864 RS.backward(std::next(
I));
1866 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1870 RS.setRegUsed(TmpReg1);
1871 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1880 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1881 : PPC::DMXXINSTDMR512_HI;
1888 }
else if (PPC::DMRRCRegClass.
contains(DestReg) &&
1889 PPC::DMRRCRegClass.
contains(SrcReg)) {
1900 if (
MCID.getNumOperands() == 3)
1910 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1911 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1913 }
else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1914 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1916 }
else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1918 }
else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1920 }
else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1922 }
else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1924 }
else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1926 }
else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1928 }
else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1930 }
else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1932 }
else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1934 }
else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1936 }
else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1937 assert(Subtarget.pairedVectorMemops() &&
1938 "Register unexpected when paired memops are disabled.");
1940 }
else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1941 assert(Subtarget.pairedVectorMemops() &&
1942 "Register unexpected when paired memops are disabled.");
1944 }
else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1945 assert(Subtarget.pairedVectorMemops() &&
1946 "Register unexpected when paired memops are disabled.");
1948 }
else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1949 assert(Subtarget.pairedVectorMemops() &&
1950 "Register unexpected when paired memops are disabled.");
1952 }
else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1954 }
else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1956 }
else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1958 }
else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1960 }
else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1971 return OpcodesForSpill[getSpillIndex(RC)];
1977 return OpcodesForSpill[getSpillIndex(RC)];
1980void PPCInstrInfo::StoreRegToStackSlot(
1994 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
1995 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2008 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2011 MBB.insert(
MI, NewMI);
2018 NewMIs.
back()->addMemOperand(MF, MMO);
2037 unsigned DestReg,
int FrameIdx,
2052 if (
MI !=
MBB.end())
DL =
MI->getDebugLoc();
2054 LoadRegFromStackSlot(MF,
DL, DestReg, FrameIdx, RC, NewMIs);
2057 MBB.insert(
MI, NewMI);
2064 NewMIs.
back()->addMemOperand(MF, MMO);
2087 assert(
Cond.size() == 2 &&
"Invalid PPC branch opcode!");
2102 unsigned DefOpc =
DefMI.getOpcode();
2103 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2105 if (!
DefMI.getOperand(1).isImm())
2107 if (
DefMI.getOperand(1).getImm() != 0)
2123 for (UseIdx = 0; UseIdx <
UseMI.getNumOperands(); ++UseIdx)
2124 if (
UseMI.getOperand(UseIdx).isReg() &&
2125 UseMI.getOperand(UseIdx).getReg() == Reg)
2128 assert(UseIdx <
UseMI.getNumOperands() &&
"Cannot find Reg in UseMI");
2135 int16_t RegClass = getOpRegClassID(UseInfo);
2136 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2137 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2143 if (UseInfo.Constraints != 0)
2147 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2151 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2163 if (
MRI->use_nodbg_empty(Reg))
2164 DefMI.eraseFromParent();
2170 if (
MI.definesRegister(PPC::CTR,
nullptr) ||
2171 MI.definesRegister(PPC::CTR8,
nullptr))
2183 unsigned NumT,
unsigned ExtraT,
2185 unsigned NumF,
unsigned ExtraF,
2205 switch (
MI.getOpcode()) {
2221 unsigned OpC =
MI.getOpcode();
2222 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2223 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2224 bool isPPC64 = Subtarget.isPPC64();
2225 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2226 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2232 MI.setDesc(
get(PPC::BCLR));
2235 MI.setDesc(
get(PPC::BCLRn));
2238 MI.setDesc(
get(PPC::BCCLR));
2245 }
else if (OpC == PPC::B) {
2246 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2247 bool isPPC64 = Subtarget.isPPC64();
2248 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2249 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2256 MI.removeOperand(0);
2258 MI.setDesc(
get(PPC::BC));
2264 MI.removeOperand(0);
2266 MI.setDesc(
get(PPC::BCn));
2272 MI.removeOperand(0);
2274 MI.setDesc(
get(PPC::BCC));
2282 }
else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2283 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2284 OpC == PPC::BCTRL8_RM) {
2285 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR)
2288 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2289 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2290 bool isPPC64 = Subtarget.isPPC64();
2293 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2294 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2297 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2298 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2301 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2302 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2313 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2325 assert(Pred1.
size() == 2 &&
"Invalid PPC first predicate");
2326 assert(Pred2.
size() == 2 &&
"Invalid PPC second predicate");
2328 if (Pred1[1].
getReg() == PPC::CTR8 || Pred1[1].
getReg() == PPC::CTR)
2330 if (Pred2[1].
getReg() == PPC::CTR8 || Pred2[1].
getReg() == PPC::CTR)
2355 std::vector<MachineOperand> &Pred,
2356 bool SkipDead)
const {
2364 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2365 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2369 for (
unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2372 if (MO.isDef() && RC->
contains(MO.getReg())) {
2376 }
else if (MO.isRegMask()) {
2378 if (MO.clobbersPhysReg(R)) {
2391 int64_t &
Value)
const {
2392 unsigned Opc =
MI.getOpcode();
2395 default:
return false;
2400 SrcReg =
MI.getOperand(1).getReg();
2402 Value =
MI.getOperand(2).getImm();
2411 SrcReg =
MI.getOperand(1).getReg();
2412 SrcReg2 =
MI.getOperand(2).getReg();
2431 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2442 bool isPPC64 = Subtarget.isPPC64();
2443 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2444 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2445 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2448 Register ActualSrc = RI.lookThruCopyLike(SrcReg,
MRI);
2454 if (!
MI)
return false;
2456 bool equalityOnly =
false;
2459 if (is32BitSignedCompare) {
2465 }
else if (is32BitUnsignedCompare) {
2470 equalityOnly =
true;
2474 equalityOnly = is64BitUnsignedCompare;
2476 equalityOnly = is32BitUnsignedCompare;
2482 I =
MRI->use_instr_begin(CRReg), IE =
MRI->use_instr_end();
2485 if (
UseMI->getOpcode() == PPC::BCC) {
2491 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2492 UseMI->getOpcode() == PPC::ISEL8) {
2493 unsigned SubIdx =
UseMI->getOperand(3).getSubReg();
2494 if (SubIdx != PPC::sub_eq)
2506 bool FoundUse =
false;
2508 J =
MRI->use_instr_begin(CRReg), JE =
MRI->use_instr_end();
2535 else if (
Value != 0) {
2544 if (equalityOnly || !
MRI->hasOneUse(CRReg))
2548 if (
UseMI->getOpcode() != PPC::BCC)
2554 int16_t Immed = (int16_t)
Value;
2578 UseMI->getOperand(0).setImm(Pred);
2588 for (;
I != E && !noSub; --
I) {
2590 unsigned IOpC = Instr.getOpcode();
2592 if (&*
I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, &RI) ||
2593 Instr.readsRegister(PPC::CR0, &RI)))
2602 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2603 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2604 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2605 ((Instr.getOperand(1).getReg() == SrcReg &&
2606 Instr.getOperand(2).getReg() == SrcReg2) ||
2607 (Instr.getOperand(1).getReg() == SrcReg2 &&
2608 Instr.getOperand(2).getReg() == SrcReg))) {
2626 int MIOpC =
MI->getOpcode();
2627 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2628 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2631 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2655 const bool IntroducesRecFormInstr = MIOpC != NewOpC;
2656 if (IntroducesRecFormInstr) {
2658 if (
MBB->computeRegisterLiveness(
2668 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2678 bool ShouldSwap =
false;
2680 ShouldSwap = SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
2681 Sub->getOperand(2).getReg() == SrcReg;
2685 ShouldSwap = !ShouldSwap;
2690 I =
MRI->use_instr_begin(CRReg), IE =
MRI->use_instr_end();
2693 if (
UseMI->getOpcode() == PPC::BCC) {
2698 "Invalid predicate for equality-only optimization");
2702 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2703 UseMI->getOpcode() == PPC::ISEL8) {
2704 unsigned NewSubReg =
UseMI->getOperand(3).getSubReg();
2705 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2706 "Invalid CR bit for equality-only optimization");
2708 if (NewSubReg == PPC::sub_lt)
2709 NewSubReg = PPC::sub_gt;
2710 else if (NewSubReg == PPC::sub_gt)
2711 NewSubReg = PPC::sub_lt;
2713 SubRegsToUpdate.
push_back(std::make_pair(&(
UseMI->getOperand(3)),
2719 "Non-zero immediate support and ShouldSwap"
2720 "may conflict in updating predicate");
2728 BuildMI(*
MI->getParent(), std::next(MII),
MI->getDebugLoc(),
2729 get(TargetOpcode::COPY), CRReg)
2734 MI->clearRegisterDeads(PPC::CR0);
2736 if (MIOpC != NewOpC) {
2746 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2747 Register GPRRes =
MI->getOperand(0).getReg();
2748 int64_t SH =
MI->getOperand(2).getImm();
2749 int64_t MB =
MI->getOperand(3).getImm();
2750 int64_t ME =
MI->getOperand(4).getImm();
2753 bool MBInLoHWord = MB >= 16;
2754 bool MEInLoHWord = ME >= 16;
2755 uint64_t Mask = ~0LLU;
2757 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2758 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2760 Mask >>= MBInLoHWord ? 0 : 16;
2761 NewOpC = MIOpC == PPC::RLWINM
2762 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2763 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2764 }
else if (
MRI->use_empty(GPRRes) && (ME == 31) &&
2765 (ME - MB + 1 == SH) && (MB >= 16)) {
2769 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2771 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2774 if (Mask != ~0LLU) {
2775 MI->removeOperand(4);
2776 MI->removeOperand(3);
2777 MI->getOperand(2).setImm(Mask);
2778 NumRcRotatesConvertedToRcAnd++;
2780 }
else if (MIOpC == PPC::RLDICL &&
MI->getOperand(2).getImm() == 0) {
2781 int64_t MB =
MI->getOperand(3).getImm();
2783 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2784 NewOpC = PPC::ANDI8_rec;
2785 MI->removeOperand(3);
2786 MI->getOperand(2).setImm(Mask);
2787 NumRcRotatesConvertedToRcAnd++;
2792 MI->setDesc(NewDesc);
2795 if (!
MI->definesRegister(ImpDef,
nullptr)) {
2796 MI->addOperand(*
MI->getParent()->getParent(),
2801 if (!
MI->readsRegister(ImpUse,
nullptr)) {
2802 MI->addOperand(*
MI->getParent()->getParent(),
2807 assert(
MI->definesRegister(PPC::CR0,
nullptr) &&
2808 "Record-form instruction does not define cr0?");
2813 for (
unsigned i = 0, e = PredsToUpdate.
size(); i < e; i++)
2814 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2816 for (
unsigned i = 0, e = SubRegsToUpdate.
size(); i < e; i++)
2817 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2828 int64_t CmpMask, CmpValue;
2833 if (CmpValue || !CmpMask || SrcReg2)
2841 if (
Opc == PPC::CMPLWI ||
Opc == PPC::CMPLDI)
2848 if (Subtarget.isPPC64() &&
Opc == PPC::CMPWI)
2855 bool SrcRegHasOtherUse =
false;
2862 if (CRReg != PPC::CR0)
2866 bool SeenUseOfCRReg =
false;
2867 bool IsCRRegKilled =
false;
2868 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI,
false, IsCRRegKilled,
2874 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2888 "Record-form instruction does not define cr0?");
2901 OffsetIsScalable =
false;
2936 case PPC::DFSTOREf64:
2937 return FirstOpc == SecondOpc;
2943 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2950 int64_t OpOffset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2951 unsigned NumBytes)
const {
2957 "Only base registers and frame indices are supported.");
2962 if (ClusterSize > 2)
2976 unsigned FirstOpc = FirstLdSt.
getOpcode();
2977 unsigned SecondOpc = SecondLdSt.
getOpcode();
2988 int64_t Offset1 = 0, Offset2 = 0;
2997 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2998 "getMemOperandWithOffsetWidth return incorrect base op");
3000 assert(Offset1 <= Offset2 &&
"Caller should have ordered offsets.");
3001 return Offset1 + (int64_t)Width1.
getValue() == Offset2;
3008 unsigned Opcode =
MI.getOpcode();
3011 case PPC::INLINEASM:
3012 case PPC::INLINEASM_BR: {
3014 const char *AsmStr =
MI.getOperand(0).getSymbolName();
3017 case TargetOpcode::STACKMAP: {
3021 case TargetOpcode::PATCHPOINT: {
3025 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
3028 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
3035 case TargetOpcode::PATCHABLE_RET: {
3037 unsigned RetOpcode =
MI.getOperand(0).getImm();
3038 bool IsConditional = RetOpcode == PPC::BCCLR;
3039 return (8 + IsConditional) * 4;
3041 case TargetOpcode::BUNDLE:
3042 return getInstBundleSize(
MI);
3044 return get(Opcode).getSize();
3051 return MI.getOpcode() == TargetOpcode::STACKMAP
3052 ? InstSizeVerifyMode::AllowOverEstimate
3053 : InstSizeVerifyMode::ExactSize;
3056std::pair<unsigned, unsigned>
3059 return std::make_pair(TF, 0u);
3064 using namespace PPCII;
3065 static const std::pair<unsigned, const char *> TargetFlags[] = {
3066 {MO_PLT,
"ppc-plt"},
3067 {MO_PIC_FLAG,
"ppc-pic"},
3068 {MO_PCREL_FLAG,
"ppc-pcrel"},
3069 {MO_GOT_FLAG,
"ppc-got"},
3070 {MO_PCREL_OPT_FLAG,
"ppc-opt-pcrel"},
3071 {MO_TLSGD_FLAG,
"ppc-tlsgd"},
3072 {MO_TPREL_FLAG,
"ppc-tprel"},
3073 {MO_TLSLDM_FLAG,
"ppc-tlsldm"},
3074 {MO_TLSLD_FLAG,
"ppc-tlsld"},
3075 {MO_TLSGDM_FLAG,
"ppc-tlsgdm"},
3076 {MO_GOT_TLSGD_PCREL_FLAG,
"ppc-got-tlsgd-pcrel"},
3077 {MO_GOT_TLSLD_PCREL_FLAG,
"ppc-got-tlsld-pcrel"},
3078 {MO_GOT_TPREL_PCREL_FLAG,
"ppc-got-tprel-pcrel"},
3081 {MO_TPREL_LO,
"ppc-tprel-lo"},
3082 {MO_TPREL_HA,
"ppc-tprel-ha"},
3083 {MO_DTPREL_LO,
"ppc-dtprel-lo"},
3084 {MO_TLSLD_LO,
"ppc-tlsld-lo"},
3085 {MO_TOC_LO,
"ppc-toc-lo"},
3086 {MO_TLS,
"ppc-tls"},
3087 {MO_PIC_HA_FLAG,
"ppc-ha-pic"},
3088 {MO_PIC_LO_FLAG,
"ppc-lo-pic"},
3089 {MO_TPREL_PCREL_FLAG,
"ppc-tprel-pcrel"},
3090 {MO_TLS_PCREL_FLAG,
"ppc-tls-pcrel"},
3091 {MO_GOT_PCREL_FLAG,
"ppc-got-pcrel"},
3103 unsigned UpperOpcode, LowerOpcode;
3104 switch (
MI.getOpcode()) {
3105 case PPC::DFLOADf32:
3106 UpperOpcode = PPC::LXSSP;
3107 LowerOpcode = PPC::LFS;
3109 case PPC::DFLOADf64:
3110 UpperOpcode = PPC::LXSD;
3111 LowerOpcode = PPC::LFD;
3113 case PPC::DFSTOREf32:
3114 UpperOpcode = PPC::STXSSP;
3115 LowerOpcode = PPC::STFS;
3117 case PPC::DFSTOREf64:
3118 UpperOpcode = PPC::STXSD;
3119 LowerOpcode = PPC::STFD;
3121 case PPC::XFLOADf32:
3122 UpperOpcode = PPC::LXSSPX;
3123 LowerOpcode = PPC::LFSX;
3125 case PPC::XFLOADf64:
3126 UpperOpcode = PPC::LXSDX;
3127 LowerOpcode = PPC::LFDX;
3129 case PPC::XFSTOREf32:
3130 UpperOpcode = PPC::STXSSPX;
3131 LowerOpcode = PPC::STFSX;
3133 case PPC::XFSTOREf64:
3134 UpperOpcode = PPC::STXSDX;
3135 LowerOpcode = PPC::STFDX;
3138 UpperOpcode = PPC::LXSIWAX;
3139 LowerOpcode = PPC::LFIWAX;
3142 UpperOpcode = PPC::LXSIWZX;
3143 LowerOpcode = PPC::LFIWZX;
3146 UpperOpcode = PPC::STXSIWX;
3147 LowerOpcode = PPC::STFIWX;
3153 Register TargetReg =
MI.getOperand(0).getReg();
3155 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3156 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3157 Opcode = LowerOpcode;
3159 Opcode = UpperOpcode;
3160 MI.setDesc(
get(Opcode));
3169 auto &
MBB = *
MI.getParent();
3170 auto DL =
MI.getDebugLoc();
3172 switch (
MI.getOpcode()) {
3173 case PPC::BUILD_UACC: {
3176 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3177 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3178 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3182 for (
int VecNo = 0; VecNo < 4; VecNo++)
3192 case PPC::KILL_PAIR: {
3193 MI.setDesc(
get(PPC::UNENCODED_NOP));
3194 MI.removeOperand(1);
3195 MI.removeOperand(0);
3198 case TargetOpcode::LOAD_STACK_GUARD: {
3199 auto M =
MBB.getParent()->getFunction().getParent();
3201 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() ==
"tls") &&
3202 "Only Linux target or tls mode are expected to contain "
3203 "LOAD_STACK_GUARD");
3205 if (M->getStackProtectorGuard() ==
"tls")
3206 Offset = M->getStackProtectorGuardOffset();
3208 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3209 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3210 MI.setDesc(
get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3216 case PPC::PPCLdFixedAddr: {
3217 assert((Subtarget.getTargetTriple().isOSGlibc() ||
3218 Subtarget.getTargetTriple().isMusl()) &&
3219 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3221 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3222 MI.setDesc(
get(PPC::LWZ));
3223 uint64_t FAType =
MI.getOperand(1).getImm();
3224#undef PPC_LNX_FEATURE
3226#define PPC_LNX_DEFINE_OFFSETS
3227#include "llvm/TargetParser/PPCTargetParser.def"
3228 bool IsLE = Subtarget.isLittleEndian();
3229 bool Is64 = Subtarget.isPPC64();
3230 if (FAType == PPC_FAWORD_HWCAP) {
3232 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3234 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3235 }
else if (FAType == PPC_FAWORD_HWCAP2) {
3237 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3239 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3240 }
else if (FAType == PPC_FAWORD_CPUID) {
3242 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3244 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3246 assert(
Offset &&
"Do not know the offset for this fixed addr load");
3247 MI.removeOperand(1);
3248 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3253#define PPC_TGT_PARSER_UNDEF_MACROS
3254#include "llvm/TargetParser/PPCTargetParser.def"
3255#undef PPC_TGT_PARSER_UNDEF_MACROS
3257 case PPC::DFLOADf32:
3258 case PPC::DFLOADf64:
3259 case PPC::DFSTOREf32:
3260 case PPC::DFSTOREf64: {
3261 assert(Subtarget.hasP9Vector() &&
3262 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3265 "D-form op must have register and immediate operands");
3268 case PPC::XFLOADf32:
3269 case PPC::XFSTOREf32:
3273 assert(Subtarget.hasP8Vector() &&
3274 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3275 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3276 "X-form op must have register and register operands");
3279 case PPC::XFLOADf64:
3280 case PPC::XFSTOREf64: {
3281 assert(Subtarget.hasVSX() &&
3282 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3283 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3284 "X-form op must have register and register operands");
3287 case PPC::SPILLTOVSR_LD: {
3288 Register TargetReg =
MI.getOperand(0).getReg();
3289 if (PPC::VSFRCRegClass.
contains(TargetReg)) {
3290 MI.setDesc(
get(PPC::DFLOADf64));
3294 MI.setDesc(
get(PPC::LD));
3297 case PPC::SPILLTOVSR_ST: {
3299 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3300 NumStoreSPILLVSRRCAsVec++;
3301 MI.setDesc(
get(PPC::DFSTOREf64));
3304 NumStoreSPILLVSRRCAsGpr++;
3305 MI.setDesc(
get(PPC::STD));
3309 case PPC::SPILLTOVSR_LDX: {
3310 Register TargetReg =
MI.getOperand(0).getReg();
3311 if (PPC::VSFRCRegClass.
contains(TargetReg))
3312 MI.setDesc(
get(PPC::LXSDX));
3314 MI.setDesc(
get(PPC::LDX));
3317 case PPC::SPILLTOVSR_STX: {
3319 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3320 NumStoreSPILLVSRRCAsVec++;
3321 MI.setDesc(
get(PPC::STXSDX));
3323 NumStoreSPILLVSRRCAsGpr++;
3324 MI.setDesc(
get(PPC::STDX));
3331 case PPC::CFENCE8: {
3332 auto Val =
MI.getOperand(0).getReg();
3333 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3339 MI.setDesc(
get(PPC::ISYNC));
3340 MI.removeOperand(0);
3343 case PPC::LWAT_CSNE_PSEUDO:
3344 case PPC::LDAT_CSNE_PSEUDO:
3354static unsigned selectReg(int64_t Imm1, int64_t Imm2,
unsigned CompareOpc,
3355 unsigned TrueReg,
unsigned FalseReg,
3356 unsigned CRSubReg) {
3358 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3362 return Imm1 < Imm2 ? TrueReg : FalseReg;
3364 return Imm1 > Imm2 ? TrueReg : FalseReg;
3366 return Imm1 == Imm2 ? TrueReg : FalseReg;
3370 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3378 return Imm1 == Imm2 ? TrueReg : FalseReg;
3381 return PPC::NoRegister;
3386 int64_t
Imm)
const {
3387 assert(
MI.getOperand(OpNo).isReg() &&
"Operand must be a REG");
3389 Register InUseReg =
MI.getOperand(OpNo).getReg();
3390 MI.getOperand(OpNo).ChangeToImmediate(
Imm);
3397 int UseOpIdx =
MI.findRegisterUseOperandIdx(InUseReg, &RI,
false);
3398 if (UseOpIdx >= 0) {
3408 MI.removeOperand(UseOpIdx);
3417 int OperandToKeep = LII.
SetCR ? 1 : 0;
3418 for (
int i =
MI.getNumOperands() - 1; i > OperandToKeep; i--)
3419 MI.removeOperand(i);
3423 MI.setDesc(
get(LII.
Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3438 bool &SeenIntermediateUse)
const {
3439 assert(!
MI.getParent()->getParent()->getRegInfo().isSSA() &&
3440 "Should be called after register allocation.");
3443 SeenIntermediateUse =
false;
3444 for (; It != E; ++It) {
3445 if (It->modifiesRegister(Reg, &RI))
3447 if (It->readsRegister(Reg, &RI))
3448 SeenIntermediateUse =
true;
3456 int64_t
Imm)
const {
3457 assert(!
MBB.getParent()->getRegInfo().isSSA() &&
3458 "Register should be in non-SSA form after RA");
3459 bool isPPC64 = Subtarget.isPPC64();
3473 assert(isPPC64 &&
"Materializing 64-bit immediate to single register is "
3474 "only supported in PPC64");
3476 if ((
Imm >> 32) & 0xFFFF)
3496 unsigned &OpNoForForwarding,
3497 bool &SeenIntermediateUse)
const {
3498 OpNoForForwarding = ~0U;
3505 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3506 if (!
MI.getOperand(i).isReg())
3509 if (!Reg.isVirtual())
3514 if (!DefMIForTrueReg)
3516 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3517 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3518 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3519 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3520 OpNoForForwarding = i;
3521 DefMI = DefMIForTrueReg;
3526 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3536 unsigned Opc =
MI.getOpcode();
3537 bool ConvertibleImmForm =
3538 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3539 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3540 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3541 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3542 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3543 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3544 Opc == PPC::RLWINM8_rec;
3545 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3552 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3553 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3555 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3556 MachineOperand &MO =
MI.getOperand(i);
3557 SeenIntermediateUse =
false;
3571 case PPC::ADDItocL8:
3574 OpNoForForwarding = i;
3581 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3584unsigned PPCInstrInfo::getSpillTarget()
const {
3587 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3589 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3590 2 : Subtarget.hasP9Vector() ?
3629 bool PostRA = !
MRI->isSSA();
3635 unsigned ToBeDeletedReg = 0;
3636 int64_t OffsetImm = 0;
3637 unsigned XFormOpcode = 0;
3645 bool OtherIntermediateUse =
false;
3649 if (OtherIntermediateUse || !ADDMI)
3656 unsigned ScaleRegIdx = 0;
3657 int64_t OffsetAddi = 0;
3671 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3676 for (
auto It = ++Start; It !=
End; It++)
3685 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3690 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3706 MI.setDesc(
get(XFormOpcode));
3708 .ChangeToRegister(ScaleReg,
false,
false,
3712 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3724 int64_t &
Imm)
const {
3728 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3744 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3748 unsigned &ToBeDeletedReg,
3749 unsigned &XFormOpcode,
3753 if (!
MI.mayLoadOrStore())
3756 unsigned Opc =
MI.getOpcode();
3758 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3761 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3775 if (!ImmOperand.
isImm())
3778 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3781 if (!RegOperand.
isKill())
3784 ToBeDeletedReg = RegOperand.
getReg();
3785 OffsetImm = ImmOperand.
getImm();
3792 int64_t &OffsetAddi,
3793 int64_t OffsetImm)
const {
3794 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3800 bool OtherIntermediateUse =
false;
3821 if (OtherIntermediateUse || !ADDIMI)
3840 bool PostRA = !
MRI->isSSA();
3841 bool SeenIntermediateUse =
true;
3842 unsigned ForwardingOperand = ~0U;
3844 SeenIntermediateUse);
3847 assert(ForwardingOperand <
MI.getNumOperands() &&
3848 "The forwarding operand needs to be valid at this point");
3849 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3850 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3851 if (KilledDef && KillFwdDefMI)
3865 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3866 PPC::INSTRUCTION_LIST_END &&
3867 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3871 bool IsVFReg =
MI.getOperand(0).isReg() &&
3872 MI.getOperand(0).getReg().isPhysical() &&
3879 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3886 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3892 simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef, &RegsToUpdate))
3901 Register FoldingReg =
MI.getOperand(1).getReg();
3907 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3908 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3912 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3915 "Invalid PPC::RLWINM Instruction!");
3917 uint64_t SHMI =
MI.getOperand(2).getImm();
3919 uint64_t MBMI =
MI.getOperand(3).getImm();
3921 uint64_t MEMI =
MI.getOperand(4).getImm();
3923 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3924 "Invalid PPC::RLWINM Instruction!");
3946 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3949 if ((MBMI > MEMI) && !SrcMaskFull)
3959 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3960 APInt FinalMask = RotatedSrcMask & MaskMI;
3962 bool Simplified =
false;
3965 if (FinalMask.
isZero()) {
3967 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3972 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3974 MI.removeOperand(4);
3975 MI.removeOperand(3);
3976 MI.removeOperand(2);
3977 MI.getOperand(1).ChangeToImmediate(0);
3978 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
3981 MI.removeOperand(4);
3982 MI.removeOperand(3);
3983 MI.getOperand(2).setImm(0);
3984 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3987 MI.getOperand(1).setIsKill(
true);
3991 MI.getOperand(1).setIsKill(
false);
4007 uint16_t NewSH = (SHSrc + SHMI) % 32;
4008 MI.getOperand(2).setImm(NewSH);
4011 MI.getOperand(3).setImm(NewMB);
4012 MI.getOperand(4).setImm(NewME);
4016 MI.getOperand(1).setIsKill(
true);
4020 MI.getOperand(1).setIsKill(
false);
4025 if (Simplified &
MRI->use_nodbg_empty(FoldingReg) &&
4050 default:
return false;
4058 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4067 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4083 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4091 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4099 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4119 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4120 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4121 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4122 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4127 case PPC::RLWNM_rec:
4128 case PPC::RLWNM8_rec:
4148 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4149 Opc == PPC::RLWNM8_rec)
4155 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4156 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4157 case PPC::RLWNM_rec:
4160 case PPC::RLWNM8_rec:
4163 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4164 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4171 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4172 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4192 case PPC::RLDCL_rec:
4194 case PPC::RLDCR_rec:
4210 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4211 Opc == PPC::RLDCR_rec)
4217 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4218 case PPC::RLDCL_rec:
4221 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4222 case PPC::RLDCR_rec:
4225 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4229 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4276 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4277 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4278 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4279 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4280 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4281 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4282 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4283 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4289 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4290 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4291 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4292 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4293 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4294 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4295 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4296 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4301 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4302 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4334 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4335 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4336 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4337 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4338 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4339 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4340 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4341 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4346 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4347 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4348 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4349 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4350 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4351 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4352 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4353 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4358 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4359 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4372 case PPC::XFLOADf32:
4373 case PPC::XFLOADf64:
4374 case PPC::XFSTOREf32:
4375 case PPC::XFSTOREf64:
4376 if (!Subtarget.hasP9Vector())
4403 case PPC::XFLOADf32:
4417 case PPC::XFLOADf64:
4435 case PPC::XFSTOREf32:
4449 case PPC::XFSTOREf64:
4460 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4462 unsigned MaxOp = std::max(Op1, Op2);
4463 unsigned MinOp = std::min(Op1, Op2);
4466 MI.removeOperand(std::max(Op1, Op2));
4467 MI.removeOperand(std::min(Op1, Op2));
4471 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4472 MI.addOperand(MOp2);
4473 MI.addOperand(MOp1);
4478 unsigned TotalOps =
MI.getNumOperands() + 2;
4479 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4481 MI.removeOperand(i);
4484 MI.addOperand(MOp2);
4486 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4488 MI.addOperand(MOp1);
4490 MI.addOperand(MOps.
back());
4501 unsigned OpNoForForwarding
4505 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
4542 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4548 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4552 "Add inst must have at least three operands");
4553 RegMO = &
DefMI.getOperand(1);
4554 ImmMO = &
DefMI.getOperand(2);
4557 if (!RegMO->
isReg())
4566bool PPCInstrInfo::isRegElgibleForForwarding(
4569 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4576 const MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
4586 for (; It !=
E; ++It) {
4590 IsFwdFeederRegKilled =
true;
4592 SeenIntermediateUse =
true;
4594 if ((&*It) == &
DefMI)
4607bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4611 int64_t BaseImm)
const {
4613 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4634 if (ImmMO.
isImm()) {
4639 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4660 unsigned OpNoForForwarding,
4663 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4664 !
DefMI.getOperand(1).isImm())
4671 int64_t Immediate =
DefMI.getOperand(1).getImm();
4675 bool ReplaceWithLI =
false;
4676 bool Is64BitLI =
false;
4679 unsigned Opc =
MI.getOpcode();
4702 int64_t Comparand =
MI.getOperand(2).getImm();
4703 int64_t SExtComparand = ((
uint64_t)Comparand & ~0x7FFFuLL) != 0
4704 ? (Comparand | 0xFFFFFFFFFFFF0000)
4708 unsigned UseOpc = CompareUseMI.getOpcode();
4709 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4711 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4712 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4713 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4714 unsigned RegToCopy =
4715 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4716 if (RegToCopy == PPC::NoRegister)
4719 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4720 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4722 CompareUseMI.removeOperand(3);
4723 CompareUseMI.removeOperand(2);
4727 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4731 for (
const MachineOperand &MO : CompareUseMI.operands())
4736 CompareUseMI.setDesc(
get(PPC::COPY));
4737 CompareUseMI.removeOperand(3);
4738 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4739 CmpIselsConverted++;
4748 MissedConvertibleImmediateInstrs++;
4756 int64_t Addend =
MI.getOperand(2).getImm();
4758 ReplaceWithLI =
true;
4759 Is64BitLI =
Opc == PPC::ADDI8;
4760 NewImm = Addend + SExtImm;
4766 case PPC::SUBFIC8: {
4768 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4770 int64_t Minuend =
MI.getOperand(2).getImm();
4772 ReplaceWithLI =
true;
4773 Is64BitLI =
Opc == PPC::SUBFIC8;
4774 NewImm = Minuend - SExtImm;
4780 case PPC::RLDICL_rec:
4781 case PPC::RLDICL_32:
4782 case PPC::RLDICL_32_64: {
4784 int64_t SH =
MI.getOperand(2).getImm();
4785 int64_t MB =
MI.getOperand(3).getImm();
4786 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4788 InVal = InVal.rotl(SH);
4795 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4796 ReplaceWithLI =
true;
4797 Is64BitLI =
Opc != PPC::RLDICL_32;
4798 NewImm = InVal.getSExtValue();
4799 SetCR =
Opc == PPC::RLDICL_rec;
4806 case PPC::RLWINM_rec:
4807 case PPC::RLWINM8_rec: {
4808 int64_t SH =
MI.getOperand(2).getImm();
4809 int64_t MB =
MI.getOperand(3).getImm();
4810 int64_t ME =
MI.getOperand(4).getImm();
4811 APInt InVal(32, SExtImm,
true);
4812 InVal = InVal.rotl(SH);
4818 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4819 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4822 ReplaceWithLI =
true;
4823 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4824 NewImm = InVal.getSExtValue();
4825 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4834 int64_t LogicalImm =
MI.getOperand(2).getImm();
4836 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4837 Result = LogicalImm | SExtImm;
4839 Result = LogicalImm ^ SExtImm;
4841 ReplaceWithLI =
true;
4842 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4850 if (ReplaceWithLI) {
4855 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4856 if (PostRA && ImmChanged)
4863 DefMI.getOperand(1).setImm(NewImm);
4869 assert(Immediate &&
"Transformation converted zero to non-zero?");
4872 }
else if (ImmChanged)
4881 LoadImmediateInfo LII;
4887 if (KilledDef && SetCR)
4888 *KilledDef =
nullptr;
4901bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4903 MachineRegisterInfo *
MRI = &
MI.getParent()->getParent()->getRegInfo();
4911 if (!
MI.mayLoadOrStore())
4914 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4916 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4917 "MI must have x-form opcode");
4921 bool IsVFReg =
MI.getOperand(0).isReg() &&
4922 MI.getOperand(0).getReg().isPhysical() &&
4934 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4935 if (!ImmOperandMI.
isImm())
4939 MachineOperand *ImmMO =
nullptr;
4940 MachineOperand *RegMO =
nullptr;
4941 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4943 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4948 int64_t ImmBase = ImmOperandMI.
getImm();
4950 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm, ImmBase))
4954 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4971bool PPCInstrInfo::transformToImmFormFedByAdd(
4981 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
4986 MachineOperand *ImmMO =
nullptr;
4987 MachineOperand *RegMO =
nullptr;
4988 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4990 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4995 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm))
4998 bool IsFwdFeederRegKilled =
false;
4999 bool SeenIntermediateUse =
false;
5001 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
5002 IsFwdFeederRegKilled, SeenIntermediateUse))
5005 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
5022 if (ImmMO->
isImm()) {
5033 if (
DefMI.getOpcode() == PPC::ADDItocL8)
5043 MI.removeOperand(i);
5049 MI.addOperand(*ImmMO);
5051 for (
auto &MO : MOps)
5068 unsigned ConstantOpNo,
5071 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5072 !
DefMI.getOperand(1).isImm())
5078 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
5088 APInt ActualValue(64,
Imm,
true);
5089 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5103 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5107 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5110 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5111 ConstantOpNo != PosForOrigZero)
5115 unsigned Opc =
MI.getOpcode();
5116 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5117 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5118 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5119 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5120 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5121 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5122 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5123 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5125 Opc == PPC::SRD_rec;
5139 if (SpecialShift32 || SpecialShift64) {
5140 LoadImmediateInfo LII;
5144 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5145 if (
Imm & (SpecialShift32 ? 0x20 : 0x40))
5150 else if (!SetCR && ShAmt == 0 && !PostRA) {
5151 MI.removeOperand(2);
5152 MI.setDesc(
get(PPC::COPY));
5155 if (SpecialShift32) {
5163 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5172 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5202 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5219 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5220 return &PPC::VSRCRegClass;
5225 return PPC::getRecordFormOpcode(Opcode);
5229 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5230 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5231 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5232 Opcode == PPC::LHZUX8);
5246 int Opcode =
MI->getOpcode();
5247 if (
TII.isSExt32To64(Opcode))
5256 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5262 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5263 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5264 MI->getOperand(3).getImm() > 0 &&
5265 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5270 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5272 if ((
Imm & 0x8000) == 0)
5292 int Opcode =
MI->getOpcode();
5293 if (
TII.isZExt32To64(Opcode))
5298 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5299 MI->getOperand(0).getReg() ==
Reg)
5304 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5305 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5306 int64_t
Imm =
MI->getOperand(1).getImm();
5313 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5314 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5315 Opcode == PPC::RLDICL_32_64) &&
5316 MI->getOperand(3).getImm() >= 32)
5319 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5320 MI->getOperand(3).getImm() >= 32 &&
5321 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5324 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5325 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5326 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5327 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5336 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5338 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5340 Register StackReg =
MI.getOperand(2).getReg();
5363 unsigned BinOpDepth)
const {
5364 if (!Reg.isVirtual())
5371 unsigned Opcode =
MI->getOpcode();
5380 unsigned OperandEnd = 3, OperandStride = 1;
5381 if (Opcode == PPC::PHI) {
5382 OperandEnd =
MI->getNumOperands();
5386 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5387 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5398 Register SrcReg =
MI->getOperand(1).getReg();
5412 if (SrcReg != PPC::X3)
5441 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5448 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5449 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5450 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5451 {PPC::AND, PPC::AND8}};
5454 auto It = OpcodeMap.
find(Opcode);
5455 if (It != OpcodeMap.
end()) {
5457 NewOpcode = It->second;
5465 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5468 assert(NewOpcode != -1 &&
5469 "Must have a 64-bit opcode to map the 32-bit opcode!");
5473 RI.getRegClass(
MCID.operands()[0].RegClass);
5475 Register SrcReg =
MI->getOperand(0).getReg();
5485 auto MBB =
MI->getParent();
5492 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5494 if (!Operand.
isReg())
5502 RI.getRegClass(
MCID.operands()[i].RegClass);
5508 if (Operand.
getSubReg() == PPC::sub_32) {
5510 "sub_32 source register class is incompatible with the promoted "
5511 "operand register class");
5516 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5517 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5519 Register TmpReg =
MRI->createVirtualRegister(NewUsedRegRC);
5520 Register DstTmpReg =
MRI->createVirtualRegister(NewUsedRegRC);
5526 Operand.
setReg(DstTmpReg);
5530 Register NewDefinedReg =
MRI->createVirtualRegister(NewRC);
5532 MI->getOperand(0).setReg(NewDefinedReg);
5539 .
addReg(NewDefinedReg, {}, PPC::sub_32);
5547std::pair<bool, bool>
5549 const unsigned BinOpDepth,
5552 return std::pair<bool, bool>(
false,
false);
5556 return std::pair<bool, bool>(
false,
false);
5563 if (IsSExt && IsZExt)
5564 return std::pair<bool, bool>(IsSExt, IsZExt);
5566 switch (
MI->getOpcode()) {
5568 Register SrcReg =
MI->getOperand(1).getReg();
5577 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5578 SrcExt.second || IsZExt);
5584 if (
MI->getParent()->getBasicBlock() ==
5590 return std::pair<bool, bool>(IsSExt, IsZExt);
5594 if (SrcReg != PPC::X3) {
5597 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5598 SrcExt.second || IsZExt);
5608 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5611 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5612 return IsExtendPair;
5616 return IsExtendPair;
5621 return IsExtendPair;
5623 if (IntTy && IntTy->getBitWidth() <= 32) {
5625 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5626 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5627 return std::pair<bool, bool>(IsSExt, IsZExt);
5630 return IsExtendPair;
5639 Register SrcReg =
MI->getOperand(1).getReg();
5641 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5642 SrcExt.second || IsZExt);
5653 Register SrcReg =
MI->getOperand(1).getReg();
5655 uint16_t
Imm =
MI->getOperand(2).getImm();
5657 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5659 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5660 SrcExt.second || IsZExt);
5670 return std::pair<bool, bool>(
false,
false);
5674 unsigned OperandEnd = 3, OperandStride = 1;
5675 if (
MI->getOpcode() == PPC::PHI) {
5676 OperandEnd =
MI->getNumOperands();
5682 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5683 if (!
MI->getOperand(
I).isReg())
5684 return std::pair<bool, bool>(
false,
false);
5688 IsSExt &= SrcExt.first;
5689 IsZExt &= SrcExt.second;
5691 return std::pair<bool, bool>(IsSExt, IsZExt);
5700 return std::pair<bool, bool>(
false,
false);
5702 Register SrcReg1 =
MI->getOperand(1).getReg();
5703 Register SrcReg2 =
MI->getOperand(2).getReg();
5706 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5707 Src1Ext.second || Src2Ext.second);
5713 return std::pair<bool, bool>(IsSExt, IsZExt);
5717 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5730 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5732 TII(MF->getSubtarget().getInstrInfo()) {
5741 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5743 return MI == EndLoop;
5746 std::optional<bool> createTripCountGreaterCondition(
5747 int TC, MachineBasicBlock &
MBB,
5748 SmallVectorImpl<MachineOperand> &
Cond)
override {
5749 if (TripCount == -1) {
5754 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5759 return TripCount > TC;
5762 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5767 void adjustTripCount(
int TripCountAdjust)
override {
5770 if (LoopCount->
getOpcode() == PPC::LI8 ||
5781 void disposed(LiveIntervals *LIS)
override {
5786 Loop->eraseFromParent();
5793std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5798 if (Preheader == LoopBB)
5799 Preheader = *std::next(LoopBB->
pred_begin());
5802 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5805 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5808 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5818 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5821 for (
auto &
I : PreHeader.
instrs())
5822 if (
I.getOpcode() == LOOPi)
5865 int64_t OffsetA = 0, OffsetB = 0;
5871 int LowOffset = std::min(OffsetA, OffsetB);
5872 int HighOffset = std::max(OffsetA, OffsetB);
5873 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5875 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
5889 bool IsLDAT =
MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
5895 if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
5899 Register DstReg64 = IsLDAT ? DstReg
5901 DstReg, PPC::sub_32, &PPC::G8RCRegClass));
5903 ScratchReg = DstReg64;
5911 if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
5913 .
addReg(IsLDAT ? PPC::X8 : PPC::R8)
5914 .
addReg(IsLDAT ? PPC::X8 : PPC::R8);
5916 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
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
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,...
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 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
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.
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.