47 #define DEBUG_TYPE "t2-reduce-size" 48 #define THUMB2_SIZE_REDUCE_NAME "Thumb2 instruction size reduce pass" 50 STATISTIC(NumNarrows,
"Number of 32-bit instrs reduced to 16-bit ones");
51 STATISTIC(Num2Addrs,
"Number of 32-bit instrs reduced to 2addr 16-bit ones");
52 STATISTIC(NumLdSts,
"Number of 32-bit load / store reduced to 16-bit ones");
71 unsigned LowRegs1 : 1;
72 unsigned LowRegs2 : 1;
77 unsigned PartFlag : 1;
79 unsigned AvoidMovs: 1;
82 static const ReduceEntry ReduceTable[] = {
84 { ARM::t2ADCrr, 0, ARM::tADC, 0, 0, 0, 1, 0,0, 0,0,0 },
85 { ARM::t2ADDri, ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 0,0, 0,1,0 },
86 { ARM::t2ADDrr, ARM::tADDrr, ARM::tADDhirr, 0, 0, 1, 0, 0,1, 0,0,0 },
87 { ARM::t2ADDSri,ARM::tADDi3, ARM::tADDi8, 3, 8, 1, 1, 2,2, 0,1,0 },
88 { ARM::t2ADDSrr,ARM::tADDrr, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
89 { ARM::t2ANDrr, 0, ARM::tAND, 0, 0, 0, 1, 0,0, 1,0,0 },
90 { ARM::t2ASRri, ARM::tASRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
91 { ARM::t2ASRrr, 0, ARM::tASRrr, 0, 0, 0, 1, 0,0, 1,0,1 },
92 { ARM::t2BICrr, 0, ARM::tBIC, 0, 0, 0, 1, 0,0, 1,0,0 },
95 { ARM::t2CMNzrr, ARM::tCMNz, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
96 { ARM::t2CMPri, ARM::tCMPi8, 0, 8, 0, 1, 0, 2,0, 0,0,0 },
97 { ARM::t2CMPrr, ARM::tCMPhir, 0, 0, 0, 0, 0, 2,0, 0,1,0 },
98 { ARM::t2EORrr, 0, ARM::tEOR, 0, 0, 0, 1, 0,0, 1,0,0 },
101 { ARM::t2LSLri, ARM::tLSLri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
102 { ARM::t2LSLrr, 0, ARM::tLSLrr, 0, 0, 0, 1, 0,0, 1,0,1 },
103 { ARM::t2LSRri, ARM::tLSRri, 0, 5, 0, 1, 0, 0,0, 1,0,1 },
104 { ARM::t2LSRrr, 0, ARM::tLSRrr, 0, 0, 0, 1, 0,0, 1,0,1 },
105 { ARM::t2MOVi, ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 1,0,0 },
106 { ARM::t2MOVi16,ARM::tMOVi8, 0, 8, 0, 1, 0, 0,0, 1,1,0 },
108 { ARM::t2MOVr,ARM::tMOVr, 0, 0, 0, 0, 0, 1,0, 0,0,0 },
109 { ARM::t2MUL, 0, ARM::tMUL, 0, 0, 0, 1, 0,0, 1,0,0 },
110 { ARM::t2MVNr, ARM::tMVN, 0, 0, 0, 1, 0, 0,0, 0,0,0 },
111 { ARM::t2ORRrr, 0, ARM::tORR, 0, 0, 0, 1, 0,0, 1,0,0 },
112 { ARM::t2REV, ARM::tREV, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
113 { ARM::t2REV16, ARM::tREV16, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
114 { ARM::t2REVSH, ARM::tREVSH, 0, 0, 0, 1, 0, 1,0, 0,0,0 },
115 { ARM::t2RORrr, 0, ARM::tROR, 0, 0, 0, 1, 0,0, 1,0,0 },
116 { ARM::t2RSBri, ARM::tRSB, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
117 { ARM::t2RSBSri,ARM::tRSB, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
118 { ARM::t2SBCrr, 0, ARM::tSBC, 0, 0, 0, 1, 0,0, 0,0,0 },
119 { ARM::t2SUBri, ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 0,0, 0,0,0 },
120 { ARM::t2SUBrr, ARM::tSUBrr, 0, 0, 0, 1, 0, 0,0, 0,0,0 },
121 { ARM::t2SUBSri,ARM::tSUBi3, ARM::tSUBi8, 3, 8, 1, 1, 2,2, 0,0,0 },
122 { ARM::t2SUBSrr,ARM::tSUBrr, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
123 { ARM::t2SXTB, ARM::tSXTB, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
124 { ARM::t2SXTH, ARM::tSXTH, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
125 { ARM::t2TEQrr, ARM::tEOR, 0, 0, 0, 1, 0, 2,0, 0,1,0 },
126 { ARM::t2TSTrr, ARM::tTST, 0, 0, 0, 1, 0, 2,0, 0,0,0 },
127 { ARM::t2UXTB, ARM::tUXTB, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
128 { ARM::t2UXTH, ARM::tUXTH, 0, 0, 0, 1, 0, 1,0, 0,1,0 },
132 { ARM::t2LDRi12,ARM::tLDRi, ARM::tLDRspi, 5, 8, 1, 0, 0,0, 0,1,0 },
133 { ARM::t2LDRs, ARM::tLDRr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
134 { ARM::t2LDRBi12,ARM::tLDRBi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
135 { ARM::t2LDRBs, ARM::tLDRBr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
136 { ARM::t2LDRHi12,ARM::tLDRHi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
137 { ARM::t2LDRHs, ARM::tLDRHr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
138 { ARM::t2LDRSBs,ARM::tLDRSB, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
139 { ARM::t2LDRSHs,ARM::tLDRSH, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
140 { ARM::t2LDR_POST,ARM::tLDMIA_UPD,0, 0, 0, 1, 0, 0,0, 0,1,0 },
141 { ARM::t2STRi12,ARM::tSTRi, ARM::tSTRspi, 5, 8, 1, 0, 0,0, 0,1,0 },
142 { ARM::t2STRs, ARM::tSTRr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
143 { ARM::t2STRBi12,ARM::tSTRBi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
144 { ARM::t2STRBs, ARM::tSTRBr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
145 { ARM::t2STRHi12,ARM::tSTRHi, 0, 5, 0, 1, 0, 0,0, 0,1,0 },
146 { ARM::t2STRHs, ARM::tSTRHr, 0, 0, 0, 1, 0, 0,0, 0,1,0 },
147 { ARM::t2STR_POST,ARM::tSTMIA_UPD,0, 0, 0, 1, 0, 0,0, 0,1,0 },
149 { ARM::t2LDMIA, ARM::tLDMIA, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
150 { ARM::t2LDMIA_RET,0, ARM::tPOP_RET, 0, 0, 1, 1, 1,1, 0,1,0 },
151 { ARM::t2LDMIA_UPD,ARM::tLDMIA_UPD,ARM::tPOP,0, 0, 1, 1, 1,1, 0,1,0 },
155 { ARM::t2STMIA, ARM::tSTMIA_UPD, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
156 { ARM::t2STMIA_UPD,ARM::tSTMIA_UPD, 0, 0, 0, 1, 1, 1,1, 0,1,0 },
157 { ARM::t2STMDB_UPD, 0, ARM::tPUSH, 0, 0, 1, 1, 1,1, 0,1,0 }
188 bool LiveCPSR,
bool &HasCC,
bool &CCDead);
191 const ReduceEntry &Entry);
194 const ReduceEntry &Entry,
bool LiveCPSR,
bool IsSelfLoop);
199 const ReduceEntry &Entry,
bool LiveCPSR,
205 const ReduceEntry &Entry,
bool LiveCPSR,
210 bool LiveCPSR,
bool IsSelfLoop);
222 bool HighLatencyCPSR;
226 bool HighLatencyCPSR =
false;
228 bool Visited =
false;
235 std::function<bool(const Function &)> PredicateFtor;
247 OptimizeSize = MinimizeSize =
false;
248 for (
unsigned i = 0, e =
array_lengthof(ReduceTable); i != e; ++i) {
249 unsigned FromOpc = ReduceTable[i].WideOpc;
250 if (!ReduceOpcodeMap.insert(std::make_pair(FromOpc, i)).second)
257 if (*Regs == ARM::CPSR)
290 Thumb2SizeReduce::canAddPseudoFlagDep(
MachineInstr *
Use,
bool FirstInSelfLoop) {
298 return HighLatencyCPSR || FirstInSelfLoop;
302 if (!MO.isReg() || MO.isUndef() || MO.isUse())
304 unsigned Reg = MO.getReg();
305 if (Reg == 0 || Reg == ARM::CPSR)
311 if (!MO.isReg() || MO.isUndef() || MO.isDef())
313 unsigned Reg = MO.getReg();
333 Thumb2SizeReduce::VerifyPredAndCC(
MachineInstr *
MI,
const ReduceEntry &Entry,
335 bool LiveCPSR,
bool &HasCC,
bool &CCDead) {
336 if ((is2Addr && Entry.PredCC2 == 0) ||
337 (!is2Addr && Entry.PredCC1 == 0)) {
356 }
else if ((is2Addr && Entry.PredCC2 == 2) ||
357 (!is2Addr && Entry.PredCC1 == 2)) {
377 bool isPCOk = (Opc == ARM::t2LDMIA_RET || Opc == ARM::t2LDMIA_UPD);
378 bool isLROk = (Opc == ARM::t2STMDB_UPD);
379 bool isSPOk = isPCOk || isLROk;
385 if (Reg == 0 || Reg == ARM::CPSR)
387 if (isPCOk && Reg == ARM::PC)
389 if (isLROk && Reg == ARM::LR)
391 if (Reg == ARM::SP) {
394 if (i == 1 && (Opc == ARM::t2LDRi12 || Opc == ARM::t2STRi12))
406 const ReduceEntry &Entry) {
411 bool HasImmOffset =
false;
412 bool HasShift =
false;
413 bool HasOffReg =
true;
414 bool isLdStMul =
false;
415 unsigned Opc = Entry.NarrowOpc1;
417 uint8_t ImmLimit = Entry.Imm1Limit;
419 switch (Entry.WideOpc) {
425 Opc = Entry.NarrowOpc2;
426 ImmLimit = Entry.Imm2Limit;
455 case ARM::t2LDR_POST:
456 case ARM::t2STR_POST: {
467 bool IsStore = Entry.WideOpc == ARM::t2STR_POST;
481 auto MIB =
BuildMI(MBB, MI, dl, TII->get(Entry.NarrowOpc1))
527 case ARM::t2LDMIA_RET: {
529 if (BaseReg != ARM::SP)
531 Opc = Entry.NarrowOpc2;
536 case ARM::t2LDMIA_UPD:
537 case ARM::t2STMIA_UPD:
538 case ARM::t2STMDB_UPD: {
542 if (BaseReg == ARM::SP &&
543 (Entry.WideOpc == ARM::t2LDMIA_UPD ||
544 Entry.WideOpc == ARM::t2STMDB_UPD)) {
545 Opc = Entry.NarrowOpc2;
548 (Entry.WideOpc != ARM::t2LDMIA_UPD &&
549 Entry.WideOpc != ARM::t2STMIA_UPD)) {
558 unsigned OffsetReg = 0;
559 bool OffsetKill =
false;
560 bool OffsetInternal =
false;
571 unsigned OffsetImm = 0;
574 unsigned MaxOffset = ((1 << ImmLimit) - 1) * Scale;
576 if ((OffsetImm & (Scale - 1)) || OffsetImm > MaxOffset)
587 if (Entry.WideOpc == ARM::t2STMIA)
595 MIB.
addImm(OffsetImm / Scale);
597 assert((!HasShift || OffsetReg) &&
"Invalid so_reg load / store address!");
615 <<
" to 16-bit: " << *MIB);
624 const ReduceEntry &Entry,
625 bool LiveCPSR,
bool IsSelfLoop) {
627 if (Opc == ARM::t2ADDri) {
631 if (ReduceTo2Addr(MBB, MI, Entry, LiveCPSR, IsSelfLoop))
633 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
640 if (Imm & 3 || Imm > 1020)
653 TII->get(ARM::tADDrSPi))
663 <<
" to 16-bit: " << *MIB);
674 return ReduceLoadStore(MBB, MI, Entry);
679 case ARM::t2ADDSrr: {
680 unsigned PredReg = 0;
685 if (ReduceTo2Addr(MBB, MI, Entry, LiveCPSR, IsSelfLoop))
689 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
701 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
707 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
715 static const ReduceEntry NarrowEntry =
716 { ARM::t2CMPrr,ARM::tCMPr, 0, 0, 0, 1, 1,2, 0, 0,1,0 };
717 if (ReduceToNarrow(MBB, MI, NarrowEntry, LiveCPSR, IsSelfLoop))
719 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
722 unsigned PredReg = 0;
729 return ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
737 const ReduceEntry &Entry,
738 bool LiveCPSR,
bool IsSelfLoop) {
762 MachineInstr *CommutedMI = TII->commuteInstruction(*MI);
766 }
else if (Reg0 != Reg1) {
768 unsigned CommOpIdx1 = 1;
770 if (!TII->findCommutedOpIndices(*MI, CommOpIdx1, CommOpIdx2) ||
774 TII->commuteInstruction(*MI,
false, CommOpIdx1, CommOpIdx2);
780 if (Entry.Imm2Limit) {
782 unsigned Limit = (1 << Entry.Imm2Limit) - 1;
792 const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc2);
793 unsigned PredReg = 0;
795 bool SkipPred =
false;
813 if (!VerifyPredAndCC(MI, Entry,
true, Pred, LiveCPSR, HasCC, CCDead))
819 canAddPseudoFlagDep(MI, IsSelfLoop))
843 <<
" to 16-bit: " << *MIB);
852 const ReduceEntry &Entry,
853 bool LiveCPSR,
bool IsSelfLoop) {
862 unsigned Limit = ~0U;
864 Limit = (1 << Entry.Imm1Limit) - 1;
873 if (!Reg || Reg == ARM::CPSR)
877 }
else if (MO.
isImm() &&
879 if (((
unsigned)MO.
getImm()) > Limit)
885 const MCInstrDesc &NewMCID = TII->get(Entry.NarrowOpc1);
886 unsigned PredReg = 0;
888 bool SkipPred =
false;
905 if (!VerifyPredAndCC(MI, Entry,
false, Pred, LiveCPSR, HasCC, CCDead))
911 canAddPseudoFlagDep(MI, IsSelfLoop))
941 if ((MCID.
getOpcode() == ARM::t2RSBSri ||
946 MCID.
getOpcode() == ARM::t2UXTH) && i == 2)
950 if (SkipPred && isPred)
966 <<
" to 16-bit: " << *MIB);
976 if (!MO.isReg() || MO.isUndef() || MO.isUse())
978 if (MO.getReg() != ARM::CPSR)
986 return HasDef || LiveCPSR;
991 if (!MO.isReg() || MO.isUndef() || MO.isDef())
993 if (MO.getReg() != ARM::CPSR)
995 assert(LiveCPSR &&
"CPSR liveness tracking is wrong!");
1006 bool LiveCPSR,
bool IsSelfLoop) {
1009 if (OPI == ReduceOpcodeMap.
end())
1011 const ReduceEntry &Entry = ReduceTable[OPI->second];
1015 return ReduceSpecial(MBB, MI, Entry, LiveCPSR, IsSelfLoop);
1018 if (Entry.NarrowOpc2 &&
1019 ReduceTo2Addr(MBB, MI, Entry, LiveCPSR, IsSelfLoop))
1023 if (Entry.NarrowOpc1 &&
1024 ReduceToNarrow(MBB, MI, Entry, LiveCPSR, IsSelfLoop))
1034 bool LiveCPSR = MBB.
isLiveIn(ARM::CPSR);
1038 HighLatencyCPSR =
false;
1042 const MBBInfo &PInfo = BlockInfo[Pred->getNumber()];
1043 if (!PInfo.Visited) {
1047 if (PInfo.HighLatencyCPSR) {
1048 HighLatencyCPSR =
true;
1058 for (; MII !=
E; MII = NextMII) {
1059 NextMII = std::next(MII);
1072 bool NextInSameBundle = NextMII !=
E && NextMII->isBundledWithPred();
1074 if (ReduceMI(MBB, MI, LiveCPSR, IsSelfLoop)) {
1080 if (NextInSameBundle && !NextMII->isBundledWithPred())
1081 NextMII->bundleWithPred();
1099 bool DefCPSR =
false;
1104 HighLatencyCPSR =
false;
1106 }
else if (DefCPSR) {
1115 Info.HighLatencyCPSR = HighLatencyCPSR;
1116 Info.Visited =
true;
1121 if (PredicateFtor && !PredicateFtor(MF.
getFunction()))
1143 Modified |= ReduceMBB(**
I);
1151 return new Thumb2SizeReduce(std::move(Ftor));
static bool VerifyLowRegs(MachineInstr *MI)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand *> MMOs) const
const MachineInstrBuilder & add(const MachineOperand &MO) const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
instr_iterator instr_begin()
bool isCall(QueryType Type=AnyInBundle) const
bool avoidCPSRPartialUpdate() const
instr_iterator instr_end()
This class represents lattice values for constants.
MachineOperand * findRegisterDefOperand(unsigned Reg, bool isDead=false, const TargetRegisterInfo *TRI=nullptr)
Wrapper for findRegisterDefOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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.
MachineOperand * findRegisterUseOperand(unsigned Reg, bool isKill=false, const TargetRegisterInfo *TRI=nullptr)
Wrapper for findRegisterUseOperandIdx, it returns a pointer to the MachineOperand rather than an inde...
bool prefers32BitThumb() const
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
unsigned getInternalReadRegState(bool B)
STATISTIC(NumFunctions, "Total number of functions")
void setIsDead(bool Val=true)
bool isThumb1Only() const
bool avoidMOVsShifterOperand() const
static cl::opt< int > ReduceLimit2Addr("t2-reduce-limit2", cl::init(-1), cl::Hidden)
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isInternalRead() const
const ARMBaseInstrInfo * getInstrInfo() const override
static uint32_t getAlignment(const MCSectionCOFF &Sec)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
A Use represents the edge between a Value definition and its users.
#define THUMB2_SIZE_REDUCE_NAME
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
bool isPredicate() const
Set if this is one of the operands that made up of the predicate operand that controls an isPredicabl...
bool isInsideBundle() const
Return true if MI is in a bundle (but not the first MI in a bundle).
Analysis containing CSE Info
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
iterator find(const_arg_type_t< KeyT > Val)
static const unsigned CommuteAnyOperandIndex
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
const MCPhysReg * getImplicitDefs() const
Return a list of registers that are potentially written by any instance of this machine instruction...
instr_iterator erase_instr(MachineInstr *I)
Remove an instruction from the instruction list and delete it.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
bool isOptionalDef() const
Set if this operand is a optional def.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool hasOptionalDef() const
Set if this instruction has an optional definition, e.g.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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).
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicable() const
Return true if this instruction has a predicate operand that controls execution.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
iterator_range< pred_iterator > predecessors()
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, unsigned &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition, otherwise returns AL.
bool isDebugInstr() const
static bool UpdateCPSRUse(MachineInstr &MI, bool LiveCPSR)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void eraseFromBundle()
Unlink 'this' form its basic block and delete it.
void setIsKill(bool Val=true)
Iterator for intrusive lists based on ilist_node.
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
static cl::opt< int > ReduceLimit("t2-reduce-limit", cl::init(-1), cl::Hidden)
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
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...
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static cl::opt< int > ReduceLimitLdSt("t2-reduce-limit3", cl::init(-1), cl::Hidden)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
static bool HasImplicitCPSRDef(const MCInstrDesc &MCID)
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
static bool isHighLatencyCPSR(MachineInstr *Def)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static bool UpdateCPSRDef(MachineInstr &MI, bool LiveCPSR, bool &DefCPSR)
MachineFunctionProperties & set(Property P)
static bool isARMLowRegister(unsigned Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr kills the specified register.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
bool optForMinSize() const
Optimize this function for minimum size (-Oz).
typename std::vector< NodeRef >::reverse_iterator rpo_iterator
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
uint16_t getFlags() const
Return the MI flags bitvector.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCOperandInfo * OpInfo
unsigned getOpcode() const
Return the opcode number for this descriptor.
print Print MemDeps of function
StringRef - Represent a constant reference to a string, i.e.
FunctionPass * createThumb2SizeReductionPass(std::function< bool(const Function &)> Ftor=nullptr)
createThumb2SizeReductionPass - Returns an instance of the Thumb2 size reduction pass.
const MachineOperand & getOperand(unsigned i) const
INITIALIZE_PASS(Thumb2SizeReduce, DEBUG_TYPE, THUMB2_SIZE_REDUCE_NAME, false, false) Thumb2SizeReduce
Properties which a MachineFunction may have at a given point in time.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.