47#define DEBUG_TYPE "ppc-instr-info"
49#define GET_INSTRMAP_INFO
50#define GET_INSTRINFO_CTOR_DTOR
51#include "PPCGenInstrInfo.inc"
54 "Number of spillvsrrc spilled to stack as vec");
56 "Number of spillvsrrc spilled to stack as gpr");
57STATISTIC(NumGPRtoVSRSpill,
"Number of gpr spills to spillvsrrc");
59 "Number of ISELs that depend on comparison of constants converted");
61 "Number of compare-immediate instructions fed by constants");
63 "Number of record-form rotates converted to record-form andi");
67 cl::desc(
"Disable analysis for CTR loops"));
73cl::desc(
"Causes the backend to crash instead of generating a nop VSX copy"),
78 cl::desc(
"Use the old (incorrect) instruction latency calculation"));
82 cl::desc(
"register pressure factor for the transformations."));
86 cl::desc(
"enable register pressure reduce in machine combiner pass."));
89void PPCInstrInfo::anchor() {}
94 STI.isPPC64() ?
PPC::BLR8 :
PPC::BLR),
95 Subtarget(STI), RI(STI.getTargetMachine()) {}
103 static_cast<const PPCSubtarget *
>(STI)->getCPUDirective();
107 static_cast<const PPCSubtarget *
>(STI)->getInstrItineraryData();
139 unsigned *PredCost)
const {
141 return PPCGenInstrInfo::getInstrLatency(ItinData,
MI, PredCost);
151 unsigned DefClass =
MI.getDesc().getSchedClass();
152 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
170 std::optional<unsigned>
Latency = PPCGenInstrInfo::getOperandLatency(
173 if (!
DefMI.getParent())
180 if (Reg.isVirtual()) {
182 &
DefMI.getParent()->getParent()->getRegInfo();
183 IsRegCR =
MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||
184 MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);
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 {
357 auto IsAllOpsVirtualReg = [](
const MachineInstr &Instr) {
358 for (
const auto &MO : Instr.explicit_operands())
359 if (!(MO.isReg() && MO.getReg().isVirtual()))
364 auto IsReassociableAddOrSub = [&](
const MachineInstr &Instr,
366 if (Instr.getOpcode() !=
377 if (!IsAllOpsVirtualReg(Instr))
383 !
MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))
389 auto IsReassociableFMA = [&](
const MachineInstr &Instr, int16_t &AddOpIdx,
390 int16_t &MulOpIdx,
bool IsLeaf) {
391 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());
402 if (!IsAllOpsVirtualReg(Instr))
422 int16_t AddOpIdx = -1;
423 int16_t MulOpIdx = -1;
425 bool IsUsedOnceL =
false;
426 bool IsUsedOnceR =
false;
430 auto IsRPReductionCandidate = [&]() {
434 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)
439 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
true)) {
440 assert((MulOpIdx >= 0) &&
"mul operand index not right!");
441 Register MULRegL =
TRI->lookThruSingleUseCopyChain(
443 Register MULRegR =
TRI->lookThruSingleUseCopyChain(
445 if (!MULRegL && !MULRegR)
448 if (MULRegL && !MULRegR) {
452 }
else if (!MULRegL && MULRegR) {
464 MULInstrL =
MRI->getVRegDef(MULRegL);
465 MULInstrR =
MRI->getVRegDef(MULRegR);
472 if (DoRegPressureReduce && IsRPReductionCandidate()) {
473 assert((MULInstrL && MULInstrR) &&
"wrong register preduction candidate!");
494 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx,
false))
497 assert((AddOpIdx >= 0) &&
"add operand index not right!");
504 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx,
false))
507 assert((AddOpIdx >= 0) &&
"add operand index not right!");
512 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx,
true)) {
528 assert(!InsInstrs.
empty() &&
"Instructions set to be inserted is empty!");
535 int16_t Idx = getFMAOpIdxInfo(Root.
getOpcode());
574 for (
auto *Inst : InsInstrs) {
576 assert(Operand.isReg() &&
"Invalid instruction in InsInstrs!");
577 if (Operand.getReg() == PPC::ZERO8) {
578 Placeholder = &Operand;
584 assert(Placeholder &&
"Placeholder does not exist!");
589 generateLoadForNewConst(ConstPoolIdx, &Root,
C->getType(), InsInstrs);
592 Placeholder->setReg(LoadNewConst);
613 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
621 auto GetMBBPressure =
627 RPTracker.
init(
MBB->getParent(), RegClassInfo,
nullptr,
MBB,
MBB->end(),
631 if (
MI.isDebugValue() ||
MI.isDebugLabel())
637 RPTracker.
recede(RegOpers);
647 unsigned VSSRCLimit =
651 return GetMBBPressure(
MBB)[PPC::RegisterPressureSets::VSSRC] >
657 if (!
I->hasOneMemOperand())
661 return Op->isLoad() &&
Op->getPseudoValue() &&
665Register PPCInstrInfo::generateLoadForNewConst(
671 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&
673 "Target not supported!\n");
679 Register VReg1 =
MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
681 BuildMI(*MF,
MI->getDebugLoc(),
get(PPC::ADDIStocHA8), VReg1)
685 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&
686 "Only float and double are supported!");
691 LoadOpcode = PPC::DFLOADf32;
693 LoadOpcode = PPC::DFLOADf64;
723 assert(
I->mayLoad() &&
"Should be a load instruction.\n");
724 for (
auto MO :
I->uses()) {
728 if (Reg == 0 || !Reg.isVirtual())
732 for (
auto MO2 :
DefMI->uses())
734 return (MCP->
getConstants())[MO2.getIndex()].Val.ConstVal;
754 bool DoRegPressureReduce)
const {
764 DoRegPressureReduce);
777 reassociateFMA(Root,
Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);
782 DelInstrs, InstrIdxForVirtReg);
787void PPCInstrInfo::reassociateFMA(
798 MRI.constrainRegClass(RegC, RC);
801 int16_t Idx = getFMAOpIdxInfo(FmaOp);
802 assert(Idx >= 0 &&
"Root must be a FMA instruction");
804 bool IsILPReassociate =
824 Leaf =
MRI.getVRegDef(MULReg);
830 Leaf =
MRI.getVRegDef(MULReg);
835 uint32_t IntersectedFlags = 0;
836 if (IsILPReassociate)
841 auto GetOperandInfo = [&](
const MachineOperand &Operand,
Register &
Reg,
844 MRI.constrainRegClass(
Reg, RC);
845 KillFlag = Operand.
isKill();
848 auto GetFMAInstrInfo = [&](
const MachineInstr &
Instr,
Register &MulOp1,
850 bool &MulOp1KillFlag,
bool &MulOp2KillFlag,
851 bool &AddOpKillFlag) {
852 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);
853 GetOperandInfo(
Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);
854 GetOperandInfo(
Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);
857 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,
859 bool KillX =
false, KillY =
false, KillM11 =
false, KillM12 =
false,
860 KillM21 =
false, KillM22 =
false, KillM31 =
false, KillM32 =
false,
861 KillA11 =
false, KillA21 =
false, KillB =
false;
863 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);
865 if (IsILPReassociate)
866 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);
869 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);
870 GetOperandInfo(Leaf->
getOperand(AddOpIdx), RegX, KillX);
872 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
873 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
876 GetOperandInfo(Leaf->
getOperand(1), RegX, KillX);
877 GetOperandInfo(Leaf->
getOperand(2), RegY, KillY);
887 InstrIdxForVirtReg.
insert(std::make_pair(NewVRA, 0));
890 if (IsILPReassociate) {
891 NewVRB =
MRI.createVirtualRegister(RC);
892 InstrIdxForVirtReg.
insert(std::make_pair(NewVRB, 1));
897 NewVRD =
MRI.createVirtualRegister(RC);
898 InstrIdxForVirtReg.
insert(std::make_pair(NewVRD, 2));
901 auto AdjustOperandOrder = [&](MachineInstr *
MI,
Register RegAdd,
bool KillAdd,
903 Register RegMul2,
bool KillRegMul2) {
904 MI->getOperand(AddOpIdx).setReg(RegAdd);
905 MI->getOperand(AddOpIdx).setIsKill(KillAdd);
906 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);
907 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);
908 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);
909 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);
912 MachineInstrBuilder NewARegPressure, NewCRegPressure;
918 MachineInstrBuilder MINewB =
923 MachineInstrBuilder MINewA =
930 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
931 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);
934 MachineInstrBuilder MINewC =
952 assert(NewVRD &&
"new FMA register not created!");
954 MachineInstrBuilder MINewA =
959 MachineInstrBuilder MINewB =
964 MachineInstrBuilder MINewD =
971 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);
972 AdjustOperandOrder(MINewD, NewVRA,
true, RegM31, KillM31, RegM32,
976 MachineInstrBuilder MINewC =
998 bool KillVarReg =
false;
1001 KillVarReg = KillM31;
1004 KillVarReg = KillM32;
1028 if (!IsILPReassociate) {
1037 "Insertion instructions set should not be empty!");
1041 if (IsILPReassociate)
1049 unsigned &SubIdx)
const {
1050 switch (
MI.getOpcode()) {
1051 default:
return false;
1054 case PPC::EXTSW_32_64:
1055 SrcReg =
MI.getOperand(1).getReg();
1056 DstReg =
MI.getOperand(0).getReg();
1057 SubIdx = PPC::sub_32;
1063 int &FrameIndex)
const {
1067 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1068 MI.getOperand(2).isFI()) {
1069 FrameIndex =
MI.getOperand(2).getIndex();
1070 return MI.getOperand(0).getReg();
1080 switch (
MI.getOpcode()) {
1090 case PPC::ADDIStocHA:
1091 case PPC::ADDIStocHA8:
1093 case PPC::ADDItocL8:
1094 case PPC::LOAD_STACK_GUARD:
1095 case PPC::PPCLdFixedAddr:
1097 case PPC::XXLXORspz:
1098 case PPC::XXLXORdpz:
1099 case PPC::XXLEQVOnes:
1100 case PPC::XXSPLTI32DX:
1102 case PPC::XXSPLTIDP:
1106 case PPC::V_SETALLONESB:
1107 case PPC::V_SETALLONESH:
1108 case PPC::V_SETALLONES:
1111 case PPC::XXSETACCZ:
1112 case PPC::DMXXSETACCZ:
1119 int &FrameIndex)
const {
1121 if (
MI.getOperand(1).isImm() && !
MI.getOperand(1).getImm() &&
1122 MI.getOperand(2).isFI()) {
1123 FrameIndex =
MI.getOperand(2).getIndex();
1124 return MI.getOperand(0).getReg();
1132 unsigned OpIdx2)
const {
1136 if (
MI.getOpcode() != PPC::RLWIMI &&
MI.getOpcode() != PPC::RLWIMI_rec)
1144 if (
MI.getOperand(3).getImm() != 0)
1155 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&
1156 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");
1160 unsigned SubReg1 =
MI.getOperand(1).getSubReg();
1161 unsigned SubReg2 =
MI.getOperand(2).getSubReg();
1162 bool Reg1IsKill =
MI.getOperand(1).isKill();
1163 bool Reg2IsKill =
MI.getOperand(2).isKill();
1164 bool ChangeReg0 =
false;
1170 "Expecting a two-address instruction!");
1171 assert(
MI.getOperand(0).getSubReg() == SubReg1 &&
"Tied subreg mismatch");
1177 unsigned MB =
MI.getOperand(4).getImm();
1178 unsigned ME =
MI.getOperand(5).getImm();
1182 if (MB == 0 && ME == 31)
1187 Register Reg0 = ChangeReg0 ? Reg2 :
MI.getOperand(0).getReg();
1188 bool Reg0IsDead =
MI.getOperand(0).isDead();
1189 return BuildMI(MF,
MI.getDebugLoc(),
MI.getDesc())
1198 MI.getOperand(0).setReg(Reg2);
1199 MI.getOperand(0).setSubReg(SubReg2);
1201 MI.getOperand(2).setReg(Reg1);
1202 MI.getOperand(1).setReg(Reg2);
1203 MI.getOperand(2).setSubReg(SubReg1);
1204 MI.getOperand(1).setSubReg(SubReg2);
1205 MI.getOperand(2).setIsKill(Reg1IsKill);
1206 MI.getOperand(1).setIsKill(Reg2IsKill);
1209 MI.getOperand(4).setImm((ME + 1) & 31);
1210 MI.getOperand(5).setImm((MB - 1) & 31);
1215 unsigned &SrcOpIdx1,
1216 unsigned &SrcOpIdx2)
const {
1227 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
1234 unsigned Directive = Subtarget.getCPUDirective();
1237 default: Opcode = PPC::NOP;
break;
1263 bool AllowModify)
const {
1264 bool isPPC64 = Subtarget.isPPC64();
1271 if (!isUnpredicatedTerminator(*
I))
1277 if (
I->getOpcode() == PPC::B &&
1278 MBB.isLayoutSuccessor(
I->getOperand(0).getMBB())) {
1279 I->eraseFromParent();
1282 I =
MBB.getLastNonDebugInstr();
1283 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1292 if (
I ==
MBB.begin() || !isUnpredicatedTerminator(*--
I)) {
1298 }
else if (LastInst.
getOpcode() == PPC::BCC) {
1306 }
else if (LastInst.
getOpcode() == PPC::BC) {
1314 }
else if (LastInst.
getOpcode() == PPC::BCn) {
1322 }
else if (LastInst.
getOpcode() == PPC::BDNZ8 ||
1333 }
else if (LastInst.
getOpcode() == PPC::BDZ8 ||
1354 if (
I !=
MBB.begin() && isUnpredicatedTerminator(*--
I))
1358 if (SecondLastInst.
getOpcode() == PPC::BCC &&
1368 }
else if (SecondLastInst.
getOpcode() == PPC::BC &&
1378 }
else if (SecondLastInst.
getOpcode() == PPC::BCn &&
1388 }
else if ((SecondLastInst.
getOpcode() == PPC::BDNZ8 ||
1389 SecondLastInst.
getOpcode() == PPC::BDNZ) &&
1402 }
else if ((SecondLastInst.
getOpcode() == PPC::BDZ8 ||
1403 SecondLastInst.
getOpcode() == PPC::BDZ) &&
1426 I->eraseFromParent();
1435 int *BytesRemoved)
const {
1436 assert(!BytesRemoved &&
"code size not handled");
1442 if (
I->getOpcode() != PPC::B &&
I->getOpcode() != PPC::BCC &&
1443 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1444 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1445 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1449 I->eraseFromParent();
1453 if (
I ==
MBB.begin())
return 1;
1455 if (
I->getOpcode() != PPC::BCC &&
1456 I->getOpcode() != PPC::BC &&
I->getOpcode() != PPC::BCn &&
1457 I->getOpcode() != PPC::BDNZ8 &&
I->getOpcode() != PPC::BDNZ &&
1458 I->getOpcode() != PPC::BDZ8 &&
I->getOpcode() != PPC::BDZ)
1462 I->eraseFromParent();
1471 int *BytesAdded)
const {
1473 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1475 "PPC branch conditions have two components!");
1476 assert(!BytesAdded &&
"code size not handled");
1478 bool isPPC64 = Subtarget.isPPC64();
1486 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1487 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1503 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
1504 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).
addMBB(
TBB);
1522 Register FalseReg,
int &CondCycles,
1523 int &TrueCycles,
int &FalseCycles)
const {
1524 if (!Subtarget.hasISEL())
1527 if (
Cond.size() != 2)
1543 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
1548 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
1549 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
1550 !PPC::G8RCRegClass.hasSubClassEq(RC) &&
1551 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
1571 "PPC branch conditions have two components!");
1576 RI.getCommonSubClass(
MRI.getRegClass(TrueReg),
MRI.getRegClass(FalseReg));
1577 assert(RC &&
"TrueReg and FalseReg must have overlapping register classes");
1579 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
1580 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
1582 PPC::GPRCRegClass.hasSubClassEq(RC) ||
1583 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
1584 "isel is for regular integer GPRs only");
1586 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
1589 unsigned SubIdx = 0;
1590 bool SwapOps =
false;
1591 switch (SelectPred) {
1595 SubIdx = PPC::sub_eq; SwapOps =
false;
break;
1599 SubIdx = PPC::sub_eq; SwapOps =
true;
break;
1603 SubIdx = PPC::sub_lt; SwapOps =
false;
break;
1607 SubIdx = PPC::sub_lt; SwapOps =
true;
break;
1611 SubIdx = PPC::sub_gt; SwapOps =
false;
break;
1615 SubIdx = PPC::sub_gt; SwapOps =
true;
break;
1619 SubIdx = PPC::sub_un; SwapOps =
false;
break;
1623 SubIdx = PPC::sub_un; SwapOps =
true;
break;
1628 Register FirstReg = SwapOps ? FalseReg : TrueReg,
1629 SecondReg = SwapOps ? TrueReg : FalseReg;
1634 if (
MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
1635 MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
1637 MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
1638 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
1640 FirstReg =
MRI.createVirtualRegister(FirstRC);
1652 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||
1653 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||
1654 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||
1655 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)
1657 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||
1658 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||
1659 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||
1660 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)
1662 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||
1663 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||
1664 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||
1665 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)
1667 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||
1668 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||
1669 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||
1670 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)
1673 assert(Ret != 4 &&
"Invalid CR bit register");
1681 bool RenamableDest,
bool RenamableSrc)
const {
1685 if (PPC::F8RCRegClass.
contains(DestReg) &&
1686 PPC::VSRCRegClass.
contains(SrcReg)) {
1688 TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);
1694 }
else if (PPC::F8RCRegClass.
contains(SrcReg) &&
1695 PPC::VSRCRegClass.
contains(DestReg)) {
1697 TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);
1706 if (PPC::CRBITRCRegClass.
contains(SrcReg) &&
1707 PPC::GPRCRegClass.
contains(DestReg)) {
1719 }
else if (PPC::CRRCRegClass.
contains(SrcReg) &&
1720 (PPC::G8RCRegClass.
contains(DestReg) ||
1721 PPC::GPRCRegClass.
contains(DestReg))) {
1722 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1723 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;
1724 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;
1725 unsigned CRNum =
TRI->getEncodingValue(SrcReg);
1737 }
else if (PPC::G8RCRegClass.
contains(SrcReg) &&
1738 PPC::VSFRCRegClass.
contains(DestReg)) {
1739 assert(Subtarget.hasDirectMove() &&
1740 "Subtarget doesn't support directmove, don't know how to copy.");
1745 }
else if (PPC::VSFRCRegClass.
contains(SrcReg) &&
1746 PPC::G8RCRegClass.
contains(DestReg)) {
1747 assert(Subtarget.hasDirectMove() &&
1748 "Subtarget doesn't support directmove, don't know how to copy.");
1752 }
else if (PPC::SPERCRegClass.
contains(SrcReg) &&
1753 PPC::GPRCRegClass.
contains(DestReg)) {
1757 }
else if (PPC::GPRCRegClass.
contains(SrcReg) &&
1758 PPC::SPERCRegClass.
contains(DestReg)) {
1762 }
else if ((PPC::G8RCRegClass.
contains(DestReg) ||
1763 PPC::GPRCRegClass.
contains(DestReg)) &&
1764 SrcReg == PPC::CARRY) {
1765 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
1770 }
else if ((PPC::G8RCRegClass.
contains(SrcReg) ||
1771 PPC::GPRCRegClass.
contains(SrcReg)) &&
1772 DestReg == PPC::CARRY) {
1773 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
1782 if (PPC::GPRCRegClass.
contains(DestReg, SrcReg))
1784 else if (PPC::G8RCRegClass.
contains(DestReg, SrcReg))
1786 else if (PPC::F4RCRegClass.
contains(DestReg, SrcReg))
1788 else if (PPC::CRRCRegClass.
contains(DestReg, SrcReg))
1790 else if (PPC::VRRCRegClass.
contains(DestReg, SrcReg))
1792 else if (PPC::VSRCRegClass.
contains(DestReg, SrcReg))
1802 else if (PPC::VSFRCRegClass.
contains(DestReg, SrcReg) ||
1803 PPC::VSSRCRegClass.
contains(DestReg, SrcReg))
1804 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;
1805 else if (Subtarget.pairedVectorMemops() &&
1806 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {
1807 if (SrcReg > PPC::VSRp15)
1808 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;
1810 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;
1811 if (DestReg > PPC::VSRp15)
1812 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;
1814 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;
1821 else if (PPC::CRBITRCRegClass.
contains(DestReg, SrcReg))
1823 else if (PPC::SPERCRegClass.
contains(DestReg, SrcReg))
1825 else if ((PPC::ACCRCRegClass.
contains(DestReg) ||
1826 PPC::UACCRCRegClass.
contains(DestReg)) &&
1827 (PPC::ACCRCRegClass.
contains(SrcReg) ||
1828 PPC::UACCRCRegClass.
contains(SrcReg))) {
1834 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);
1835 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);
1837 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1839 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;
1842 for (
unsigned Idx = 0; Idx < 4; Idx++)
1848 if (SrcPrimed && !KillSrc)
1851 }
else if (PPC::G8pRCRegClass.
contains(DestReg) &&
1852 PPC::G8pRCRegClass.
contains(SrcReg)) {
1854 unsigned DestRegIdx = DestReg - PPC::G8p0;
1855 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;
1856 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;
1857 unsigned SrcRegIdx = SrcReg - PPC::G8p0;
1858 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;
1859 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;
1867 }
else if ((PPC::WACCRCRegClass.
contains(DestReg) ||
1868 PPC::WACC_HIRCRegClass.
contains(DestReg)) &&
1869 (PPC::WACCRCRegClass.
contains(SrcReg) ||
1870 PPC::WACC_HIRCRegClass.
contains(SrcReg))) {
1872 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512
1873 : PPC::DMXXEXTFDMR512_HI;
1876 RS.enterBasicBlockEnd(
MBB);
1877 RS.backward(std::next(
I));
1879 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1883 RS.setRegUsed(TmpReg1);
1884 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass,
I,
1893 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512
1894 : PPC::DMXXINSTDMR512_HI;
1901 }
else if (PPC::DMRRCRegClass.
contains(DestReg) &&
1902 PPC::DMRRCRegClass.
contains(SrcReg)) {
1913 if (
MCID.getNumOperands() == 3)
1923 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||
1924 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {
1926 }
else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||
1927 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {
1929 }
else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
1931 }
else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
1933 }
else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {
1935 }
else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
1937 }
else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
1939 }
else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
1941 }
else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {
1943 }
else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {
1945 }
else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {
1947 }
else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {
1949 }
else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {
1950 assert(Subtarget.pairedVectorMemops() &&
1951 "Register unexpected when paired memops are disabled.");
1953 }
else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {
1954 assert(Subtarget.pairedVectorMemops() &&
1955 "Register unexpected when paired memops are disabled.");
1957 }
else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {
1958 assert(Subtarget.pairedVectorMemops() &&
1959 "Register unexpected when paired memops are disabled.");
1961 }
else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {
1962 assert(Subtarget.pairedVectorMemops() &&
1963 "Register unexpected when paired memops are disabled.");
1965 }
else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {
1967 }
else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {
1969 }
else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {
1971 }
else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {
1973 }
else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {
1984 return OpcodesForSpill[getSpillIndex(RC)];
1990 return OpcodesForSpill[getSpillIndex(RC)];
1993void PPCInstrInfo::StoreRegToStackSlot(
2007 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||
2008 PPC::CRBITRCRegClass.hasSubClassEq(RC))
2021 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);
2024 MBB.insert(
MI, NewMI);
2031 NewMIs.
back()->addMemOperand(MF, MMO);
2050 unsigned DestReg,
int FrameIdx,
2065 if (
MI !=
MBB.end())
DL =
MI->getDebugLoc();
2067 LoadRegFromStackSlot(MF,
DL, DestReg, FrameIdx, RC, NewMIs);
2070 MBB.insert(
MI, NewMI);
2077 NewMIs.
back()->addMemOperand(MF, MMO);
2100 assert(
Cond.size() == 2 &&
"Invalid PPC branch opcode!");
2115 unsigned DefOpc =
DefMI.getOpcode();
2116 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
2118 if (!
DefMI.getOperand(1).isImm())
2120 if (
DefMI.getOperand(1).getImm() != 0)
2136 for (UseIdx = 0; UseIdx <
UseMI.getNumOperands(); ++UseIdx)
2137 if (
UseMI.getOperand(UseIdx).isReg() &&
2138 UseMI.getOperand(UseIdx).getReg() == Reg)
2141 assert(UseIdx <
UseMI.getNumOperands() &&
"Cannot find Reg in UseMI");
2148 int16_t RegClass = getOpRegClassID(UseInfo);
2149 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&
2150 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)
2156 if (UseInfo.Constraints != 0)
2160 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;
2164 UseMI.getOperand(UseIdx).setReg(ZeroReg);
2176 if (
MRI->use_nodbg_empty(Reg))
2177 DefMI.eraseFromParent();
2183 if (
MI.definesRegister(PPC::CTR,
nullptr) ||
2184 MI.definesRegister(PPC::CTR8,
nullptr))
2196 unsigned NumT,
unsigned ExtraT,
2198 unsigned NumF,
unsigned ExtraF,
2218 switch (
MI.getOpcode()) {
2234 unsigned OpC =
MI.getOpcode();
2235 if (OpC == PPC::BLR || OpC == PPC::BLR8) {
2236 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2237 bool isPPC64 = Subtarget.isPPC64();
2238 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)
2239 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));
2245 MI.setDesc(
get(PPC::BCLR));
2248 MI.setDesc(
get(PPC::BCLRn));
2251 MI.setDesc(
get(PPC::BCCLR));
2258 }
else if (OpC == PPC::B) {
2259 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR) {
2260 bool isPPC64 = Subtarget.isPPC64();
2261 MI.setDesc(
get(Pred[0].
getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
2262 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));
2269 MI.removeOperand(0);
2271 MI.setDesc(
get(PPC::BC));
2277 MI.removeOperand(0);
2279 MI.setDesc(
get(PPC::BCn));
2285 MI.removeOperand(0);
2287 MI.setDesc(
get(PPC::BCC));
2295 }
else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||
2296 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||
2297 OpC == PPC::BCTRL8_RM) {
2298 if (Pred[1].
getReg() == PPC::CTR8 || Pred[1].
getReg() == PPC::CTR)
2301 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||
2302 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;
2303 bool isPPC64 = Subtarget.isPPC64();
2306 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)
2307 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));
2310 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)
2311 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));
2314 MI.setDesc(
get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)
2315 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));
2326 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)
2338 assert(Pred1.
size() == 2 &&
"Invalid PPC first predicate");
2339 assert(Pred2.
size() == 2 &&
"Invalid PPC second predicate");
2341 if (Pred1[1].
getReg() == PPC::CTR8 || Pred1[1].
getReg() == PPC::CTR)
2343 if (Pred2[1].
getReg() == PPC::CTR8 || Pred2[1].
getReg() == PPC::CTR)
2368 std::vector<MachineOperand> &Pred,
2369 bool SkipDead)
const {
2377 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
2378 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
2382 for (
unsigned c = 0; c < std::size(RCs) && !Found; ++c) {
2385 if (MO.isDef() && RC->
contains(MO.getReg())) {
2389 }
else if (MO.isRegMask()) {
2391 if (MO.clobbersPhysReg(R)) {
2404 int64_t &
Value)
const {
2405 unsigned Opc =
MI.getOpcode();
2408 default:
return false;
2413 SrcReg =
MI.getOperand(1).getReg();
2415 Value =
MI.getOperand(2).getImm();
2424 SrcReg =
MI.getOperand(1).getReg();
2425 SrcReg2 =
MI.getOperand(2).getReg();
2444 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
2456 bool isPPC64 = Subtarget.isPPC64();
2457 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;
2458 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
2459 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
2468 if (!
MI)
return false;
2470 bool equalityOnly =
false;
2473 if (is32BitSignedCompare) {
2479 }
else if (is32BitUnsignedCompare) {
2484 equalityOnly =
true;
2488 equalityOnly = is64BitUnsignedCompare;
2490 equalityOnly = is32BitUnsignedCompare;
2496 I =
MRI->use_instr_begin(CRReg), IE =
MRI->use_instr_end();
2499 if (
UseMI->getOpcode() == PPC::BCC) {
2505 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2506 UseMI->getOpcode() == PPC::ISEL8) {
2507 unsigned SubIdx =
UseMI->getOperand(3).getSubReg();
2508 if (SubIdx != PPC::sub_eq)
2520 bool FoundUse =
false;
2522 J =
MRI->use_instr_begin(CRReg), JE =
MRI->use_instr_end();
2549 else if (
Value != 0) {
2558 if (equalityOnly || !
MRI->hasOneUse(CRReg))
2562 if (
UseMI->getOpcode() != PPC::BCC)
2568 int16_t Immed = (int16_t)
Value;
2592 UseMI->getOperand(0).setImm(Pred);
2602 for (;
I != E && !noSub; --
I) {
2604 unsigned IOpC = Instr.getOpcode();
2606 if (&*
I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0,
TRI) ||
2607 Instr.readsRegister(PPC::CR0,
TRI)))
2616 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
2617 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
2618 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
2619 ((Instr.getOperand(1).getReg() == SrcReg &&
2620 Instr.getOperand(2).getReg() == SrcReg2) ||
2621 (Instr.getOperand(1).getReg() == SrcReg2 &&
2622 Instr.getOperand(2).getReg() == SrcReg))) {
2640 int MIOpC =
MI->getOpcode();
2641 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||
2642 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)
2645 NewOpC = PPC::getRecordFormOpcode(MIOpC);
2663 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&
2673 bool ShouldSwap =
false;
2675 ShouldSwap = SrcReg2 != 0 &&
Sub->getOperand(1).getReg() == SrcReg2 &&
2676 Sub->getOperand(2).getReg() == SrcReg;
2680 ShouldSwap = !ShouldSwap;
2685 I =
MRI->use_instr_begin(CRReg), IE =
MRI->use_instr_end();
2688 if (
UseMI->getOpcode() == PPC::BCC) {
2693 "Invalid predicate for equality-only optimization");
2697 }
else if (
UseMI->getOpcode() == PPC::ISEL ||
2698 UseMI->getOpcode() == PPC::ISEL8) {
2699 unsigned NewSubReg =
UseMI->getOperand(3).getSubReg();
2700 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
2701 "Invalid CR bit for equality-only optimization");
2703 if (NewSubReg == PPC::sub_lt)
2704 NewSubReg = PPC::sub_gt;
2705 else if (NewSubReg == PPC::sub_gt)
2706 NewSubReg = PPC::sub_lt;
2708 SubRegsToUpdate.
push_back(std::make_pair(&(
UseMI->getOperand(3)),
2714 "Non-zero immediate support and ShouldSwap"
2715 "may conflict in updating predicate");
2723 BuildMI(*
MI->getParent(), std::next(MII),
MI->getDebugLoc(),
2724 get(TargetOpcode::COPY), CRReg)
2729 MI->clearRegisterDeads(PPC::CR0);
2731 if (MIOpC != NewOpC) {
2741 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {
2742 Register GPRRes =
MI->getOperand(0).getReg();
2743 int64_t SH =
MI->getOperand(2).getImm();
2744 int64_t MB =
MI->getOperand(3).getImm();
2745 int64_t ME =
MI->getOperand(4).getImm();
2748 bool MBInLoHWord = MB >= 16;
2749 bool MEInLoHWord = ME >= 16;
2752 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {
2753 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
2755 Mask >>= MBInLoHWord ? 0 : 16;
2756 NewOpC = MIOpC == PPC::RLWINM
2757 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)
2758 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);
2759 }
else if (
MRI->use_empty(GPRRes) && (ME == 31) &&
2760 (ME - MB + 1 == SH) && (MB >= 16)) {
2764 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);
2766 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;
2769 if (Mask != ~0LLU) {
2770 MI->removeOperand(4);
2771 MI->removeOperand(3);
2772 MI->getOperand(2).setImm(Mask);
2773 NumRcRotatesConvertedToRcAnd++;
2775 }
else if (MIOpC == PPC::RLDICL &&
MI->getOperand(2).getImm() == 0) {
2776 int64_t MB =
MI->getOperand(3).getImm();
2778 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
2779 NewOpC = PPC::ANDI8_rec;
2780 MI->removeOperand(3);
2781 MI->getOperand(2).setImm(Mask);
2782 NumRcRotatesConvertedToRcAnd++;
2787 MI->setDesc(NewDesc);
2790 if (!
MI->definesRegister(ImpDef,
nullptr)) {
2791 MI->addOperand(*
MI->getParent()->getParent(),
2796 if (!
MI->readsRegister(ImpUse,
nullptr)) {
2797 MI->addOperand(*
MI->getParent()->getParent(),
2802 assert(
MI->definesRegister(PPC::CR0,
nullptr) &&
2803 "Record-form instruction does not define cr0?");
2808 for (
unsigned i = 0, e = PredsToUpdate.
size(); i < e; i++)
2809 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
2811 for (
unsigned i = 0, e = SubRegsToUpdate.
size(); i < e; i++)
2812 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
2823 int64_t CmpMask, CmpValue;
2828 if (CmpValue || !CmpMask || SrcReg2)
2836 if (
Opc == PPC::CMPLWI ||
Opc == PPC::CMPLDI)
2843 if (Subtarget.isPPC64() &&
Opc == PPC::CMPWI)
2850 bool SrcRegHasOtherUse =
false;
2857 if (CRReg != PPC::CR0)
2861 bool SeenUseOfCRReg =
false;
2862 bool IsCRRegKilled =
false;
2863 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI,
false, IsCRRegKilled,
2869 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);
2883 "Record-form instruction does not define cr0?");
2897 OffsetIsScalable =
false;
2932 case PPC::DFSTOREf64:
2933 return FirstOpc == SecondOpc;
2939 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;
2946 int64_t OpOffset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2947 unsigned NumBytes)
const {
2953 "Only base registers and frame indices are supported.");
2958 if (ClusterSize > 2)
2972 unsigned FirstOpc = FirstLdSt.
getOpcode();
2973 unsigned SecondOpc = SecondLdSt.
getOpcode();
2985 int64_t Offset1 = 0, Offset2 = 0;
2994 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&
2995 "getMemOperandWithOffsetWidth return incorrect base op");
2997 assert(Offset1 <= Offset2 &&
"Caller should have ordered offsets.");
2998 return Offset1 + (int64_t)Width1.
getValue() == Offset2;
3005 unsigned Opcode =
MI.getOpcode();
3007 if (Opcode == PPC::INLINEASM || Opcode == PPC::INLINEASM_BR) {
3009 const char *AsmStr =
MI.getOperand(0).getSymbolName();
3011 }
else if (Opcode == TargetOpcode::STACKMAP) {
3014 }
else if (Opcode == TargetOpcode::PATCHPOINT) {
3018 return get(Opcode).getSize();
3022std::pair<unsigned, unsigned>
3025 return std::make_pair(TF, 0u);
3030 using namespace PPCII;
3031 static const std::pair<unsigned, const char *> TargetFlags[] = {
3032 {MO_PLT,
"ppc-plt"},
3033 {MO_PIC_FLAG,
"ppc-pic"},
3034 {MO_PCREL_FLAG,
"ppc-pcrel"},
3035 {MO_GOT_FLAG,
"ppc-got"},
3036 {MO_PCREL_OPT_FLAG,
"ppc-opt-pcrel"},
3037 {MO_TLSGD_FLAG,
"ppc-tlsgd"},
3038 {MO_TPREL_FLAG,
"ppc-tprel"},
3039 {MO_TLSLDM_FLAG,
"ppc-tlsldm"},
3040 {MO_TLSLD_FLAG,
"ppc-tlsld"},
3041 {MO_TLSGDM_FLAG,
"ppc-tlsgdm"},
3042 {MO_GOT_TLSGD_PCREL_FLAG,
"ppc-got-tlsgd-pcrel"},
3043 {MO_GOT_TLSLD_PCREL_FLAG,
"ppc-got-tlsld-pcrel"},
3044 {MO_GOT_TPREL_PCREL_FLAG,
"ppc-got-tprel-pcrel"},
3047 {MO_TPREL_LO,
"ppc-tprel-lo"},
3048 {MO_TPREL_HA,
"ppc-tprel-ha"},
3049 {MO_DTPREL_LO,
"ppc-dtprel-lo"},
3050 {MO_TLSLD_LO,
"ppc-tlsld-lo"},
3051 {MO_TOC_LO,
"ppc-toc-lo"},
3052 {MO_TLS,
"ppc-tls"},
3053 {MO_PIC_HA_FLAG,
"ppc-ha-pic"},
3054 {MO_PIC_LO_FLAG,
"ppc-lo-pic"},
3055 {MO_TPREL_PCREL_FLAG,
"ppc-tprel-pcrel"},
3056 {MO_TLS_PCREL_FLAG,
"ppc-tls-pcrel"},
3057 {MO_GOT_PCREL_FLAG,
"ppc-got-pcrel"},
3069 unsigned UpperOpcode, LowerOpcode;
3070 switch (
MI.getOpcode()) {
3071 case PPC::DFLOADf32:
3072 UpperOpcode = PPC::LXSSP;
3073 LowerOpcode = PPC::LFS;
3075 case PPC::DFLOADf64:
3076 UpperOpcode = PPC::LXSD;
3077 LowerOpcode = PPC::LFD;
3079 case PPC::DFSTOREf32:
3080 UpperOpcode = PPC::STXSSP;
3081 LowerOpcode = PPC::STFS;
3083 case PPC::DFSTOREf64:
3084 UpperOpcode = PPC::STXSD;
3085 LowerOpcode = PPC::STFD;
3087 case PPC::XFLOADf32:
3088 UpperOpcode = PPC::LXSSPX;
3089 LowerOpcode = PPC::LFSX;
3091 case PPC::XFLOADf64:
3092 UpperOpcode = PPC::LXSDX;
3093 LowerOpcode = PPC::LFDX;
3095 case PPC::XFSTOREf32:
3096 UpperOpcode = PPC::STXSSPX;
3097 LowerOpcode = PPC::STFSX;
3099 case PPC::XFSTOREf64:
3100 UpperOpcode = PPC::STXSDX;
3101 LowerOpcode = PPC::STFDX;
3104 UpperOpcode = PPC::LXSIWAX;
3105 LowerOpcode = PPC::LFIWAX;
3108 UpperOpcode = PPC::LXSIWZX;
3109 LowerOpcode = PPC::LFIWZX;
3112 UpperOpcode = PPC::STXSIWX;
3113 LowerOpcode = PPC::STFIWX;
3119 Register TargetReg =
MI.getOperand(0).getReg();
3121 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||
3122 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))
3123 Opcode = LowerOpcode;
3125 Opcode = UpperOpcode;
3126 MI.setDesc(
get(Opcode));
3135 auto &
MBB = *
MI.getParent();
3136 auto DL =
MI.getDebugLoc();
3138 switch (
MI.getOpcode()) {
3139 case PPC::BUILD_UACC: {
3142 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {
3143 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;
3144 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;
3148 for (
int VecNo = 0; VecNo < 4; VecNo++)
3158 case PPC::KILL_PAIR: {
3159 MI.setDesc(
get(PPC::UNENCODED_NOP));
3160 MI.removeOperand(1);
3161 MI.removeOperand(0);
3164 case TargetOpcode::LOAD_STACK_GUARD: {
3165 auto M =
MBB.getParent()->getFunction().getParent();
3167 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() ==
"tls") &&
3168 "Only Linux target or tls mode are expected to contain "
3169 "LOAD_STACK_GUARD");
3171 if (M->getStackProtectorGuard() ==
"tls")
3172 Offset = M->getStackProtectorGuardOffset();
3174 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;
3175 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3176 MI.setDesc(
get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));
3182 case PPC::PPCLdFixedAddr: {
3183 assert(Subtarget.getTargetTriple().isOSGlibc() &&
3184 "Only targets with Glibc expected to contain PPCLdFixedAddr");
3186 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;
3187 MI.setDesc(
get(PPC::LWZ));
3189#undef PPC_LNX_FEATURE
3191#define PPC_LNX_DEFINE_OFFSETS
3192#include "llvm/TargetParser/PPCTargetParser.def"
3193 bool IsLE = Subtarget.isLittleEndian();
3194 bool Is64 = Subtarget.isPPC64();
3195 if (FAType == PPC_FAWORD_HWCAP) {
3197 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;
3199 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;
3200 }
else if (FAType == PPC_FAWORD_HWCAP2) {
3202 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;
3204 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;
3205 }
else if (FAType == PPC_FAWORD_CPUID) {
3207 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;
3209 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;
3211 assert(
Offset &&
"Do not know the offset for this fixed addr load");
3212 MI.removeOperand(1);
3213 Subtarget.getTargetMachine().setGlibcHWCAPAccess();
3218#define PPC_TGT_PARSER_UNDEF_MACROS
3219#include "llvm/TargetParser/PPCTargetParser.def"
3220#undef PPC_TGT_PARSER_UNDEF_MACROS
3222 case PPC::DFLOADf32:
3223 case PPC::DFLOADf64:
3224 case PPC::DFSTOREf32:
3225 case PPC::DFSTOREf64: {
3226 assert(Subtarget.hasP9Vector() &&
3227 "Invalid D-Form Pseudo-ops on Pre-P9 target.");
3230 "D-form op must have register and immediate operands");
3233 case PPC::XFLOADf32:
3234 case PPC::XFSTOREf32:
3238 assert(Subtarget.hasP8Vector() &&
3239 "Invalid X-Form Pseudo-ops on Pre-P8 target.");
3240 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3241 "X-form op must have register and register operands");
3244 case PPC::XFLOADf64:
3245 case PPC::XFSTOREf64: {
3246 assert(Subtarget.hasVSX() &&
3247 "Invalid X-Form Pseudo-ops on target that has no VSX.");
3248 assert(
MI.getOperand(2).isReg() &&
MI.getOperand(1).isReg() &&
3249 "X-form op must have register and register operands");
3252 case PPC::SPILLTOVSR_LD: {
3253 Register TargetReg =
MI.getOperand(0).getReg();
3254 if (PPC::VSFRCRegClass.
contains(TargetReg)) {
3255 MI.setDesc(
get(PPC::DFLOADf64));
3259 MI.setDesc(
get(PPC::LD));
3262 case PPC::SPILLTOVSR_ST: {
3264 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3265 NumStoreSPILLVSRRCAsVec++;
3266 MI.setDesc(
get(PPC::DFSTOREf64));
3269 NumStoreSPILLVSRRCAsGpr++;
3270 MI.setDesc(
get(PPC::STD));
3274 case PPC::SPILLTOVSR_LDX: {
3275 Register TargetReg =
MI.getOperand(0).getReg();
3276 if (PPC::VSFRCRegClass.
contains(TargetReg))
3277 MI.setDesc(
get(PPC::LXSDX));
3279 MI.setDesc(
get(PPC::LDX));
3282 case PPC::SPILLTOVSR_STX: {
3284 if (PPC::VSFRCRegClass.
contains(SrcReg)) {
3285 NumStoreSPILLVSRRCAsVec++;
3286 MI.setDesc(
get(PPC::STXSDX));
3288 NumStoreSPILLVSRRCAsGpr++;
3289 MI.setDesc(
get(PPC::STDX));
3296 case PPC::CFENCE8: {
3297 auto Val =
MI.getOperand(0).getReg();
3298 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;
3304 MI.setDesc(
get(PPC::ISYNC));
3305 MI.removeOperand(0);
3316static unsigned selectReg(int64_t Imm1, int64_t Imm2,
unsigned CompareOpc,
3317 unsigned TrueReg,
unsigned FalseReg,
3318 unsigned CRSubReg) {
3320 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {
3324 return Imm1 < Imm2 ? TrueReg : FalseReg;
3326 return Imm1 > Imm2 ? TrueReg : FalseReg;
3328 return Imm1 == Imm2 ? TrueReg : FalseReg;
3332 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {
3340 return Imm1 == Imm2 ? TrueReg : FalseReg;
3343 return PPC::NoRegister;
3348 int64_t Imm)
const {
3349 assert(
MI.getOperand(OpNo).isReg() &&
"Operand must be a REG");
3351 Register InUseReg =
MI.getOperand(OpNo).getReg();
3352 MI.getOperand(OpNo).ChangeToImmediate(Imm);
3360 int UseOpIdx =
MI.findRegisterUseOperandIdx(InUseReg,
TRI,
false);
3361 if (UseOpIdx >= 0) {
3371 MI.removeOperand(UseOpIdx);
3380 int OperandToKeep = LII.
SetCR ? 1 : 0;
3381 for (
int i =
MI.getNumOperands() - 1; i > OperandToKeep; i--)
3382 MI.removeOperand(i);
3386 MI.setDesc(
get(LII.
Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3401 bool &SeenIntermediateUse)
const {
3402 assert(!
MI.getParent()->getParent()->getRegInfo().isSSA() &&
3403 "Should be called after register allocation.");
3407 SeenIntermediateUse =
false;
3408 for (; It != E; ++It) {
3409 if (It->modifiesRegister(Reg,
TRI))
3411 if (It->readsRegister(Reg,
TRI))
3412 SeenIntermediateUse =
true;
3420 int64_t Imm)
const {
3421 assert(!
MBB.getParent()->getRegInfo().isSSA() &&
3422 "Register should be in non-SSA form after RA");
3423 bool isPPC64 = Subtarget.isPPC64();
3437 assert(isPPC64 &&
"Materializing 64-bit immediate to single register is "
3438 "only supported in PPC64");
3440 if ((Imm >> 32) & 0xFFFF)
3443 .
addImm((Imm >> 32) & 0xFFFF);
3450 .
addImm((Imm >> 16) & 0xFFFF);
3460 unsigned &OpNoForForwarding,
3461 bool &SeenIntermediateUse)
const {
3462 OpNoForForwarding = ~0U;
3470 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3471 if (!
MI.getOperand(i).isReg())
3474 if (!Reg.isVirtual())
3479 if (DefMIForTrueReg->
getOpcode() == PPC::LI ||
3480 DefMIForTrueReg->
getOpcode() == PPC::LI8 ||
3481 DefMIForTrueReg->
getOpcode() == PPC::ADDI ||
3482 DefMIForTrueReg->
getOpcode() == PPC::ADDI8) {
3483 OpNoForForwarding = i;
3484 DefMI = DefMIForTrueReg;
3489 if (
DefMI->getOpcode() == PPC::LI ||
DefMI->getOpcode() == PPC::LI8)
3499 unsigned Opc =
MI.getOpcode();
3500 bool ConvertibleImmForm =
3501 Opc == PPC::CMPWI ||
Opc == PPC::CMPLWI ||
Opc == PPC::CMPDI ||
3502 Opc == PPC::CMPLDI ||
Opc == PPC::ADDI ||
Opc == PPC::ADDI8 ||
3503 Opc == PPC::ORI ||
Opc == PPC::ORI8 ||
Opc == PPC::XORI ||
3504 Opc == PPC::XORI8 ||
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec ||
3505 Opc == PPC::RLDICL_32 ||
Opc == PPC::RLDICL_32_64 ||
3506 Opc == PPC::RLWINM ||
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8 ||
3507 Opc == PPC::RLWINM8_rec;
3508 bool IsVFReg = (
MI.getNumOperands() &&
MI.getOperand(0).isReg())
3515 if ((
Opc == PPC::OR ||
Opc == PPC::OR8) &&
3516 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
3518 for (
int i = 1, e =
MI.getNumOperands(); i < e; i++) {
3519 MachineOperand &MO =
MI.getOperand(i);
3520 SeenIntermediateUse =
false;
3534 case PPC::ADDItocL8:
3537 OpNoForForwarding = i;
3544 return OpNoForForwarding == ~0
U ? nullptr :
DefMI;
3547unsigned PPCInstrInfo::getSpillTarget()
const {
3550 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();
3552 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?
3553 2 : Subtarget.hasP9Vector() ?
3592 bool PostRA = !
MRI->isSSA();
3598 unsigned ToBeDeletedReg = 0;
3599 int64_t OffsetImm = 0;
3600 unsigned XFormOpcode = 0;
3608 bool OtherIntermediateUse =
false;
3612 if (OtherIntermediateUse || !ADDMI)
3619 unsigned ScaleRegIdx = 0;
3620 int64_t OffsetAddi = 0;
3634 assert(ADDIMI &&
"There should be ADDIMI for valid ToBeChangedReg.");
3639 for (
auto It = ++Start; It != End; It++)
3648 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))
3653 if (NewDefFor(ToBeChangedReg, *ADDMI,
MI) || NewDefFor(ScaleReg, *ADDMI,
MI))
3669 MI.setDesc(
get(XFormOpcode));
3671 .ChangeToRegister(ScaleReg,
false,
false,
3675 .ChangeToRegister(ToBeChangedReg,
false,
false,
true);
3687 int64_t &Imm)
const {
3691 if (
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
3707 return Opc == PPC::ADD4 ||
Opc == PPC::ADD8;
3711 unsigned &ToBeDeletedReg,
3712 unsigned &XFormOpcode,
3716 if (!
MI.mayLoadOrStore())
3719 unsigned Opc =
MI.getOpcode();
3721 XFormOpcode = RI.getMappedIdxOpcForImmOpc(
Opc);
3724 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)
3738 if (!ImmOperand.
isImm())
3741 assert(RegOperand.
isReg() &&
"Instruction format is not right");
3744 if (!RegOperand.
isKill())
3747 ToBeDeletedReg = RegOperand.
getReg();
3748 OffsetImm = ImmOperand.
getImm();
3755 int64_t &OffsetAddi,
3756 int64_t OffsetImm)
const {
3757 assert((Index == 1 || Index == 2) &&
"Invalid operand index for add.");
3763 bool OtherIntermediateUse =
false;
3784 if (OtherIntermediateUse || !ADDIMI)
3803 bool PostRA = !
MRI->isSSA();
3804 bool SeenIntermediateUse =
true;
3805 unsigned ForwardingOperand = ~0U;
3807 SeenIntermediateUse);
3810 assert(ForwardingOperand <
MI.getNumOperands() &&
3811 "The forwarding operand needs to be valid at this point");
3812 bool IsForwardingOperandKilled =
MI.getOperand(ForwardingOperand).isKill();
3813 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
3814 if (KilledDef && KillFwdDefMI)
3828 if (RI.getMappedIdxOpcForImmOpc(
MI.getOpcode()) !=
3829 PPC::INSTRUCTION_LIST_END &&
3830 transformToNewImmFormFedByAdd(
MI, *
DefMI, ForwardingOperand))
3834 bool IsVFReg =
MI.getOperand(0).isReg()
3842 transformToImmFormFedByAdd(
MI, III, ForwardingOperand, *
DefMI,
3849 transformToImmFormFedByLI(
MI, III, ForwardingOperand, *
DefMI))
3854 if (!HasImmForm && simplifyToLI(
MI, *
DefMI, ForwardingOperand, KilledDef))
3863 Register FoldingReg =
MI.getOperand(1).getReg();
3867 if (SrcMI->
getOpcode() != PPC::RLWINM &&
3868 SrcMI->
getOpcode() != PPC::RLWINM_rec &&
3872 assert((
MI.getOperand(2).isImm() &&
MI.getOperand(3).isImm() &&
3875 "Invalid PPC::RLWINM Instruction!");
3883 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&
3884 "Invalid PPC::RLWINM Instruction!");
3906 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);
3909 if ((MBMI > MEMI) && !SrcMaskFull)
3919 APInt RotatedSrcMask = MaskSrc.
rotl(SHMI);
3920 APInt FinalMask = RotatedSrcMask & MaskMI;
3922 bool Simplified =
false;
3925 if (FinalMask.
isZero()) {
3927 (
MI.getOpcode() == PPC::RLWINM8 ||
MI.getOpcode() == PPC::RLWINM8_rec);
3932 if (
MI.getOpcode() == PPC::RLWINM ||
MI.getOpcode() == PPC::RLWINM8) {
3934 MI.removeOperand(4);
3935 MI.removeOperand(3);
3936 MI.removeOperand(2);
3937 MI.getOperand(1).ChangeToImmediate(0);
3938 MI.setDesc(
get(Is64Bit ? PPC::LI8 : PPC::LI));
3941 MI.removeOperand(4);
3942 MI.removeOperand(3);
3943 MI.getOperand(2).setImm(0);
3944 MI.setDesc(
get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));
3947 MI.getOperand(1).setIsKill(
true);
3951 MI.getOperand(1).setIsKill(
false);
3967 uint16_t NewSH = (SHSrc + SHMI) % 32;
3968 MI.getOperand(2).setImm(NewSH);
3971 MI.getOperand(3).setImm(NewMB);
3972 MI.getOperand(4).setImm(NewME);
3976 MI.getOperand(1).setIsKill(
true);
3980 MI.getOperand(1).setIsKill(
false);
3985 if (Simplified &
MRI->use_nodbg_empty(FoldingReg) &&
4010 default:
return false;
4018 III.
ImmOpcode =
Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;
4027 III.
ImmOpcode =
Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;
4043 III.
ImmOpcode =
Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;
4051 III.
ImmOpcode =
Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;
4059 III.
ImmOpcode =
Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;
4079 case PPC::OR: III.
ImmOpcode = PPC::ORI;
break;
4080 case PPC::OR8: III.
ImmOpcode = PPC::ORI8;
break;
4081 case PPC::XOR: III.
ImmOpcode = PPC::XORI;
break;
4082 case PPC::XOR8: III.
ImmOpcode = PPC::XORI8;
break;
4087 case PPC::RLWNM_rec:
4088 case PPC::RLWNM8_rec:
4108 if (
Opc == PPC::RLWNM ||
Opc == PPC::RLWNM8 ||
Opc == PPC::RLWNM_rec ||
4109 Opc == PPC::RLWNM8_rec)
4115 case PPC::RLWNM: III.
ImmOpcode = PPC::RLWINM;
break;
4116 case PPC::RLWNM8: III.
ImmOpcode = PPC::RLWINM8;
break;
4117 case PPC::RLWNM_rec:
4120 case PPC::RLWNM8_rec:
4123 case PPC::SLW: III.
ImmOpcode = PPC::RLWINM;
break;
4124 case PPC::SLW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4131 case PPC::SRW: III.
ImmOpcode = PPC::RLWINM;
break;
4132 case PPC::SRW8: III.
ImmOpcode = PPC::RLWINM8;
break;
4152 case PPC::RLDCL_rec:
4154 case PPC::RLDCR_rec:
4170 if (
Opc == PPC::RLDCL ||
Opc == PPC::RLDCL_rec ||
Opc == PPC::RLDCR ||
4171 Opc == PPC::RLDCR_rec)
4177 case PPC::RLDCL: III.
ImmOpcode = PPC::RLDICL;
break;
4178 case PPC::RLDCL_rec:
4181 case PPC::RLDCR: III.
ImmOpcode = PPC::RLDICR;
break;
4182 case PPC::RLDCR_rec:
4185 case PPC::SLD: III.
ImmOpcode = PPC::RLDICR;
break;
4189 case PPC::SRD: III.
ImmOpcode = PPC::RLDICL;
break;
4236 case PPC::LBZX: III.
ImmOpcode = PPC::LBZ;
break;
4237 case PPC::LBZX8: III.
ImmOpcode = PPC::LBZ8;
break;
4238 case PPC::LHZX: III.
ImmOpcode = PPC::LHZ;
break;
4239 case PPC::LHZX8: III.
ImmOpcode = PPC::LHZ8;
break;
4240 case PPC::LHAX: III.
ImmOpcode = PPC::LHA;
break;
4241 case PPC::LHAX8: III.
ImmOpcode = PPC::LHA8;
break;
4242 case PPC::LWZX: III.
ImmOpcode = PPC::LWZ;
break;
4243 case PPC::LWZX8: III.
ImmOpcode = PPC::LWZ8;
break;
4249 case PPC::LFSX: III.
ImmOpcode = PPC::LFS;
break;
4250 case PPC::LFDX: III.
ImmOpcode = PPC::LFD;
break;
4251 case PPC::STBX: III.
ImmOpcode = PPC::STB;
break;
4252 case PPC::STBX8: III.
ImmOpcode = PPC::STB8;
break;
4253 case PPC::STHX: III.
ImmOpcode = PPC::STH;
break;
4254 case PPC::STHX8: III.
ImmOpcode = PPC::STH8;
break;
4255 case PPC::STWX: III.
ImmOpcode = PPC::STW;
break;
4256 case PPC::STWX8: III.
ImmOpcode = PPC::STW8;
break;
4261 case PPC::STFSX: III.
ImmOpcode = PPC::STFS;
break;
4262 case PPC::STFDX: III.
ImmOpcode = PPC::STFD;
break;
4294 case PPC::LBZUX: III.
ImmOpcode = PPC::LBZU;
break;
4295 case PPC::LBZUX8: III.
ImmOpcode = PPC::LBZU8;
break;
4296 case PPC::LHZUX: III.
ImmOpcode = PPC::LHZU;
break;
4297 case PPC::LHZUX8: III.
ImmOpcode = PPC::LHZU8;
break;
4298 case PPC::LHAUX: III.
ImmOpcode = PPC::LHAU;
break;
4299 case PPC::LHAUX8: III.
ImmOpcode = PPC::LHAU8;
break;
4300 case PPC::LWZUX: III.
ImmOpcode = PPC::LWZU;
break;
4301 case PPC::LWZUX8: III.
ImmOpcode = PPC::LWZU8;
break;
4306 case PPC::LFSUX: III.
ImmOpcode = PPC::LFSU;
break;
4307 case PPC::LFDUX: III.
ImmOpcode = PPC::LFDU;
break;
4308 case PPC::STBUX: III.
ImmOpcode = PPC::STBU;
break;
4309 case PPC::STBUX8: III.
ImmOpcode = PPC::STBU8;
break;
4310 case PPC::STHUX: III.
ImmOpcode = PPC::STHU;
break;
4311 case PPC::STHUX8: III.
ImmOpcode = PPC::STHU8;
break;
4312 case PPC::STWUX: III.
ImmOpcode = PPC::STWU;
break;
4313 case PPC::STWUX8: III.
ImmOpcode = PPC::STWU8;
break;
4318 case PPC::STFSUX: III.
ImmOpcode = PPC::STFSU;
break;
4319 case PPC::STFDUX: III.
ImmOpcode = PPC::STFDU;
break;
4332 case PPC::XFLOADf32:
4333 case PPC::XFLOADf64:
4334 case PPC::XFSTOREf32:
4335 case PPC::XFSTOREf64:
4336 if (!Subtarget.hasP9Vector())
4363 case PPC::XFLOADf32:
4377 case PPC::XFLOADf64:
4395 case PPC::XFSTOREf32:
4409 case PPC::XFSTOREf64:
4420 assert(Op1 != Op2 &&
"Cannot swap operand with itself.");
4422 unsigned MaxOp = std::max(Op1, Op2);
4423 unsigned MinOp = std::min(Op1, Op2);
4426 MI.removeOperand(std::max(Op1, Op2));
4427 MI.removeOperand(std::min(Op1, Op2));
4431 if (MaxOp - MinOp == 1 &&
MI.getNumOperands() == MinOp) {
4432 MI.addOperand(MOp2);
4433 MI.addOperand(MOp1);
4438 unsigned TotalOps =
MI.getNumOperands() + 2;
4439 for (
unsigned i =
MI.getNumOperands() - 1; i >= MinOp; i--) {
4441 MI.removeOperand(i);
4444 MI.addOperand(MOp2);
4446 for (
unsigned i =
MI.getNumOperands(); i < TotalOps; i++) {
4448 MI.addOperand(MOp1);
4450 MI.addOperand(MOps.
back());
4461 unsigned OpNoForForwarding
4465 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
4502 if (
Opc != PPC::ADDItocL8 &&
Opc != PPC::ADDI &&
Opc != PPC::ADDI8)
4508 if (
Opc == PPC::ADDItocL8 && Subtarget.isAIX())
4512 "Add inst must have at least three operands");
4513 RegMO = &
DefMI.getOperand(1);
4514 ImmMO = &
DefMI.getOperand(2);
4517 if (!RegMO->
isReg())
4526bool PPCInstrInfo::isRegElgibleForForwarding(
4529 bool &IsFwdFeederRegKilled,
bool &SeenIntermediateUse)
const {
4536 const MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
4546 for (; It !=
E; ++It) {
4550 IsFwdFeederRegKilled =
true;
4552 SeenIntermediateUse =
true;
4554 if ((&*It) == &
DefMI)
4567bool PPCInstrInfo::isImmElgibleForForwarding(
const MachineOperand &ImmMO,
4571 int64_t BaseImm)
const {
4573 if (
DefMI.getOpcode() == PPC::ADDItocL8) {
4594 if (ImmMO.
isImm()) {
4599 APInt ActualValue(64, ImmMO.
getImm() + BaseImm,
true);
4620 unsigned OpNoForForwarding,
4622 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
4623 !
DefMI.getOperand(1).isImm())
4626 MachineFunction *MF =
MI.getParent()->getParent();
4630 int64_t Immediate =
DefMI.getOperand(1).getImm();
4634 bool ReplaceWithLI =
false;
4635 bool Is64BitLI =
false;
4638 unsigned Opc =
MI.getOpcode();
4661 int64_t Comparand =
MI.getOperand(2).getImm();
4662 int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0
4663 ? (Comparand | 0xFFFFFFFFFFFF0000)
4666 for (
auto &CompareUseMI :
MRI->use_instructions(DefReg)) {
4667 unsigned UseOpc = CompareUseMI.getOpcode();
4668 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)
4670 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();
4671 Register TrueReg = CompareUseMI.getOperand(1).getReg();
4672 Register FalseReg = CompareUseMI.getOperand(2).getReg();
4673 unsigned RegToCopy =
4674 selectReg(SExtImm, SExtComparand,
Opc, TrueReg, FalseReg, CRSubReg);
4675 if (RegToCopy == PPC::NoRegister)
4678 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {
4679 CompareUseMI.setDesc(
get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));
4681 CompareUseMI.removeOperand(3);
4682 CompareUseMI.removeOperand(2);
4686 dbgs() <<
"Found LI -> CMPI -> ISEL, replacing with a copy.\n");
4690 CompareUseMI.setDesc(
get(PPC::COPY));
4691 CompareUseMI.removeOperand(3);
4692 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);
4693 CmpIselsConverted++;
4702 MissedConvertibleImmediateInstrs++;
4710 int64_t Addend =
MI.getOperand(2).getImm();
4712 ReplaceWithLI =
true;
4713 Is64BitLI =
Opc == PPC::ADDI8;
4714 NewImm = Addend + SExtImm;
4720 case PPC::SUBFIC8: {
4722 if (
MI.getNumOperands() > 3 && !
MI.getOperand(3).isDead())
4724 int64_t Minuend =
MI.getOperand(2).getImm();
4726 ReplaceWithLI =
true;
4727 Is64BitLI =
Opc == PPC::SUBFIC8;
4728 NewImm = Minuend - SExtImm;
4734 case PPC::RLDICL_rec:
4735 case PPC::RLDICL_32:
4736 case PPC::RLDICL_32_64: {
4738 int64_t SH =
MI.getOperand(2).getImm();
4739 int64_t MB =
MI.getOperand(3).getImm();
4740 APInt InVal((
Opc == PPC::RLDICL ||
Opc == PPC::RLDICL_rec) ? 64 : 32,
4742 InVal = InVal.rotl(SH);
4743 uint64_t
Mask = MB == 0 ? -1LL
U : (1LL
U << (63 - MB + 1)) - 1;
4749 (
Opc == PPC::RLDICL_rec &&
isUInt<16>(InVal.getSExtValue()))) {
4750 ReplaceWithLI =
true;
4751 Is64BitLI =
Opc != PPC::RLDICL_32;
4752 NewImm = InVal.getSExtValue();
4753 SetCR =
Opc == PPC::RLDICL_rec;
4760 case PPC::RLWINM_rec:
4761 case PPC::RLWINM8_rec: {
4762 int64_t SH =
MI.getOperand(2).getImm();
4763 int64_t MB =
MI.getOperand(3).getImm();
4764 int64_t ME =
MI.getOperand(4).getImm();
4765 APInt InVal(32, SExtImm,
true);
4766 InVal = InVal.rotl(SH);
4772 bool ValueFits =
isUInt<15>(InVal.getSExtValue());
4773 ValueFits |= ((
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec) &&
4776 ReplaceWithLI =
true;
4777 Is64BitLI =
Opc == PPC::RLWINM8 ||
Opc == PPC::RLWINM8_rec;
4778 NewImm = InVal.getSExtValue();
4779 SetCR =
Opc == PPC::RLWINM_rec ||
Opc == PPC::RLWINM8_rec;
4788 int64_t LogicalImm =
MI.getOperand(2).getImm();
4790 if (
Opc == PPC::ORI ||
Opc == PPC::ORI8)
4791 Result = LogicalImm | SExtImm;
4793 Result = LogicalImm ^ SExtImm;
4795 ReplaceWithLI =
true;
4796 Is64BitLI =
Opc == PPC::ORI8 ||
Opc == PPC::XORI8;
4804 if (ReplaceWithLI) {
4809 bool ImmChanged = (SExtImm & NewImm) != NewImm;
4810 if (PostRA && ImmChanged)
4817 DefMI.getOperand(1).setImm(NewImm);
4821 else if (
MRI->use_empty(
MI.getOperand(0).getReg())) {
4823 assert(Immediate &&
"Transformation converted zero to non-zero?");
4826 }
else if (ImmChanged)
4835 LoadImmediateInfo LII;
4841 if (KilledDef && SetCR)
4842 *KilledDef =
nullptr;
4855bool PPCInstrInfo::transformToNewImmFormFedByAdd(
4857 MachineRegisterInfo *
MRI = &
MI.getParent()->getParent()->getRegInfo();
4865 if (!
MI.mayLoadOrStore())
4868 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(
MI.getOpcode());
4870 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&
4871 "MI must have x-form opcode");
4875 bool IsVFReg =
MI.getOperand(0).isReg()
4888 MachineOperand ImmOperandMI =
MI.getOperand(III.
ImmOpNo);
4889 if (!ImmOperandMI.
isImm())
4893 MachineOperand *ImmMO =
nullptr;
4894 MachineOperand *RegMO =
nullptr;
4895 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4897 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4902 int64_t ImmBase = ImmOperandMI.
getImm();
4904 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III, Imm, ImmBase))
4908 LLVM_DEBUG(
dbgs() <<
"Replacing existing reg+imm instruction:\n");
4925bool PPCInstrInfo::transformToImmFormFedByAdd(
4935 if (!isUseMIElgibleForForwarding(
MI, III, OpNoForForwarding))
4940 MachineOperand *ImmMO =
nullptr;
4941 MachineOperand *RegMO =
nullptr;
4942 if (!isDefMIElgibleForForwarding(
DefMI, III, ImmMO, RegMO))
4944 assert(ImmMO && RegMO &&
"Imm and Reg operand must have been set");
4949 if (!isImmElgibleForForwarding(*ImmMO,
DefMI, III, Imm))
4952 bool IsFwdFeederRegKilled =
false;
4953 bool SeenIntermediateUse =
false;
4955 if (!isRegElgibleForForwarding(*RegMO,
DefMI,
MI, KillDefMI,
4956 IsFwdFeederRegKilled, SeenIntermediateUse))
4959 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
4976 if (ImmMO->
isImm()) {
4987 if (
DefMI.getOpcode() == PPC::ADDItocL8)
4997 MI.removeOperand(i);
5003 MI.addOperand(*ImmMO);
5005 for (
auto &MO : MOps)
5022 unsigned ConstantOpNo,
5025 if ((
DefMI.getOpcode() != PPC::LI &&
DefMI.getOpcode() != PPC::LI8) ||
5026 !
DefMI.getOperand(1).isImm())
5032 MachineRegisterInfo &
MRI =
MI.getParent()->getParent()->getRegInfo();
5042 APInt ActualValue(64, Imm,
true);
5043 if (!ActualValue.isSignedIntN(III.
ImmWidth))
5046 uint64_t UnsignedMax = (1 << III.
ImmWidth) - 1;
5047 if ((uint64_t)Imm > UnsignedMax)
5057 Register OrigZeroReg =
MI.getOperand(PosForOrigZero).getReg();
5061 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&
5064 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&
5065 ConstantOpNo != PosForOrigZero)
5069 unsigned Opc =
MI.getOpcode();
5070 bool SpecialShift32 =
Opc == PPC::SLW ||
Opc == PPC::SLW_rec ||
5071 Opc == PPC::SRW ||
Opc == PPC::SRW_rec ||
5072 Opc == PPC::SLW8 ||
Opc == PPC::SLW8_rec ||
5073 Opc == PPC::SRW8 ||
Opc == PPC::SRW8_rec;
5074 bool SpecialShift64 =
Opc == PPC::SLD ||
Opc == PPC::SLD_rec ||
5075 Opc == PPC::SRD ||
Opc == PPC::SRD_rec;
5076 bool SetCR =
Opc == PPC::SLW_rec ||
Opc == PPC::SRW_rec ||
5077 Opc == PPC::SLD_rec ||
Opc == PPC::SRD_rec;
5079 Opc == PPC::SRD_rec;
5093 if (SpecialShift32 || SpecialShift64) {
5094 LoadImmediateInfo LII;
5098 uint64_t ShAmt =
Imm & (SpecialShift32 ? 0x1F : 0x3F);
5099 if (Imm & (SpecialShift32 ? 0x20 : 0x40))
5104 else if (!SetCR && ShAmt == 0 && !PostRA) {
5105 MI.removeOperand(2);
5106 MI.setDesc(
get(PPC::COPY));
5109 if (SpecialShift32) {
5113 uint64_t SH = ShAmt == 0 ? 0 :
RightShift ? 32 - ShAmt : ShAmt;
5117 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(MB)
5123 uint64_t SH = ShAmt == 0 ? 0 :
RightShift ? 64 - ShAmt : ShAmt;
5124 uint64_t ME =
RightShift ? ShAmt : 63 - ShAmt;
5126 MachineInstrBuilder(*
MI.getParent()->getParent(),
MI).addImm(ME);
5154 const TargetRegisterClass *NewRC =
5155 MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?
5156 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;
5157 MRI.setRegClass(RegToModify, NewRC);
5173 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)
5174 return &PPC::VSRCRegClass;
5179 return PPC::getRecordFormOpcode(Opcode);
5183 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||
5184 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||
5185 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||
5186 Opcode == PPC::LHZUX8);
5199 int Opcode =
MI->getOpcode();
5202 if (
TII->isSExt32To64(Opcode))
5211 if (Opcode == PPC::RLDICL &&
MI->getOperand(3).getImm() >= 33)
5217 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5218 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&
5219 MI->getOperand(3).getImm() > 0 &&
5220 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5225 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {
5227 if ((Imm & 0x8000) == 0)
5246 int Opcode =
MI->getOpcode();
5249 if (
TII->isZExt32To64(Opcode))
5254 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&
5255 MI->getOperand(0).getReg() ==
Reg)
5260 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||
5261 Opcode == PPC::LIS || Opcode == PPC::LIS8) {
5262 int64_t Imm =
MI->getOperand(1).getImm();
5263 if (((
uint64_t)Imm & ~0x7FFFuLL) == 0)
5269 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||
5270 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||
5271 Opcode == PPC::RLDICL_32_64) &&
5272 MI->getOperand(3).getImm() >= 32)
5275 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&
5276 MI->getOperand(3).getImm() >= 32 &&
5277 MI->getOperand(3).getImm() <= 63 -
MI->getOperand(2).getImm())
5280 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||
5281 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||
5282 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&
5283 MI->getOperand(3).getImm() <=
MI->getOperand(4).getImm())
5292 if (!
MI.getOperand(1).isImm() || !
MI.getOperand(2).isReg())
5294 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
5296 Register StackReg =
MI.getOperand(2).getReg();
5319 unsigned BinOpDepth,
5321 if (!Reg.isVirtual())
5328 unsigned Opcode =
MI->getOpcode();
5337 unsigned OperandEnd = 3, OperandStride = 1;
5338 if (Opcode == PPC::PHI) {
5339 OperandEnd =
MI->getNumOperands();
5343 for (
unsigned I = 1;
I < OperandEnd;
I += OperandStride) {
5344 assert(
MI->getOperand(
I).isReg() &&
"Operand must be register");
5346 BinOpDepth + 1, LV);
5355 Register SrcReg =
MI->getOperand(1).getReg();
5369 if (SrcReg != PPC::X3)
5392 BinOpDepth + 1, LV);
5394 BinOpDepth + 1, LV);
5399 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5408 std::unordered_map<unsigned, unsigned> OpcodeMap = {
5409 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5410 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5411 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5412 {PPC::AND, PPC::AND8}};
5415 auto It = OpcodeMap.find(Opcode);
5416 if (It != OpcodeMap.end()) {
5418 NewOpcode = It->second;
5420 if (!
TII->isSExt32To64(Opcode))
5426 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);
5429 assert(NewOpcode != -1 &&
5430 "Must have a 64-bit opcode to map the 32-bit opcode!");
5435 TRI->getRegClass(
MCID.operands()[0].RegClass);
5437 Register SrcReg =
MI->getOperand(0).getReg();
5447 auto MBB =
MI->getParent();
5455 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5457 if (!Operand.
isReg())
5465 TRI->getRegClass(
MCID.operands()[i].RegClass);
5467 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5468 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5470 Register TmpReg =
MRI->createVirtualRegister(NewUsedRegRC);
5471 Register DstTmpReg =
MRI->createVirtualRegister(NewUsedRegRC);
5477 PromoteRegs[i] = DstTmpReg;
5481 Register NewDefinedReg =
MRI->createVirtualRegister(NewRC);
5487 for (
unsigned i = 1; i <
MI->getNumOperands(); i++) {
5488 if (
auto It = PromoteRegs.
find(i); It != PromoteRegs.
end())
5494 for (
unsigned i = 1; i < Iter->getNumOperands(); i++) {
5496 if (!Operand.
isReg())
5504 MI->eraseFromParent();
5520std::pair<bool, bool>
5522 const unsigned BinOpDepth,
5525 return std::pair<bool, bool>(
false,
false);
5529 return std::pair<bool, bool>(
false,
false);
5536 if (IsSExt && IsZExt)
5537 return std::pair<bool, bool>(IsSExt, IsZExt);
5539 switch (
MI->getOpcode()) {
5541 Register SrcReg =
MI->getOperand(1).getReg();
5550 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5551 SrcExt.second || IsZExt);
5557 if (
MI->getParent()->getBasicBlock() ==
5563 return std::pair<bool, bool>(IsSExt, IsZExt);
5567 if (SrcReg != PPC::X3) {
5570 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5571 SrcExt.second || IsZExt);
5581 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);
5584 if (
II ==
MBB->instr_begin() || (--
II)->getOpcode() != PPC::ADJCALLSTACKUP)
5585 return IsExtendPair;
5589 return IsExtendPair;
5594 return IsExtendPair;
5596 if (IntTy && IntTy->getBitWidth() <= 32) {
5598 IsSExt |= Attrs.hasAttribute(Attribute::SExt);
5599 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);
5600 return std::pair<bool, bool>(IsSExt, IsZExt);
5603 return IsExtendPair;
5612 Register SrcReg =
MI->getOperand(1).getReg();
5614 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5615 SrcExt.second || IsZExt);
5626 Register SrcReg =
MI->getOperand(1).getReg();
5630 return std::pair<bool, bool>(
false, SrcExt.second || IsZExt);
5632 return std::pair<bool, bool>(SrcExt.first || IsSExt,
5633 SrcExt.second || IsZExt);
5643 return std::pair<bool, bool>(
false,
false);
5647 unsigned OperandEnd = 3, OperandStride = 1;
5648 if (
MI->getOpcode() == PPC::PHI) {
5649 OperandEnd =
MI->getNumOperands();
5655 for (
unsigned I = 1;
I != OperandEnd;
I += OperandStride) {
5656 if (!
MI->getOperand(
I).isReg())
5657 return std::pair<bool, bool>(
false,
false);
5661 IsSExt &= SrcExt.first;
5662 IsZExt &= SrcExt.second;
5664 return std::pair<bool, bool>(IsSExt, IsZExt);
5673 return std::pair<bool, bool>(
false,
false);
5675 Register SrcReg1 =
MI->getOperand(1).getReg();
5676 Register SrcReg2 =
MI->getOperand(2).getReg();
5679 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,
5680 Src1Ext.second || Src2Ext.second);
5686 return std::pair<bool, bool>(IsSExt, IsZExt);
5690 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));
5703 :
Loop(
Loop), EndLoop(EndLoop), LoopCount(LoopCount),
5705 TII(MF->getSubtarget().getInstrInfo()) {
5714 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5716 return MI == EndLoop;
5719 std::optional<bool> createTripCountGreaterCondition(
5720 int TC, MachineBasicBlock &
MBB,
5721 SmallVectorImpl<MachineOperand> &
Cond)
override {
5722 if (TripCount == -1) {
5727 MF->
getSubtarget<PPCSubtarget>().isPPC64() ? PPC::CTR8 : PPC::CTR,
5732 return TripCount > TC;
5735 void setPreheader(MachineBasicBlock *NewPreheader)
override {
5740 void adjustTripCount(
int TripCountAdjust)
override {
5743 if (LoopCount->
getOpcode() == PPC::LI8 ||
5754 void disposed(LiveIntervals *LIS)
override {
5766std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5771 if (Preheader == LoopBB)
5772 Preheader = *std::next(LoopBB->
pred_begin());
5775 if (
I != LoopBB->
end() &&
isBDNZ(
I->getOpcode())) {
5778 Register LoopCountReg = LoopInst->getOperand(0).getReg();
5781 return std::make_unique<PPCPipelinerLoopInfo>(LoopInst, &*
I, LoopCount);
5791 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);
5794 for (
auto &
I : PreHeader.
instrs())
5795 if (
I.getOpcode() == LOOPi)
5841 int64_t OffsetA = 0, OffsetB = 0;
5847 int LowOffset = std::min(OffsetA, OffsetB);
5848 int HighOffset = std::max(OffsetA, OffsetB);
5849 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
5851 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static const Function * getParent(const Value *V)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
static bool isOpZeroOfSubwordPreincLoad(int Opcode)
static bool MBBDefinesCTR(MachineBasicBlock &MBB)
static bool definedByZeroExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)
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"))
#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
#define InfoArrayIdxFMULInst
static bool definedBySignExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)
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.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - 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 ...
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
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & 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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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 eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
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.
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,...
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,...
LLVM_ABI bool isLiveIn(Register Reg) const
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
unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const
unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) 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 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
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
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...
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.
CodeModel::Model getCodeModel() const
Returns the code model.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.
Define some predicates that are used for node matching.
Predicate getSwappedPredicate(Predicate Opcode)
Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
int getAltVSXFMAOpcode(uint16_t Opcode)
int getNonRecordFormOpcode(uint16_t)
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. != -> ==, < -> >=.
static bool isVFRegister(MCRegister Reg)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
unsigned getDeadRegState(bool B)
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)
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...
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
@ Sub
Subtraction of integers.
unsigned getKillRegState(bool B)
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.
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.