Skip to content

Commit 1c055e8

Browse files
committed
[Mips][ASM] Optimize SW+ADDIU
We want to optimize `sw $4, 0($2) addiu $2, $2, 4 bne $2, $3, $BB0_1` to `addiu $2, $2, 4 sw $4, -4($2) bne $2, $3, $BB0_1`, so that the sw can be placed into delay slot. Fix #132685.
1 parent 5d8e8e8 commit 1c055e8

File tree

2 files changed

+135
-2
lines changed

2 files changed

+135
-2
lines changed

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ class MipsAsmParser : public MCTargetAsmParser {
146146
// nullptr, which indicates that no function is currently
147147
// selected. This usually happens after an '.end func'
148148
// directive.
149+
// Because we want do `sw $4, 0($2)
150+
// addiu $2, $2, 4
151+
// bne $2, $3, $BB0_1`
152+
// to
153+
// `addiu $2, $2, 4
154+
// sw $4, -4($2)
155+
// bne $2, $3, $BB0_1`,
156+
// so that the sw can be placed into delay slot.
157+
// If true, reprents inst `addiu` following inst `sw`, and save inst
158+
// `sw`. Later we will check if inst 'bne' following inst `addiu`.
159+
bool saveCurInst;
160+
MCInst CurInst;
161+
149162
bool IsLittleEndian;
150163
bool IsPicEnabled;
151164
bool IsCpRestoreSet;
@@ -351,6 +364,9 @@ class MipsAsmParser : public MCTargetAsmParser {
351364
bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
352365
const MCSubtargetInfo *STI);
353366

367+
MipsAsmParser::MacroExpanderResultTy expandSW(MCInst &Inst, SMLoc IDLoc,
368+
MCStreamer &Out,
369+
const MCSubtargetInfo *STI);
354370
bool reportParseError(const Twine &ErrorMsg);
355371
bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
356372

@@ -550,6 +566,7 @@ class MipsAsmParser : public MCTargetAsmParser {
550566
report_fatal_error("-mno-odd-spreg requires the O32 ABI");
551567

552568
CurrentFn = nullptr;
569+
saveCurInst = false;
553570

554571
CurForbiddenSlotAttr = false;
555572
IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
@@ -2572,8 +2589,82 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
25722589
if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
25732590
Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
25742591
int64_t ImmValue = Inst.getOperand(2).getImm();
2575-
if (isInt<16>(ImmValue))
2576-
return MER_NotAMacro;
2592+
if (isInt<16>(ImmValue)) {
2593+
if (saveCurInst == true) {
2594+
AsmToken ID = getTok();
2595+
saveCurInst = false;
2596+
bool doLex = false;
2597+
2598+
// If this is a line comment we can drop it safely.
2599+
while (getLexer().is(AsmToken::EndOfStatement)) {
2600+
doLex = true;
2601+
getLexer().Lex();
2602+
}
2603+
2604+
// Get last inst `sw` register info and offset value.
2605+
MipsTargetStreamer &TOut = getTargetStreamer();
2606+
MCRegister FirstReg = CurInst.getOperand(0).getReg();
2607+
MCRegister BaseReg = CurInst.getOperand(1).getReg();
2608+
MCOperand &OffsetImmOp = CurInst.getOperand(2);
2609+
unsigned OffsetValue = OffsetImmOp.getImm();
2610+
2611+
// Optimize `sw $4, 0($2)
2612+
// addiu $2, $2, 4
2613+
// bne $2, $3, $BB0_1`
2614+
// to
2615+
// `addiu $2, $2, 4
2616+
// sw $4, -4($2)
2617+
// bne $2, $3, $BB0_1`.
2618+
// If match sw+addiu+bne, then emit addiu+sw.
2619+
if (getTok().getString() == "bne") {
2620+
if (OffsetValue != 0) {
2621+
// Back to initial location before return.
2622+
if (doLex == true)
2623+
getLexer().UnLex(ID);
2624+
// If not match, we need to emit the last reserved instruction
2625+
// `sw`.
2626+
TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
2627+
IDLoc, STI);
2628+
return MER_NotAMacro;
2629+
}
2630+
2631+
// Get inst `addiu` register info and imm value.
2632+
MCRegister destReg = Inst.getOperand(0).getReg();
2633+
MCRegister srcReg = Inst.getOperand(1).getReg();
2634+
unsigned addImm = Inst.getOperand(2).getImm();
2635+
2636+
if (destReg == srcReg && BaseReg == destReg && addImm == 4) {
2637+
// Emit addiu+sw.
2638+
TOut.emitRRI(Inst.getOpcode(), destReg, srcReg, addImm, IDLoc,
2639+
STI);
2640+
TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg,
2641+
OffsetValue - addImm, IDLoc, STI);
2642+
// Back to initial location before return.
2643+
if (doLex == true)
2644+
getLexer().UnLex(ID);
2645+
return MER_Success;
2646+
} else {
2647+
// Back to initial location before return.
2648+
if (doLex == true)
2649+
getLexer().UnLex(ID);
2650+
// If not match, we need to emit the last reserved instruction
2651+
// `sw`.
2652+
TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
2653+
IDLoc, STI);
2654+
return MER_NotAMacro;
2655+
}
2656+
} else {
2657+
// Back to initial location before return.
2658+
if (doLex == true)
2659+
getLexer().UnLex(ID);
2660+
// If not match, we need to emit the last reserved instruction `sw`.
2661+
TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
2662+
IDLoc, STI);
2663+
return MER_NotAMacro;
2664+
}
2665+
} else
2666+
return MER_NotAMacro;
2667+
}
25772668
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
25782669
: MER_Success;
25792670
}
@@ -2646,6 +2737,8 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
26462737
case Mips::SaaAddr:
26472738
case Mips::SaadAddr:
26482739
return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2740+
case Mips::SW:
2741+
return expandSW(Inst, IDLoc, Out, STI);
26492742
}
26502743
}
26512744

