23 #define DEBUG_TYPE "micromips-reduce-size" 24 #define MICROMIPS_SIZE_REDUCE_NAME "MicroMips instruction size reduce pass" 26 STATISTIC(NumReduced,
"Number of instructions reduced (32-bit to 16-bit ones, " 27 "or two instructions into one");
53 ImmField() : ImmFieldOperand(-1), Shift(0), LBound(0), HBound(0) {}
54 ImmField(uint8_t Shift, int16_t LBound, int16_t HBound,
55 int8_t ImmFieldOperand)
56 : ImmFieldOperand(ImmFieldOperand), Shift(Shift), LBound(LBound),
58 int8_t ImmFieldOperand;
68 : TransferOperands(TransferOperands) {}
69 OpInfo() : TransferOperands(OT_NA) {}
77 OpCodes(
unsigned WideOpc,
unsigned NarrowOpc)
78 : WideOpc(WideOpc), NarrowOpc(NarrowOpc) {}
84 typedef struct ReduceEntryFunArgs ReduceEntryFunArgs;
91 bool (*ReduceFunction)(
98 bool (*
F)(ReduceEntryFunArgs *
Arguments),
struct OpInfo OpInf,
100 : eRType(RType), ReduceFunction(
F), Ops(Op), OpInf(OpInf), Imm(Imm) {}
102 unsigned NarrowOpc()
const {
return Ops.NarrowOpc; }
103 unsigned WideOpc()
const {
return Ops.WideOpc; }
104 int16_t LBound()
const {
return Imm.LBound; }
105 int16_t HBound()
const {
return Imm.HBound; }
106 uint8_t Shift()
const {
return Imm.Shift; }
107 int8_t ImmField()
const {
return Imm.ImmFieldOperand; }
109 return OpInf.TransferOperands;
111 enum ReduceType RType()
const {
return eRType; }
114 bool operator<(
const unsigned int r)
const {
return (WideOpc() < r); }
117 friend bool operator<(
const unsigned int r,
const struct ReduceEntry &re) {
118 return (r < re.WideOpc());
123 struct ReduceEntryFunArgs {
125 const ReduceEntry &Entry;
129 ReduceEntryFunArgs(
MachineInstr *argMI,
const ReduceEntry &argEntry,
131 :
MI(argMI), Entry(argEntry), NextMII(argNextMII) {}
139 MicroMipsSizeReduce();
147 return "microMIPS instruction size reduction pass";
160 static bool ReduceXWtoXWSP(ReduceEntryFunArgs *
Arguments);
164 static bool ReduceXWtoXWP(ReduceEntryFunArgs *Arguments);
168 static bool ReduceLXUtoLXU16(ReduceEntryFunArgs *Arguments);
172 static bool ReduceSXtoSX16(ReduceEntryFunArgs *Arguments);
176 static bool ReduceMoveToMovep(ReduceEntryFunArgs *Arguments);
179 static bool ReduceArithmeticInstructions(ReduceEntryFunArgs *Arguments);
183 static bool ReduceADDIUToADDIUSP(ReduceEntryFunArgs *Arguments);
187 static bool ReduceADDIUToADDIUR1SP(ReduceEntryFunArgs *Arguments);
191 static bool ReduceXORtoXOR16(ReduceEntryFunArgs *Arguments);
197 static bool ReplaceInstruction(
MachineInstr *
MI,
const ReduceEntry &Entry,
199 bool ConsecutiveForward =
true);
202 static ReduceEntryVector ReduceTable;
210 ReduceEntryVector MicroMipsSizeReduce::ReduceTable = {
215 {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUR1SP_MM),
216 ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
217 {RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUSP_MM), ReduceADDIUToADDIUSP,
218 OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
219 {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUR1SP_MM),
220 ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
221 {RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUSP_MM),
222 ReduceADDIUToADDIUSP, OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
223 {RT_OneInstr, OpCodes(Mips::ADDu, Mips::ADDU16_MM),
224 ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
225 ImmField(0, 0, 0, -1)},
226 {RT_OneInstr, OpCodes(Mips::ADDu_MM, Mips::ADDU16_MM),
227 ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
228 ImmField(0, 0, 0, -1)},
229 {RT_OneInstr, OpCodes(Mips::LBu, Mips::LBU16_MM), ReduceLXUtoLXU16,
230 OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
231 {RT_OneInstr, OpCodes(Mips::LBu_MM, Mips::LBU16_MM), ReduceLXUtoLXU16,
232 OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
233 {RT_OneInstr, OpCodes(Mips::LEA_ADDiu, Mips::ADDIUR1SP_MM),
234 ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
235 {RT_OneInstr, OpCodes(Mips::LEA_ADDiu_MM, Mips::ADDIUR1SP_MM),
236 ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
237 {RT_OneInstr, OpCodes(Mips::LHu, Mips::LHU16_MM), ReduceLXUtoLXU16,
238 OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
239 {RT_OneInstr, OpCodes(Mips::LHu_MM, Mips::LHU16_MM), ReduceLXUtoLXU16,
240 OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
241 {RT_TwoInstr, OpCodes(Mips::LW, Mips::LWP_MM), ReduceXWtoXWP,
242 OpInfo(OT_OperandsLwp), ImmField(0, -2048, 2048, 2)},
243 {RT_OneInstr, OpCodes(Mips::LW, Mips::LWSP_MM), ReduceXWtoXWSP,
244 OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
245 {RT_TwoInstr, OpCodes(Mips::LW16_MM, Mips::LWP_MM), ReduceXWtoXWP,
246 OpInfo(OT_OperandsLwp), ImmField(0, -2048, 2048, 2)},
247 {RT_TwoInstr, OpCodes(Mips::LW_MM, Mips::LWP_MM), ReduceXWtoXWP,
248 OpInfo(OT_OperandsLwp), ImmField(0, -2048, 2048, 2)},
249 {RT_OneInstr, OpCodes(Mips::LW_MM, Mips::LWSP_MM), ReduceXWtoXWSP,
250 OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
251 {RT_TwoInstr, OpCodes(Mips::MOVE16_MM, Mips::MOVEP_MM), ReduceMoveToMovep,
252 OpInfo(OT_OperandsMovep), ImmField(0, 0, 0, -1)},
253 {RT_OneInstr, OpCodes(Mips::SB, Mips::SB16_MM), ReduceSXtoSX16,
254 OpInfo(OT_OperandsAll), ImmField(0, 0, 16, 2)},
255 {RT_OneInstr, OpCodes(Mips::SB_MM, Mips::SB16_MM), ReduceSXtoSX16,
256 OpInfo(OT_OperandsAll), ImmField(0, 0, 16, 2)},
257 {RT_OneInstr, OpCodes(Mips::SH, Mips::SH16_MM), ReduceSXtoSX16,
258 OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
259 {RT_OneInstr, OpCodes(Mips::SH_MM, Mips::SH16_MM), ReduceSXtoSX16,
260 OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
261 {RT_OneInstr, OpCodes(Mips::SUBu, Mips::SUBU16_MM),
262 ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
263 ImmField(0, 0, 0, -1)},
264 {RT_OneInstr, OpCodes(Mips::SUBu_MM, Mips::SUBU16_MM),
265 ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
266 ImmField(0, 0, 0, -1)},
267 {RT_TwoInstr, OpCodes(Mips::SW, Mips::SWP_MM), ReduceXWtoXWP,
268 OpInfo(OT_OperandsSwp), ImmField(0, -2048, 2048, 2)},
269 {RT_OneInstr, OpCodes(Mips::SW, Mips::SWSP_MM), ReduceXWtoXWSP,
270 OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
271 {RT_TwoInstr, OpCodes(Mips::SW16_MM, Mips::SWP_MM), ReduceXWtoXWP,
272 OpInfo(OT_OperandsSwp), ImmField(0, -2048, 2048, 2)},
273 {RT_TwoInstr, OpCodes(Mips::SW_MM, Mips::SWP_MM), ReduceXWtoXWP,
274 OpInfo(OT_OperandsSwp), ImmField(0, -2048, 2048, 2)},
275 {RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
276 OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
277 {RT_OneInstr, OpCodes(
Mips::XOR, Mips::XOR16_MM), ReduceXORtoXOR16,
278 OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)},
279 {RT_OneInstr, OpCodes(Mips::XOR_MM, Mips::XOR16_MM), ReduceXORtoXOR16,
280 OpInfo(OT_OperandsXOR), ImmField(0, 0, 0, -1)}};
288 if (MO.isReg() && ((MO.getReg() == Mips::SP)))
295 if (MO.
isReg() && Mips::GPRMM16RegClass.contains(MO.
getReg()))
302 if (MO.
isReg() && Mips::GPRMM16ZeroRegClass.contains(MO.
getReg()))
319 int64_t Value2 = Value >> 2;
320 if (((Value & (int64_t)maskTrailingZeros<uint64_t>(2)) == Value) &&
321 ((Value2 >= 2 && Value2 <= 257) || (Value2 >= -258 && Value2 <= -3)))
330 int64_t Value2 = Value >> Shift;
331 if (((Value & (int64_t)maskTrailingZeros<uint64_t>(Shift)) == Value) &&
332 (Value2 >= LBound) && (Value2 < HBound))
342 if (!
GetImm(MI, Entry.ImmField(), offset))
345 if (!
InRange(offset, Entry.Shift(), Entry.LBound(), Entry.HBound()))
353 const ReduceEntry &Entry) {
381 Mips::AT, Mips::V0, Mips::V1, Mips::A0, Mips::A1, Mips::A2, Mips::A3,
382 Mips::T0,
Mips::T1, Mips::T2, Mips::T3, Mips::T4, Mips::T5, Mips::T6,
383 Mips::T7, Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5,
384 Mips::S6, Mips::S7,
Mips::T8, Mips::T9, Mips::K0, Mips::K1, Mips::GP,
387 for (uint8_t i = 0; i < Registers.
size() - 1; i++) {
388 if (Registers[i] == Reg1) {
389 if (Registers[i + 1] == Reg2)
401 int64_t Offset1, Offset2;
402 if (!
GetImm(MI1, 2, Offset1))
404 if (!
GetImm(MI2, 2, Offset2))
422 ReduceEntryVector::const_iterator Start =
std::begin(ReduceTable);
423 ReduceEntryVector::const_iterator End =
std::end(ReduceTable);
425 std::pair<ReduceEntryVector::const_iterator,
426 ReduceEntryVector::const_iterator>
427 Range = std::equal_range(Start, End, Opcode);
429 if (Range.first == Range.second)
432 for (ReduceEntryVector::const_iterator Entry = Range.first;
433 Entry != Range.second; ++Entry) {
434 ReduceEntryFunArgs
Arguments(&(*MII), *Entry, NextMII);
435 if (((*Entry).ReduceFunction)(&Arguments))
441 bool MicroMipsSizeReduce::ReduceXWtoXWSP(ReduceEntryFunArgs *
Arguments) {
444 const ReduceEntry &Entry = Arguments->Entry;
452 return ReplaceInstruction(MI, Entry);
455 bool MicroMipsSizeReduce::ReduceXWtoXWP(ReduceEntryFunArgs *Arguments) {
457 const ReduceEntry &Entry = Arguments->Entry;
460 Arguments->MI->getParent()->instr_end();
469 bool ReduceToLwp = (MI1->
getOpcode() == Mips::LW) ||
488 if (!(ConsecutiveForward || ConsecutiveBackward))
491 NextMII = std::next(NextMII);
492 return ReplaceInstruction(MI1, Entry, MI2, ConsecutiveForward);
495 bool MicroMipsSizeReduce::ReduceArithmeticInstructions(
496 ReduceEntryFunArgs *Arguments) {
499 const ReduceEntry &Entry = Arguments->Entry;
506 return ReplaceInstruction(MI, Entry);
509 bool MicroMipsSizeReduce::ReduceADDIUToADDIUR1SP(
510 ReduceEntryFunArgs *Arguments) {
513 const ReduceEntry &Entry = Arguments->Entry;
521 return ReplaceInstruction(MI, Entry);
524 bool MicroMipsSizeReduce::ReduceADDIUToADDIUSP(ReduceEntryFunArgs *Arguments) {
527 const ReduceEntry &Entry = Arguments->Entry;
530 if (!
GetImm(MI, Entry.ImmField(), ImmValue))
539 return ReplaceInstruction(MI, Entry);
542 bool MicroMipsSizeReduce::ReduceLXUtoLXU16(ReduceEntryFunArgs *Arguments) {
545 const ReduceEntry &Entry = Arguments->Entry;
554 return ReplaceInstruction(MI, Entry);
557 bool MicroMipsSizeReduce::ReduceSXtoSX16(ReduceEntryFunArgs *Arguments) {
560 const ReduceEntry &Entry = Arguments->Entry;
569 return ReplaceInstruction(MI, Entry);
576 if (Reg == Mips::ZERO || Reg == Mips::V0 || Reg == Mips::V1 ||
577 Reg == Mips::S0 || Reg == Mips::S1 || Reg == Mips::S2 ||
578 Reg == Mips::S3 || Reg == Mips::S4)
588 if (Reg == Mips::A0 || Reg == Mips::A1 || Reg == Mips::A2 ||
589 Reg == Mips::A3 || Reg == Mips::S5 || Reg == Mips::S6)
599 if ((R0 == Mips::A0 && R1 == Mips::S5) ||
600 (R0 == Mips::A0 && R1 == Mips::S6) ||
601 (R0 == Mips::A0 && R1 == Mips::A1) ||
602 (R0 == Mips::A0 && R1 == Mips::A2) ||
603 (R0 == Mips::A0 && R1 == Mips::A3) ||
604 (R0 == Mips::A1 && R1 == Mips::A2) ||
605 (R0 == Mips::A1 && R1 == Mips::A3) ||
606 (R0 == Mips::A2 && R1 == Mips::A3))
612 bool MicroMipsSizeReduce::ReduceMoveToMovep(ReduceEntryFunArgs *Arguments) {
614 const ReduceEntry &Entry = Arguments->Entry;
617 Arguments->MI->getParent()->instr_end();
643 bool ConsecutiveForward;
645 ConsecutiveForward =
true;
647 ConsecutiveForward =
false;
651 NextMII = std::next(NextMII);
652 return ReplaceInstruction(MI1, Entry, MI2, ConsecutiveForward);
655 bool MicroMipsSizeReduce::ReduceXORtoXOR16(ReduceEntryFunArgs *Arguments) {
658 const ReduceEntry &Entry = Arguments->Entry;
669 return ReplaceInstruction(MI, Entry);
679 for (; MII !=
E; MII = NextMII) {
680 NextMII = std::next(MII);
688 Modified |= ReduceMI(MII, NextMII);
695 const ReduceEntry &Entry,
697 bool ConsecutiveForward) {
704 if (OpTransfer == OT_OperandsAll) {
705 MI->
setDesc(MipsII->get(Entry.NarrowOpc()));
710 const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc());
713 switch (OpTransfer) {
717 case OT_Operands02: {
722 case OT_OperandsXOR: {
734 case OT_OperandsMovep:
736 case OT_OperandsSwp: {
737 if (ConsecutiveForward) {
741 if (OpTransfer == OT_OperandsMovep)
749 if (OpTransfer == OT_OperandsMovep)
781 if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2() ||
782 Subtarget->hasMips32r6())
785 MipsII =
static_cast<const MipsInstrInfo *
>(Subtarget->getInstrInfo());
791 Modified |= ReduceMBB(*I);
797 return new MicroMipsSizeReduce();
const MachineInstrBuilder & add(const MachineOperand &MO) const
const_iterator end(StringRef path)
Get end iterator over path.
instr_iterator instr_begin()
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
instr_iterator instr_end()
OperandTransfer
Order of operands to transfer.
This class represents lattice values for constants.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Describe properties that are true of each instruction in the target description file.
unsigned getReg() const
getReg - Returns the register number.
bool isTransient() const
Return true if this is a transient instruction that is either very likely to be eliminated during reg...
STATISTIC(NumFunctions, "Total number of functions")
INITIALIZE_PASS(MicroMipsSizeReduce, DEBUG_TYPE, MICROMIPS_SIZE_REDUCE_NAME, false, false) static bool IsSP(const MachineOperand &MO)
static bool ImmInRange(MachineInstr *MI, const ReduceEntry &Entry)
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static bool ConsecutiveInstr(MachineInstr *MI1, MachineInstr *MI2)
static bool IsMovepSrcRegister(unsigned Reg)
SI optimize exec mask operations pre RA
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm)
static bool AddiuspImmValue(int64_t Value)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
static bool ConsecutiveRegisters(unsigned Reg1, unsigned Reg2)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static bool IsMovepDestinationRegPair(unsigned R0, unsigned R1)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
instr_iterator erase_instr(MachineInstr *I)
Remove an instruction from the instruction list and delete it.
#define MICROMIPS_SIZE_REDUCE_NAME
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool IsMovepDestinationReg(unsigned Reg)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMDGPU Lower Kernel Arguments
FunctionPass class - This class is used to implement most global optimizations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool isMMSourceRegister(const MachineOperand &MO)
Iterator for intrusive lists based on ilist_node.
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createMicroMipsSizeReducePass()
Returns an instance of the MicroMips size reduction pass.
const MachineBasicBlock * getParent() const
Representation of each machine instruction.
ReduceType
Reduction type.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
static bool isMMThreeBitGPRegister(const MachineOperand &MO)
static bool CheckXWPInstr(MachineInstr *MI, bool ReduceToLwp, const ReduceEntry &Entry)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
uint16_t getFlags() const
Return the MI flags bitvector.
bool operator<(int64_t V1, const APSInt &V2)
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
const MachineOperand & getOperand(unsigned i) const