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) {
157 std::optional<unsigned> Cycle = ItinData->
getOperandCycle(DefClass, 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) {
464 return MULInstrL && MULInstrR;
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;
2744 uint64_t Mask = ~0LLU;
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));
3213 uint64_t FAType =
MI.getOperand(1).getImm();
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)
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)
3506 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3507 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3508 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3509 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3510 OpNoForForwarding = i;
3511 DefMI = DefMIForTrueReg;
3516 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3526 unsigned Opc =
MI.getOpcode();
3527 bool ConvertibleImmForm =
3528 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3529 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3530 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3531 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3532 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3533 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3534 Opc == PPC::RLWINM8_rec;
3535 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3542 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3543 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3545 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3546 MachineOperand &MO =
MI.getOperand(i);
3547 SeenIntermediateUse =
false;
3561 case PPC::ADDItocL8:
3564 OpNoForForwarding = i;
3571 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3574unsigned PPCInstrInfo::getSpillTarget()
const {
3577 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3579 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3580 2 : Subtarget.hasP9Vector() ?
3619 bool PostRA = !MRI->
isSSA();
3625 unsigned ToBeDeletedReg = 0;
3626 int64_t OffsetImm = 0;
3627 unsigned XFormOpcode = 0;
3635 bool OtherIntermediateUse =
false;
3639 if (OtherIntermediateUse || !ADDMI)
3646 unsigned ScaleRegIdx = 0;
3647 int64_t OffsetAddi = 0;
3661 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3666 for (
auto It = ++Start; It != End; It++)
3675 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3680 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3696 MI.setDesc(
get(XFormOpcode));
3698 .ChangeToRegister(ScaleReg,
false,
false,
3702 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3714 int64_t &
Imm)
const {
3718 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3734 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3738 unsigned &ToBeDeletedReg,
3739 unsigned &XFormOpcode,
3743 if (!
MI.mayLoadOrStore())
3746 unsigned Opc =
MI.getOpcode();
3748 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3751 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3765 if (!ImmOperand.
isImm())
3768 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3771 if (!RegOperand.
isKill())
3774 ToBeDeletedReg = RegOperand.
getReg();
3775 OffsetImm = ImmOperand.
getImm();
3782 int64_t &OffsetAddi,
3783 int64_t OffsetImm)
const {
3784 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3790 bool OtherIntermediateUse =
false;
3811 if (OtherIntermediateUse || !ADDIMI)
3830 bool PostRA = !MRI->
isSSA();
3831 bool SeenIntermediateUse =
true;
3832 unsigned ForwardingOperand = ~0U;
3834 SeenIntermediateUse);
3837 assert(ForwardingOperand <
MI.getNumOperands() &&
3838 "The forwarding operand needs to be valid at this point");
3839 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3840 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3841 if (KilledDef && KillFwdDefMI)
3855 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3856 PPC::INSTRUCTION_LIST_END &&
3857 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3861 bool IsVFReg =
MI.getOperand(0).isReg() &&
3862 MI.getOperand(0).getReg().isPhysical() &&
3869 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3876 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3882 simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef, &RegsToUpdate))
3891 Register FoldingReg =
MI.getOperand(1).getReg();
3897 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3898 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3902 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3905 "Invalid PPC::RLWINM Instruction!");
3907 uint64_t SHMI =
MI.getOperand(2).getImm();
3909 uint64_t MBMI =
MI.getOperand(3).getImm();
3911 uint64_t MEMI =
MI.getOperand(4).getImm();
3913 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3914 "Invalid PPC::RLWINM Instruction!");
3936 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3939 if ((MBMI > MEMI) && !SrcMaskFull)
3949 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3950 APInt FinalMask = RotatedSrcMask & MaskMI;
3952 bool Simplified =
false;
3955 if (FinalMask.
isZero()) {
3957 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3962 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3964 MI.removeOperand(4);
3965 MI.removeOperand(3);
3966 MI.removeOperand(2);
3967 MI.getOperand(1).ChangeToImmediate(0);
3968 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
3971 MI.removeOperand(4);
3972 MI.removeOperand(3);
3973 MI.getOperand(2).setImm(0);
3974 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3977 MI.getOperand(1).setIsKill(
true);
3981 MI.getOperand(1).setIsKill(
false);
3997 uint16_t NewSH = (SHSrc + SHMI) % 32;
3998 MI.getOperand(2).setImm(NewSH);
4001 MI.getOperand(3).setImm(NewMB);
4002 MI.getOperand(4).setImm(NewME);
4006 MI.getOperand(1).setIsKill(
true);
4010 MI.getOperand(1).setIsKill(
false);
4040 default:
return false;
4048 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4057 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4073 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4081 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4089 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4109 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4110 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4111 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4112 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4117 case PPC::RLWNM_rec:
4118 case PPC::RLWNM8_rec:
4138 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4139 Opc == PPC::RLWNM8_rec)
4145 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4146 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4147 case PPC::RLWNM_rec:
4150 case PPC::RLWNM8_rec:
4153 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4154 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4161 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4162 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4182 case PPC::RLDCL_rec:
4184 case PPC::RLDCR_rec:
4200 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4201 Opc == PPC::RLDCR_rec)
4207 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4208 case PPC::RLDCL_rec:
4211 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4212 case PPC::RLDCR_rec:
4215 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4219 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4266 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4267 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4268 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4269 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4270 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4271 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4272 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4273 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4279 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4280 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4281 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4282 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4283 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4284 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4285 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4286 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4291 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4292 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4324 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4325 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4326 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4327 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4328 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4329 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4330 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4331 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4336 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4337 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4338 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4339 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4340 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4341 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4342 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4343 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4348 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4349 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4362 case PPC::XFLOADf32:
4363 case PPC::XFLOADf64:
4364 case PPC::XFSTOREf32:
4365 case PPC::XFSTOREf64:
4366 if (!Subtarget.hasP9Vector())
4393 case PPC::XFLOADf32:
4407 case PPC::XFLOADf64:
4425 case PPC::XFSTOREf32:
4439 case PPC::XFSTOREf64:
4450 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4452 unsigned MaxOp = std::max(Op1, Op2);
4453 unsigned MinOp = std::min(Op1, Op2);
4456 MI.removeOperand(std::max(Op1, Op2));
4457 MI.removeOperand(std::min(Op1, Op2));
4461 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4462 MI.addOperand(MOp2);
4463 MI.addOperand(MOp1);
4468 unsigned TotalOps =
MI.getNumOperands() + 2;
4469 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4471 MI.removeOperand(i);
4474 MI.addOperand(MOp2);
4476 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4478 MI.addOperand(MOp1);
4480 MI.addOperand(MOps.
back());
4491 unsigned OpNoForForwarding
4495 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4532 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4538 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4542 "Add inst must have at least three operands");
4543 RegMO = &
DefMI.getOperand(1);
4544 ImmMO = &
DefMI.getOperand(2);
4547 if (!RegMO->
isReg())
4556bool PPCInstrInfo::isRegElgibleForForwarding(
4559 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4566 const MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
4576 for (; It !=
E; ++It) {
4580 IsFwdFeederRegKilled =
true;
4582 SeenIntermediateUse =
true;
4584 if ((&*It) == &
DefMI)
4597bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4601 int64_t BaseImm)
const {
4603 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4624 if (ImmMO.
isImm()) {
4629 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4650 unsigned OpNoForForwarding,
4653 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4654 !
DefMI.getOperand(1).isImm())
4658 MachineRegisterInfo *MRI = &MF->
getRegInfo();
4661 int64_t Immediate =
DefMI.getOperand(1).getImm();
4665 bool ReplaceWithLI =
false;
4666 bool Is64BitLI =
false;
4669 unsigned Opc =
MI.getOpcode();
4692 int64_t Comparand =
MI.getOperand(2).getImm();
4693 int64_t SExtComparand = ((
uint64_t)Comparand & ~0x7FFFuLL) != 0
4694 ? (Comparand | 0xFFFFFFFFFFFF0000)
4698 unsigned UseOpc = CompareUseMI.getOpcode();
4699 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4701 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4702 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4703 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4704 unsigned RegToCopy =
4705 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4706 if (RegToCopy == PPC::NoRegister)
4709 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4710 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4712 CompareUseMI.removeOperand(3);
4713 CompareUseMI.removeOperand(2);
4717 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4721 for (
const MachineOperand &MO : CompareUseMI.operands())
4726 CompareUseMI.setDesc(
get(PPC::COPY));
4727 CompareUseMI.removeOperand(3);
4728 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4729 CmpIselsConverted++;
4738 MissedConvertibleImmediateInstrs++;
4746 int64_t Addend =
MI.getOperand(2).getImm();
4748 ReplaceWithLI =
true;
4749 Is64BitLI =
Opc == PPC::ADDI8;
4750 NewImm = Addend + SExtImm;
4756 case PPC::SUBFIC8: {
4758 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4760 int64_t Minuend =
MI.getOperand(2).getImm();
4762 ReplaceWithLI =
true;
4763 Is64BitLI =
Opc == PPC::SUBFIC8;
4764 NewImm = Minuend - SExtImm;
4770 case PPC::RLDICL_rec:
4771 case PPC::RLDICL_32:
4772 case PPC::RLDICL_32_64: {
4774 int64_t SH =
MI.getOperand(2).getImm();
4775 int64_t MB =
MI.getOperand(3).getImm();
4776 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4778 InVal = InVal.rotl(SH);
4785 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4786 ReplaceWithLI =
true;
4787 Is64BitLI =
Opc != PPC::RLDICL_32;
4788 NewImm = InVal.getSExtValue();
4789 SetCR =
Opc == PPC::RLDICL_rec;
4796 case PPC::RLWINM_rec:
4797 case PPC::RLWINM8_rec: {
4798 int64_t SH =
MI.getOperand(2).getImm();
4799 int64_t MB =
MI.getOperand(3).getImm();
4800 int64_t ME =
MI.getOperand(4).getImm();
4801 APInt InVal(32, SExtImm,
true);
4802 InVal = InVal.rotl(SH);
4808 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4809 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4812 ReplaceWithLI =
true;
4813 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4814 NewImm = InVal.getSExtValue();
4815 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4824 int64_t LogicalImm =
MI.getOperand(2).getImm();
4826 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4827 Result = LogicalImm | SExtImm;
4829 Result = LogicalImm ^ SExtImm;
4831 ReplaceWithLI =
true;
4832 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4840 if (ReplaceWithLI) {
4845 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4846 if (PostRA && ImmChanged)
4853 DefMI.getOperand(1).setImm(NewImm);
4857 else if (MRI->
use_empty(
MI.getOperand(0).getReg())) {
4859 assert(Immediate &&
"Transformation converted zero to non-zero?");
4862 }
else if (ImmChanged)
4871 LoadImmediateInfo LII;
4877 if (KilledDef && SetCR)
4878 *KilledDef =
nullptr;
4891bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4893 MachineRegisterInfo *MRI = &
MI.getParent()->getParent()->getRegInfo();
4901 if (!
MI.mayLoadOrStore())
4904 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4906 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4907 "MI must have x-form opcode");
4911 bool IsVFReg =
MI.getOperand(0).isReg() &&
4912 MI.getOperand(0).getReg().isPhysical() &&
4924 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4925 if (!ImmOperandMI.
isImm())
4929 MachineOperand *ImmMO =
nullptr;
4930 MachineOperand *RegMO =
nullptr;
4931 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4933 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4938 int64_t ImmBase = ImmOperandMI.
getImm();
4940 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm, ImmBase))
4944 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4961bool PPCInstrInfo::transformToImmFormFedByAdd(
4971 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
4976 MachineOperand *ImmMO =
nullptr;
4977 MachineOperand *RegMO =
nullptr;
4978 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4980 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4985 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III,
Imm))
4988 bool IsFwdFeederRegKilled =
false;
4989 bool SeenIntermediateUse =
false;
4991 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
4992 IsFwdFeederRegKilled, SeenIntermediateUse))
4995 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5012 if (ImmMO->
isImm()) {
5023 if (
DefMI.getOpcode() == PPC::ADDItocL8)
5033 MI.removeOperand(i);
5039 MI.addOperand(*ImmMO);
5041 for (
auto &MO : MOps)
5058 unsigned ConstantOpNo,
5061 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5062 !
DefMI.getOperand(1).isImm())
5068 MachineRegisterInfo &MRI =
MI.getParent()->getParent()->getRegInfo();
5078 APInt ActualValue(64,
Imm,
true);
5079 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5093 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5097 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5100 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5101 ConstantOpNo != PosForOrigZero)
5105 unsigned Opc =
MI.getOpcode();
5106 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5107 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5108 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5109 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5110 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5111 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5112 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5113 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5115 Opc == PPC::SRD_rec;
5129 if (SpecialShift32 || SpecialShift64) {
5130 LoadImmediateInfo LII;
5134 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5135 if (
Imm & (SpecialShift32 ? 0x20 : 0x40))
5140 else if (!SetCR && ShAmt == 0 && !PostRA) {
5141 MI.removeOperand(2);
5142 MI.setDesc(
get(PPC::COPY));
5145 if (SpecialShift32) {
5153 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5162 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5192 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5209 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5210 return &PPC::VSRCRegClass;
5215 return PPC::getRecordFormOpcode(Opcode);
5219 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5220 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5221 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5222 Opcode == PPC::LHZUX8);
5236 int Opcode =
MI->getOpcode();
5237 if (
TII.isSExt32To64(Opcode))
5246 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5252 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5253 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5254 MI->getOperand(3).getImm() > 0 &&
5255 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5260 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5262 if ((
Imm & 0x8000) == 0)
5282 int Opcode =
MI->getOpcode();
5283 if (
TII.isZExt32To64(Opcode))
5288 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5289 MI->getOperand(0).getReg() ==
Reg)
5294 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5295 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5296 int64_t
Imm =
MI->getOperand(1).getImm();
5303 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5304 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5305 Opcode == PPC::RLDICL_32_64) &&
5306 MI->getOperand(3).getImm() >= 32)
5309 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5310 MI->getOperand(3).getImm() >= 32 &&
5311 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5314 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5315 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5316 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5317 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5326 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5328 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5330 Register StackReg =
MI.getOperand(2).getReg();
5353 unsigned BinOpDepth,
5355 if (!Reg.isVirtual())
5362 unsigned Opcode =
MI->getOpcode();
5371 unsigned OperandEnd = 3, OperandStride = 1;
5372 if (Opcode == PPC::PHI) {
5373 OperandEnd =
MI->getNumOperands();
5377 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5378 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5380 BinOpDepth + 1, LV);
5389 Register SrcReg =
MI->getOperand(1).getReg();
5403 if (SrcReg != PPC::X3)
5426 BinOpDepth + 1, LV);
5428 BinOpDepth + 1, LV);
5433 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5440 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5441 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5442 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5443 {PPC::AND, PPC::AND8}};
5446 auto It = OpcodeMap.
find(Opcode);
5447 if (It != OpcodeMap.
end()) {
5449 NewOpcode = It->second;
5457 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5460 assert(NewOpcode != -1 &&
5461 "Must have a 64-bit opcode to map the 32-bit opcode!");
5465 RI.getRegClass(
MCID.operands()[0].RegClass);
5467 Register SrcReg =
MI->getOperand(0).getReg();
5477 auto MBB =
MI->getParent();
5485 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5487 if (!Operand.
isReg())
5495 RI.getRegClass(
MCID.operands()[i].RegClass);
5497 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5498 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5507 PromoteRegs[i] = DstTmpReg;
5517 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5524 for (
unsigned i = 1; i < Iter->getNumOperands(); i++) {
5526 if (!Operand.
isReg())
5534 MI->eraseFromParent();
5550std::pair<bool, bool>
5552 const unsigned BinOpDepth,
5555 return std::pair<bool, bool>(
false,
false);
5559 return std::pair<bool, bool>(
false,
false);
5566 if (IsSExt && IsZExt)
5567 return std::pair<bool, bool>(IsSExt, IsZExt);
5569 switch (
MI->getOpcode()) {
5571 Register SrcReg =
MI->getOperand(1).getReg();
5580 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5581 SrcExt.second || IsZExt);
5587 if (
MI->getParent()->getBasicBlock() ==
5593 return std::pair<bool, bool>(IsSExt, IsZExt);
5597 if (SrcReg != PPC::X3) {
5600 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5601 SrcExt.second || IsZExt);
5611 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5614 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5615 return IsExtendPair;
5619 return IsExtendPair;
5624 return IsExtendPair;
5626 if (IntTy && IntTy->getBitWidth() <= 32) {
5628 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5629 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5630 return std::pair<bool, bool>(IsSExt, IsZExt);
5633 return IsExtendPair;
5642 Register SrcReg =
MI->getOperand(1).getReg();
5644 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5645 SrcExt.second || IsZExt);
5656 Register SrcReg =
MI->getOperand(1).getReg();
5660 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5662 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5663 SrcExt.second || IsZExt);
5673 return std::pair<bool, bool>(
false,
false);
5677 unsigned OperandEnd = 3, OperandStride = 1;
5678 if (
MI->getOpcode() == PPC::PHI) {
5679 OperandEnd =
MI->getNumOperands();
5685 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5686 if (!
MI->getOperand(
I).isReg())
5687 return std::pair<bool, bool>(
false,
false);
5691 IsSExt &= SrcExt.first;
5692 IsZExt &= SrcExt.second;
5694 return std::pair<bool, bool>(IsSExt, IsZExt);
5703 return std::pair<bool, bool>(
false,
false);
5705 Register SrcReg1 =
MI->getOperand(1).getReg();
5706 Register SrcReg2 =
MI->getOperand(2).getReg();
5709 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5710 Src1Ext.second || Src2Ext.second);
5716 return std::pair<bool, bool>(IsSExt, IsZExt);
5720 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5733 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5735 TII(MF->getSubtarget().getInstrInfo()) {
5744 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5746 return MI == EndLoop;
5749 std::optional<bool> createTripCountGreaterCondition(
5750 int TC, MachineBasicBlock &
MBB,
5751 SmallVectorImpl<MachineOperand> &
Cond)
override {
5752 if (TripCount == -1) {
5757 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5762 return TripCount > TC;
5765 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5770 void adjustTripCount(
int TripCountAdjust)
override {
5773 if (LoopCount->
getOpcode() == PPC::LI8 ||
5784 void disposed(LiveIntervals *LIS)
override {
5789 Loop->eraseFromParent();
5796std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5801 if (Preheader == LoopBB)
5802 Preheader = *std::next(LoopBB->
pred_begin());
5805 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5808 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5811 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5821 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5824 for (
auto &
I : PreHeader.
instrs())
5825 if (
I.getOpcode() == LOOPi)
5867 int64_t OffsetA = 0, OffsetB = 0;
5873 int LowOffset = std::min(OffsetA, OffsetB);
5874 int HighOffset = std::max(OffsetA, OffsetB);
5875 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5877 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
5891 bool IsLDAT =
MI.getOpcode() == PPC::LDAT_CSNE_PSEUDO;
5897 if (PtrReg == PPC::X8 || PtrReg == PPC::X9 || PtrReg == PPC::X10) {
5901 Register DstReg64 = IsLDAT ? DstReg
5903 DstReg, PPC::sub_32, &PPC::G8RCRegClass));
5905 ScratchReg = DstReg64;
5913 if (DstReg != (IsLDAT ? PPC::X8 : PPC::R8)) {
5915 .
addReg(IsLDAT ? PPC::X8 : PPC::R8)
5916 .
addReg(IsLDAT ? PPC::X8 : PPC::R8);
5918 MI.eraseFromParent();
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
static bool isOpZeroOfSubwordPreincLoad(int Opcode)
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
static cl::opt< float > FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5), cl::desc("register pressure factor for the transformations."))
#define InfoArrayIdxMULOpIdx
static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, unsigned TrueReg, unsigned FalseReg, unsigned CRSubReg)
static unsigned getCRBitValue(unsigned CRBit)
static bool isAnImmediateOperand(const MachineOperand &MO)
static const uint16_t FMAOpIdxInfo[][6]
static cl::opt< bool > DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops"))
#define InfoArrayIdxAddOpIdx
static cl::opt< bool > UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation"))
static bool definedBySignExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMAInst
static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc, const PPCSubtarget &Subtarget)
static cl::opt< bool > EnableFMARegPressureReduction("ppc-fma-rp-reduction", cl::Hidden, cl::init(true), cl::desc("enable register pressure reduce in machine combiner pass."))
static bool isLdStSafeToCluster(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
const unsigned MAX_BINOP_DEPTH
static cl::opt< bool > DisableCmpOpt("disable-ppc-cmp-opt", cl::desc("Disable compare instruction optimization"), cl::Hidden)
#define InfoArrayIdxFSubInst
#define InfoArrayIdxFAddInst
static bool definedByZeroExtendingOp(const PPCInstrInfo &TII, const unsigned Reg, const MachineRegisterInfo *MRI)
#define InfoArrayIdxFMULInst
static cl::opt< bool > VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)
static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool isPhysical(const MachineOperand &MO)
This file declares the machine register scavenger class.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
LLVM_ABI APInt rotl(unsigned rotateAmt) const
Rotate left by rotateAmt.
static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit, unsigned hiBit)
Wrap version of getBitsSet.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
Get the array size.
This class holds the attributes for a particular argument, parameter, function, or return value.
This is an important base class in LLVM.
LLVM_ABI Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const BasicBlock & getEntryBlock() const
AttributeList getAttributes() const
Return the attribute list for this Function.
Type * getReturnType() const
Returns the type of the ret val.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Itinerary data supplied by a subtarget to be used by a target.
std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
Class to represent integer types.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
Represents a single loop in the control flow graph.
Instances of this class represent a single low-level machine instruction.
void setOpcode(unsigned Op)
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
ArrayRef< MCOperandInfo > operands() const
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
ArrayRef< MCPhysReg > implicit_uses() const
Return a list of registers that are potentially read by any instance of this machine instruction.
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
This holds information about one operand of a machine instruction, indicating the register class for ...
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Instructions::iterator instr_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
const std::vector< MachineConstantPoolEntry > & getConstants() const
LLVM_ABI unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool isCall(QueryType Type=AnyInBundle) const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool hasImplicitDef() const
Returns true if the instruction has implicit definition.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr fully defines the specified register.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void dump() const
LLVM_ABI void clearRegisterDeads(Register Reg)
Clear all dead flags on operands defining register Reg.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Register getReg() const
getReg - Returns the register number.
void setTargetFlags(unsigned F)
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI bool isLiveIn(Register Reg) const
static use_instr_iterator use_instr_end()
LLVM_ABI void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
iterator_range< use_instr_iterator > use_instructions(Register Reg) const
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based hazard recognizer for P...
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
bool isLiveInSExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and sign-extended.
bool isLiveInZExt(Register VReg) const
This function returns true if the specified vreg is a live-in register and zero-extended.
PPCHazardRecognizer970 - This class defines a finite state automata that models the dispatch logic on...
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for a fma chain ending in Root.
bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase=nullptr) const
bool isReMaterializableImpl(const MachineInstr &MI) const override
PPCInstrInfo(const PPCSubtarget &STI)
const TargetRegisterClass * updatedRC(const TargetRegisterClass *RC) const
bool isPredicated(const MachineInstr &MI) const override
bool expandVSXMemPseudo(MachineInstr &MI) const
bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
Fixup the placeholders we put in genAlternativeCodeSequence() for MachineCombiner.
MCInst getNop() const override
Return the noop instruction to use for a noop.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static int getRecordFormOpcode(unsigned Opcode)
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
bool isXFormMemOp(unsigned Opcode) const
const PPCRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
CombinerObjective getCombinerObjective(unsigned Pattern) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const
unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const
bool expandAMOCSNEPseudo(MachineInstr &MI) const
void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth, LiveVariables *LV) const
bool isTOCSaveMI(const MachineInstr &MI) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer to use for this target when ...
bool isSExt32To64(unsigned Opcode) const
bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override
bool isBDNZ(unsigned Opcode) const
Check Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
bool isZeroExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
std::pair< bool, bool > isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, const MachineRegisterInfo *MRI) const
bool expandPostRAPseudo(MachineInstr &MI) const override
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index, MachineInstr *&ADDIMI, int64_t &OffsetAddi, int64_t OffsetImm) const
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
void materializeImmPostRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register Reg, int64_t Imm) const
bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
Return true if two MIs access different memory addresses and false otherwise.
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
CreateTargetHazardRecognizer - Return the hazard recognizer to use for this target when scheduling th...
bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
Get the base operand and byte offset of an instruction that reads/writes memory.
void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const
bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const
void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const
bool foldFrameOffset(MachineInstr &MI) const
bool isLoadFromConstantPool(MachineInstr *I) const
MachineInstr * findLoopInstr(MachineBasicBlock &PreHeader, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const
Find the hardware loop instruction used to set-up the specified loop.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override
void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const
bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override
bool convertToImmediateForm(MachineInstr &MI, SmallSet< Register, 4 > &RegsToUpdate, MachineInstr **KilledDef=nullptr) const
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
Return true if get the base operand, byte offset of an instruction and the memory width.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool shouldReduceRegisterPressure(const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const override
On PowerPC, we leverage machine combiner pass to reduce register pressure when the register pressure ...
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
InstSizeVerifyMode getInstSizeVerifyMode(const MachineInstr &MI) const override
bool isSignExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, int64_t Imm) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
Returns true if the two given memory operations should be scheduled adjacent.
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const
bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...
bool optimizeCmpPostRA(MachineInstr &MI) const
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
const Constant * getConstantFromConstantPool(MachineInstr *I) const
bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, bool PostRA) const
MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const
static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg)
const PPCTargetMachine & getTargetMachine() const
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void closeRegion()
Finalize the region boundaries and recored live ins and live outs.
LLVM_ABI void recede(SmallVectorImpl< VRegMaskOrUnit > *LiveUses=nullptr)
Recede across the previous instruction.
RegisterPressure & getPressure()
Get the resulting register pressure over the traversed region.
LLVM_ABI void recedeSkipDebugValues()
Recede until we find an instruction which is not a DebugValue.
LLVM_ABI void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)
Setup the RegPressureTracker.
MachineBasicBlock::const_iterator getPos() const
Get the MI position corresponding to this register pressure.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
List of registers defined and used by a machine instruction.
LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
const TargetInstrInfo * TII
Target instruction information.
MachineFunction & MF
Machine function.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
StackOffset holds a fixed and a scalable offset in bytes.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
const Triple & getTargetTriple() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
LLVM_ABI bool isLittleEndian() const
Tests whether the target triple is little endian.
bool isOSAIX() const
Tests whether the OS is AIX.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.
Define some predicates that are used for node matching.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
unsigned getPredicateCondition(Predicate Opcode)
Return the condition without hint bits.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getPredicateHint(Predicate Opcode)
Return the hint bits of the predicate.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
int32_t getNonRecordFormOpcode(uint32_t)
int32_t getAltVSXFMAOpcode(uint32_t Opcode)
static bool isVFRegister(MCRegister Reg)
template class LLVM_TEMPLATE_ABI opt< bool >
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static unsigned getCRFromCRBit(unsigned SrcReg)
constexpr RegState getDeadRegState(bool B)
auto reverse(ContainerTy &&C)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
@ MustReduceRegisterPressure
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t IsSummingOperands
uint64_t OpNoForForwarding
uint64_t ImmMustBeMultipleOf
uint64_t ZeroIsSpecialNew
uint64_t ZeroIsSpecialOrig
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.