@@ -5280,6 +5373,33 @@ bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
52805373
return false;
52815374
}
52825375

5376+
// Check if match sw+addiu.
5377+
MipsAsmParser::MacroExpanderResultTy
5378+
MipsAsmParser::expandSW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
5379+
const MCSubtargetInfo *STI) {
5380+
AsmToken ID = getTok();
5381+
bool doLex = false;
5382+
5383+
// If this is a line comment we can drop it safely.
5384+
while (getLexer().is(AsmToken::EndOfStatement)) {
5385+
getLexer().Lex();
5386+
doLex = true;
5387+
}
5388+
// If match sw+addiu, then save current Inst,
5389+
// and back to initial location before return.
5390+
if (getTok().getString() == "addiu") {
5391+
if (doLex == true)
5392+
getLexer().UnLex(ID);
5393+
CurInst = Inst;
5394+
saveCurInst = true;
5395+
return MER_Success;
5396+
} else {
5397+
if (doLex == true)
5398+
getLexer().UnLex(ID);
5399+
return MER_NotAMacro;
5400+
}
5401+
}
5402+
52835403
// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
52845404
// lw $<reg+1>>, offset+4($reg2)'
52855405
// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);

llvm/test/MC/Mips/sw-add-bne.s

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# RUN: llvm-mc -assemble -mcpu=mips32r6 -arch=mipsel -filetype=obj %s -o tmp.o
2+
# RUN: llvm-objdump -d tmp.o | FileCheck %s --check-prefix=MIPSELR6
3+
4+
# MIPSELR6: 00000000 <xxx>:
5+
# MIPSELR6-NEXT: addiu $2, $2, 0x4 <xxx+0x4>
6+
# MIPSELR6-NEXT: sw $4, -0x4($2)
7+
# MIPSELR6-NEXT: bne $2, $3, 0x0 <xxx>
8+
# MIPSELR6-NEXT: nop <xxx>
9+
xxx:
10+
$BB0_1: # %for.body
11+
sw $4, 0($2)
12+
addiu $2, $2, 4
13+
bne $2, $3, $BB0_1

0 commit comments

Comments
 (0)