47#define DEBUG_TYPE "ppc-instr-info"
49#define GET_INSTRMAP_INFO
50#define GET_INSTRINFO_CTOR_DTOR
51#include "PPCGenInstrInfo.inc"
54 "Number of spillvsrrc spilled to stack as vec");
56 "Number of spillvsrrc spilled to stack as gpr");
57STATISTIC(NumGPRtoVSRSpill,
"Number of gpr spills to spillvsrrc");
59 "Number of ISELs that depend on comparison of constants converted");
61 "Number of compare-immediate instructions fed by constants");
63 "Number of record-form rotates converted to record-form andi");
67 cl::desc(
"Disable analysis for CTR loops"));
73cl::desc(
"Causes the backend to crash instead of generating a nop VSX copy"),
78 cl::desc(
"Use the old (incorrect) instruction latency calculation"));
82 cl::desc(
"register pressure factor for the transformations."));
86 cl::desc(
"enable register pressure reduce in machine combiner pass."));
89void PPCInstrInfo::anchor() {}
94 STI.isPPC64() ?
PPC::BLR8 :
PPC::BLR),
95 Subtarget(STI), RI(STI.getTargetMachine()) {}
103 static_cast<const PPCSubtarget *
>(STI)->getCPUDirective();
107 static_cast<const PPCSubtarget *
>(STI)->getInstrItineraryData();
139 unsigned *PredCost)
const {
141 return PPCGenInstrInfo::getInstrLatency(ItinData,
MI, PredCost);
151 unsigned DefClass =
MI.getDesc().getSchedClass();
152 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
170 std::optional<unsigned>
Latency = PPCGenInstrInfo::getOperandLatency(
173 if (!
DefMI.getParent())
180 if (Reg.isVirtual()) {
182 &
DefMI.getParent()->getParent()->getRegInfo();
186 IsRegCR = PPC::CRRCRegClass.contains(Reg) ||
187 PPC::CRBITRCRegClass.contains(Reg);
190 if (
UseMI.isBranch() && IsRegCR) {
196 unsigned Directive = Subtarget.getCPUDirective();
270#define InfoArrayIdxFMAInst 0
271#define InfoArrayIdxFAddInst 1
272#define InfoArrayIdxFMULInst 2
273#define InfoArrayIdxAddOpIdx 3
274#define InfoArrayIdxMULOpIdx 4
275#define InfoArrayIdxFSubInst 5
286 {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},
287 {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},
288 {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},
289 {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},
290 {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},
291 {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};
295int16_t PPCInstrInfo::getFMAOpIdxInfo(
unsigned Opcode)
const {
352 bool DoRegPressureReduce)
const {
356 auto IsAllOpsVirtualReg = [](
const MachineInstr &Instr) {
357 for (
const auto &MO : Instr.explicit_operands())
358 if (!(MO.isReg() && MO.getReg().isVirtual()))
363 auto IsReassociableAddOrSub = [&](
const MachineInstr &Instr,
365 if (Instr.getOpcode() !=
376 if (!IsAllOpsVirtualReg(Instr))
388 auto IsReassociableFMA = [&](
const MachineInstr &Instr, int16_t &AddOpIdx,
389 int16_t &MulOpIdx,
bool IsLeaf) {
390 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
401 if (!IsAllOpsVirtualReg(Instr))
421 int16_t AddOpIdx = -1;
422 int16_t MulOpIdx = -1;
424 bool IsUsedOnceL =
false;
425 bool IsUsedOnceR =
false;
429 auto IsRPReductionCandidate = [&]() {
433 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
438 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
true)) {
439 assert((MulOpIdx >= 0) &&
"mul operand index not right!");
440 Register MULRegL = RI.lookThruSingleUseCopyChain(
442 Register MULRegR = RI.lookThruSingleUseCopyChain(
444 if (!MULRegL && !MULRegR)
447 if (MULRegL && !MULRegR) {
451 }
else if (!MULRegL && MULRegR) {
470 if (DoRegPressureReduce && IsRPReductionCandidate()) {
471 assert((MULInstrL && MULInstrR) &&
"wrong register preduction candidate!");
492 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
false))
495 assert((AddOpIdx >= 0) &&
"add operand index not right!");
502 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx,
false))
505 assert((AddOpIdx >= 0) &&
"add operand index not right!");
510 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx,
true)) {
526 assert(!InsInstrs.
empty() &&
"Instructions set to be inserted is empty!");
532 int16_t Idx = getFMAOpIdxInfo(Root.
getOpcode());
571 for (
auto *Inst : InsInstrs) {
573 assert(Operand.isReg() &&
"Invalid instruction in InsInstrs!");
574 if (Operand.getReg() == PPC::ZERO8) {
575 Placeholder = &Operand;
581 assert(Placeholder &&
"Placeholder does not exist!");
586 generateLoadForNewConst(ConstPoolIdx, &Root,
C->getType(), InsInstrs);
589 Placeholder->setReg(LoadNewConst);
610 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
617 auto GetMBBPressure =
623 RPTracker.
init(
MBB->getParent(), RegClassInfo,
nullptr,
MBB,
MBB->end(),
627 if (
MI.isDebugValue() ||
MI.isDebugLabel())
630 RegOpers.
collect(
MI, RI, *MRI,
false,
false);
633 RPTracker.
recede(RegOpers);
643 unsigned VSSRCLimit =
647 return GetMBBPressure(
MBB)[PPC::RegisterPressureSets::VSSRC] >
653 if (!
I->hasOneMemOperand())
657 return Op->isLoad() &&
Op->getPseudoValue() &&
661Register PPCInstrInfo::generateLoadForNewConst(
667 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
669 "Target not supported!\n");
677 BuildMI(*MF,
MI->getDebugLoc(),
get(PPC::ADDIStocHA8), VReg1)
681 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
682 "Only float and double are supported!");
687 LoadOpcode = PPC::DFLOADf32;
689 LoadOpcode = PPC::DFLOADf64;
719 assert(
I->mayLoad() &&
"Should be a load instruction.\n");
720 for (
auto MO :
I->uses()) {
724 if (Reg == 0 || !Reg.isVirtual())
728 for (
auto MO2 :
DefMI->uses())
730 return (MCP->
getConstants())[MO2.getIndex()].Val.ConstVal;
750 bool DoRegPressureReduce)
const {
760 DoRegPressureReduce);
773 reassociateFMA(Root,
Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
778 DelInstrs, InstrIdxForVirtReg);
783void PPCInstrInfo::reassociateFMA(
796 int16_t Idx = getFMAOpIdxInfo(FmaOp);
797 assert(Idx >= 0 &&
"Root must be a FMA instruction");
799 bool IsILPReassociate =
830 uint32_t IntersectedFlags = 0;
831 if (IsILPReassociate)
836 auto GetOperandInfo = [&](
const MachineOperand &Operand,
Register &
Reg,
840 KillFlag = Operand.
isKill();
843 auto GetFMAInstrInfo = [&](
const MachineInstr &
Instr,
Register &MulOp1,
845 bool &MulOp1KillFlag,
bool &MulOp2KillFlag,
846 bool &AddOpKillFlag) {
847 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
848 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
849 GetOperandInfo(
Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
852 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
854 bool KillX =
false, KillY =
false, KillM11 =
false, KillM12 =
false,
855 KillM21 =
false, KillM22 =
false, KillM31 =
false, KillM32 =
false,
856 KillA11 =
false, KillA21 =
false, KillB =
false;
858 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
860 if (IsILPReassociate)
861 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
864 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
865 GetOperandInfo(Leaf->
getOperand(AddOpIdx), RegX, KillX);
867 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
868 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
871 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
872 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
882 InstrIdxForVirtReg.
insert(std::make_pair(NewVRA, 0));
885 if (IsILPReassociate) {
887 InstrIdxForVirtReg.
insert(std::make_pair(NewVRB, 1));
893 InstrIdxForVirtReg.
insert(std::make_pair(NewVRD, 2));
896 auto AdjustOperandOrder = [&](MachineInstr *
MI,
Register RegAdd,
bool KillAdd,
898 Register RegMul2,
bool KillRegMul2) {
899 MI->getOperand(AddOpIdx).setReg(RegAdd);
900 MI->getOperand(AddOpIdx).setIsKill(KillAdd);
901 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
902 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
903 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
904 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
907 MachineInstrBuilder NewARegPressure, NewCRegPressure;
913 MachineInstrBuilder MINewB =
918 MachineInstrBuilder MINewA =
925 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
926 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
929 MachineInstrBuilder MINewC =
947 assert(NewVRD &&
"new FMA register not created!");
949 MachineInstrBuilder MINewA =
954 MachineInstrBuilder MINewB =
959 MachineInstrBuilder MINewD =
966 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
967 AdjustOperandOrder(MINewD, NewVRA,
true, RegM31, KillM31, RegM32,
971 MachineInstrBuilder MINewC =
993 bool KillVarReg =
false;
996 KillVarReg = KillM31;
999 KillVarReg = KillM32;
1023 if (!IsILPReassociate) {
1032 "Insertion instructions set should not be empty!");
1036 if (IsILPReassociate)
1044 unsigned &SubIdx)
const {
1045 switch (
MI.getOpcode()) {
1046 default:
return false;
1049 case PPC::EXTSW_32_64:
1050 SrcReg =
MI.getOperand(1).getReg();
1051 DstReg =
MI.getOperand(0).getReg();
1052 SubIdx = PPC::sub_32;
1058 int &FrameIndex)
const {
1062 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1063 MI.getOperand(2).isFI()) {
1064 FrameIndex =
MI.getOperand(2).getIndex();
1065 return MI.getOperand(0).getReg();
1075 switch (
MI.getOpcode()) {
1085 case PPC::ADDIStocHA:
1086 case PPC::ADDIStocHA8:
1088 case PPC::ADDItocL8:
1089 case PPC::LOAD_STACK_GUARD:
1090 case PPC::PPCLdFixedAddr:
1092 case PPC::XXLXORspz:
1093 case PPC::XXLXORdpz:
1094 case PPC::XXLEQVOnes:
1095 case PPC::XXSPLTI32DX:
1097 case PPC::XXSPLTIDP:
1101 case PPC::V_SETALLONESB:
1102 case PPC::V_SETALLONESH:
1103 case PPC::V_SETALLONES:
1106 case PPC::XXSETACCZ:
1107 case PPC::DMXXSETACCZ:
1114 int &FrameIndex)
const {
1116 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1117 MI.getOperand(2).isFI()) {
1118 FrameIndex =
MI.getOperand(2).getIndex();
1119 return MI.getOperand(0).getReg();
1127 unsigned OpIdx2)
const {
1131 if (
MI.getOpcode() != PPC::RLWIMI &&
MI.getOpcode() != PPC::RLWIMI_rec)
1139 if (
MI.getOperand(3).getImm() != 0)
1150 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1151 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1155 unsigned SubReg1 =
MI.getOperand(1).getSubReg();
1156 unsigned SubReg2 =
MI.getOperand(2).getSubReg();
1157 bool Reg1IsKill =
MI.getOperand(1).isKill();
1158 bool Reg2IsKill =
MI.getOperand(2).isKill();
1159 bool ChangeReg0 =
false;
1165 "Expecting a two-address instruction!");
1166 assert(
MI.getOperand(0).getSubReg() == SubReg1 &&
"Tied subreg mismatch");
1172 unsigned MB =
MI.getOperand(4).getImm();
1173 unsigned ME =
MI.getOperand(5).getImm();
1177 if (MB == 0 && ME == 31)
1182 Register Reg0 = ChangeReg0 ? Reg2 :
MI.getOperand(0).getReg();
1183 bool Reg0IsDead =
MI.getOperand(0).isDead();
1184 return BuildMI(MF,
MI.getDebugLoc(),
MI.getDesc())
1193 MI.getOperand(0).setReg(Reg2);
1194 MI.getOperand(0).setSubReg(SubReg2);
1196 MI.getOperand(2).setReg(Reg1);
1197 MI.getOperand(1).setReg(Reg2);
1198 MI.getOperand(2).setSubReg(SubReg1);
1199 MI.getOperand(1).setSubReg(SubReg2);
1200 MI.getOperand(2).setIsKill(Reg1IsKill);
1201 MI.getOperand(1).setIsKill(Reg2IsKill);
1204 MI.getOperand(4).setImm((ME + 1) & 31);
1205 MI.getOperand(5).setImm((MB - 1) & 31);
1210 unsigned &SrcOpIdx1,
1211 unsigned &SrcOpIdx2)
const {
1222 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1229 unsigned Directive = Subtarget.getCPUDirective();
1232 default: Opcode = PPC::NOP;
break;
1258 bool AllowModify)
const {
1259 bool isPPC64 = Subtarget.isPPC64();
1266 if (!isUnpredicatedTerminator(*
I))
1272 if (
I->getOpcode() == PPC::B &&
1273 MBB.isLayoutSuccessor(
I->getOperand(0).getMBB())) {
1274 I->eraseFromParent();
1277 I =
MBB.getLastNonDebugInstr();
1278 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1287 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
1293 }
else if (LastInst.
getOpcode() == PPC::BCC) {
1301 }
else if (LastInst.
getOpcode() == PPC::BC) {
1309 }
else if (LastInst.
getOpcode() == PPC::BCn) {
1317 }
else if (LastInst.
getOpcode() == PPC::BDNZ8 ||
1328 }
else if (LastInst.
getOpcode() == PPC::BDZ8 ||
1349 if (
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
1353 if (SecondLastInst.
getOpcode() == PPC::BCC &&
1363 }
else if (SecondLastInst.
getOpcode() == PPC::BC &&
1373 }
else if (SecondLastInst.
getOpcode() == PPC::BCn &&
1383 }
else if ((SecondLastInst.
getOpcode() == PPC::BDNZ8 ||
1384 SecondLastInst.
getOpcode() == PPC::BDNZ) &&
1397 }
else if ((SecondLastInst.
getOpcode() == PPC::BDZ8 ||
1398 SecondLastInst.
getOpcode() == PPC::BDZ) &&
1421 I->eraseFromParent();
1430 int *BytesRemoved)
const {
1431 assert(!BytesRemoved &&
"code size not handled");
1437 if (
I->getOpcode() != PPC::B &&
I->getOpcode() != PPC::BCC &&
1438 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1439 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1440 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1444 I->eraseFromParent();
1448 if (
I ==
MBB.begin())
return 1;
1450 if (
I->getOpcode() != PPC::BCC &&
1451 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1452 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1453 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1457 I->eraseFromParent();
1466 int *BytesAdded)
const {
1468 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1470 "PPC branch conditions have two components!");
1471 assert(!BytesAdded &&
"code size not handled");
1473 bool isPPC64 = Subtarget.isPPC64();
1481 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1482 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1498 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1499 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1517 Register FalseReg,
int &CondCycles,
1518 int &TrueCycles,
int &FalseCycles)
const {
1519 if (!Subtarget.hasISEL())
1522 if (
Cond.size() != 2)
1543 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1544 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1545 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1546 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1566 "PPC branch conditions have two components!");
1572 assert(RC &&
"TrueReg and FalseReg must have overlapping register classes");
1574 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1575 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1577 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1578 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1579 "isel is for regular integer GPRs only");
1581 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1584 unsigned SubIdx = 0;
1585 bool SwapOps =
false;
1586 switch (SelectPred) {
1590 SubIdx = PPC::sub_eq; SwapOps =
false;
break;
1594 SubIdx = PPC::sub_eq; SwapOps =
true;
break;
1598 SubIdx = PPC::sub_lt; SwapOps =
false;
break;
1602 SubIdx = PPC::sub_lt; SwapOps =
true;
break;
1606 SubIdx = PPC::sub_gt; SwapOps =
false;
break;
1610 SubIdx = PPC::sub_gt; SwapOps =
true;
break;
1614 SubIdx = PPC::sub_un; SwapOps =
false;
break;
1618 SubIdx = PPC::sub_un; SwapOps =
true;
break;
1623 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1624 SecondReg = SwapOps ? TrueReg : FalseReg;
1633 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1648 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1649 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1650 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1651 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1653 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1654 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1655 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1656 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1658 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1659 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1660 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1661 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1663 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1664 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1665 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1666 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1669 assert(Ret != 4 &&
"Invalid CR bit register");
1677 bool RenamableDest,
bool RenamableSrc)
const {
1680 if (PPC::F8RCRegClass.
contains(DestReg) &&
1681 PPC::VSRCRegClass.
contains(SrcReg)) {
1683 RI.getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1689 }
else if (PPC::F8RCRegClass.
contains(SrcReg) &&
1690 PPC::VSRCRegClass.
contains(DestReg)) {
1692 RI.getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1701 if (PPC::CRBITRCRegClass.
contains(SrcReg) &&
1702 PPC::GPRCRegClass.
contains(DestReg)) {
1714 }
else if (PPC::CRRCRegClass.
contains(SrcReg) &&
1715 (PPC::G8RCRegClass.
contains(DestReg) ||
1716 PPC::GPRCRegClass.
contains(DestReg))) {
1717 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1718 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1719 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1720 unsigned CRNum = RI.getEncodingValue(SrcReg);
1732 }
else if (PPC::G8RCRegClass.
contains(SrcReg) &&
1733 PPC::VSFRCRegClass.
contains(DestReg)) {
1734 assert(Subtarget.hasDirectMove() &&
1735 "Subtarget doesn't support directmove, don't know how to copy.");
1740 }
else if (PPC::VSFRCRegClass.
contains(SrcReg) &&
1741 PPC::G8RCRegClass.
contains(DestReg)) {
1742 assert(Subtarget.hasDirectMove() &&
1743 "Subtarget doesn't support directmove, don't know how to copy.");
1747 }
else if (PPC::SPERCRegClass.
contains(SrcReg) &&
1748 PPC::GPRCRegClass.
contains(DestReg)) {
1752 }
else if (PPC::GPRCRegClass.
contains(SrcReg) &&
1753 PPC::SPERCRegClass.
contains(DestReg)) {
1757 }
else if ((PPC::G8RCRegClass.
contains(DestReg) ||
1758 PPC::GPRCRegClass.
contains(DestReg)) &&
1759 SrcReg == PPC::CARRY) {
1760 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1765 }
else if ((PPC::G8RCRegClass.
contains(SrcReg) ||
1766 PPC::GPRCRegClass.
contains(SrcReg)) &&
1767 DestReg == PPC::CARRY) {
1768 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1777 if (PPC::GPRCRegClass.
contains(DestReg, SrcReg))
1779 else if (PPC::G8RCRegClass.
contains(DestReg, SrcReg))
1781 else if (PPC::F4RCRegClass.
contains(DestReg, SrcReg))
1783 else if (PPC::CRRCRegClass.
contains(DestReg, SrcReg))
1785 else if (PPC::VRRCRegClass.
contains(DestReg, SrcReg))
1787 else if (PPC::VSRCRegClass.
contains(DestReg, SrcReg))
1797 else if (PPC::VSFRCRegClass.
contains(DestReg, SrcReg) ||
1798 PPC::VSSRCRegClass.
contains(DestReg, SrcReg))
1799 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1800 else if (Subtarget.pairedVectorMemops() &&
1801 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1802 if (SrcReg > PPC::VSRp15)
1803 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1805 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1806 if (DestReg > PPC::VSRp15)
1807 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1809 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1816 else if (PPC::CRBITRCRegClass.
contains(DestReg, SrcReg))
1818 else if (PPC::SPERCRegClass.
contains(DestReg, SrcReg))
1820 else if ((PPC::ACCRCRegClass.
contains(DestReg) ||
1821 PPC::UACCRCRegClass.
contains(DestReg)) &&
1822 (PPC::ACCRCRegClass.
contains(SrcReg) ||
1823 PPC::UACCRCRegClass.
contains(SrcReg))) {
1829 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1830 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1832 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1834 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1837 for (
unsigned Idx = 0; Idx < 4; Idx++)
1843 if (SrcPrimed && !KillSrc)
1846 }
else if (PPC::G8pRCRegClass.
contains(DestReg) &&
1847 PPC::G8pRCRegClass.
contains(SrcReg)) {
1849 unsigned DestRegIdx = DestReg - PPC::G8p0;
1850 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1851 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1852 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1853 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1854 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1862 }
else if ((PPC::WACCRCRegClass.
contains(DestReg) ||
1863 PPC::WACC_HIRCRegClass.
contains(DestReg)) &&
1864 (PPC::WACCRCRegClass.
contains(SrcReg) ||
1865 PPC::WACC_HIRCRegClass.
contains(SrcReg))) {
1867 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1868 : PPC::DMXXEXTFDMR512_HI;
1871 RS.enterBasicBlockEnd(
MBB);
1872 RS.backward(std::next(
I));
1874 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1878 RS.setRegUsed(TmpReg1);
1879 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1888 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1889 : PPC::DMXXINSTDMR512_HI;
1896 }
else if (PPC::DMRRCRegClass.
contains(DestReg) &&
1897 PPC::DMRRCRegClass.
contains(SrcReg)) {
1908 if (
MCID.getNumOperands() == 3)
1918 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1919 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1921 }
else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1922 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1924 }
else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1926 }
else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1928 }
else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1930 }
else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1932 }
else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1934 }
else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1936 }
else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1938 }
else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1940 }
else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1942 }
else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1944 }
else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1945 assert(Subtarget.pairedVectorMemops() &&
1946 "Register unexpected when paired memops are disabled.");
1948 }
else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1949 assert(Subtarget.pairedVectorMemops() &&
1950 "Register unexpected when paired memops are disabled.");
1952 }
else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1953 assert(Subtarget.pairedVectorMemops() &&
1954 "Register unexpected when paired memops are disabled.");
1956 }
else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1957 assert(Subtarget.pairedVectorMemops() &&
1958 "Register unexpected when paired memops are disabled.");
1960 }
else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1962 }
else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1964 }
else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1966 }
else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1968 }
else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1979 return OpcodesForSpill[getSpillIndex(RC)];
1985 return OpcodesForSpill[getSpillIndex(RC)];
1988void PPCInstrInfo::StoreRegToStackSlot(
2002 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
2003 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2016 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2019 MBB.insert(
MI, NewMI);
2026 NewMIs.
back()->addMemOperand(MF, MMO);
2045 unsigned DestReg,
int FrameIdx,
2060 if (
MI !=
MBB.end())
DL =
MI->getDebugLoc();
2062 LoadRegFromStackSlot(MF,
DL, DestReg, FrameIdx, RC, NewMIs);
2065 MBB.insert(
MI, NewMI);
2072 NewMIs.
back()->addMemOperand(MF, MMO);
2095 assert(
Cond.size() == 2 &&
"Invalid PPC branch opcode!");
2110 unsigned DefOpc =
DefMI.getOpcode();
2111 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2113 if (!
DefMI.getOperand(1).isImm())
2115 if (
DefMI.getOperand(1).getImm() != 0)
2131 for (UseIdx = 0; UseIdx <
UseMI.getNumOperands(); ++UseIdx)
2132 if (
UseMI.getOperand(UseIdx).isReg() &&
2133 UseMI.getOperand(UseIdx).getReg() == Reg)
2136 assert(UseIdx <
UseMI.getNumOperands() &&
"Cannot find Reg in UseMI");
2143 int16_t RegClass = getOpRegClassID(UseInfo);
2144 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2145 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2151 if (UseInfo.Constraints != 0)
2155 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2159 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2172 DefMI.eraseFromParent();
2178 if (
MI.definesRegister(PPC::CTR,
nullptr) ||
2179 MI.definesRegister(PPC::CTR8,
nullptr))
2191 unsigned NumT,
unsigned ExtraT,
2193 unsigned NumF,
unsigned ExtraF,
2213 switch (
MI.getOpcode()) {
2229 unsigned OpC =
MI.getOpcode();
2230 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2231 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2232 bool isPPC64 = Subtarget.isPPC64();
2233 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2234 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2240 MI.setDesc(
get(PPC::BCLR));
2243 MI.setDesc(
get(PPC::BCLRn));
2246 MI.setDesc(
get(PPC::BCCLR));
2253 }
else if (OpC == PPC::B) {
2254 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2255 bool isPPC64 = Subtarget.isPPC64();
2256 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2257 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2264 MI.removeOperand(0);
2266 MI.setDesc(
get(PPC::BC));
2272 MI.removeOperand(0);
2274 MI.setDesc(
get(PPC::BCn));
2280 MI.removeOperand(0);
2282 MI.setDesc(
get(PPC::BCC));
2290 }
else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2291 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2292 OpC == PPC::BCTRL8_RM) {
2293 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR)
2296 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2297 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2298 bool isPPC64 = Subtarget.isPPC64();
2301 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2302 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2305 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2306 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2309 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2310 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2321 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2333 assert(Pred1.
size() == 2 &&
"Invalid PPC first predicate");
2334 assert(Pred2.
size() == 2 &&
"Invalid PPC second predicate");
2336 if (Pred1[1].
getReg() == PPC::CTR8 || Pred1[1].
getReg() == PPC::CTR)
2338 if (Pred2[1].
getReg() == PPC::CTR8 || Pred2[1].
getReg() == PPC::CTR)
2363 std::vector<MachineOperand> &Pred,
2364 bool SkipDead)
const {
2372 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2373 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2377 for (
unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2380 if (MO.isDef() && RC->
contains(MO.getReg())) {
2384 }
else if (MO.isRegMask()) {
2386 if (MO.clobbersPhysReg(R)) {
2399 int64_t &
Value)
const {
2400 unsigned Opc =
MI.getOpcode();
2403 default:
return false;
2408 SrcReg =
MI.getOperand(1).getReg();
2410 Value =
MI.getOperand(2).getImm();
2419 SrcReg =
MI.getOperand(1).getReg();
2420 SrcReg2 =
MI.getOperand(2).getReg();
2439 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2450 bool isPPC64 = Subtarget.isPPC64();
2451 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2452 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2453 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2456 Register ActualSrc = RI.lookThruCopyLike(SrcReg, MRI);
2462 if (!
MI)
return false;
2464 bool equalityOnly =
false;
2467 if (is32BitSignedCompare) {
2473 }
else if (is32BitUnsignedCompare) {
2478 equalityOnly =
true;
2482 equalityOnly = is64BitUnsignedCompare;
2484 equalityOnly = is32BitUnsignedCompare;
2493 if (
UseMI->getOpcode() == PPC::BCC) {
2499 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2500 UseMI->getOpcode() == PPC::ISEL8) {
2501 unsigned SubIdx =
UseMI->getOperand(3).getSubReg();
2502 if (SubIdx != PPC::sub_eq)
2514 bool FoundUse =
false;
2543 else if (
Value != 0) {
2552 if (equalityOnly || !MRI->
hasOneUse(CRReg))
2556 if (
UseMI->getOpcode() != PPC::BCC)
2562 int16_t Immed = (int16_t)
Value;
2586 UseMI->getOperand(0).setImm(Pred);
2596 for (;
I != E && !noSub; --
I) {
2598 unsigned IOpC = Instr.getOpcode();
2600 if (&*
I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, &RI) ||
2601 Instr.readsRegister(PPC::CR0, &RI)))
2610 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2611 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2612 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2613 ((Instr.getOperand(1).getReg() == SrcReg &&
2614 Instr.getOperand(2).getReg() == SrcReg2) ||
2615 (Instr.getOperand(1).getReg() == SrcReg2 &&
2616 Instr.getOperand(2).getReg() == SrcReg))) {
2634 int MIOpC =
MI->getOpcode();
2635 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2636 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2639 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2657 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2667 bool ShouldSwap =
false;
2669 ShouldSwap = SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
2670 Sub->getOperand(2).getReg() == SrcReg;
2674 ShouldSwap = !ShouldSwap;
2682 if (
UseMI->getOpcode() == PPC::BCC) {
2687 "Invalid predicate for equality-only optimization");
2691 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2692 UseMI->getOpcode() == PPC::ISEL8) {
2693 unsigned NewSubReg =
UseMI->getOperand(3).getSubReg();
2694 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2695 "Invalid CR bit for equality-only optimization");
2697 if (NewSubReg == PPC::sub_lt)
2698 NewSubReg = PPC::sub_gt;
2699 else if (NewSubReg == PPC::sub_gt)
2700 NewSubReg = PPC::sub_lt;
2702 SubRegsToUpdate.
push_back(std::make_pair(&(
UseMI->getOperand(3)),
2708 "Non-zero immediate support and ShouldSwap"
2709 "may conflict in updating predicate");
2717 BuildMI(*
MI->getParent(), std::next(MII),
MI->getDebugLoc(),
2718 get(TargetOpcode::COPY), CRReg)
2723 MI->clearRegisterDeads(PPC::CR0);
2725 if (MIOpC != NewOpC) {
2735 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2736 Register GPRRes =
MI->getOperand(0).getReg();
2737 int64_t SH =
MI->getOperand(2).getImm();
2738 int64_t MB =
MI->getOperand(3).getImm();
2739 int64_t ME =
MI->getOperand(4).getImm();
2742 bool MBInLoHWord = MB >= 16;
2743 bool MEInLoHWord = ME >= 16;
2746 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2747 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2749 Mask >>= MBInLoHWord ? 0 : 16;
2750 NewOpC = MIOpC == PPC::RLWINM
2751 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2752 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2753 }
else if (MRI->
use_empty(GPRRes) && (ME == 31) &&
2754 (ME - MB + 1 == SH) && (MB >= 16)) {
2758 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2760 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2763 if (Mask != ~0LLU) {
2764 MI->removeOperand(4);
2765 MI->removeOperand(3);
2766 MI->getOperand(2).setImm(Mask);
2767 NumRcRotatesConvertedToRcAnd++;
2769 }
else if (MIOpC == PPC::RLDICL &&
MI->getOperand(2).getImm() == 0) {
2770 int64_t MB =
MI->getOperand(3).getImm();
2772 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2773 NewOpC = PPC::ANDI8_rec;
2774 MI->removeOperand(3);
2775 MI->getOperand(2).setImm(Mask);
2776 NumRcRotatesConvertedToRcAnd++;
2781 MI->setDesc(NewDesc);
2784 if (!
MI->definesRegister(ImpDef,
nullptr)) {
2785 MI->addOperand(*
MI->getParent()->getParent(),
2790 if (!
MI->readsRegister(ImpUse,
nullptr)) {
2791 MI->addOperand(*
MI->getParent()->getParent(),
2796 assert(
MI->definesRegister(PPC::CR0,
nullptr) &&
2797 "Record-form instruction does not define cr0?");
2802 for (
unsigned i = 0, e = PredsToUpdate.
size(); i < e; i++)
2803 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2805 for (
unsigned i = 0, e = SubRegsToUpdate.
size(); i < e; i++)
2806 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2817 int64_t CmpMask, CmpValue;
2822 if (CmpValue || !CmpMask || SrcReg2)
2830 if (
Opc == PPC::CMPLWI ||
Opc == PPC::CMPLDI)
2837 if (Subtarget.isPPC64() &&
Opc == PPC::CMPWI)
2844 bool SrcRegHasOtherUse =
false;
2851 if (CRReg != PPC::CR0)
2855 bool SeenUseOfCRReg =
false;
2856 bool IsCRRegKilled =
false;
2857 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI,
false, IsCRRegKilled,
2863 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2877 "Record-form instruction does not define cr0?");
2891 OffsetIsScalable =
false;
2926 case PPC::DFSTOREf64:
2927 return FirstOpc == SecondOpc;
2933 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2940 int64_t OpOffset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2941 unsigned NumBytes)
const {
2947 "Only base registers and frame indices are supported.");
2952 if (ClusterSize > 2)
2966 unsigned FirstOpc = FirstLdSt.
getOpcode();
2967 unsigned SecondOpc = SecondLdSt.
getOpcode();
2978 int64_t Offset1 = 0, Offset2 = 0;
2987 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2988 "getMemOperandWithOffsetWidth return incorrect base op");
2990 assert(Offset1 <= Offset2 &&
"Caller should have ordered offsets.");
2991 return Offset1 + (int64_t)Width1.
getValue() == Offset2;
2998 unsigned Opcode =
MI.getOpcode();
3001 case PPC::INLINEASM:
3002 case PPC::INLINEASM_BR: {
3004 const char *AsmStr =
MI.getOperand(0).getSymbolName();
3007 case TargetOpcode::STACKMAP: {
3011 case TargetOpcode::PATCHPOINT: {
3015 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
3018 unsigned Num =
F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
3025 case TargetOpcode::PATCHABLE_RET: {
3027 unsigned RetOpcode =
MI.getOperand(0).getImm();
3028 bool IsConditional = RetOpcode == PPC::BCCLR;
3029 return (8 + IsConditional) * 4;
3031 case TargetOpcode::BUNDLE:
3032 return getInstBundleSize(
MI);
3034 return get(Opcode).getSize();
3041 return MI.getOpcode() == TargetOpcode::STACKMAP
3042 ? InstSizeVerifyMode::AllowOverEstimate
3043 : InstSizeVerifyMode::ExactSize;
3046std::pair<unsigned, unsigned>
3049 return std::make_pair(TF, 0u);
3054 using namespace PPCII;
3055 static const std::pair<unsigned, const char *> TargetFlags[] = {
3056 {MO_PLT,
"ppc-plt"},
3057 {MO_PIC_FLAG,
"ppc-pic"},
3058 {MO_PCREL_FLAG,
"ppc-pcrel"},
3059 {MO_GOT_FLAG,
"ppc-got"},
3060 {MO_PCREL_OPT_FLAG,
"ppc-opt-pcrel"},
3061 {MO_TLSGD_FLAG,
"ppc-tlsgd"},
3062 {MO_TPREL_FLAG,
"ppc-tprel"},
3063 {MO_TLSLDM_FLAG,
"ppc-tlsldm"},
3064 {MO_TLSLD_FLAG,
"ppc-tlsld"},
3065 {MO_TLSGDM_FLAG,
"ppc-tlsgdm"},
3066 {MO_GOT_TLSGD_PCREL_FLAG,
"ppc-got-tlsgd-pcrel"},
3067 {MO_GOT_TLSLD_PCREL_FLAG,
"ppc-got-tlsld-pcrel"},
3068 {MO_GOT_TPREL_PCREL_FLAG,
"ppc-got-tprel-pcrel"},
3071 {MO_TPREL_LO,
"ppc-tprel-lo"},
3072 {MO_TPREL_HA,
"ppc-tprel-ha"},
3073 {MO_DTPREL_LO,
"ppc-dtprel-lo"},
3074 {MO_TLSLD_LO,
"ppc-tlsld-lo"},
3075 {MO_TOC_LO,
"ppc-toc-lo"},
3076 {MO_TLS,
"ppc-tls"},
3077 {MO_PIC_HA_FLAG,
"ppc-ha-pic"},
3078 {MO_PIC_LO_FLAG,
"ppc-lo-pic"},
3079 {MO_TPREL_PCREL_FLAG,
"ppc-tprel-pcrel"},
3080 {MO_TLS_PCREL_FLAG,
"ppc-tls-pcrel"},
3081 {MO_GOT_PCREL_FLAG,
"ppc-got-pcrel"},
3093 unsigned UpperOpcode, LowerOpcode;
3094 switch (
MI.getOpcode()) {
3095 case PPC::DFLOADf32:
3096 UpperOpcode = PPC::LXSSP;
3097 LowerOpcode = PPC::LFS;
3099 case PPC::DFLOADf64:
3100 UpperOpcode = PPC::LXSD;
3101 LowerOpcode = PPC::LFD;
3103 case PPC::DFSTOREf32:
3104 UpperOpcode = PPC::STXSSP;
3105 LowerOpcode = PPC::STFS;
3107 case PPC::DFSTOREf64:
3108 UpperOpcode = PPC::STXSD;
3109 LowerOpcode = PPC::STFD;
3111 case PPC::XFLOADf32:
3112 UpperOpcode = PPC::LXSSPX;
3113 LowerOpcode = PPC::LFSX;
3115 case PPC::XFLOADf64:
3116 UpperOpcode = PPC::LXSDX;
3117 LowerOpcode = PPC::LFDX;
3119 case PPC::XFSTOREf32:
3120 UpperOpcode = PPC::STXSSPX;
3121 LowerOpcode = PPC::STFSX;
3123 case PPC::XFSTOREf64:
3124 UpperOpcode = PPC::STXSDX;
3125 LowerOpcode = PPC::STFDX;
3128 UpperOpcode = PPC::LXSIWAX;
3129 LowerOpcode = PPC::LFIWAX;
3132 UpperOpcode = PPC::LXSIWZX;
3133 LowerOpcode = PPC::LFIWZX;
3136 UpperOpcode = PPC::STXSIWX;
3137 LowerOpcode = PPC::STFIWX;
3143 Register TargetReg =
MI.getOperand(0).getReg();
3145 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3146 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3147 Opcode = LowerOpcode;
3149 Opcode = UpperOpcode;
3150 MI.setDesc(
get(Opcode));
3159 auto &
MBB = *
MI.getParent();
3160 auto DL =
MI.getDebugLoc();
3162 switch (
MI.getOpcode()) {
3163 case PPC::BUILD_UACC: {
3166 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3167 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3168 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3172 for (
int VecNo = 0; VecNo < 4; VecNo++)
3182 case PPC::KILL_PAIR: {
3183 MI.setDesc(
get(PPC::UNENCODED_NOP));
3184 MI.removeOperand(1);
3185 MI.removeOperand(0);
3188 case TargetOpcode::LOAD_STACK_GUARD: {
3189 auto M =
MBB.getParent()->getFunction().getParent();
3191 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() ==
"tls") &&
3192 "Only Linux target or tls mode are expected to contain "
3193 "LOAD_STACK_GUARD");
3195 if (M->getStackProtectorGuard() ==
"tls")
3196 Offset = M->getStackProtectorGuardOffset();
3198 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3199 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3200 MI.setDesc(
get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3206 case PPC::PPCLdFixedAddr: {
3207 assert((Subtarget.getTargetTriple().isOSGlibc() ||
3208 Subtarget.getTargetTriple().isMusl()) &&
3209 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3211 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3212 MI.setDesc(
get(PPC::LWZ));
3214#undef PPC_LNX_FEATURE
3216#define PPC_LNX_DEFINE_OFFSETS
3217#include "llvm/TargetParser/PPCTargetParser.def"
3218 bool IsLE = Subtarget.isLittleEndian();
3219 bool Is64 = Subtarget.isPPC64();
3220 if (FAType == PPC_FAWORD_HWCAP) {
3222 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3224 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3225 }
else if (FAType == PPC_FAWORD_HWCAP2) {
3227 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3229 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3230 }
else if (FAType == PPC_FAWORD_CPUID) {
3232 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3234 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3236 assert(
Offset &&
"Do not know the offset for this fixed addr load");
3237 MI.removeOperand(1);
3238 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3243#define PPC_TGT_PARSER_UNDEF_MACROS
3244#include "llvm/TargetParser/PPCTargetParser.def"
3245#undef PPC_TGT_PARSER_UNDEF_MACROS
3247 case PPC::DFLOADf32:
3248 case PPC::DFLOADf64:
3249 case PPC::DFSTOREf32:
3250 case PPC::DFSTOREf64: {
3251 assert(Subtarget.hasP9Vector() &&
3252 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3255 "D-form op must have register and immediate operands");
3258 case PPC::XFLOADf32:
3259 case PPC::XFSTOREf32:
3263 assert(Subtarget.hasP8Vector() &&
3264 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3265 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3266 "X-form op must have register and register operands");
3269 case PPC::XFLOADf64:
3270 case PPC::XFSTOREf64: {
3271 assert(Subtarget.hasVSX() &&
3272 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3273 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3274 "X-form op must have register and register operands");
3277 case PPC::SPILLTOVSR_LD: {
3278 Register TargetReg =
MI.getOperand(0).getReg();
3279 if (PPC::VSFRCRegClass.
contains(TargetReg)) {
3280 MI.setDesc(
get(PPC::DFLOADf64));
3284 MI.setDesc(
get(PPC::LD));
3287 case PPC::SPILLTOVSR_ST: {
3289 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3290 NumStoreSPILLVSRRCAsVec++;
3291 MI.setDesc(
get(PPC::DFSTOREf64));
3294 NumStoreSPILLVSRRCAsGpr++;
3295 MI.setDesc(
get(PPC::STD));
3299 case PPC::SPILLTOVSR_LDX: {
3300 Register TargetReg =
MI.getOperand(0).getReg();
3301 if (PPC::VSFRCRegClass.
contains(TargetReg))
3302 MI.setDesc(
get(PPC::LXSDX));
3304 MI.setDesc(
get(PPC::LDX));
3307 case PPC::SPILLTOVSR_STX: {
3309 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3310 NumStoreSPILLVSRRCAsVec++;
3311 MI.setDesc(
get(PPC::STXSDX));
3313 NumStoreSPILLVSRRCAsGpr++;
3314 MI.setDesc(
get(PPC::STDX));
3321 case PPC::CFENCE8: {
3322 auto Val =
MI.getOperand(0).getReg();
3323 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3329 MI.setDesc(
get(PPC::ISYNC));
3330 MI.removeOperand(0);
3333 case PPC::LWAT_CSNE_PSEUDO:
3334 case PPC::LDAT_CSNE_PSEUDO:
3344static unsigned selectReg(int64_t Imm1, int64_t Imm2,
unsigned CompareOpc,
3345 unsigned TrueReg,
unsigned FalseReg,
3346 unsigned CRSubReg) {
3348 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3352 return Imm1 < Imm2 ? TrueReg : FalseReg;
3354 return Imm1 > Imm2 ? TrueReg : FalseReg;
3356 return Imm1 == Imm2 ? TrueReg : FalseReg;
3360 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3368 return Imm1 == Imm2 ? TrueReg : FalseReg;
3371 return PPC::NoRegister;
3376 int64_t Imm)
const {
3377 assert(
MI.getOperand(OpNo).isReg() &&
"Operand must be a REG");
3379 Register InUseReg =
MI.getOperand(OpNo).getReg();
3380 MI.getOperand(OpNo).ChangeToImmediate(Imm);
3387 int UseOpIdx =
MI.findRegisterUseOperandIdx(InUseReg, &RI,
false);
3388 if (UseOpIdx >= 0) {
3398 MI.removeOperand(UseOpIdx);
3407 int OperandToKeep = LII.
SetCR ? 1 : 0;
3408 for (
int i =
MI.getNumOperands() - 1; i > OperandToKeep; i--)
3409 MI.removeOperand(i);
3413 MI.setDesc(
get(LII.
Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3428 bool &SeenIntermediateUse)
const {
3429 assert(!
MI.getParent()->getParent()->getRegInfo().isSSA() &&
3430 "Should be called after register allocation.");
3433 SeenIntermediateUse =
false;
3434 for (; It != E; ++It) {
3435 if (It->modifiesRegister(Reg, &RI))
3437 if (It->readsRegister(Reg, &RI))
3438 SeenIntermediateUse =
true;
3446 int64_t Imm)
const {
3447 assert(!
MBB.getParent()->getRegInfo().isSSA() &&
3448 "Register should be in non-SSA form after RA");
3449 bool isPPC64 = Subtarget.isPPC64();
3463 assert(isPPC64 &&
"Materializing 64-bit immediate to single register is "
3464 "only supported in PPC64");
3466 if ((Imm >> 32) & 0xFFFF)
3469 .
addImm((Imm >> 32) & 0xFFFF);
3476 .
addImm((Imm >> 16) & 0xFFFF);
3486 unsigned &OpNoForForwarding,
3487 bool &SeenIntermediateUse)
const {
3488 OpNoForForwarding = ~0U;
3495 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3496 if (!
MI.getOperand(i).isReg())
3499 if (!Reg.isVirtual())
3501 Register TrueReg = RI.lookThruCopyLike(Reg, MRI);
3504 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3505 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3506 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3507 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3508 OpNoForForwarding = i;
3509 DefMI = DefMIForTrueReg;
3514 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3524 unsigned Opc =
MI.getOpcode();
3525 bool ConvertibleImmForm =
3526 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3527 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3528 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3529 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3530 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3531 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3532 Opc == PPC::RLWINM8_rec;
3533 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3540 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3541 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3543 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3544 MachineOperand &MO =
MI.getOperand(i);
3545 SeenIntermediateUse =
false;
3559 case PPC::ADDItocL8:
3562 OpNoForForwarding = i;
3569 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3572unsigned PPCInstrInfo::getSpillTarget()
const {
3575 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3577 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3578 2 : Subtarget.hasP9Vector() ?
3617 bool PostRA = !MRI->
isSSA();
3623 unsigned ToBeDeletedReg = 0;
3624 int64_t OffsetImm = 0;
3625 unsigned XFormOpcode = 0;
3633 bool OtherIntermediateUse =
false;
3637 if (OtherIntermediateUse || !ADDMI)
3644 unsigned ScaleRegIdx = 0;
3645 int64_t OffsetAddi = 0;
3659 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3664 for (
auto It = ++Start; It != End; It++)
3673 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3678 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3694 MI.setDesc(
get(XFormOpcode));
3696 .ChangeToRegister(ScaleReg,
false,
false,
3700 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3712 int64_t &Imm)
const {
3716 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3732 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3736 unsigned &ToBeDeletedReg,
3737 unsigned &XFormOpcode,
3741 if (!
MI.mayLoadOrStore())
3744 unsigned Opc =
MI.getOpcode();
3746 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3749 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3763 if (!ImmOperand.
isImm())
3766 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3769 if (!RegOperand.
isKill())
3772 ToBeDeletedReg = RegOperand.
getReg();
3773 OffsetImm = ImmOperand.
getImm();
3780 int64_t &OffsetAddi,
3781 int64_t OffsetImm)
const {
3782 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3788 bool OtherIntermediateUse =
false;
3809 if (OtherIntermediateUse || !ADDIMI)
3828 bool PostRA = !MRI->
isSSA();
3829 bool SeenIntermediateUse =
true;
3830 unsigned ForwardingOperand = ~0U;
3832 SeenIntermediateUse);
3835 assert(ForwardingOperand <
MI.getNumOperands() &&
3836 "The forwarding operand needs to be valid at this point");
3837 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3838 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3839 if (KilledDef && KillFwdDefMI)
3853 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3854 PPC::INSTRUCTION_LIST_END &&
3855 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3859 bool IsVFReg =
MI.getOperand(0).isReg() &&
3860 MI.getOperand(0).getReg().isPhysical() &&
3867 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3874 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3880 simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef, &RegsToUpdate))
3889 Register FoldingReg =
MI.getOperand(1).getReg();
3893 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3894 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3898 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3901 "Invalid PPC::RLWINM Instruction!");
3909 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3910 "Invalid PPC::RLWINM Instruction!");
3932 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3935 if ((MBMI > MEMI) && !SrcMaskFull)
3945 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3946 APInt FinalMask = RotatedSrcMask & MaskMI;
3948 bool Simplified =
false;
3951 if (FinalMask.
isZero()) {
3953 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3958 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3960 MI.removeOperand(4);
3961 MI.removeOperand(3);
3962 MI.removeOperand(2);
3963 MI.getOperand(1).ChangeToImmediate(0);
3964 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
3967 MI.removeOperand(4);
3968 MI.removeOperand(3);
3969 MI.getOperand(2).setImm(0);
3970 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3973 MI.getOperand(1).setIsKill(
true);
3977 MI.getOperand(1).setIsKill(
false);
3993 uint16_t NewSH = (SHSrc + SHMI) % 32;
3994 MI.getOperand(2).setImm(NewSH);
3997 MI.getOperand(3).setImm(NewMB);
3998 MI.getOperand(4).setImm(NewME);
4002 MI.getOperand(1).setIsKill(
true);
4006 MI.getOperand(1).setIsKill(
false);
4036 default:
return false;
4044 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4053 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4069 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4077 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4085 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4105 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4106 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4107 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4108 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4113 case PPC::RLWNM_rec:
4114 case PPC::RLWNM8_rec:
4134 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4135 Opc == PPC::RLWNM8_rec)
4141 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4142 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4143 case PPC::RLWNM_rec:
4146 case PPC::RLWNM8_rec:
4149 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4150 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4157 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4158 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4178 case PPC::RLDCL_rec:
4180 case PPC::RLDCR_rec:
4196 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4197 Opc == PPC::RLDCR_rec)
4203 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4204 case PPC::RLDCL_rec:
4207 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4208 case PPC::RLDCR_rec:
4211 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4215 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4262 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4263 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4264 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4265 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4266 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4267 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4268 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4269 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4275 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4276 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4277 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4278 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4279 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4280 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4281 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4282 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4287 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4288 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4320 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4321 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4322 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4323 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4324 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4325 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4326 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4327 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4332 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4333 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4334 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4335 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4336 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4337 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4338 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4339 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4344 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4345 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4358 case PPC::XFLOADf32:
4359 case PPC::XFLOADf64:
4360 case PPC::XFSTOREf32:
4361 case PPC::XFSTOREf64:
4362 if (!Subtarget.hasP9Vector())
4389 case PPC::XFLOADf32:
4403 case PPC::XFLOADf64:
4421 case PPC::XFSTOREf32:
4435 case PPC::XFSTOREf64:
4446 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4448 unsigned MaxOp = std::max(Op1, Op2);
4449 unsigned MinOp = std::min(Op1, Op2);
4452 MI.removeOperand(std::max(Op1, Op2));
4453 MI.removeOperand(std::min(Op1, Op2));
4457 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4458 MI.addOperand(MOp2);
4459 MI.addOperand(MOp1);
4464 unsigned TotalOps =
MI.getNumOperands() + 2;
4465 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4467 MI.removeOperand(i);
4470 MI.addOperand(MOp2);
4472 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4474 MI.addOperand(MOp1);
4476 MI.addOperand(MOps.
back());
4487 unsigned OpNoForForwarding
4491 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4528 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4534 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4538 "Add inst must have at least three operands");
4539 RegMO = &
DefMI.getOperand(1);
4540 ImmMO = &
DefMI.getOperand(2);
4543 if (!RegMO->
isReg())
4552bool PPCInstrInfo::isRegElgibleForForwarding(
4555 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4562 const MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4572 for (; It !=
E; ++It) {
4576 IsFwdFeederRegKilled =
true;
4578 SeenIntermediateUse =
true;
4580 if ((&*It) == &
DefMI)
4593bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4597 int64_t BaseImm)
const {
4599 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4620 if (ImmMO.
isImm()) {
4625 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4646 unsigned OpNoForForwarding,
4649 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4650 !
DefMI.getOperand(1).isImm())
4653 MachineFunction *MF =
MI.getParent()->getParent();
4654 MachineRegisterInfo *MRI = &MF->
getRegInfo();
4657 int64_t Immediate =
DefMI.getOperand(1).getImm();
4661 bool ReplaceWithLI =
false;
4662 bool Is64BitLI =
false;
4665 unsigned Opc =
MI.getOpcode();
4688 int64_t Comparand =
MI.getOperand(2).getImm();
4689 int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
4690 ? (Comparand | 0xFFFFFFFFFFFF0000)
4694 unsigned UseOpc = CompareUseMI.getOpcode();
4695 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4697 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4698 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4699 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4700 unsigned RegToCopy =
4701 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4702 if (RegToCopy == PPC::NoRegister)
4705 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4706 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4708 CompareUseMI.removeOperand(3);
4709 CompareUseMI.removeOperand(2);
4713 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4717 for (
const MachineOperand &MO : CompareUseMI.operands())
4722 CompareUseMI.setDesc(
get(PPC::COPY));
4723 CompareUseMI.removeOperand(3);
4724 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4725 CmpIselsConverted++;
4734 MissedConvertibleImmediateInstrs++;
4742 int64_t Addend =
MI.getOperand(2).getImm();
4744 ReplaceWithLI =
true;
4745 Is64BitLI =
Opc == PPC::ADDI8;
4746 NewImm = Addend + SExtImm;
4752 case PPC::SUBFIC8: {
4754 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4756 int64_t Minuend =
MI.getOperand(2).getImm();
4758 ReplaceWithLI =
true;
4759 Is64BitLI =
Opc == PPC::SUBFIC8;
4760 NewImm = Minuend - SExtImm;
4766 case PPC::RLDICL_rec:
4767 case PPC::RLDICL_32:
4768 case PPC::RLDICL_32_64: {
4770 int64_t SH =
MI.getOperand(2).getImm();
4771 int64_t MB =
MI.getOperand(3).getImm();
4772 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4774 InVal = InVal.rotl(SH);
4775 uint64_t
Mask = MB == 0 ? -1LL
U : (1LL
U << (63 - MB + 1)) - 1;
4781 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4782 ReplaceWithLI =
true;
4783 Is64BitLI =
Opc != PPC::RLDICL_32;
4784 NewImm = InVal.getSExtValue();
4785 SetCR =
Opc == PPC::RLDICL_rec;
4792 case PPC::RLWINM_rec:
4793 case PPC::RLWINM8_rec: {
4794 int64_t SH =
MI.getOperand(2).getImm();
4795 int64_t MB =
MI.getOperand(3).getImm();
4796 int64_t ME =
MI.getOperand(4).getImm();
4797 APInt InVal(32, SExtImm,
true);
4798 InVal = InVal.rotl(SH);
4804 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4805 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4808 ReplaceWithLI =
true;
4809 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4810 NewImm = InVal.getSExtValue();
4811 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4820 int64_t LogicalImm =
MI.getOperand(2).getImm();
4822 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4823 Result = LogicalImm | SExtImm;
4825 Result = LogicalImm ^ SExtImm;
4827 ReplaceWithLI =
true;
4828 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4836 if (ReplaceWithLI) {
4841 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4842 if (PostRA && ImmChanged)
4849 DefMI.getOperand(1).setImm(NewImm);
4853 else if (MRI->
use_empty(
MI.getOperand(0).getReg())) {
4855 assert(Immediate &&
"Transformation converted zero to non-zero?");
4858 }
else if (ImmChanged)
4867 LoadImmediateInfo LII;
4873 if (KilledDef && SetCR)
4874 *KilledDef =
nullptr;
4887bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4889 MachineRegisterInfo *MRI = &
MI.getParent()->getParent()->getRegInfo();
4897 if (!
MI.mayLoadOrStore())
4900 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4902 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4903 "MI must have x-form opcode");
4907 bool IsVFReg =
MI.getOperand(0).isReg() &&
4908 MI.getOperand(0).getReg().isPhysical() &&
4920 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4921 if (!ImmOperandMI.
isImm())
4925 MachineOperand *ImmMO =
nullptr;
4926 MachineOperand *RegMO =
nullptr;
4927 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4929 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4934 int64_t ImmBase = ImmOperandMI.
getImm();
4936 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III, Imm, ImmBase))
4940 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4957bool PPCInstrInfo::transformToImmFormFedByAdd(
4967 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
4972 MachineOperand *ImmMO =
nullptr;
4973 MachineOperand *RegMO =
nullptr;
4974 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4976 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4981 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III, Imm))
4984 bool IsFwdFeederRegKilled =
false;
4985 bool SeenIntermediateUse =
false;
4987 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
4988 IsFwdFeederRegKilled, SeenIntermediateUse))
4991 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5008 if (ImmMO->
isImm()) {
5019 if (
DefMI.getOpcode() == PPC::ADDItocL8)
5029 MI.removeOperand(i);
5035 MI.addOperand(*ImmMO);
5037 for (
auto &MO : MOps)
5054 unsigned ConstantOpNo,
5057 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5058 !
DefMI.getOperand(1).isImm())
5064 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5074 APInt ActualValue(64, Imm,
true);
5075 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5078 uint64_t UnsignedMax = (1 << III.
ImmWidth) - 1;
5079 if ((uint64_t)Imm > UnsignedMax)
5089 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5093 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5096 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5097 ConstantOpNo != PosForOrigZero)
5101 unsigned Opc =
MI.getOpcode();
5102 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5103 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5104 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5105 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5106 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5107 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5108 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5109 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5111 Opc == PPC::SRD_rec;
5125 if (SpecialShift32 || SpecialShift64) {
5126 LoadImmediateInfo LII;
5130 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5131 if (Imm & (SpecialShift32 ? 0x20 : 0x40))
5136 else if (!SetCR && ShAmt == 0 && !PostRA) {
5137 MI.removeOperand(2);
5138 MI.setDesc(
get(PPC::COPY));
5141 if (SpecialShift32) {
5145 uint64_t SH = ShAmt == 0 ? 0 :
RightShift ? 32 - ShAmt : ShAmt;
5149 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5155 uint64_t SH = ShAmt == 0 ? 0 :
RightShift ? 64 - ShAmt : ShAmt;
5156 uint64_t ME =
RightShift ? ShAmt : 63 - ShAmt;
5158 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5188 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5205 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5206 return &PPC::VSRCRegClass;
5211 return PPC::getRecordFormOpcode(Opcode);
5215 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5216 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5217 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5218 Opcode == PPC::LHZUX8);
5232 int Opcode =
MI->getOpcode();
5233 if (
TII.isSExt32To64(Opcode))
5242 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5248 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5249 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5250 MI->getOperand(3).getImm() > 0 &&
5251 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5256 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5258 if ((Imm & 0x8000) == 0)
5278 int Opcode =
MI->getOpcode();
5279 if (
TII.isZExt32To64(Opcode))
5284 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5285 MI->getOperand(0).getReg() ==
Reg)
5290 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5291 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5292 int64_t Imm =
MI->getOperand(1).getImm();
5293 if (((
uint64_t)Imm & ~0x7FFFuLL) == 0)
5299 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5300 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5301 Opcode == PPC::RLDICL_32_64) &&
5302 MI->getOperand(3).getImm() >= 32)
5305 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5306 MI->getOperand(3).getImm() >= 32 &&
5307 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5310 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5311 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5312 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5313 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5322 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5324 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5326 Register StackReg =
MI.getOperand(2).getReg();
5349 unsigned BinOpDepth,
5351 if (!Reg.isVirtual())
5358 unsigned Opcode =
MI->getOpcode();
5367 unsigned OperandEnd = 3, OperandStride = 1;
5368 if (Opcode == PPC::PHI) {
5369 OperandEnd =
MI->getNumOperands();
5373 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5374 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5376 BinOpDepth + 1, LV);
5385 Register SrcReg =
MI->getOperand(1).getReg();
5399 if (SrcReg != PPC::X3)
5422 BinOpDepth + 1, LV);
5424 BinOpDepth + 1, LV);
5429 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5436 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5437 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5438 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5439 {PPC::AND, PPC::AND8}};
5442 auto It = OpcodeMap.
find(Opcode);
5443 if (It != OpcodeMap.
end()) {
5445 NewOpcode = It->second;
5453 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5456 assert(NewOpcode != -1 &&
5457 "Must have a 64-bit opcode to map the 32-bit opcode!");
5461 RI.getRegClass(
MCID.operands()[0].RegClass);
5463 Register SrcReg =
MI->getOperand(0).getReg();
5473 auto MBB =
MI->getParent();
5481 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5483 if (!Operand.
isReg())
5491 RI.getRegClass(
MCID.operands()[i].RegClass);
5493 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5494 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5503 PromoteRegs[i] = DstTmpReg;
5513 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5520 for (
unsigned i = 1; i < Iter->getNumOperands(); i++) {
5522 if (!Operand.
isReg())
5530 MI->eraseFromParent();
5546std::pair<bool, bool>
5548 const unsigned BinOpDepth,
5551 return std::pair<bool, bool>(
false,
false);
5555 return std::pair<bool, bool>(
false,
false);
5562 if (IsSExt && IsZExt)
5563 return std::pair<bool, bool>(IsSExt, IsZExt);
5565 switch (
MI->getOpcode()) {
5567 Register SrcReg =
MI->getOperand(1).getReg();
5576 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5577 SrcExt.second || IsZExt);
5583 if (
MI->getParent()->getBasicBlock() ==
5589 return std::pair<bool, bool>(IsSExt, IsZExt);
5593 if (SrcReg != PPC::X3) {
5596 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5597 SrcExt.second || IsZExt);
5607 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5610 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5611 return IsExtendPair;
5615 return IsExtendPair;
5620 return IsExtendPair;
5622 if (IntTy && IntTy->getBitWidth() <= 32) {
5624 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5625 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5626 return std::pair<bool, bool>(IsSExt, IsZExt);
5629 return IsExtendPair;
5638 Register SrcReg =
MI->getOperand(1).getReg();
5640 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5641 SrcExt.second || IsZExt);
5652 Register SrcReg =
MI->getOperand(1).getReg();
5656 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5658 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5659 SrcExt.second || IsZExt);
5669 return std::pair<bool, bool>(
false,
false);
5673 unsigned OperandEnd = 3, OperandStride = 1;
5674 if (
MI->getOpcode() == PPC::PHI) {
5675 OperandEnd =
MI->getNumOperands();
5681 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5682 if (!
MI->getOperand(
I).isReg())
5683 return std::pair<bool, bool>(
false,
false);
5687 IsSExt &= SrcExt.first;
5688 IsZExt &= SrcExt.second;
5690 return std::pair<bool, bool>(IsSExt, IsZExt);
5699 return std::pair<bool, bool>(
false,
false);
5701 Register SrcReg1 =
MI->getOperand(1).getReg();
5702 Register SrcReg2 =
MI->getOperand(2).getReg();
5705 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5706 Src1Ext.second || Src2Ext.second);
5712 return std::pair<bool, bool>(IsSExt, IsZExt);
5716 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5729 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5731 TII(MF->getSubtarget().getInstrInfo()) {
5740 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5742 return MI == EndLoop;
5745 std::optional<bool> createTripCountGreaterCondition(
5746 int TC, MachineBasicBlock &
MBB,
5747 SmallVectorImpl<MachineOperand> &
Cond)
override {
5748 if (TripCount == -1) {
5753 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5758 return TripCount > TC;
5761 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5766 void adjustTripCount(
int TripCountAdjust)
override {
5769 if (LoopCount->
getOpcode() == PPC::LI8 ||
5780 void disposed(LiveIntervals *LIS)
override {
5792std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5797 if (Preheader == LoopBB)
5798 Preheader = *std::next(LoopBB->
pred_begin());
5801 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5804 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5807 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5817 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5820 for (
auto &
I : PreHeader.
instrs())
5821 if (
I.getOpcode() == LOOPi)
5863 int64_t OffsetA = 0, OffsetB = 0;
5869 int LowOffset = std::min(OffsetA, OffsetB);
5870 int HighOffset = std::max(OffsetA, OffsetB);
5871 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5873 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
5887 bool IsLDAT =
MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
5893 if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
5897 Register DstReg64 = IsLDAT ? DstReg
5899 DstReg, PPC::sub_32, &PPC::G8RCRegClass));
5901 ScratchReg = DstReg64;
5909 if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
5911 .
addReg(IsLDAT ? PPC::X8 : PPC::R8)
5912 .
addReg(IsLDAT ? PPC::X8 : PPC::R8);
5914 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< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
static bool isOpZeroOfSubwordPreincLoad(int Opcode)
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
static cl::opt< float > FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5), cl::desc("register pressure factor for the transformations."))
#define InfoArrayIdxMULOpIdx
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, unsigned TrueReg, unsigned FalseReg, unsigned CRSubReg)
static unsigned getCRBitValue(unsigned CRBit)
static bool isAnImmediateOperand(const MachineOperand &MO)
static const uint16_t FMAOpIdxInfo[][6]
static cl::opt< bool > DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops"))
#define InfoArrayIdxAddOpIdx
static cl::opt< bool > UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation"))
static bool definedBySignExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMAInst
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc, const PPCSubtarget &Subtarget)
static cl::opt< bool > EnableFMARegPressureReduction("ppc-fma-rp-reduction", cl::Hidden, cl::init(true), cl::desc("enable register pressure reduce in machine combiner pass."))
static bool isLdStSafeToCluster(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
const unsigned MAX_BINOP_DEPTH
static cl::opt< bool > DisableCmpOpt("disable-ppc-cmp-opt", cl::desc("Disable compare instruction optimization"), cl::Hidden)
#define InfoArrayIdxFSubInst
#define InfoArrayIdxFAddInst
static bool definedByZeroExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMULInst
static cl::opt< bool > VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool isPhysical(const MachineOperand &MO)
This file declares the machine register scavenger class.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
LLVM_ABI APInt rotl(unsigned rotateAmt) const
Rotate left by rotateAmt.
static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit, unsigned hiBit)
Wrap version of getBitsSet.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
Get the array size.
This class holds the attributes for a particular argument, parameter, function, or return value.
This is an important base class in LLVM.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const BasicBlock & getEntryBlock() const
AttributeList getAttributes() const
Return the attribute list for this Function.
Type * getReturnType() const
Returns the type of the ret val.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Itinerary data supplied by a subtarget to be used by a target.
std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
Class to represent integer types.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
Represents a single loop in the control flow graph.
Instances of this class represent a single low-level machine instruction.
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
ArrayRef< MCPhysReg > implicit_uses() const
Return a list of registers that are potentially read by any instance of this machine instruction.
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
This holds information about one operand of a machine instruction, indicating the register class for ...
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasImplicitDef() const
Returns true if the instruction has implicit definition.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
LLVM_ABI void clearRegisterDeads(Register Reg)
Clear all dead flags on operands defining register Reg.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI bool isLiveIn(Register Reg) const
static use_instr_iterator use_instr_end()
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based hazard recognizer for P...
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isLiveInSExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and sign-extended.
bool isLiveInZExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and zero-extended.
PPCHazardRecognizer970 - This class defines a finite state automata that models the dispatch logic on...
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for a fma chain ending in Root.
bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase=nullptr) const
bool isReMaterializableImpl(const MachineInstr &MI) const override
PPCInstrInfo(const PPCSubtarget &STI)
const TargetRegisterClass * updatedRC(const TargetRegisterClass *RC) const
bool isPredicated(const MachineInstr &MI) const override
bool expandVSXMemPseudo(MachineInstr &MI) const
bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
Fixup the placeholders we put in genAlternativeCodeSequence() for MachineCombiner.
MCInst getNop() const override
Return the noop instruction to use for a noop.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static int getRecordFormOpcode(unsigned Opcode)
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
bool isXFormMemOp(unsigned Opcode) const
const PPCRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
CombinerObjective getCombinerObjective(unsigned Pattern) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const
unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const
bool expandAMOCSNEPseudo(MachineInstr &MI) const
void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth, LiveVariables *LV) const
bool isTOCSaveMI(const MachineInstr &MI) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer to use for this target when ...
bool isSExt32To64(unsigned Opcode) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool isBDNZ(unsigned Opcode) const
Check Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isZeroExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
std::pair< bool, bool > isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, const MachineRegisterInfo *MRI) const
bool expandPostRAPseudo(MachineInstr &MI) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index, MachineInstr *&ADDIMI, int64_t &OffsetAddi, int64_t OffsetImm) const
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
void materializeImmPostRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register Reg, int64_t Imm) const
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
Return true if two MIs access different memory addresses and false otherwise.
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
CreateTargetHazardRecognizer - Return the hazard recognizer to use for this target when scheduling th...
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
Get the base operand and byte offset of an instruction that reads/writes memory.
void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const
void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const
bool foldFrameOffset(MachineInstr &MI) const
bool isLoadFromConstantPool(MachineInstr *I) const
MachineInstr * findLoopInstr(MachineBasicBlock &PreHeader, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
bool convertToImmediateForm(MachineInstr &MI, SmallSet< Register, 4 > &RegsToUpdate, MachineInstr **KilledDef=nullptr) const
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
Return true if get the base operand, byte offset of an instruction and the memory width.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool shouldReduceRegisterPressure(const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const override
On PowerPC, we leverage machine combiner pass to reduce register pressure when the register pressure ...
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
InstSizeVerifyMode getInstSizeVerifyMode(const MachineInstr &MI) const override
bool isSignExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, int64_t Imm) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
Returns true if the two given memory operations should be scheduled adjacent.
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...
bool optimizeCmpPostRA(MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
const Constant * getConstantFromConstantPool(MachineInstr *I) const
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, bool PostRA) const
MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const
static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg)
const PPCTargetMachine & getTargetMachine() const
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void closeRegion()
Finalize the region boundaries and recored live ins and live outs.
LLVM_ABI void recede(SmallVectorImpl< VRegMaskOrUnit > *LiveUses=nullptr)
Recede across the previous instruction.
RegisterPressure & getPressure()
Get the resulting register pressure over the traversed region.
LLVM_ABI void recedeSkipDebugValues()
Recede until we find an instruction which is not a DebugValue.
LLVM_ABI void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)
Setup the RegPressureTracker.
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
List of registers defined and used by a machine instruction.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const TargetInstrInfo * TII
Target instruction information.
MachineFunction & MF
Machine function.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
StackOffset holds a fixed and a scalable offset in bytes.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const Triple & getTargetTriple() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
bool isOSAIX() const
Tests whether the OS is AIX.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.
Define some predicates that are used for node matching.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
int32_t getNonRecordFormOpcode(uint32_t)
int32_t getAltVSXFMAOpcode(uint32_t Opcode)
static bool isVFRegister(MCRegister Reg)
template class LLVM_TEMPLATE_ABI opt< bool >
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static unsigned getCRFromCRBit(unsigned SrcReg)
constexpr RegState getDeadRegState(bool B)
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
@ MustReduceRegisterPressure
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t IsSummingOperands
uint64_t OpNoForForwarding
uint64_t ImmMustBeMultipleOf
uint64_t ZeroIsSpecialNew
uint64_t ZeroIsSpecialOrig
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.