Skip to content

Commit d374c59

Browse files
author
Zoran Jovanovic
committedJul 14, 2017
[mips][microMIPS] Extending size reduction pass with ADDIUSP and ADDIUR1SP
Author: milena.vujosevic.janicic Reviewers: sdardis The patch extends size reduction pass for MicroMIPS. The following instructions are examined and transformed, if possible: ADDIU instruction is transformed into 16-bit instruction ADDIUSP ADDIU instruction is transformed into 16-bit instruction ADDIUR1SP Function InRange is changed to avoid left shifting of negative values, since that caused some sanitizer tests to fail (so the previous patch Differential Revision: https://reviews.llvm.org/D34511 llvm-svn: 308011
1 parent 03346c2 commit d374c59

File tree

2 files changed

+118
-14
lines changed

2 files changed

+118
-14
lines changed
 

‎llvm/lib/Target/Mips/MicroMipsSizeReduction.cpp

+101-14
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ namespace {
3232
enum OperandTransfer {
3333
OT_NA, ///< Not applicable
3434
OT_OperandsAll, ///< Transfer all operands
35+
OT_Operands02, ///< Transfer operands 0 and 2
36+
OT_Operand2, ///< Transfer just operand 2
3537
};
3638

3739
/// Reduction type
@@ -143,27 +145,44 @@ class MicroMipsSizeReduce : public MachineFunctionPass {
143145
// returns true on success.
144146
static bool ReduceSXtoSX16(MachineInstr *MI, const ReduceEntry &Entry);
145147

146-
// Attempts to reduce arithmetic instructions, returns true on success
148+
// Attempts to reduce arithmetic instructions, returns true on success.
147149
static bool ReduceArithmeticInstructions(MachineInstr *MI,
148150
const ReduceEntry &Entry);
149151

150-
// Changes opcode of an instruction
152+
// Attempts to reduce ADDIU into ADDIUSP instruction,
153+
// returns true on success.
154+
static bool ReduceADDIUToADDIUSP(MachineInstr *MI, const ReduceEntry &Entry);
155+
156+
// Attempts to reduce ADDIU into ADDIUR1SP instruction,
157+
// returns true on success.
158+
static bool ReduceADDIUToADDIUR1SP(MachineInstr *MI,
159+
const ReduceEntry &Entry);
160+
161+
// Changes opcode of an instruction.
151162
static bool ReplaceInstruction(MachineInstr *MI, const ReduceEntry &Entry);
152163

153-
// Table with transformation rules for each instruction
164+
// Table with transformation rules for each instruction.
154165
static llvm::SmallVector<ReduceEntry, 16> ReduceTable;
155166
};
156167

157168
char MicroMipsSizeReduce::ID = 0;
158169
const MipsInstrInfo *MicroMipsSizeReduce::MipsII;
159170

160171
// This table must be sorted by WideOpc as a main criterion and
161-
// ReduceType as a sub-criterion (when wide opcodes are the same)
172+
// ReduceType as a sub-criterion (when wide opcodes are the same).
162173
llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
163174

164175
// ReduceType, OpCodes, ReduceFunction,
165176
// OpInfo(TransferOperands),
166177
// ImmField(Shift, LBound, HBound, ImmFieldPosition)
178+
{RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUR1SP_MM),
179+
ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
180+
{RT_OneInstr, OpCodes(Mips::ADDiu, Mips::ADDIUSP_MM), ReduceADDIUToADDIUSP,
181+
OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
182+
{RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUR1SP_MM),
183+
ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
184+
{RT_OneInstr, OpCodes(Mips::ADDiu_MM, Mips::ADDIUSP_MM),
185+
ReduceADDIUToADDIUSP, OpInfo(OT_Operand2), ImmField(0, 0, 0, 2)},
167186
{RT_OneInstr, OpCodes(Mips::ADDu, Mips::ADDU16_MM),
168187
ReduceArithmeticInstructions, OpInfo(OT_OperandsAll),
169188
ImmField(0, 0, 0, -1)},
@@ -174,6 +193,8 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
174193
OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
175194
{RT_OneInstr, OpCodes(Mips::LBu_MM, Mips::LBU16_MM), ReduceLXUtoLXU16,
176195
OpInfo(OT_OperandsAll), ImmField(0, -1, 15, 2)},
196+
{RT_OneInstr, OpCodes(Mips::LEA_ADDiu, Mips::ADDIUR1SP_MM),
197+
ReduceADDIUToADDIUR1SP, OpInfo(OT_Operands02), ImmField(2, 0, 64, 2)},
177198
{RT_OneInstr, OpCodes(Mips::LHu, Mips::LHU16_MM), ReduceLXUtoLXU16,
178199
OpInfo(OT_OperandsAll), ImmField(1, 0, 16, 2)},
179200
{RT_OneInstr, OpCodes(Mips::LHu_MM, Mips::LHU16_MM), ReduceLXUtoLXU16,
@@ -201,9 +222,9 @@ llvm::SmallVector<ReduceEntry, 16> MicroMipsSizeReduce::ReduceTable = {
201222
{RT_OneInstr, OpCodes(Mips::SW_MM, Mips::SWSP_MM), ReduceXWtoXWSP,
202223
OpInfo(OT_OperandsAll), ImmField(2, 0, 32, 2)},
203224
};
204-
}
225+
} // namespace
205226

206-
// Returns true if the machine operand MO is register SP
227+
// Returns true if the machine operand MO is register SP.
207228
static bool IsSP(const MachineOperand &MO) {
208229
if (MO.isReg() && ((MO.getReg() == Mips::SP)))
209230
return true;
@@ -225,7 +246,7 @@ static bool isMMSourceRegister(const MachineOperand &MO) {
225246
}
226247

227248
// Returns true if the operand Op is an immediate value
228-
// and writes the immediate value into variable Imm
249+
// and writes the immediate value into variable Imm.
229250
static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm) {
230251

231252
if (!MI->getOperand(Op).isImm())
@@ -234,17 +255,27 @@ static bool GetImm(MachineInstr *MI, unsigned Op, int64_t &Imm) {
234255
return true;
235256
}
236257

258+
// Returns true if the value is a valid immediate for ADDIUSP.
259+
static bool AddiuspImmValue(int64_t Value) {
260+
int64_t Value2 = Value >> 2;
261+
if (((Value & (int64_t)maskTrailingZeros<u_int64_t>(2)) == Value) &&
262+
((Value2 >= 2 && Value2 <= 257) || (Value2 >= -258 && Value2 <= -3)))
263+
return true;
264+
return false;
265+
}
266+
237267
// Returns true if the variable Value has the number of least-significant zero
238-
// bits equal to Shift and if the shifted value is between the bounds
268+
// bits equal to Shift and if the shifted value is between the bounds.
239269
static bool InRange(int64_t Value, unsigned short Shift, int LBound,
240270
int HBound) {
241271
int64_t Value2 = Value >> Shift;
242-
if ((Value2 << Shift) == Value && (Value2 >= LBound) && (Value2 < HBound))
272+
if (((Value & (int64_t)maskTrailingZeros<u_int64_t>(Shift)) == Value) &&
273+
(Value2 >= LBound) && (Value2 < HBound))
243274
return true;
244275
return false;
245276
}
246277

247-
// Returns true if immediate operand is in range
278+
// Returns true if immediate operand is in range.
248279
static bool ImmInRange(MachineInstr *MI, const ReduceEntry &Entry) {
249280

250281
int64_t offset;
@@ -310,6 +341,34 @@ bool MicroMipsSizeReduce::ReduceArithmeticInstructions(
310341
return ReplaceInstruction(MI, Entry);
311342
}
312343

344+
bool MicroMipsSizeReduce::ReduceADDIUToADDIUR1SP(MachineInstr *MI,
345+
const ReduceEntry &Entry) {
346+
347+
if (!ImmInRange(MI, Entry))
348+
return false;
349+
350+
if (!isMMThreeBitGPRegister(MI->getOperand(0)) || !IsSP(MI->getOperand(1)))
351+
return false;
352+
353+
return ReplaceInstruction(MI, Entry);
354+
}
355+
356+
bool MicroMipsSizeReduce::ReduceADDIUToADDIUSP(MachineInstr *MI,
357+
const ReduceEntry &Entry) {
358+
359+
int64_t ImmValue;
360+
if (!GetImm(MI, Entry.ImmField(), ImmValue))
361+
return false;
362+
363+
if (!AddiuspImmValue(ImmValue))
364+
return false;
365+
366+
if (!IsSP(MI->getOperand(0)) || !IsSP(MI->getOperand(1)))
367+
return false;
368+
369+
return ReplaceInstruction(MI, Entry);
370+
}
371+
313372
bool MicroMipsSizeReduce::ReduceLXUtoLXU16(MachineInstr *MI,
314373
const ReduceEntry &Entry) {
315374

@@ -361,10 +420,37 @@ bool MicroMipsSizeReduce::ReduceMBB(MachineBasicBlock &MBB) {
361420
bool MicroMipsSizeReduce::ReplaceInstruction(MachineInstr *MI,
362421
const ReduceEntry &Entry) {
363422

364-
MI->setDesc(MipsII->get(Entry.NarrowOpc()));
365-
DEBUG(dbgs() << "Converted into 16-bit: " << *MI);
423+
enum OperandTransfer OpTransfer = Entry.TransferOperands();
424+
425+
DEBUG(dbgs() << "Converting 32-bit: " << *MI);
366426
++NumReduced;
367-
return true;
427+
428+
if (OpTransfer == OT_OperandsAll) {
429+
MI->setDesc(MipsII->get(Entry.NarrowOpc()));
430+
DEBUG(dbgs() << " to 16-bit: " << *MI);
431+
return true;
432+
} else {
433+
MachineBasicBlock &MBB = *MI->getParent();
434+
const MCInstrDesc &NewMCID = MipsII->get(Entry.NarrowOpc());
435+
DebugLoc dl = MI->getDebugLoc();
436+
MachineInstrBuilder MIB = BuildMI(MBB, MI, dl, NewMCID);
437+
438+
if (OpTransfer == OT_Operand2)
439+
MIB.add(MI->getOperand(2));
440+
else if (OpTransfer == OT_Operands02) {
441+
MIB.add(MI->getOperand(0));
442+
MIB.add(MI->getOperand(2));
443+
} else
444+
llvm_unreachable("Unknown operand transfer!");
445+
446+
// Transfer MI flags.
447+
MIB.setMIFlags(MI->getFlags());
448+
449+
DEBUG(dbgs() << " to 16-bit: " << *MIB);
450+
MBB.erase_instr(MI);
451+
return true;
452+
}
453+
return false;
368454
}
369455

370456
bool MicroMipsSizeReduce::runOnMachineFunction(MachineFunction &MF) {
@@ -373,7 +459,8 @@ bool MicroMipsSizeReduce::runOnMachineFunction(MachineFunction &MF) {
373459

374460
// TODO: Add support for other subtargets:
375461
// microMIPS32r6 and microMIPS64r6
376-
if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2())
462+
if (!Subtarget->inMicroMipsMode() || !Subtarget->hasMips32r2() ||
463+
Subtarget->hasMips32r6())
377464
return false;
378465

379466
MipsII = static_cast<const MipsInstrInfo *>(Subtarget->getInstrInfo());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips -verify-machineinstrs < %s | FileCheck %s
2+
3+
define i32 @f1() {
4+
entry:
5+
; CHECK-LABEL: f1:
6+
; CHECK: addiusp
7+
; CHECK: addiur1sp
8+
; CHECK: addiusp
9+
%a = alloca [10 x i32], align 4
10+
%index = getelementptr inbounds [10 x i32], [10 x i32]* %a, i32 0, i32 0
11+
call void @init(i32* %index)
12+
%0 = load i32, i32* %index, align 4
13+
ret i32 %0
14+
}
15+
16+
declare void @init(i32*)
17+

0 commit comments

Comments
 (0)
Please sign in to comment.