45#define DEBUG_TYPE "thumb2-reduce-size"
46#define THUMB2_SIZE_REDUCE_NAME "Thumb2 instruction size reduce pass"
48STATISTIC(NumNarrows,
"Number of 32-bit instrs reduced to 16-bit ones");
49STATISTIC(Num2Addrs,
"Number of 32-bit instrs reduced to 2addr 16-bit ones");
50STATISTIC(NumLdSts,
"Number of 32-bit load / store reduced to 16-bit ones");
69 unsigned LowRegs1 : 1;
70 unsigned LowRegs2 : 1;
75 unsigned PartFlag : 1;
77 unsigned AvoidMovs: 1;
80 static const ReduceEntry ReduceTable[] = {
82 { ARM::t2ADCrr, 0, ARM::tADC, 0, 0, 0, 1, 0,0, 0,0,0 },
83 { ARM::t2ADDri, ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 0,0, 0,1,0 },
84 { ARM::t2ADDrr, ARM::tADDrr, ARM::tADDhirr, 0, 0, 1, 0, 0,1, 0,0,0 },
85 { ARM::t2ADDSri,ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 2,2, 0,1,0 },
86 { ARM::t2ADDSrr,ARM::tADDrr, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
87 { ARM::t2ANDrr, 0, ARM::tAND, 0, 0, 0, 1, 0,0, 1,0,0 },
88 { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
89 { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 1,0,1 },
90 { ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 1,0,0 },
93 { ARM::t2CMNzrr, ARM::tCMNz, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
94 { ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0,0,0 },
95 { ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0,1,0 },
96 { ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 1,0,0 },
99 { ARM::t2LSLri, ARM::tLSLri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
100 { ARM::t2LSLrr, 0, ARM::tLSLrr, 0, 0, 0, 1, 0,0, 1,0,1 },
101 { ARM::t2LSRri, ARM::tLSRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
102 { ARM::t2LSRrr, 0, ARM::tLSRrr, 0, 0, 0, 1, 0,0, 1,0,1 },
103 { ARM::t2MOVi, ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 1,0,0 },
104 { ARM::t2MOVi16,ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 1,1,0 },
106 { ARM::t2MOVr,ARM::tMOVr, 0, 0, 0, 0, 0, 1,0, 0,0,0 },
107 { ARM::t2MUL, 0, ARM::tMUL, 0, 0, 0, 1, 0,0, 1,0,0 },
108 { ARM::t2MVNr, ARM::tMVN, 0, 0, 0, 1, 0, 0,0, 0,0,0 },
109 { ARM::t2ORRrr, 0, ARM::tORR, 0, 0, 0, 1, 0,0, 1,0,0 },
110 { ARM::t2REV, ARM::tREV, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
111 { ARM::t2REV16, ARM::tREV16, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
112 { ARM::t2REVSH, ARM::tREVSH, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
113 { ARM::t2RORrr, 0, ARM::tROR, 0, 0, 0, 1, 0,0, 1,0,0 },
114 { ARM::t2RSBri, ARM::tRSB, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
115 { ARM::t2RSBSri,ARM::tRSB, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
116 { ARM::t2SBCrr, 0, ARM::tSBC, 0, 0, 0, 1, 0,0, 0,0,0 },
117 { ARM::t2SUBri, ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 0,0, 0,0,0 },
118 { ARM::t2SUBrr, ARM::tSUBrr, 0, 0, 0, 1, 0, 0,0, 0,0,0 },
119 { ARM::t2SUBSri,ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 2,2, 0,0,0 },
120 { ARM::t2SUBSrr,ARM::tSUBrr, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
121 { ARM::t2SXTB, ARM::tSXTB, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
122 { ARM::t2SXTH, ARM::tSXTH, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
123 { ARM::t2TEQrr, ARM::tEOR, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
124 { ARM::t2TSTrr, ARM::tTST, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
125 { ARM::t2UXTB, ARM::tUXTB, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
126 { ARM::t2UXTH, ARM::tUXTH, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
130 { ARM::t2LDRi12,ARM::tLDRi, ARM::tLDRspi, 5, 8, 1, 0, 0,0, 0,1,0 },
131 { ARM::t2LDRs, ARM::tLDRr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
132 { ARM::t2LDRBi12,ARM::tLDRBi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
133 { ARM::t2LDRBs, ARM::tLDRBr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
134 { ARM::t2LDRHi12,ARM::tLDRHi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
135 { ARM::t2LDRHs, ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
136 { ARM::t2LDRSBs,ARM::tLDRSB, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
137 { ARM::t2LDRSHs,ARM::tLDRSH, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
138 { ARM::t2LDR_POST,ARM::tLDMIA_UPD,0, 0, 0, 1, 0, 0,0, 0,1,0 },
139 { ARM::t2STRi12,ARM::tSTRi, ARM::tSTRspi, 5, 8, 1, 0, 0,0, 0,1,0 },
140 { ARM::t2STRs, ARM::tSTRr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
141 { ARM::t2STRBi12,ARM::tSTRBi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
142 { ARM::t2STRBs, ARM::tSTRBr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
143 { ARM::t2STRHi12,ARM::tSTRHi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
144 { ARM::t2STRHs, ARM::tSTRHr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
145 { ARM::t2STR_POST,ARM::tSTMIA_UPD,0, 0, 0, 1, 0, 0,0, 0,1,0 },
147 { ARM::t2LDMIA, ARM::tLDMIA, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
148 { ARM::t2LDMIA_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 0,1,0 },
149 { ARM::t2LDMIA_UPD,ARM::tLDMIA_UPD,ARM::tPOP,0, 0, 1, 1, 1,1, 0,1,0 },
153 { ARM::t2STMIA, ARM::tSTMIA_UPD, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
154 { ARM::t2STMIA_UPD,ARM::tSTMIA_UPD, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
155 { ARM::t2STMDB_UPD, 0, ARM::tPUSH, 0, 0, 1, 1, 1,1, 0,1,0 }
165 Thumb2SizeReduce(std::function<
bool(
const Function &)> Ftor =
nullptr);
185 bool LiveCPSR,
bool &HasCC,
bool &CCDead);
188 const ReduceEntry &Entry);
191 const ReduceEntry &Entry,
bool LiveCPSR,
bool IsSelfLoop);
196 const ReduceEntry &Entry,
bool LiveCPSR,
202 const ReduceEntry &Entry,
bool LiveCPSR,
207 bool IsSelfLoop,
bool SkipPrologueEpilogue);
219 bool HighLatencyCPSR;
223 bool HighLatencyCPSR =
false;
225 bool Visited =
false;
235 char Thumb2SizeReduce::ID = 0;
244 OptimizeSize = MinimizeSize =
false;
245 for (
unsigned i = 0, e = std::size(ReduceTable); i != e; ++i) {
246 unsigned FromOpc = ReduceTable[i].WideOpc;
247 if (!ReduceOpcodeMap.insert(std::make_pair(FromOpc, i)).second)
258 switch(Def->getOpcode()) {
284Thumb2SizeReduce::canAddPseudoFlagDep(
MachineInstr *
Use,
bool FirstInSelfLoop) {
286 if (MinimizeSize || !STI->avoidCPSRPartialUpdate())
292 return HighLatencyCPSR || FirstInSelfLoop;
296 if (!MO.isReg() || MO.isUndef() || MO.isUse())
299 if (Reg == 0 || Reg == ARM::CPSR)
305 if (!MO.isReg() || MO.isUndef() || MO.isDef())
318 if (
Use->getOpcode() == ARM::t2MOVi ||
319 Use->getOpcode() == ARM::t2MOVi16)
327Thumb2SizeReduce::VerifyPredAndCC(
MachineInstr *
MI,
const ReduceEntry &Entry,
329 bool LiveCPSR,
bool &HasCC,
bool &CCDead) {
330 if ((is2Addr &&
Entry.PredCC2 == 0) ||
331 (!is2Addr &&
Entry.PredCC1 == 0)) {
350 }
else if ((is2Addr &&
Entry.PredCC2 == 2) ||
351 (!is2Addr &&
Entry.PredCC1 == 2)) {
370 unsigned Opc =
MI->getOpcode();
371 bool isPCOk = (
Opc == ARM::t2LDMIA_RET ||
Opc == ARM::t2LDMIA_UPD);
372 bool isLROk = (
Opc == ARM::t2STMDB_UPD);
373 bool isSPOk = isPCOk || isLROk;
374 for (
unsigned i = 0, e =
MI->getNumOperands(); i != e; ++i) {
379 if (Reg == 0 || Reg == ARM::CPSR)
381 if (isPCOk && Reg == ARM::PC)
383 if (isLROk && Reg == ARM::LR)
385 if (Reg == ARM::SP) {
388 if (i == 1 && (
Opc == ARM::t2LDRi12 ||
Opc == ARM::t2STRi12))
400 const ReduceEntry &Entry) {
405 bool HasImmOffset =
false;
406 bool HasShift =
false;
407 bool HasOffReg =
true;
408 bool isLdStMul =
false;
413 switch (
Entry.WideOpc) {
418 if (
MI->getOperand(1).getReg() == ARM::SP) {
420 ImmLimit =
Entry.Imm2Limit;
449 case ARM::t2LDR_POST:
450 case ARM::t2STR_POST: {
454 if (!
MI->hasOneMemOperand() ||
455 (*
MI->memoperands_begin())->getAlign() <
Align(4))
461 bool IsStore =
Entry.WideOpc == ARM::t2STR_POST;
462 Register Rt =
MI->getOperand(IsStore ? 1 : 0).getReg();
463 Register Rn =
MI->getOperand(IsStore ? 0 : 1).getReg();
464 unsigned Offset =
MI->getOperand(3).getImm();
465 unsigned PredImm =
MI->getOperand(4).getImm();
466 Register PredReg =
MI->getOperand(5).getReg();
489 MI->eraseFromBundle();
501 if (MO.getReg() == BaseReg) {
518 if (!
MI->getOperand(0).isKill())
526 if (MO.getReg() == BaseReg)
531 case ARM::t2LDMIA_RET: {
533 if (BaseReg != ARM::SP)
540 case ARM::t2LDMIA_UPD:
541 case ARM::t2STMIA_UPD:
542 case ARM::t2STMDB_UPD: {
546 if (BaseReg == ARM::SP &&
547 (
Entry.WideOpc == ARM::t2LDMIA_UPD ||
548 Entry.WideOpc == ARM::t2STMDB_UPD)) {
552 (
Entry.WideOpc != ARM::t2LDMIA_UPD &&
553 Entry.WideOpc != ARM::t2STMIA_UPD)) {
562 unsigned OffsetReg = 0;
563 bool OffsetKill =
false;
564 bool OffsetInternal =
false;
566 OffsetReg =
MI->getOperand(2).getReg();
567 OffsetKill =
MI->getOperand(2).isKill();
568 OffsetInternal =
MI->getOperand(2).isInternalRead();
570 if (
MI->getOperand(3).getImm())
575 unsigned OffsetImm = 0;
577 OffsetImm =
MI->getOperand(2).getImm();
578 unsigned MaxOffset = ((1 << ImmLimit) - 1) * Scale;
580 if ((OffsetImm & (Scale - 1)) || OffsetImm > MaxOffset)
591 if (
Entry.WideOpc == ARM::t2STMIA)
595 MIB.
add(
MI->getOperand(0));
596 MIB.
add(
MI->getOperand(1));
599 MIB.
addImm(OffsetImm / Scale);
601 assert((!HasShift || OffsetReg) &&
"Invalid so_reg load / store address!");
619 <<
" to 16-bit: " << *MIB);
628 const ReduceEntry &Entry,
629 bool LiveCPSR,
bool IsSelfLoop) {
630 unsigned Opc =
MI->getOpcode();
631 if (
Opc == ARM::t2ADDri) {
634 if (
MI->getOperand(1).getReg() != ARM::SP) {
635 if (ReduceTo2Addr(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop))
637 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
640 unsigned Imm =
MI->getOperand(2).getImm();
644 if (Imm & 3 || Imm > 1020)
657 TII->get(ARM::tADDrSPi))
658 .
add(
MI->getOperand(0))
659 .
add(
MI->getOperand(1))
667 <<
" to 16-bit: " << *MIB);
677 if (
MI->mayLoadOrStore())
678 return ReduceLoadStore(
MBB,
MI, Entry);
683 case ARM::t2ADDSrr: {
689 if (ReduceTo2Addr(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop))
693 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
704 if (
MI->getOperand(2).getImm() == 0)
705 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
710 if (
MI->getOperand(1).isImm())
711 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
719 static const ReduceEntry NarrowEntry =
720 { ARM::t2CMPrr,ARM::tCMPr, 0, 0, 0, 1, 1,2, 0, 0,1,0 };
721 if (ReduceToNarrow(
MBB,
MI, NarrowEntry, LiveCPSR, IsSelfLoop))
723 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
732 if (
MI->getOperand(0).isKill())
733 return ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
741 const ReduceEntry &Entry,
742 bool LiveCPSR,
bool IsSelfLoop) {
746 if (!OptimizeSize &&
Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
754 if (
MI->getOpcode() == ARM::t2MUL) {
756 if (!MinimizeSize && STI->avoidMULS())
773 }
else if (Reg0 != Reg1) {
775 unsigned CommOpIdx1 = 1;
777 if (!
TII->findCommutedOpIndices(*
MI, CommOpIdx1, CommOpIdx2) ||
778 MI->getOperand(CommOpIdx2).getReg() != Reg0)
781 TII->commuteInstruction(*
MI,
false, CommOpIdx1, CommOpIdx2);
787 if (
Entry.Imm2Limit) {
788 unsigned Imm =
MI->getOperand(2).getImm();
789 unsigned Limit = (1 <<
Entry.Imm2Limit) - 1;
802 bool SkipPred =
false;
816 HasCC = (
MI->getOperand(NumOps-1).getReg() == ARM::CPSR);
817 if (HasCC &&
MI->getOperand(NumOps-1).isDead())
820 if (!VerifyPredAndCC(
MI, Entry,
true, Pred, LiveCPSR, HasCC, CCDead))
826 canAddPseudoFlagDep(
MI, IsSelfLoop))
832 MIB.
add(
MI->getOperand(0));
838 for (
unsigned i = 1, e =
MI->getNumOperands(); i != e; ++i) {
839 if (i < NumOps && MCID.
operands()[i].isOptionalDef())
841 if (SkipPred && MCID.
operands()[i].isPredicate())
843 MIB.
add(
MI->getOperand(i));
850 <<
" to 16-bit: " << *MIB);
859 const ReduceEntry &Entry,
860 bool LiveCPSR,
bool IsSelfLoop) {
864 if (!OptimizeSize &&
Entry.AvoidMovs && STI->avoidMOVsShifterOperand())
869 unsigned Limit = ~0
U;
871 Limit = (1 <<
Entry.Imm1Limit) - 1;
875 if (MCID.
operands()[i].isPredicate())
880 if (!Reg || Reg == ARM::CPSR)
884 }
else if (MO.
isImm() && !MCID.
operands()[i].isPredicate()) {
885 if (((
unsigned)MO.
getImm()) > Limit)
894 bool SkipPred =
false;
907 HasCC = (
MI->getOperand(NumOps-1).getReg() == ARM::CPSR);
908 if (HasCC &&
MI->getOperand(NumOps-1).isDead())
911 if (!VerifyPredAndCC(
MI, Entry,
false, Pred, LiveCPSR, HasCC, CCDead))
917 canAddPseudoFlagDep(
MI, IsSelfLoop))
928 MIB.
add(
MI->getOperand(0));
935 MIB.
add(
MI->getOperand(0));
937 MIB.
add(
MI->getOperand(0));
944 for (
unsigned i = 1, e =
MI->getNumOperands(); i != e; ++i) {
945 if (i < NumOps && MCID.
operands()[i].isOptionalDef())
947 if ((MCID.
getOpcode() == ARM::t2RSBSri ||
952 MCID.
getOpcode() == ARM::t2UXTH) && i == 2)
955 bool isPred = (i < NumOps && MCID.
operands()[i].isPredicate());
956 if (SkipPred && isPred)
972 <<
" to 16-bit: " << *MIB);
984 if (MO.
getReg() != ARM::CPSR)
992 return HasDef || LiveCPSR;
999 if (MO.
getReg() != ARM::CPSR)
1001 assert(LiveCPSR &&
"CPSR liveness tracking is wrong!");
1012 bool LiveCPSR,
bool IsSelfLoop,
1013 bool SkipPrologueEpilogue) {
1014 unsigned Opcode =
MI->getOpcode();
1016 if (OPI == ReduceOpcodeMap.end())
1021 const ReduceEntry &
Entry = ReduceTable[OPI->second];
1025 return ReduceSpecial(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop);
1028 if (
Entry.NarrowOpc2 &&
1029 ReduceTo2Addr(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop))
1033 if (
Entry.NarrowOpc1 &&
1034 ReduceToNarrow(
MBB,
MI, Entry, LiveCPSR, IsSelfLoop))
1041 bool SkipPrologueEpilogue) {
1049 HighLatencyCPSR =
false;
1053 const MBBInfo &PInfo = BlockInfo[Pred->getNumber()];
1054 if (!PInfo.Visited) {
1058 if (PInfo.HighLatencyCPSR) {
1059 HighLatencyCPSR =
true;
1069 for (; MII != E; MII = NextMII) {
1070 NextMII = std::next(MII);
1073 if (
MI->isBundle()) {
1077 if (
MI->isDebugInstr())
1083 bool NextInSameBundle = NextMII != E && NextMII->isBundledWithPred();
1085 if (ReduceMI(
MBB,
MI, LiveCPSR, IsSelfLoop, SkipPrologueEpilogue)) {
1091 if (NextInSameBundle && !NextMII->isBundledWithPred())
1092 NextMII->bundleWithPred();
1095 if (BundleMI && !NextInSameBundle &&
MI->isInsideBundle()) {
1111 bool DefCPSR =
false;
1116 HighLatencyCPSR =
false;
1118 }
else if (DefCPSR) {
1127 Info.HighLatencyCPSR = HighLatencyCPSR;
1128 Info.Visited =
true;
1133 if (PredicateFtor && !PredicateFtor(MF.
getFunction()))
1163 std::function<
bool(
const Function &)> Ftor) {
1164 return new Thumb2SizeReduce(std::move(Ftor));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
Performs the initial survey of the specified function
This file defines the DenseMap class.
const HexagonInstrInfo * TII
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static cl::opt< int > ReduceLimit("t2-reduce-limit", cl::init(-1), cl::Hidden)
static cl::opt< int > ReduceLimitLdSt("t2-reduce-limit3", cl::init(-1), cl::Hidden)
static cl::opt< int > ReduceLimit2Addr("t2-reduce-limit2", cl::init(-1), cl::Hidden)
static bool HasImplicitCPSRDef(const MCInstrDesc &MCID)
static bool isHighLatencyCPSR(MachineInstr *Def)
static bool UpdateCPSRUse(MachineInstr &MI, bool LiveCPSR)
static bool VerifyLowRegs(MachineInstr *MI)
#define THUMB2_SIZE_REDUCE_NAME
static bool UpdateCPSRDef(MachineInstr &MI, bool LiveCPSR, bool &DefCPSR)
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
iterator find(const_arg_type_t< KeyT > Val)
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
bool usesWindowsCFI() const
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
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
ArrayRef< MCPhysReg > implicit_defs() const
Return a list of registers that are potentially written by any instance of this machine instruction.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
unsigned getOpcode() const
Return the opcode number for this descriptor.
instr_iterator instr_begin()
instr_iterator erase_instr(MachineInstr *I)
Remove an instruction from the instruction list and delete it.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
Instructions::iterator instr_iterator
instr_iterator instr_end()
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
iterator_range< pred_iterator > predecessors()
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
MachineOperand * findRegisterUseOperand(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false)
Wrapper for findRegisterUseOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
const MachineOperand & getOperand(unsigned i) const
MachineOperand * findRegisterDefOperand(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI void setIsDef(bool Val=true)
Change a def to a use, or a use to a def.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
static const unsigned CommuteAnyOperandIndex
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
A Use represents the edge between a Value definition and its users.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getInternalReadRegState(bool B)
unsigned getKillRegState(bool B)
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
FunctionPass * createThumb2SizeReductionPass(std::function< bool(const Function &)> Ftor=nullptr)
createThumb2SizeReductionPass - Returns an instance of the Thumb2 size reduction pass.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.