69 #define DEBUG_TYPE "arm-instrinfo" 71 #define GET_INSTRINFO_CTOR_DTOR 72 #include "ARMGenInstrInfo.inc" 76 cl::desc(
"Enable ARM 2-addr to 3-addr conv"));
90 { ARM::VMLAS, ARM::VMULS, ARM::VADDS,
false,
false },
91 { ARM::VMLSS, ARM::VMULS, ARM::VSUBS,
false,
false },
92 { ARM::VMLAD, ARM::VMULD, ARM::VADDD,
false,
false },
93 { ARM::VMLSD, ARM::VMULD, ARM::VSUBD,
false,
false },
94 { ARM::VNMLAS, ARM::VNMULS, ARM::VSUBS,
true,
false },
95 { ARM::VNMLSS, ARM::VMULS, ARM::VSUBS,
true,
false },
96 { ARM::VNMLAD, ARM::VNMULD, ARM::VSUBD,
true,
false },
97 { ARM::VNMLSD, ARM::VMULD, ARM::VSUBD,
true,
false },
100 { ARM::VMLAfd, ARM::VMULfd, ARM::VADDfd,
false,
false },
101 { ARM::VMLSfd, ARM::VMULfd, ARM::VSUBfd,
false,
false },
102 { ARM::VMLAfq, ARM::VMULfq, ARM::VADDfq,
false,
false },
103 { ARM::VMLSfq, ARM::VMULfq, ARM::VSUBfq,
false,
false },
104 { ARM::VMLAslfd, ARM::VMULslfd, ARM::VADDfd,
false,
true },
105 { ARM::VMLSslfd, ARM::VMULslfd, ARM::VSUBfd,
false,
true },
106 { ARM::VMLAslfq, ARM::VMULslfq, ARM::VADDfq,
false,
true },
107 { ARM::VMLSslfq, ARM::VMULslfq, ARM::VSUBfq,
false,
true },
113 for (
unsigned i = 0, e =
array_lengthof(ARM_MLxTable); i != e; ++i) {
114 if (!MLxEntryMap.
insert(std::make_pair(ARM_MLxTable[i].
MLxOpc, i)).second)
116 MLxHazardOpcodes.
insert(ARM_MLxTable[i].AddSubOpc);
117 MLxHazardOpcodes.
insert(ARM_MLxTable[i].MulOpc);
126 if (usePreRAHazardRecognizer()) {
128 static_cast<const ARMSubtarget *
>(STI)->getInstrItineraryData();
153 default:
return nullptr;
176 unsigned WBReg = WB.
getReg();
177 unsigned BaseReg = Base.
getReg();
178 unsigned OffReg = Offset.
getReg();
192 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
197 }
else if (Amt != 0) {
201 get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg)
210 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
223 get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
230 get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
239 std::vector<MachineInstr*> NewMIs;
254 NewMIs.push_back(MemMI);
255 NewMIs.push_back(UpdateMI);
272 NewMIs.push_back(UpdateMI);
273 NewMIs.push_back(MemMI);
285 MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
290 for (
unsigned j = 0; j < 2; ++j) {
297 VI.
Kills.push_back(NewMI);
306 MFI->insert(MBBI, NewMIs[1]);
307 MFI->insert(MBBI, NewMIs[0]);
316 bool AllowModify)
const {
321 if (I == MBB.
begin())
327 while (
isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
331 bool CantAnalyze =
false;
334 while (I->isDebugInstr() || !I->isTerminator()) {
335 if (I == MBB.
begin())
346 TBB = I->getOperand(0).getMBB();
352 assert(!FBB &&
"FBB should have been null.");
354 TBB = I->getOperand(0).getMBB();
357 }
else if (I->isReturn()) {
380 while (DI != MBB.
end()) {
391 if (I == MBB.
begin())
403 int *BytesRemoved)
const {
404 assert(!BytesRemoved &&
"code size not handled");
415 I->eraseFromParent();
419 if (I == MBB.
begin())
return 1;
425 I->eraseFromParent();
434 int *BytesAdded)
const {
435 assert(!BytesAdded &&
"code size not handled");
444 assert(TBB &&
"insertBranch must not be told to insert a fallthrough");
446 "ARM branch conditions have two components!");
487 while (++I != E && I->isInsideBundle()) {
488 int PIdx = I->findFirstPredOperandIdx();
489 if (PIdx != -1 && I->getOperand(PIdx).getImm() !=
ARMCC::AL)
505 .addImm(Pred[0].getImm())
506 .addReg(Pred[1].
getReg());
513 PMO.
setImm(Pred[0].getImm());
522 if (Pred1.
size() > 2 || Pred2.
size() > 2)
562 for (
const auto &MO : MI.
operands())
563 if (MO.isReg() && MO.getReg() == ARM::CPSR && MO.isDef() && !MO.isDead())
571 return Offset.
getReg() != 0;
582 int64_t OpcImm = Opc.
getImm();
585 return (isSub && Offset.
getReg() != 0);
591 unsigned OffImm = Opc.
getImm();
599 unsigned OffImm = Opc.
getImm();
605 bool SimpleScaled = (isAdd && ShiftOpc ==
ARM_AM::lsl && Amt == 2);
606 return !SimpleScaled;
625 default:
return true;
684 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
688 if (MO.
getReg() != ARM::CPSR)
722 case TargetOpcode::BUNDLE:
723 return getInstBundleLength(MI);
724 case ARM::MOVi16_ga_pcrel:
725 case ARM::MOVTi16_ga_pcrel:
726 case ARM::t2MOVi16_ga_pcrel:
727 case ARM::t2MOVTi16_ga_pcrel:
730 case ARM::t2MOVi32imm:
732 case ARM::CONSTPOOL_ENTRY:
733 case ARM::JUMPTABLE_INSTS:
734 case ARM::JUMPTABLE_ADDRS:
735 case ARM::JUMPTABLE_TBB:
736 case ARM::JUMPTABLE_TBH:
740 case ARM::Int_eh_sjlj_longjmp:
742 case ARM::tInt_eh_sjlj_longjmp:
744 case ARM::tInt_WIN_eh_sjlj_longjmp:
746 case ARM::Int_eh_sjlj_setjmp:
747 case ARM::Int_eh_sjlj_setjmp_nofp:
749 case ARM::tInt_eh_sjlj_setjmp:
750 case ARM::t2Int_eh_sjlj_setjmp:
751 case ARM::t2Int_eh_sjlj_setjmp_nofp:
758 unsigned ARMBaseInstrInfo::getInstBundleLength(
const MachineInstr &
MI)
const {
762 while (++I != E && I->isInsideBundle()) {
763 assert(!I->isBundle() &&
"No nested bundle!");
771 unsigned DestReg,
bool KillSrc,
773 unsigned Opc = Subtarget.
isThumb()
774 ? (Subtarget.
isMClass() ? ARM::t2MRS_M : ARM::t2MRS_AR)
778 BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), DestReg);
791 unsigned SrcReg,
bool KillSrc,
793 unsigned Opc = Subtarget.
isThumb()
794 ? (Subtarget.
isMClass() ? ARM::t2MSR_M : ARM::t2MSR_AR)
811 const DebugLoc &DL,
unsigned DestReg,
812 unsigned SrcReg,
bool KillSrc)
const {
813 bool GPRDest = ARM::GPRRegClass.contains(DestReg);
814 bool GPRSrc = ARM::GPRRegClass.contains(SrcReg);
816 if (GPRDest && GPRSrc) {
817 BuildMI(MBB, I, DL,
get(ARM::MOVr), DestReg)
824 bool SPRDest = ARM::SPRRegClass.contains(DestReg);
825 bool SPRSrc = ARM::SPRRegClass.contains(SrcReg);
828 if (SPRDest && SPRSrc)
830 else if (GPRDest && SPRSrc)
832 else if (SPRDest && GPRSrc)
834 else if (ARM::DPRRegClass.
contains(DestReg, SrcReg) && !Subtarget.isFPOnlySP())
836 else if (ARM::QPRRegClass.
contains(DestReg, SrcReg))
842 if (Opc == ARM::VORRq)
849 unsigned BeginIdx = 0;
850 unsigned SubRegs = 0;
854 if (ARM::QQPRRegClass.
contains(DestReg, SrcReg)) {
856 BeginIdx = ARM::qsub_0;
858 }
else if (ARM::QQQQPRRegClass.
contains(DestReg, SrcReg)) {
860 BeginIdx = ARM::qsub_0;
863 }
else if (ARM::DPairRegClass.
contains(DestReg, SrcReg)) {
865 BeginIdx = ARM::dsub_0;
867 }
else if (ARM::DTripleRegClass.
contains(DestReg, SrcReg)) {
869 BeginIdx = ARM::dsub_0;
871 }
else if (ARM::DQuadRegClass.
contains(DestReg, SrcReg)) {
873 BeginIdx = ARM::dsub_0;
875 }
else if (ARM::GPRPairRegClass.
contains(DestReg, SrcReg)) {
876 Opc = Subtarget.isThumb2() ? ARM::tMOVr : ARM::MOVr;
877 BeginIdx = ARM::gsub_0;
879 }
else if (ARM::DPairSpcRegClass.
contains(DestReg, SrcReg)) {
881 BeginIdx = ARM::dsub_0;
884 }
else if (ARM::DTripleSpcRegClass.
contains(DestReg, SrcReg)) {
886 BeginIdx = ARM::dsub_0;
889 }
else if (ARM::DQuadSpcRegClass.
contains(DestReg, SrcReg)) {
891 BeginIdx = ARM::dsub_0;
894 }
else if (ARM::DPRRegClass.
contains(DestReg, SrcReg) && Subtarget.isFPOnlySP()) {
896 BeginIdx = ARM::ssub_0;
898 }
else if (SrcReg == ARM::CPSR) {
901 }
else if (DestReg == ARM::CPSR) {
902 copyToCPSR(MBB, I, SrcReg, KillSrc, Subtarget);
906 assert(Opc &&
"Impossible reg-to-reg copy");
913 BeginIdx = BeginIdx + ((SubRegs - 1) * Spacing);
919 for (
unsigned i = 0; i != SubRegs; ++i) {
920 unsigned Dst = TRI->
getSubReg(DestReg, BeginIdx + i * Spacing);
921 unsigned Src = TRI->
getSubReg(SrcReg, BeginIdx + i * Spacing);
922 assert(Dst && Src &&
"Bad sub-register");
924 assert(!DstRegs.
count(Src) &&
"destructive vector copy");
927 Mov =
BuildMI(MBB, I, I->getDebugLoc(),
get(Opc), Dst).
addReg(Src);
929 if (Opc == ARM::VORRq)
933 if (Opc == ARM::MOVr)
963 unsigned SubIdx,
unsigned State,
966 return MIB.
addReg(Reg, State);
970 return MIB.
addReg(Reg, State, SubIdx);
975 unsigned SrcReg,
bool isKill,
int FI,
988 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
999 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1006 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1017 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1024 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1025 if (Subtarget.hasV5TEOps()) {
1028 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
1039 AddDReg(MIB, SrcReg, ARM::gsub_1, 0, TRI);
1045 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
1065 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1081 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
1082 AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
1088 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1105 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
1106 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
1107 AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
1113 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1119 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI);
1120 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI);
1121 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI);
1122 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI);
1123 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI);
1124 MIB =
AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI);
1125 AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI);
1159 case ARM::VST1d64TPseudo:
1160 case ARM::VST1d64QPseudo:
1180 if (MI.
mayStore() && hasStoreToStackSlot(MI, Accesses)) {
1191 unsigned DestReg,
int FI,
1195 if (I != MBB.
end()) DL = I->getDebugLoc();
1205 if (ARM::HPRRegClass.hasSubClassEq(RC)) {
1206 BuildMI(MBB, I, DL,
get(ARM::VLDRH), DestReg)
1215 if (ARM::GPRRegClass.hasSubClassEq(RC)) {
1216 BuildMI(MBB, I, DL,
get(ARM::LDRi12), DestReg)
1221 }
else if (ARM::SPRRegClass.hasSubClassEq(RC)) {
1222 BuildMI(MBB, I, DL,
get(ARM::VLDRS), DestReg)
1231 if (ARM::DPRRegClass.hasSubClassEq(RC)) {
1232 BuildMI(MBB, I, DL,
get(ARM::VLDRD), DestReg)
1237 }
else if (ARM::GPRPairRegClass.hasSubClassEq(RC)) {
1240 if (Subtarget.hasV5TEOps()) {
1241 MIB =
BuildMI(MBB, I, DL,
get(ARM::LDRD));
1249 MIB =
BuildMI(MBB, I, DL,
get(ARM::LDMIA))
1263 if (ARM::DPairRegClass.hasSubClassEq(RC)) {
1265 BuildMI(MBB, I, DL,
get(ARM::VLD1q64), DestReg)
1271 BuildMI(MBB, I, DL,
get(ARM::VLDMQIA), DestReg)
1280 if (ARM::DTripleRegClass.hasSubClassEq(RC)) {
1282 BuildMI(MBB, I, DL,
get(ARM::VLD1d64TPseudo), DestReg)
1302 if (ARM::QQPRRegClass.hasSubClassEq(RC) || ARM::DQuadRegClass.hasSubClassEq(RC)) {
1304 BuildMI(MBB, I, DL,
get(ARM::VLD1d64QPseudo), DestReg)
1325 if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) {
1373 case ARM::VLD1d8TPseudo:
1374 case ARM::VLD1d16TPseudo:
1375 case ARM::VLD1d32TPseudo:
1376 case ARM::VLD1d64TPseudo:
1377 case ARM::VLD1d8QPseudo:
1378 case ARM::VLD1d16QPseudo:
1379 case ARM::VLD1d32QPseudo:
1380 case ARM::VLD1d64QPseudo:
1400 if (MI.
mayLoad() && hasLoadFromStackSlot(MI, Accesses)) {
1412 bool isThumb1 = Subtarget.isThumb1Only();
1413 bool isThumb2 = Subtarget.isThumb2();
1420 if (isThumb1 || !MI->getOperand(1).isDead()) {
1422 LDM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA_UPD
1423 : isThumb1 ? ARM::tLDMIA_UPD
1427 LDM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2LDMIA : ARM::LDMIA));
1430 if (isThumb1 || !MI->getOperand(0).isDead()) {
1432 STM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA_UPD
1433 : isThumb1 ? ARM::tSTMIA_UPD
1437 STM =
BuildMI(*BB, MI, dl, TII->get(isThumb2 ? ARM::t2STMIA : ARM::STMIA));
1449 for(
unsigned I = 5;
I < MI->getNumOperands(); ++
I)
1450 ScratchRegs.
push_back(MI->getOperand(
I).getReg());
1452 [&TRI](
const unsigned &Reg1,
const unsigned &Reg2) ->
bool {
1457 for (
const auto &
Reg : ScratchRegs) {
1466 if (MI.
getOpcode() == TargetOpcode::LOAD_STACK_GUARD) {
1468 "LOAD_STACK_GUARD currently supported only for MachO.");
1469 expandLoadStackGuard(MI);
1483 if (!MI.
isCopy() || Subtarget.dontWidenVMOVS() || Subtarget.isFPOnlySP())
1490 if (!ARM::SPRRegClass.
contains(DstRegS, SrcRegS))
1498 if (!DstRegD || !SrcRegD)
1518 if (ImpDefIdx != -1)
1552 assert(MCPE.isMachineConstantPoolEntry() &&
1553 "Expecting a machine constantpool entry!");
1565 if (ACPV->isGlobalValue())
1567 cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
ARMCP::CPValue,
1568 4, ACPV->getModifier(), ACPV->mustAddCurrentAddress());
1569 else if (ACPV->isExtSymbol())
1572 cast<ARMConstantPoolSymbol>(ACPV)->
getSymbol(), PCLabelId, 4);
1573 else if (ACPV->isBlockAddress())
1575 Create(cast<ARMConstantPoolConstant>(ACPV)->getBlockAddress(), PCLabelId,
1577 else if (ACPV->isLSDA())
1580 else if (ACPV->isMachineBasicBlock())
1583 cast<ARMConstantPoolMBB>(ACPV)->getMBB(), PCLabelId, 4);
1592 unsigned DestReg,
unsigned SubIdx,
1603 case ARM::tLDRpci_pic:
1604 case ARM::t2LDRpci_pic: {
1624 switch (I->getOpcode()) {
1625 case ARM::tLDRpci_pic:
1626 case ARM::t2LDRpci_pic: {
1628 unsigned CPI = I->getOperand(1).getIndex();
1630 I->getOperand(1).setIndex(CPI);
1631 I->getOperand(2).setImm(PCLabelId);
1635 if (!I->isBundledWithSucc())
1646 if (Opcode == ARM::t2LDRpci ||
1647 Opcode == ARM::t2LDRpci_pic ||
1648 Opcode == ARM::tLDRpci ||
1649 Opcode == ARM::tLDRpci_pic ||
1650 Opcode == ARM::LDRLIT_ga_pcrel ||
1651 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1652 Opcode == ARM::tLDRLIT_ga_pcrel ||
1653 Opcode == ARM::MOV_ga_pcrel ||
1654 Opcode == ARM::MOV_ga_pcrel_ldr ||
1655 Opcode == ARM::t2MOV_ga_pcrel) {
1666 if (Opcode == ARM::LDRLIT_ga_pcrel ||
1667 Opcode == ARM::LDRLIT_ga_pcrel_ldr ||
1668 Opcode == ARM::tLDRLIT_ga_pcrel ||
1669 Opcode == ARM::MOV_ga_pcrel ||
1670 Opcode == ARM::MOV_ga_pcrel_ldr ||
1671 Opcode == ARM::t2MOV_ga_pcrel)
1683 if (isARMCP0 && isARMCP1) {
1689 }
else if (!isARMCP0 && !isARMCP1) {
1693 }
else if (Opcode == ARM::PICLDR) {
1701 if (Addr0 != Addr1) {
1739 int64_t &Offset2)
const {
1741 if (Subtarget.isThumb1Only())
return false;
1760 case ARM::t2LDRSHi8:
1762 case ARM::t2LDRBi12:
1763 case ARM::t2LDRSHi12:
1780 case ARM::t2LDRSHi8:
1782 case ARM::t2LDRBi12:
1783 case ARM::t2LDRSHi12:
1797 if (isa<ConstantSDNode>(Load1->
getOperand(1)) &&
1799 Offset1 = cast<ConstantSDNode>(Load1->
getOperand(1))->getSExtValue();
1800 Offset2 = cast<ConstantSDNode>(Load2->
getOperand(1))->getSExtValue();
1819 int64_t Offset1, int64_t Offset2,
1820 unsigned NumLoads)
const {
1822 if (Subtarget.isThumb1Only())
return false;
1824 assert(Offset2 > Offset1);
1826 if ((Offset2 - Offset1) / 8 > 64)
1872 while (++I != MBB->
end() && I->isDebugInstr())
1874 if (I != MBB->
end() && I->getOpcode() == ARM::t2IT)
1893 unsigned NumCycles,
unsigned ExtraPredCycles,
1903 if (!Pred->
empty()) {
1905 if (LastMI->
getOpcode() == ARM::t2Bcc) {
1907 if (CmpMI != Pred->
begin()) {
1909 if (CmpMI->getOpcode() == ARM::tCMPi8 ||
1910 CmpMI->getOpcode() == ARM::t2CMPri) {
1911 unsigned Reg = CmpMI->getOperand(0).getReg();
1912 unsigned PredReg = 0;
1914 if (P ==
ARMCC::AL && CmpMI->getOperand(1).getImm() == 0 &&
1923 MBB, 0, 0, Probability);
1928 unsigned TCycles,
unsigned TExtra,
1930 unsigned FCycles,
unsigned FExtra,
1938 const unsigned ScalingUpFactor = 1024;
1940 unsigned PredCost = (TCycles + FCycles + TExtra + FExtra) * ScalingUpFactor;
1941 unsigned UnpredCost;
1942 if (!Subtarget.hasBranchPredictor()) {
1945 unsigned NotTakenBranchCost = 1;
1946 unsigned TakenBranchCost = Subtarget.getMispredictionPenalty();
1947 unsigned TUnpredCycles, FUnpredCycles;
1950 TUnpredCycles = TCycles + NotTakenBranchCost;
1951 FUnpredCycles = TakenBranchCost;
1954 TUnpredCycles = TCycles + TakenBranchCost;
1955 FUnpredCycles = FCycles + NotTakenBranchCost;
1958 PredCost -= 1 * ScalingUpFactor;
1961 unsigned TUnpredCost = Probability.
scale(TUnpredCycles * ScalingUpFactor);
1962 unsigned FUnpredCost = Probability.
getCompl().
scale(FUnpredCycles * ScalingUpFactor);
1963 UnpredCost = TUnpredCost + FUnpredCost;
1966 if (Subtarget.isThumb2() && TCycles + FCycles > 4) {
1967 PredCost += ((TCycles + FCycles - 4) / 4) * ScalingUpFactor;
1970 unsigned TUnpredCost = Probability.
scale(TCycles * ScalingUpFactor);
1971 unsigned FUnpredCost =
1973 UnpredCost = TUnpredCost + FUnpredCost;
1974 UnpredCost += 1 * ScalingUpFactor;
1975 UnpredCost += Subtarget.getMispredictionPenalty() * ScalingUpFactor / 10;
1978 return PredCost <= UnpredCost;
1986 return Subtarget.isProfitableToUnpredicate();
1993 unsigned &PredReg) {
2009 if (Opc == ARM::t2B)
2018 unsigned OpIdx2)
const {
2021 case ARM::t2MOVCCr: {
2023 unsigned PredReg = 0;
2026 if (CC ==
ARMCC::AL || PredReg != ARM::CPSR)
2073 bool DontMoveAcrossStores =
true;
2081 unsigned &TrueOp,
unsigned &FalseOp,
2082 bool &Optimizable)
const {
2084 "Unknown select instruction");
2103 bool PreferFalse)
const {
2105 "Unknown select instruction");
2108 bool Invert = !
DefMI;
2128 for (
unsigned i = 1, e = DefDesc.getNumOperands();
2129 i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
2148 NewMI.
add(FalseReg);
2153 SeenMIs.
erase(DefMI);
2179 {ARM::ADDSri, ARM::ADDri},
2180 {ARM::ADDSrr, ARM::ADDrr},
2181 {ARM::ADDSrsi, ARM::ADDrsi},
2182 {ARM::ADDSrsr, ARM::ADDrsr},
2184 {ARM::SUBSri, ARM::SUBri},
2185 {ARM::SUBSrr, ARM::SUBrr},
2186 {ARM::SUBSrsi, ARM::SUBrsi},
2187 {ARM::SUBSrsr, ARM::SUBrsr},
2189 {ARM::RSBSri, ARM::RSBri},
2190 {ARM::RSBSrsi, ARM::RSBrsi},
2191 {ARM::RSBSrsr, ARM::RSBrsr},
2193 {ARM::tADDSi3, ARM::tADDi3},
2194 {ARM::tADDSi8, ARM::tADDi8},
2195 {ARM::tADDSrr, ARM::tADDrr},
2196 {ARM::tADCS, ARM::tADC},
2198 {ARM::tSUBSi3, ARM::tSUBi3},
2199 {ARM::tSUBSi8, ARM::tSUBi8},
2200 {ARM::tSUBSrr, ARM::tSUBrr},
2201 {ARM::tSBCS, ARM::tSBC},
2202 {ARM::tRSBS, ARM::tRSB},
2204 {ARM::t2ADDSri, ARM::t2ADDri},
2205 {ARM::t2ADDSrr, ARM::t2ADDrr},
2206 {ARM::t2ADDSrs, ARM::t2ADDrs},
2208 {ARM::t2SUBSri, ARM::t2SUBri},
2209 {ARM::t2SUBSrr, ARM::t2SUBrr},
2210 {ARM::t2SUBSrs, ARM::t2SUBrs},
2212 {ARM::t2RSBSri, ARM::t2RSBri},
2213 {ARM::t2RSBSrs, ARM::t2RSBrs},
2217 for (
unsigned i = 0, e =
array_lengthof(AddSubFlagsOpcodeMap); i != e; ++i)
2218 if (OldOpc == AddSubFlagsOpcodeMap[i].PseudoOpc)
2225 const DebugLoc &dl,
unsigned DestReg,
2226 unsigned BaseReg,
int NumBytes,
2230 if (NumBytes == 0 && DestReg != BaseReg) {
2231 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
2239 bool isSub = NumBytes < 0;
2240 if (isSub) NumBytes = -NumBytes;
2245 assert(ThisVal &&
"Didn't extract field correctly");
2248 NumBytes &= ~ThisVal;
2253 unsigned Opc = isSub ? ARM::SUBri : ARM::ADDri;
2254 BuildMI(MBB, MBBI, dl, TII.get(Opc), DestReg)
2266 unsigned NumBytes) {
2277 if (!IsPush && !IsPop)
2280 bool IsVFPPushPop = MI->
getOpcode() == ARM::VSTMDDB_UPD ||
2282 bool IsT1PushPop = MI->
getOpcode() == ARM::tPUSH ||
2288 "trying to fold sp update into non-sp-updating push/pop");
2293 if (NumBytes % (IsVFPPushPop ? 8 : 4) != 0)
2298 int RegListIdx = IsT1PushPop ? 2 : 4;
2301 unsigned RegsNeeded;
2304 RegsNeeded = NumBytes / 8;
2305 RegClass = &ARM::DPRRegClass;
2307 RegsNeeded = NumBytes / 4;
2308 RegClass = &ARM::GPRRegClass;
2318 unsigned FirstRegEnc = -1;
2332 for (
int CurRegEnc = FirstRegEnc - 1; CurRegEnc >= 0 && RegsNeeded;
2334 unsigned CurReg = RegClass->
getRegister(CurRegEnc);
2340 false,
false,
true));
2377 for (
int i = RegList.
size() - 1; i >= 0; --i)
2378 MIB.
add(RegList[i]);
2384 unsigned FrameReg,
int &
Offset,
2395 if (Opcode == ARM::ADDri) {
2399 MI.
setDesc(TII.get(ARM::MOVr));
2404 }
else if (Offset < 0) {
2407 MI.
setDesc(TII.get(ARM::SUBri));
2425 Offset &= ~ThisImmVal;
2429 "Bit extraction didn't work?");
2432 unsigned ImmIdx = 0;
2434 unsigned NumBits = 0;
2438 ImmIdx = FrameRegIdx + 1;
2443 ImmIdx = FrameRegIdx+2;
2450 ImmIdx = FrameRegIdx+2;
2461 ImmIdx = FrameRegIdx+1;
2469 ImmIdx = FrameRegIdx+1;
2480 Offset += InstrOffs * Scale;
2481 assert((Offset & (Scale-1)) == 0 &&
"Can't encode this offset!");
2491 int ImmedOffset = Offset / Scale;
2492 unsigned Mask = (1 << NumBits) - 1;
2493 if ((
unsigned)Offset <= Mask * Scale) {
2501 ImmedOffset = -ImmedOffset;
2503 ImmedOffset |= 1 << NumBits;
2511 ImmedOffset = ImmedOffset &
Mask;
2514 ImmedOffset = -ImmedOffset;
2516 ImmedOffset |= 1 << NumBits;
2519 Offset &= ~(Mask*Scale);
2523 Offset = (isSub) ? -Offset : Offset;
2532 unsigned &SrcReg2,
int &CmpMask,
2533 int &CmpValue)
const {
2568 int CmpMask,
bool CommonUse) {
2621 unsigned SrcReg,
unsigned SrcReg2,
2653 default:
return false;
2716 MachineInstr &CmpInstr,
unsigned SrcReg,
unsigned SrcReg2,
int CmpMask,
2720 if (!MI)
return false;
2723 if (CmpMask != ~0) {
2729 if (UI->getParent() != CmpInstr.
getParent())
2738 if (!MI)
return false;
2747 if (I == B)
return false;
2763 if (CmpInstr.
getOpcode() == ARM::CMPri ||
2770 bool IsThumb1 =
false;
2786 if (MI && IsThumb1) {
2788 bool CanReorder =
true;
2789 const bool HasStmts = I !=
E;
2790 for (; I !=
E; --
I) {
2791 if (I->getOpcode() != ARM::tMOVi8) {
2796 if (HasStmts && CanReorder) {
2834 if (!MI) MI = SubAdd;
2848 bool isSafe =
false;
2851 while (!isSafe && ++I != E) {
2854 !isSafe && IO != EO; ++IO) {
2868 bool IsInstrVSel =
true;
2871 IsInstrVSel =
false;
2901 bool IsSub = Opc == ARM::SUBrr || Opc == ARM::t2SUBrr ||
2902 Opc == ARM::SUBri || Opc == ARM::t2SUBri;
2903 if (!IsSub || (SrcReg2 != 0 && SubAdd->
getOperand(1).
getReg() == SrcReg2 &&
2913 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
2948 if ((*SI)->isLiveIn(ARM::CPSR))
2964 for (
unsigned i = 0, e = OperandsToUpdate.
size(); i < e; i++)
2965 OperandsToUpdate[i].
first->setImm(OperandsToUpdate[i].second);
2980 unsigned SrcReg, SrcReg2;
2981 int CmpMask, CmpValue;
2994 if (DefOpc != ARM::t2MOVi32imm && DefOpc != ARM::MOVi32imm)
3023 unsigned NewUseOpc = 0;
3025 uint32_t SOImmValV1 = 0, SOImmValV2 = 0;
3026 bool Commute =
false;
3028 default:
return false;
3036 case ARM::t2EORrr: {
3042 if (UseOpc == ARM::SUBrr && Commute)
3048 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::ADDri : ARM::SUBri;
3051 NewUseOpc = UseOpc == ARM::ADDrr ? ARM::SUBri : ARM::ADDri;
3065 case ARM::ORRrr: NewUseOpc = ARM::ORRri;
break;
3066 case ARM::EORrr: NewUseOpc = ARM::EORri;
break;
3071 if (UseOpc == ARM::t2SUBrr && Commute)
3077 NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2ADDri : ARM::t2SUBri;
3080 NewUseOpc = UseOpc == ARM::t2ADDrr ? ARM::t2SUBri : ARM::t2ADDri;
3094 case ARM::t2ORRrr: NewUseOpc = ARM::t2ORRri;
break;
3095 case ARM::t2EORrr: NewUseOpc = ARM::t2EORri;
break;
3102 unsigned OpIdx = Commute ? 2 : 1;
3112 UseMI.
setDesc(
get(NewUseOpc));
3126 assert(UOps >= 0 &&
"bad # UOps");
3139 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3155 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3165 case ARM::LDRSB_POST:
3166 case ARM::LDRSH_POST: {
3169 return (Rt == Rm) ? 4 : 3;
3172 case ARM::LDR_PRE_REG:
3173 case ARM::LDRB_PRE_REG: {
3183 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3189 case ARM::STR_PRE_REG:
3190 case ARM::STRB_PRE_REG: {
3196 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3203 case ARM::STRH_PRE: {
3213 case ARM::LDR_POST_REG:
3214 case ARM::LDRB_POST_REG:
3215 case ARM::LDRH_POST: {
3218 return (Rt == Rm) ? 3 : 2;
3221 case ARM::LDR_PRE_IMM:
3222 case ARM::LDRB_PRE_IMM:
3223 case ARM::LDR_POST_IMM:
3224 case ARM::LDRB_POST_IMM:
3225 case ARM::STRB_POST_IMM:
3226 case ARM::STRB_POST_REG:
3227 case ARM::STRB_PRE_IMM:
3228 case ARM::STRH_POST:
3229 case ARM::STR_POST_IMM:
3230 case ARM::STR_POST_REG:
3231 case ARM::STR_PRE_IMM:
3234 case ARM::LDRSB_PRE:
3235 case ARM::LDRSH_PRE: {
3247 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3260 return (Rt == Rn) ? 3 : 2;
3271 case ARM::LDRD_POST:
3272 case ARM::t2LDRD_POST:
3275 case ARM::STRD_POST:
3276 case ARM::t2STRD_POST:
3279 case ARM::LDRD_PRE: {
3286 return (Rt == Rn) ? 4 : 3;
3289 case ARM::t2LDRD_PRE: {
3292 return (Rt == Rn) ? 4 : 3;
3295 case ARM::STRD_PRE: {
3303 case ARM::t2STRD_PRE:
3306 case ARM::t2LDR_POST:
3307 case ARM::t2LDRB_POST:
3308 case ARM::t2LDRB_PRE:
3309 case ARM::t2LDRSBi12:
3310 case ARM::t2LDRSBi8:
3311 case ARM::t2LDRSBpci:
3313 case ARM::t2LDRH_POST:
3314 case ARM::t2LDRH_PRE:
3316 case ARM::t2LDRSB_POST:
3317 case ARM::t2LDRSB_PRE:
3318 case ARM::t2LDRSH_POST:
3319 case ARM::t2LDRSH_PRE:
3320 case ARM::t2LDRSHi12:
3321 case ARM::t2LDRSHi8:
3322 case ARM::t2LDRSHpci:
3326 case ARM::t2LDRDi8: {
3329 return (Rt == Rn) ? 3 : 2;
3332 case ARM::t2STRB_POST:
3333 case ARM::t2STRB_PRE:
3336 case ARM::t2STRH_POST:
3337 case ARM::t2STRH_PRE:
3339 case ARM::t2STR_POST:
3340 case ARM::t2STR_PRE:
3373 Size += (*I)->getSize();
3380 unsigned UOps = 1 + NumRegs;
3384 case ARM::VLDMDIA_UPD:
3385 case ARM::VLDMDDB_UPD:
3386 case ARM::VLDMSIA_UPD:
3387 case ARM::VLDMSDB_UPD:
3388 case ARM::VSTMDIA_UPD:
3389 case ARM::VSTMDDB_UPD:
3390 case ARM::VSTMSIA_UPD:
3391 case ARM::VSTMSDB_UPD:
3392 case ARM::LDMIA_UPD:
3393 case ARM::LDMDA_UPD:
3394 case ARM::LDMDB_UPD:
3395 case ARM::LDMIB_UPD:
3396 case ARM::STMIA_UPD:
3397 case ARM::STMDA_UPD:
3398 case ARM::STMDB_UPD:
3399 case ARM::STMIB_UPD:
3400 case ARM::tLDMIA_UPD:
3401 case ARM::tSTMIA_UPD:
3402 case ARM::t2LDMIA_UPD:
3403 case ARM::t2LDMDB_UPD:
3404 case ARM::t2STMIA_UPD:
3405 case ARM::t2STMDB_UPD:
3408 case ARM::LDMIA_RET:
3410 case ARM::t2LDMIA_RET:
3419 if (!ItinData || ItinData->
isEmpty())
3425 if (ItinUOps >= 0) {
3451 case ARM::VLDMDIA_UPD:
3452 case ARM::VLDMDDB_UPD:
3454 case ARM::VLDMSIA_UPD:
3455 case ARM::VLDMSDB_UPD:
3457 case ARM::VSTMDIA_UPD:
3458 case ARM::VSTMDDB_UPD:
3460 case ARM::VSTMSIA_UPD:
3461 case ARM::VSTMSDB_UPD: {
3463 return (NumRegs / 2) + (NumRegs % 2) + 1;
3466 case ARM::LDMIA_RET:
3471 case ARM::LDMIA_UPD:
3472 case ARM::LDMDA_UPD:
3473 case ARM::LDMDB_UPD:
3474 case ARM::LDMIB_UPD:
3479 case ARM::STMIA_UPD:
3480 case ARM::STMDA_UPD:
3481 case ARM::STMDB_UPD:
3482 case ARM::STMIB_UPD:
3484 case ARM::tLDMIA_UPD:
3485 case ARM::tSTMIA_UPD:
3489 case ARM::t2LDMIA_RET:
3492 case ARM::t2LDMIA_UPD:
3493 case ARM::t2LDMDB_UPD:
3496 case ARM::t2STMIA_UPD:
3497 case ARM::t2STMDB_UPD: {
3499 switch (Subtarget.getLdStMultipleTiming()) {
3510 unsigned UOps = (NumRegs / 2);
3516 unsigned UOps = (NumRegs / 2);
3534 unsigned DefIdx,
unsigned DefAlign)
const {
3541 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3543 DefCycle = RegNo / 2 + 1;
3546 }
else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3548 bool isSLoad =
false;
3553 case ARM::VLDMSIA_UPD:
3554 case ARM::VLDMSDB_UPD:
3561 if ((isSLoad && (RegNo % 2)) || DefAlign < 8)
3565 DefCycle = RegNo + 2;
3575 if (
Op.isReg() &&
Op.getReg() == BaseReg)
3591 unsigned DefIdx,
unsigned DefAlign)
const {
3598 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3601 DefCycle = RegNo / 2;
3606 }
else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3607 DefCycle = (RegNo / 2);
3610 if ((RegNo % 2) || DefAlign < 8)
3616 DefCycle = RegNo + 2;
3626 unsigned UseIdx,
unsigned UseAlign)
const {
3632 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3634 UseCycle = RegNo / 2 + 1;
3637 }
else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3639 bool isSStore =
false;
3644 case ARM::VSTMSIA_UPD:
3645 case ARM::VSTMSDB_UPD:
3652 if ((isSStore && (RegNo % 2)) || UseAlign < 8)
3656 UseCycle = RegNo + 2;
3666 unsigned UseIdx,
unsigned UseAlign)
const {
3672 if (Subtarget.isCortexA8() || Subtarget.isCortexA7()) {
3673 UseCycle = RegNo / 2;
3678 }
else if (Subtarget.isLikeA9() || Subtarget.isSwift()) {
3679 UseCycle = (RegNo / 2);
3682 if ((RegNo % 2) || UseAlign < 8)
3694 unsigned DefIdx,
unsigned DefAlign,
3696 unsigned UseIdx,
unsigned UseAlign)
const {
3707 bool LdmBypass =
false;
3714 case ARM::VLDMDIA_UPD:
3715 case ARM::VLDMDDB_UPD:
3717 case ARM::VLDMSIA_UPD:
3718 case ARM::VLDMSDB_UPD:
3719 DefCycle = getVLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3722 case ARM::LDMIA_RET:
3727 case ARM::LDMIA_UPD:
3728 case ARM::LDMDA_UPD:
3729 case ARM::LDMDB_UPD:
3730 case ARM::LDMIB_UPD:
3732 case ARM::tLDMIA_UPD:
3734 case ARM::t2LDMIA_RET:
3737 case ARM::t2LDMIA_UPD:
3738 case ARM::t2LDMDB_UPD:
3740 DefCycle = getLDMDefCycle(ItinData, DefMCID, DefClass, DefIdx, DefAlign);
3755 case ARM::VSTMDIA_UPD:
3756 case ARM::VSTMDDB_UPD:
3758 case ARM::VSTMSIA_UPD:
3759 case ARM::VSTMSDB_UPD:
3760 UseCycle = getVSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3767 case ARM::STMIA_UPD:
3768 case ARM::STMDA_UPD:
3769 case ARM::STMDB_UPD:
3770 case ARM::STMIB_UPD:
3771 case ARM::tSTMIA_UPD:
3776 case ARM::t2STMIA_UPD:
3777 case ARM::t2STMDB_UPD:
3778 UseCycle = getSTMUseCycle(ItinData, UseMCID, UseClass, UseIdx, UseAlign);
3786 UseCycle = DefCycle - UseCycle + 1;
3795 UseClass, UseIdx)) {
3805 unsigned &DefIdx,
unsigned &Dist) {
3810 assert(II->isInsideBundle() &&
"Empty bundle?");
3813 while (II->isInsideBundle()) {
3814 Idx = II->findRegisterDefOperandIdx(Reg,
false,
true, TRI);
3821 assert(Idx != -1 &&
"Cannot find bundled definition!");
3828 unsigned &UseIdx,
unsigned &Dist) {
3832 assert(II->isInsideBundle() &&
"Empty bundle?");
3837 while (II != E && II->isInsideBundle()) {
3838 Idx = II->findRegisterUseOperandIdx(Reg,
false, TRI);
3841 if (II->getOpcode() != ARM::t2IT)
3879 case ARM::t2LDRSHs: {
3882 if (ShAmt == 0 || ShAmt == 2)
3887 }
else if (Subtarget.
isSwift()) {
3899 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
3910 case ARM::t2LDRSHs: {
3913 if (ShAmt == 0 || ShAmt == 1 || ShAmt == 2 || ShAmt == 3)
3927 case ARM::VLD1q8wb_fixed:
3928 case ARM::VLD1q16wb_fixed:
3929 case ARM::VLD1q32wb_fixed:
3930 case ARM::VLD1q64wb_fixed:
3931 case ARM::VLD1q8wb_register:
3932 case ARM::VLD1q16wb_register:
3933 case ARM::VLD1q32wb_register:
3934 case ARM::VLD1q64wb_register:
3941 case ARM::VLD2d8wb_fixed:
3942 case ARM::VLD2d16wb_fixed:
3943 case ARM::VLD2d32wb_fixed:
3944 case ARM::VLD2q8wb_fixed:
3945 case ARM::VLD2q16wb_fixed:
3946 case ARM::VLD2q32wb_fixed:
3947 case ARM::VLD2d8wb_register:
3948 case ARM::VLD2d16wb_register:
3949 case ARM::VLD2d32wb_register:
3950 case ARM::VLD2q8wb_register:
3951 case ARM::VLD2q16wb_register:
3952 case ARM::VLD2q32wb_register:
3957 case ARM::VLD3d8_UPD:
3958 case ARM::VLD3d16_UPD:
3959 case ARM::VLD3d32_UPD:
3960 case ARM::VLD1d64Twb_fixed:
3961 case ARM::VLD1d64Twb_register:
3962 case ARM::VLD3q8_UPD:
3963 case ARM::VLD3q16_UPD:
3964 case ARM::VLD3q32_UPD:
3969 case ARM::VLD4d8_UPD:
3970 case ARM::VLD4d16_UPD:
3971 case ARM::VLD4d32_UPD:
3972 case ARM::VLD1d64Qwb_fixed:
3973 case ARM::VLD1d64Qwb_register:
3974 case ARM::VLD4q8_UPD:
3975 case ARM::VLD4q16_UPD:
3976 case ARM::VLD4q32_UPD:
3977 case ARM::VLD1DUPq8:
3978 case ARM::VLD1DUPq16:
3979 case ARM::VLD1DUPq32:
3980 case ARM::VLD1DUPq8wb_fixed:
3981 case ARM::VLD1DUPq16wb_fixed:
3982 case ARM::VLD1DUPq32wb_fixed:
3983 case ARM::VLD1DUPq8wb_register:
3984 case ARM::VLD1DUPq16wb_register:
3985 case ARM::VLD1DUPq32wb_register:
3986 case ARM::VLD2DUPd8:
3987 case ARM::VLD2DUPd16:
3988 case ARM::VLD2DUPd32:
3989 case ARM::VLD2DUPd8wb_fixed:
3990 case ARM::VLD2DUPd16wb_fixed:
3991 case ARM::VLD2DUPd32wb_fixed:
3992 case ARM::VLD2DUPd8wb_register:
3993 case ARM::VLD2DUPd16wb_register:
3994 case ARM::VLD2DUPd32wb_register:
3995 case ARM::VLD4DUPd8:
3996 case ARM::VLD4DUPd16:
3997 case ARM::VLD4DUPd32:
3998 case ARM::VLD4DUPd8_UPD:
3999 case ARM::VLD4DUPd16_UPD:
4000 case ARM::VLD4DUPd32_UPD:
4002 case ARM::VLD1LNd16:
4003 case ARM::VLD1LNd32:
4004 case ARM::VLD1LNd8_UPD:
4005 case ARM::VLD1LNd16_UPD:
4006 case ARM::VLD1LNd32_UPD:
4008 case ARM::VLD2LNd16:
4009 case ARM::VLD2LNd32:
4010 case ARM::VLD2LNq16:
4011 case ARM::VLD2LNq32:
4012 case ARM::VLD2LNd8_UPD:
4013 case ARM::VLD2LNd16_UPD:
4014 case ARM::VLD2LNd32_UPD:
4015 case ARM::VLD2LNq16_UPD:
4016 case ARM::VLD2LNq32_UPD:
4018 case ARM::VLD4LNd16:
4019 case ARM::VLD4LNd32:
4020 case ARM::VLD4LNq16:
4021 case ARM::VLD4LNq32:
4022 case ARM::VLD4LNd8_UPD:
4023 case ARM::VLD4LNd16_UPD:
4024 case ARM::VLD4LNd32_UPD:
4025 case ARM::VLD4LNq16_UPD:
4026 case ARM::VLD4LNq32_UPD:
4040 unsigned UseIdx)
const {
4042 if (!ItinData || ItinData->
isEmpty())
4049 unsigned DefAdj = 0;
4059 unsigned UseAdj = 0;
4067 return getOperandLatencyImpl(
4068 ItinData, *ResolvedDefMI, DefIdx, ResolvedDefMI->
getDesc(), DefAdj, DefMO,
4069 Reg, *ResolvedUseMI, UseIdx, ResolvedUseMI->getDesc(), UseAdj);
4072 int ARMBaseInstrInfo::getOperandLatencyImpl(
4074 unsigned DefIdx,
const MCInstrDesc &DefMCID,
unsigned DefAdj,
4076 unsigned UseIdx,
const MCInstrDesc &UseMCID,
unsigned UseAdj)
const {
4077 if (Reg == ARM::CPSR) {
4080 return Subtarget.isLikeA9() ? 1 : 20;
4088 unsigned Latency = getInstrLatency(ItinData, DefMI);
4094 if (Latency > 0 && Subtarget.isThumb2()) {
4121 int Adj = DefAdj + UseAdj;
4125 if (Adj >= 0 || (
int)Latency > -Adj) {
4126 return Latency + Adj;
4134 SDNode *DefNode,
unsigned DefIdx,
4135 SDNode *UseNode,
unsigned UseIdx)
const {
4141 if (isZeroCost(DefMCID.
Opcode))
4144 if (!ItinData || ItinData->
isEmpty())
4145 return DefMCID.
mayLoad() ? 3 : 1;
4149 int Adj = Subtarget.getPreISelOperandLatencyAdjustment();
4151 return Latency <= Threshold ? 1 : Latency - Adj;
4162 UseMCID, UseIdx, UseAlign);
4165 (Subtarget.isCortexA8() || Subtarget.isLikeA9() ||
4166 Subtarget.isCortexA7())) {
4174 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4184 case ARM::t2LDRSHs: {
4187 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4188 if (ShAmt == 0 || ShAmt == 2)
4193 }
else if (DefIdx == 0 && Latency > 2 && Subtarget.isSwift()) {
4201 cast<ConstantSDNode>(DefNode->
getOperand(2))->getZExtValue();
4204 ((ShImm == 1 || ShImm == 2 || ShImm == 3) &&
4221 if (DefAlign < 8 && Subtarget.checkVLDnAccessAlignment())
4228 case ARM::VLD1q8wb_register:
4229 case ARM::VLD1q16wb_register:
4230 case ARM::VLD1q32wb_register:
4231 case ARM::VLD1q64wb_register:
4232 case ARM::VLD1q8wb_fixed:
4233 case ARM::VLD1q16wb_fixed:
4234 case ARM::VLD1q32wb_fixed:
4235 case ARM::VLD1q64wb_fixed:
4239 case ARM::VLD2q8Pseudo:
4240 case ARM::VLD2q16Pseudo:
4241 case ARM::VLD2q32Pseudo:
4242 case ARM::VLD2d8wb_fixed:
4243 case ARM::VLD2d16wb_fixed:
4244 case ARM::VLD2d32wb_fixed:
4245 case ARM::VLD2q8PseudoWB_fixed:
4246 case ARM::VLD2q16PseudoWB_fixed:
4247 case ARM::VLD2q32PseudoWB_fixed:
4248 case ARM::VLD2d8wb_register:
4249 case ARM::VLD2d16wb_register:
4250 case ARM::VLD2d32wb_register:
4251 case ARM::VLD2q8PseudoWB_register:
4252 case ARM::VLD2q16PseudoWB_register:
4253 case ARM::VLD2q32PseudoWB_register:
4254 case ARM::VLD3d8Pseudo:
4255 case ARM::VLD3d16Pseudo:
4256 case ARM::VLD3d32Pseudo:
4257 case ARM::VLD1d8TPseudo:
4258 case ARM::VLD1d16TPseudo:
4259 case ARM::VLD1d32TPseudo:
4260 case ARM::VLD1d64TPseudo:
4261 case ARM::VLD1d64TPseudoWB_fixed:
4262 case ARM::VLD1d64TPseudoWB_register:
4263 case ARM::VLD3d8Pseudo_UPD:
4264 case ARM::VLD3d16Pseudo_UPD:
4265 case ARM::VLD3d32Pseudo_UPD:
4266 case ARM::VLD3q8Pseudo_UPD:
4267 case ARM::VLD3q16Pseudo_UPD:
4268 case ARM::VLD3q32Pseudo_UPD:
4269 case ARM::VLD3q8oddPseudo:
4270 case ARM::VLD3q16oddPseudo:
4271 case ARM::VLD3q32oddPseudo:
4272 case ARM::VLD3q8oddPseudo_UPD:
4273 case ARM::VLD3q16oddPseudo_UPD:
4274 case ARM::VLD3q32oddPseudo_UPD:
4275 case ARM::VLD4d8Pseudo:
4276 case ARM::VLD4d16Pseudo:
4277 case ARM::VLD4d32Pseudo:
4278 case ARM::VLD1d8QPseudo:
4279 case ARM::VLD1d16QPseudo:
4280 case ARM::VLD1d32QPseudo:
4281 case ARM::VLD1d64QPseudo:
4282 case ARM::VLD1d64QPseudoWB_fixed:
4283 case ARM::VLD1d64QPseudoWB_register:
4284 case ARM::VLD1q8HighQPseudo:
4285 case ARM::VLD1q8LowQPseudo_UPD:
4286 case ARM::VLD1q8HighTPseudo:
4287 case ARM::VLD1q8LowTPseudo_UPD:
4288 case ARM::VLD1q16HighQPseudo:
4289 case ARM::VLD1q16LowQPseudo_UPD:
4290 case ARM::VLD1q16HighTPseudo:
4291 case ARM::VLD1q16LowTPseudo_UPD:
4292 case ARM::VLD1q32HighQPseudo:
4293 case ARM::VLD1q32LowQPseudo_UPD:
4294 case ARM::VLD1q32HighTPseudo:
4295 case ARM::VLD1q32LowTPseudo_UPD:
4296 case ARM::VLD1q64HighQPseudo:
4297 case ARM::VLD1q64LowQPseudo_UPD:
4298 case ARM::VLD1q64HighTPseudo:
4299 case ARM::VLD1q64LowTPseudo_UPD:
4300 case ARM::VLD4d8Pseudo_UPD:
4301 case ARM::VLD4d16Pseudo_UPD:
4302 case ARM::VLD4d32Pseudo_UPD:
4303 case ARM::VLD4q8Pseudo_UPD:
4304 case ARM::VLD4q16Pseudo_UPD:
4305 case ARM::VLD4q32Pseudo_UPD:
4306 case ARM::VLD4q8oddPseudo:
4307 case ARM::VLD4q16oddPseudo:
4308 case ARM::VLD4q32oddPseudo:
4309 case ARM::VLD4q8oddPseudo_UPD:
4310 case ARM::VLD4q16oddPseudo_UPD:
4311 case ARM::VLD4q32oddPseudo_UPD:
4312 case ARM::VLD1DUPq8:
4313 case ARM::VLD1DUPq16:
4314 case ARM::VLD1DUPq32:
4315 case ARM::VLD1DUPq8wb_fixed:
4316 case ARM::VLD1DUPq16wb_fixed:
4317 case ARM::VLD1DUPq32wb_fixed:
4318 case ARM::VLD1DUPq8wb_register:
4319 case ARM::VLD1DUPq16wb_register:
4320 case ARM::VLD1DUPq32wb_register:
4321 case ARM::VLD2DUPd8:
4322 case ARM::VLD2DUPd16:
4323 case ARM::VLD2DUPd32:
4324 case ARM::VLD2DUPd8wb_fixed:
4325 case ARM::VLD2DUPd16wb_fixed:
4326 case ARM::VLD2DUPd32wb_fixed:
4327 case ARM::VLD2DUPd8wb_register:
4328 case ARM::VLD2DUPd16wb_register:
4329 case ARM::VLD2DUPd32wb_register:
4330 case ARM::VLD2DUPq8EvenPseudo:
4331 case ARM::VLD2DUPq8OddPseudo:
4332 case ARM::VLD2DUPq16EvenPseudo:
4333 case ARM::VLD2DUPq16OddPseudo:
4334 case ARM::VLD2DUPq32EvenPseudo:
4335 case ARM::VLD2DUPq32OddPseudo:
4336 case ARM::VLD3DUPq8EvenPseudo:
4337 case ARM::VLD3DUPq8OddPseudo:
4338 case ARM::VLD3DUPq16EvenPseudo:
4339 case ARM::VLD3DUPq16OddPseudo:
4340 case ARM::VLD3DUPq32EvenPseudo:
4341 case ARM::VLD3DUPq32OddPseudo:
4342 case ARM::VLD4DUPd8Pseudo:
4343 case ARM::VLD4DUPd16Pseudo:
4344 case ARM::VLD4DUPd32Pseudo:
4345 case ARM::VLD4DUPd8Pseudo_UPD:
4346 case ARM::VLD4DUPd16Pseudo_UPD:
4347 case ARM::VLD4DUPd32Pseudo_UPD:
4348 case ARM::VLD4DUPq8EvenPseudo:
4349 case ARM::VLD4DUPq8OddPseudo:
4350 case ARM::VLD4DUPq16EvenPseudo:
4351 case ARM::VLD4DUPq16OddPseudo:
4352 case ARM::VLD4DUPq32EvenPseudo:
4353 case ARM::VLD4DUPq32OddPseudo:
4354 case ARM::VLD1LNq8Pseudo:
4355 case ARM::VLD1LNq16Pseudo:
4356 case ARM::VLD1LNq32Pseudo:
4357 case ARM::VLD1LNq8Pseudo_UPD:
4358 case ARM::VLD1LNq16Pseudo_UPD:
4359 case ARM::VLD1LNq32Pseudo_UPD:
4360 case ARM::VLD2LNd8Pseudo:
4361 case ARM::VLD2LNd16Pseudo:
4362 case ARM::VLD2LNd32Pseudo:
4363 case ARM::VLD2LNq16Pseudo:
4364 case ARM::VLD2LNq32Pseudo:
4365 case ARM::VLD2LNd8Pseudo_UPD:
4366 case ARM::VLD2LNd16Pseudo_UPD:
4367 case ARM::VLD2LNd32Pseudo_UPD:
4368 case ARM::VLD2LNq16Pseudo_UPD:
4369 case ARM::VLD2LNq32Pseudo_UPD:
4370 case ARM::VLD4LNd8Pseudo:
4371 case ARM::VLD4LNd16Pseudo:
4372 case ARM::VLD4LNd32Pseudo:
4373 case ARM::VLD4LNq16Pseudo:
4374 case ARM::VLD4LNq32Pseudo:
4375 case ARM::VLD4LNd8Pseudo_UPD:
4376 case ARM::VLD4LNd16Pseudo_UPD:
4377 case ARM::VLD4LNd32Pseudo_UPD:
4378 case ARM::VLD4LNq16Pseudo_UPD:
4379 case ARM::VLD4LNq32Pseudo_UPD:
4389 unsigned ARMBaseInstrInfo::getPredicationCost(
const MachineInstr &MI)
const {
4400 !Subtarget.cheapPredicableCPSRDef())) {
4410 unsigned *PredCost)
const {
4421 while (++I != E && I->isInsideBundle()) {
4422 if (I->getOpcode() != ARM::t2IT)
4423 Latency += getInstrLatency(ItinData, *I, PredCost);
4430 !Subtarget.cheapPredicableCPSRDef()))) {
4453 if (Adj >= 0 || (
int)Latency > -Adj) {
4454 return Latency + Adj;
4464 if (!ItinData || ItinData->
isEmpty())
4477 bool ARMBaseInstrInfo::hasHighOperandLatency(
const TargetSchedModel &SchedModel,
4482 unsigned UseIdx)
const {
4485 if (Subtarget.nonpipelinedVFP() &&
4498 bool ARMBaseInstrInfo::hasLowDefLatency(
const TargetSchedModel &SchedModel,
4500 unsigned DefIdx)
const {
4502 if (!ItinData || ItinData->
isEmpty())
4509 return (DefCycle != -1 && DefCycle <= 2);
4514 bool ARMBaseInstrInfo::verifyInstruction(
const MachineInstr &MI,
4517 ErrInfo =
"Pseudo flag setting opcodes only exist in Selection DAG";
4526 unsigned LoadImmOpc,
4527 unsigned LoadOpc)
const {
4528 assert(!Subtarget.isROPI() && !Subtarget.isRWPI() &&
4529 "ROPI/RWPI not currently supported with stack guard");
4533 unsigned Reg = MI->getOperand(0).getReg();
4535 cast<GlobalValue>((*MI->memoperands_begin())->getValue());
4538 BuildMI(MBB, MI, DL,
get(LoadImmOpc), Reg)
4541 if (Subtarget.isGVIndirectSymbol(GV)) {
4542 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4552 MIB =
BuildMI(MBB, MI, DL,
get(LoadOpc), Reg);
4561 unsigned &AddSubOpc,
4562 bool &NegAcc,
bool &HasLane)
const {
4564 if (I == MLxEntryMap.
end())
4595 std::pair<uint16_t, uint16_t>
4599 if (Subtarget.hasNEON()) {
4607 if (Subtarget.useNEONForFPMovs() && !
isPredicated(MI) &&
4616 return std::make_pair(
ExeNEON, 0);
4621 return std::make_pair(
ExeNEON, 0);
4624 return std::make_pair(
ExeVFP, 0);
4630 unsigned SReg,
unsigned &Lane) {
4634 if (DReg != ARM::NoRegister)
4640 assert(DReg &&
"S-register with no D super-register?");
4661 unsigned Lane,
unsigned &ImplicitSReg) {
4671 (Lane & 1) ? ARM::ssub_0 : ARM::ssub_1);
4687 unsigned Domain)
const {
4688 unsigned DstReg, SrcReg, DReg;
4704 assert(Subtarget.hasNEON() &&
"VORRd requires NEON");
4737 MI.
setDesc(
get(ARM::VGETLNi32));
4758 unsigned ImplicitSReg;
4767 MI.
setDesc(
get(ARM::VSETLNi32));
4777 if (ImplicitSReg != 0)
4789 unsigned DstLane = 0, SrcLane = 0, DDst, DSrc;
4793 unsigned ImplicitSReg;
4803 MI.
setDesc(
get(ARM::VDUPLN32d));
4813 if (ImplicitSReg != 0)
4837 unsigned CurReg = SrcLane == 1 && DstLane == 1 ? DSrc : DDst;
4841 CurReg = SrcLane == 0 && DstLane == 0 ? DSrc : DDst;
4847 if (SrcLane == DstLane)
4850 MI.
setDesc(
get(ARM::VEXTd32));
4855 CurReg = SrcLane == 1 && DstLane == 0 ? DSrc : DDst;
4856 CurUndef = CurReg == DSrc && !MI.
readsRegister(CurReg, TRI);
4859 CurReg = SrcLane == 0 && DstLane == 1 ? DSrc : DDst;
4860 CurUndef = CurReg == DSrc && !MI.
readsRegister(CurReg, TRI);
4865 if (SrcLane != DstLane)
4871 if (ImplicitSReg != 0)
4897 auto PartialUpdateClearance = Subtarget.getPartialUpdateClearance();
4898 if (!PartialUpdateClearance)
4901 assert(TRI &&
"Need TRI instance");
4906 unsigned Reg = MO.
getReg();
4915 case ARM::VMOVv4i16:
4916 case ARM::VMOVv2i32:
4917 case ARM::VMOVv2f32:
4918 case ARM::VMOVv1i64:
4923 case ARM::VLD1LNd32:
4940 }
else if (ARM::SPRRegClass.
contains(Reg)) {
4950 return PartialUpdateClearance;
4958 assert(TRI &&
"Need TRI instance");
4961 unsigned Reg = MO.
getReg();
4963 "Can't break virtual register dependencies.");
4964 unsigned DReg =
Reg;
4967 if (ARM::SPRRegClass.
contains(Reg)) {
4968 DReg = ARM::D0 + (Reg - ARM::S0) / 2;
4972 assert(ARM::DPRRegClass.
contains(DReg) &&
"Can only break D-reg deps");
4990 return Subtarget.getFeatureBits()[ARM::HasV6KOps];
5000 ((ShImm == 1 || ShImm == 2) &&
5051 InputReg.
SubIdx = DefIdx == 0 ? ARM::ssub_0 : ARM::ssub_1;
5064 case ARM::VSETLNi32:
5074 InsertedReg.
Reg = MOInsertedReg.
getReg();
5076 InsertedReg.
SubIdx = MOIndex.
getImm() == 0 ? ARM::ssub_0 : ARM::ssub_1;
5082 std::pair<unsigned, unsigned>
5085 return std::make_pair(TF & Mask, TF & ~Mask);
5090 using namespace ARMII;
5092 static const std::pair<unsigned, const char *>
TargetFlags[] = {
5099 using namespace ARMII;
5101 static const std::pair<unsigned, const char *>
TargetFlags[] = {
bool isLdstSoMinusReg(const MachineInstr &MI, unsigned Op) const
MachineConstantPoolValue * MachineCPVal
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
bool isProfitableToUnpredicate(MachineBasicBlock &TMBB, MachineBasicBlock &FMBB) const override
bool getInsertSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const override
Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
bool checkVLDnAccessAlignment() const
BranchProbability getCompl() const
int findFirstPredOperandIdx() const
Find the index of the first operand in the operand list that is used to represent the predicate...
bool isCall(QueryType Type=AnyInBundle) const
instr_iterator instr_end()
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
unsigned getT2SOImmTwoPartFirst(unsigned Imm)
bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override
This class represents lattice values for constants.
bool DefinesPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred) const override
void ChangeToRegister(unsigned Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value...
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI, unsigned Reg, const_iterator Before, unsigned Neighborhood=10) const
Return whether (physical) register Reg has been defined and not killed as of just before Before...
unsigned getRegister(unsigned i) const
Return the specified register in the class.
bool isExtractSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic EXTRACT_SUBREG instructions...
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
ARMConstantPoolValue - ARM specific constantpool value.
void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
bool expandPostRAPseudo(MachineInstr &MI) const override
void setIsUndef(bool Val=true)
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
static bool isSuitableForMask(MachineInstr *&MI, unsigned SrcReg, int CmpMask, bool CommonUse)
isSuitableForMask - Identify a suitable 'and' instruction that operates on the given source register ...
bool isPredicated(const MachineInstr &MI) const override
virtual MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const
Clones instruction or the whole instruction bundle Orig and insert into MBB before InsertBefore...
unsigned getSubReg() const
bool isPredicable(QueryType Type=AllInBundle) const
Return true if this instruction has a predicate operand that controls execution.
bool isV8EligibleForIT(const InstrType *Instr)
static unsigned getCorrespondingDRegAndLane(const TargetRegisterInfo *TRI, unsigned SReg, unsigned &Lane)
bool isRegSequence() const
unsigned computeOperandLatency(const MachineInstr *DefMI, unsigned DefOperIdx, const MachineInstr *UseMI, unsigned UseOperIdx) const
Compute operand latency based on the available machine model.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
VarInfo - This represents the regions where a virtual register is live in the program.
unsigned const TargetRegisterInfo * TRI
void setIsDead(bool Val=true)
unsigned getPartialRegUpdateClearance(const MachineInstr &, unsigned, const TargetRegisterInfo *) const override
setjmp/longjmp based exceptions
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
bool isLdstScaledRegNotPlusLsl2(const MachineInstr &MI, unsigned Op) const
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
bool mayLoad() const
Return true if this instruction could possibly read memory.
unsigned getSOImmTwoPartSecond(unsigned V)
getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of ...
iterator_range< mop_iterator > operands()
bool isCopyLike() const
Return true if the instruction behaves like a copy.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned createPICLabelUId()
static bool isThumb(const MCSubtargetInfo &STI)
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
static bool isOptimizeCompareCandidate(MachineInstr *MI, bool &IsThumb1)
return AArch64::GPR64RegClass contains(Reg)
static MachineOperand CreateReg(unsigned 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)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool removeKill(MachineInstr &MI)
removeKill - Delete a kill corresponding to the specified machine instruction.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void clearKillInfo()
Clears kill flags on all operands.
static bool isCPSRDefined(const MachineInstr &MI)
Can load/store 1 register/cycle.
static uint32_t getAlignment(const MCSectionCOFF &Sec)
bool isFpMLxInstruction(unsigned Opcode) const
isFpMLxInstruction - Return true if the specified opcode is a fp MLA / MLS instruction.
A description of a memory reference used in the backend.
MO_SBREL - On a symbol operand, this represents a static base relative relocation.
bool isMachineConstantPoolEntry() const
isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry is indeed a target specific ...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
ShiftOpc getAM2ShiftOpc(unsigned AM2Opc)
unsigned getSOImmValRotate(unsigned Imm)
getSOImmValRotate - Try to handle Imm with an immediate shifter operand, computing the rotate amount ...
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
unsigned getNumOperands() const
Retuns the total number of operands.
bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, unsigned &SrcReg2, int &CmpMask, int &CmpValue) const override
analyzeCompare - For a comparison instruction, return the source registers in SrcReg and SrcReg2 if h...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void setImplicit(bool Val=true)
static bool isLoad(int Opcode)
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx, unsigned FrameReg, int &Offset, const ARMBaseInstrInfo &TII)
rewriteARMFrameIndex / rewriteT2FrameIndex - Rewrite MI to access 'Offset' bytes from the FP...
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
const MachineInstrBuilder & AddDReg(MachineInstrBuilder &MIB, unsigned Reg, unsigned SubIdx, unsigned State, const TargetRegisterInfo *TRI) const
void setExecutionDomain(MachineInstr &MI, unsigned Domain) const override
bool isAm2ScaledReg(const MachineInstr &MI, unsigned Op) const
The memory access is dereferenceable (i.e., doesn't trap).
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override
const InstrItineraryData * getInstrItineraries() const
bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2, int64_t Offset1, int64_t Offset2, unsigned NumLoads) const override
shouldScheduleLoadsNear - This is a used by the pre-regalloc scheduler to determine (in conjunction w...
const char * getSymbolName() const
static ARMCC::CondCodes getCmpToAddCondition(ARMCC::CondCodes CC)
getCmpToAddCondition - assume the flags are set by CMP(a,b), return the condition code if we modify t...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned 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.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
INLINEASM - Represents an inline asm block.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
defusechain_iterator - This class provides iterator support for machine operands in the function that...
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override
bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, unsigned Reg, MachineRegisterInfo *MRI) const override
FoldImmediate - 'Reg' is known to be defined by a move immediate instruction, try to fold the immedia...
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register. ...
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
unsigned char getAM3Offset(unsigned AM3Opc)
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
Commutes the operands in the given instruction.
Can load/store 2 registers/cycle, but needs an extra cycle if the access is not 64-bit aligned...
instr_iterator getInstrIterator() const
unsigned getNumMicroOps(const InstrItineraryData *ItinData, const MachineInstr &MI) const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool isThumb2Function() const
Itinerary data supplied by a subtarget to be used by a target.
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
const ARMSubtarget & getSubtarget() const
int getNumMicroOps(unsigned ItinClassIndx) const
Return the number of micro-ops that the given class decodes to.
This class is a data container for one entry in a MachineConstantPool.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
static const ARM_MLxEntry ARM_MLxTable[]
unsigned getMatchingCondBranchOpcode(unsigned Opc)
ARM_MLxEntry - Record information about MLA / MLS instructions.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
unsigned getUndefRegState(bool B)
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
Return a null-terminated list of all of the callee-saved registers on this target.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getStageLatency(unsigned ItinClassIndx) const
Return the total stage latency of the given class.
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
const TargetRegisterClass * constrainRegClass(unsigned Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
reverse_iterator rbegin()
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
BasicBlockListType::iterator iterator
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void ChangeToImmediate(int64_t ImmVal)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value...
TargetInstrInfo - Interface to description of machine instruction set.
AddrOpc getAM2Op(unsigned AM2Opc)
bool isSuperRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a super-register of RegA.
static bool isCondBranchOpcode(int Opc)
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
const Constant * ConstVal
This class is intended to be used as a base class for asm properties and features specific to the tar...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
static bool isCalleeSavedRegister(unsigned Reg, const MCPhysReg *CSRegs)
MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
unsigned char getAM5Offset(unsigned AM5Opc)
const TargetRegisterInfo * getTargetRegisterInfo() const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AddrOpc getAM3Op(unsigned AM3Opc)
unsigned const MachineRegisterInfo * MRI
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
HazardRecognizer - This determines whether or not an instruction can be issued this cycle...
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
bool readsVirtualRegister(unsigned Reg) const
Return true if the MachineInstr reads the specified virtual register.
unsigned getSORegOffset(unsigned Op)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
int getOperandLatency(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Compute and return the use operand latency of a given itinerary class and operand index if the value ...
void clearRegisterDeads(unsigned Reg)
Clear all dead flags on operands defining register Reg.
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2, int64_t &Offset1, int64_t &Offset2) const override
areLoadsFromSameBasePtr - This is used by the pre-regalloc scheduler to determine if two loads are lo...
MachineInstrBuilder & UseMI
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const SDValue & getOperand(unsigned Num) const
unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const GlobalValue * getGlobal() const
void expandLoadStackGuardBase(MachineBasicBlock::iterator MI, unsigned LoadImmOpc, unsigned LoadOpc) const
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Returns the size of the specified MachineInstr.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static bool isJumpTableBranchOpcode(int Opc)
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
bool isAddrMode3OpImm(const MachineInstr &MI, unsigned Op) const
virtual bool hasSameValue(ARMConstantPoolValue *ACPV)
hasSameValue - Return true if this ARM constpool value can share the same constantpool entry as anoth...
static bool isEligibleForITBlock(const MachineInstr *MI)
Register is known to be fully dead.
static const MachineInstr * getBundledUseMI(const TargetRegisterInfo *TRI, const MachineInstr &MI, unsigned Reg, unsigned &UseIdx, unsigned &Dist)
use_instr_iterator use_instr_begin(unsigned RegNo) const
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const PseudoSourceValue * getPseudoValue() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void setImm(int64_t immVal)
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
unsigned convertAddSubFlagsOpcode(unsigned OldOpc)
Map pseudo instructions that imply an 'S' bit onto real opcodes.
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addFrameIndex(int Idx) const
LivenessQueryResult
Possible outcome of a register liveness query to computeRegisterLiveness()
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Register is known to be (at least partially) live.
unsigned rotr32(unsigned Val, unsigned Amt)
rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
succ_iterator succ_begin()
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
bool isInsertSubregLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic INSERT_SUBREG instructions...
bool isImplicitDef() const
VarInfo & getVarInfo(unsigned RegIdx)
getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
static const MachineInstr * getBundledDefMI(const TargetRegisterInfo *TRI, const MachineInstr *MI, unsigned Reg, unsigned &DefIdx, unsigned &Dist)
bool isCopyInstrImpl(const MachineInstr &MI, const MachineOperand *&Source, const MachineOperand *&Destination) const override
If the specific machine instruction is a instruction that moves/copies value from one register to ano...
bool isDebugInstr() const
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address...
void setIsKill(bool Val=true)
void sort(IteratorTy Start, IteratorTy End)
The memory access writes data.
std::pair< uint16_t, uint16_t > getExecutionDomain(const MachineInstr &MI) const override
VFP/NEON execution domains.
const std::vector< MachineConstantPoolEntry > & getConstants() const
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
ARMConstantPoolConstant - ARM-specific constant pool values for Constants, Functions, and BlockAddresses.
static bool isIndirectBranchOpcode(int Opc)
void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const override
bool memoperands_empty() const
Iterator for intrusive lists based on ilist_node.
bool isT2SOImmTwoPartVal(unsigned Imm)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
static bool isUncondBranchOpcode(int Opc)
virtual unsigned getUnindexedOpcode(unsigned Opc) const =0
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
unsigned getLDMVariableDefsSize(const MachineInstr &MI) const
void substituteRegister(unsigned FromReg, unsigned ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
ARMConstantPoolSymbol - ARM-specific constantpool values for external symbols.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI)
Create a copy of a const pool value.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
bool isInsertSubreg() const
A pair composed of a register and a sub-register index.
MachineInstrBuilder MachineInstrBuilder & DefMI
Map pseudo instructions that imply an 'S' bit onto real opcodes.
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
void breakPartialRegDependency(MachineInstr &, unsigned, const TargetRegisterInfo *TRI) const override
An SDNode that represents everything that will be needed to construct a MachineInstr.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned char TargetFlags=0) const
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
uint64_t scale(uint64_t Num) const
Scale a large integer.
unsigned getAM2Offset(unsigned AM2Opc)
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Represents one node in the SelectionDAG.
static bool isPushOpcode(int Opc)
ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic block.
MachineInstr * getUniqueVRegDef(unsigned Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getNumLDMAddresses(const MachineInstr &MI) const
Get the number of addresses by LDM or VLDM or zero for unknown.
void addRegisterDefined(unsigned Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
union llvm::MachineConstantPoolEntry::@159 Val
The constant itself.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
void copyToCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, bool KillSrc, const ARMSubtarget &Subtarget) const
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
bool mayStore() const
Return true if this instruction could possibly modify memory.
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr *> &SeenMIs, bool) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableBitmaskMachineOperandTargetFlags() const override
ShiftOpc getSORegShOp(unsigned Op)
ARMBaseInstrInfo(const ARMSubtarget &STI)
bool isEmpty() const
Returns true if there are no itineraries.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
bool IsCPSRDead< MachineInstr >(const MachineInstr *MI)
TargetSubtargetInfo - Generic base class for all target subtargets.
MachineInstr & duplicate(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) const override
static bool isPopOpcode(int Opc)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static unsigned getNumMicroOpsSwiftLdSt(const InstrItineraryData *ItinData, const MachineInstr &MI)
bool isPredicable(const MachineInstr &MI) const override
isPredicable - Return true if the specified instruction can be predicated.
bool isRegSequenceLike(QueryType Type=IgnoreBundle) const
Return true if this instruction behaves the same way as the generic REG_SEQUENCE instructions.
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Representation of each machine instruction.
static MachineInstr * canFoldIntoMOVCC(unsigned Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Identify instructions that can be folded into a MOVCC instruction, and return the defining instructio...
mmo_iterator memoperands_begin() const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static CondCodes getOppositeCondition(CondCodes CC)
static const AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[]
bool isMoveReg(QueryType Type=IgnoreBundle) const
Return true if this instruction is a register move.
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr &MI, bool AddIfNotFound=false)
addVirtualRegisterDead - Add information about the fact that the specified register is dead after bei...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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...
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isLDMBaseRegInList(const MachineInstr &MI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool getExtractSubregLikeInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const override
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "...
LLVM_NODISCARD bool empty() const
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
MO_DLLIMPORT - On a symbol operand, this represents that the reference to the symbol is for an import...
Register liveness not decidable from local neighborhood.
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
int64_t getOffset() const
Return the offset from the symbol in this operand.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
int getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override
bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx, unsigned UseClass, unsigned UseIdx) const
Return true if there is a pipeline forwarding between instructions of itinerary classes DefClass and ...
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
bool getRegSequenceLikeInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const override
Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.
The memory access always returns the same value (or traps).
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
static bool isRedundantFlagInstr(const MachineInstr *CmpI, unsigned SrcReg, unsigned SrcReg2, int ImmValue, const MachineInstr *OI)
isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags...
bool isCall() const
Return true if the instruction is a call.
MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects just that part of the flag set...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, int CmpValue, const MachineRegisterInfo *MRI) const override
optimizeCompareInstr - Convert the instruction to set the zero flag so that we can remove a "comparis...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
bool isSwiftFastImmShift(const MachineInstr *MI) const
Returns true if the instruction has a shift by immediate that can be executed in one cycle less...
unsigned isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override
bool isAddrMode3OpMinusReg(const MachineInstr &MI, unsigned Op) const
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it. ...
bool hasOptionalDef(QueryType Type=IgnoreBundle) const
Set if this instruction has an optional definition, e.g.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void copyFromCPSR(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, bool KillSrc, const ARMSubtarget &Subtarget) const
ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override
ARMHazardRecognizer handles special constraints that are not expressed in the scheduling itinerary...
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
bool shouldSink(const MachineInstr &MI) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to Other.
unsigned getT2SOImmTwoPartSecond(unsigned Imm)
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
virtual const ARMBaseRegisterInfo & getRegisterInfo() const =0
Can load/store 1 register/cycle, but needs an extra cycle for address computation and potentially als...
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
static use_instr_iterator use_instr_end()
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const
Return the cycle for the given class and operand.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const override
MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it represents a symbol which...
unsigned getOpcode() const
Return the opcode number for this descriptor.
Can load/store 2 registers/cycle.
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
static int adjustDefLatency(const ARMSubtarget &Subtarget, const MachineInstr &DefMI, const MCInstrDesc &DefMCID, unsigned DefAlign)
Return the number of cycles to add to (or subtract from) the static itinerary based on the def opcode...
bool isLdstScaledReg(const MachineInstr &MI, unsigned Op) const
StringRef - Represent a constant reference to a string, i.e.
void RemoveOperand(unsigned OpNo)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
AddrOpc getAM5Op(unsigned AM5Opc)
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
static bool getImplicitSPRUseForDPRUse(const TargetRegisterInfo *TRI, MachineInstr &MI, unsigned DReg, unsigned Lane, unsigned &ImplicitSReg)
getImplicitSPRUseForDPRUse - Given a use of a DPR register and lane, set ImplicitSReg to a register n...
static unsigned getNumMicroOpsSingleIssuePlusExtras(unsigned Opc, unsigned NumRegs)
bool produceSameValue(const MachineInstr &MI0, const MachineInstr &MI1, const MachineRegisterInfo *MRI) const override
bool hasImplicitDefOfPhysReg(unsigned Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
const MachineOperand & getOperand(unsigned i) const
MachineInstr * convertToThreeAddress(MachineFunction::iterator &MFI, MachineInstr &MI, LiveVariables *LV) const override
bool isThumbFunction() const
unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
virtual ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
int findRegisterUseOperandIdx(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a use of the specific register or -1 if it is not found...
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one...
void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr &MI, bool AddIfNotFound=false)
addVirtualRegisterKilled - Add information about the fact that the specified register is killed after...
std::vector< MachineBasicBlock * >::iterator succ_iterator
unsigned createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address...
bool empty() const
empty - Check if the array is empty.
static cl::opt< bool > EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv"))
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
mmo_iterator memoperands_end() const
Access to memory operands of the instruction.
A pair composed of a pair of a register and a sub-register index, and another sub-register index...
unsigned isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.