-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Mips][ASM] Optimize SW+ADDIU #144997
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Mips][ASM] Optimize SW+ADDIU #144997
Conversation
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 llvm#132685.
|
@llvm/pr-subscribers-backend-mips @llvm/pr-subscribers-mc Author: None (yingopq) ChangesWe want to optimize Fix #132685. Full diff: https://github.com/llvm/llvm-project/pull/144997.diff 2 Files Affected:
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 640ae52d05dd1..2aeb868ad3794 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -146,6 +146,19 @@ class MipsAsmParser : public MCTargetAsmParser {
// nullptr, which indicates that no function is currently
// selected. This usually happens after an '.end func'
// directive.
+ // Because we want do `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.
+ // If true, reprents inst `addiu` following inst `sw`, and save inst
+ // `sw`. Later we will check if inst 'bne' following inst `addiu`.
+ bool saveCurInst;
+ MCInst CurInst;
+
bool IsLittleEndian;
bool IsPicEnabled;
bool IsCpRestoreSet;
@@ -351,6 +364,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
+ MipsAsmParser::MacroExpanderResultTy expandSW(MCInst &Inst, SMLoc IDLoc,
+ MCStreamer &Out,
+ const MCSubtargetInfo *STI);
bool reportParseError(const Twine &ErrorMsg);
bool reportParseError(SMLoc Loc, const Twine &ErrorMsg);
@@ -550,6 +566,7 @@ class MipsAsmParser : public MCTargetAsmParser {
report_fatal_error("-mno-odd-spreg requires the O32 ABI");
CurrentFn = nullptr;
+ saveCurInst = false;
CurForbiddenSlotAttr = false;
IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
@@ -2572,8 +2589,82 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
int64_t ImmValue = Inst.getOperand(2).getImm();
- if (isInt<16>(ImmValue))
- return MER_NotAMacro;
+ if (isInt<16>(ImmValue)) {
+ if (saveCurInst == true) {
+ AsmToken ID = getTok();
+ saveCurInst = false;
+ bool doLex = false;
+
+ // If this is a line comment we can drop it safely.
+ while (getLexer().is(AsmToken::EndOfStatement)) {
+ doLex = true;
+ getLexer().Lex();
+ }
+
+ // Get last inst `sw` register info and offset value.
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ MCRegister FirstReg = CurInst.getOperand(0).getReg();
+ MCRegister BaseReg = CurInst.getOperand(1).getReg();
+ MCOperand &OffsetImmOp = CurInst.getOperand(2);
+ unsigned OffsetValue = OffsetImmOp.getImm();
+
+ // 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`.
+ // If match sw+addiu+bne, then emit addiu+sw.
+ if (getTok().getString() == "bne") {
+ if (OffsetValue != 0) {
+ // Back to initial location before return.
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ // If not match, we need to emit the last reserved instruction
+ // `sw`.
+ TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
+ IDLoc, STI);
+ return MER_NotAMacro;
+ }
+
+ // Get inst `addiu` register info and imm value.
+ MCRegister destReg = Inst.getOperand(0).getReg();
+ MCRegister srcReg = Inst.getOperand(1).getReg();
+ unsigned addImm = Inst.getOperand(2).getImm();
+
+ if (destReg == srcReg && BaseReg == destReg && addImm == 4) {
+ // Emit addiu+sw.
+ TOut.emitRRI(Inst.getOpcode(), destReg, srcReg, addImm, IDLoc,
+ STI);
+ TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg,
+ OffsetValue - addImm, IDLoc, STI);
+ // Back to initial location before return.
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ return MER_Success;
+ } else {
+ // Back to initial location before return.
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ // If not match, we need to emit the last reserved instruction
+ // `sw`.
+ TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
+ IDLoc, STI);
+ return MER_NotAMacro;
+ }
+ } else {
+ // Back to initial location before return.
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ // If not match, we need to emit the last reserved instruction `sw`.
+ TOut.emitRRI(CurInst.getOpcode(), FirstReg, BaseReg, OffsetValue,
+ IDLoc, STI);
+ return MER_NotAMacro;
+ }
+ } else
+ return MER_NotAMacro;
+ }
return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
: MER_Success;
}
@@ -2646,6 +2737,8 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
case Mips::SaaAddr:
case Mips::SaadAddr:
return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
+ case Mips::SW:
+ return expandSW(Inst, IDLoc, Out, STI);
}
}
@@ -5280,6 +5373,33 @@ bool MipsAsmParser::expandDMULMacro(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
+// Check if match sw+addiu.
+MipsAsmParser::MacroExpanderResultTy
+MipsAsmParser::expandSW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ AsmToken ID = getTok();
+ bool doLex = false;
+
+ // If this is a line comment we can drop it safely.
+ while (getLexer().is(AsmToken::EndOfStatement)) {
+ getLexer().Lex();
+ doLex = true;
+ }
+ // If match sw+addiu, then save current Inst,
+ // and back to initial location before return.
+ if (getTok().getString() == "addiu") {
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ CurInst = Inst;
+ saveCurInst = true;
+ return MER_Success;
+ } else {
+ if (doLex == true)
+ getLexer().UnLex(ID);
+ return MER_NotAMacro;
+ }
+}
+
// Expand 'ld $<reg> offset($reg2)' to 'lw $<reg>, offset($reg2);
// lw $<reg+1>>, offset+4($reg2)'
// or expand 'sd $<reg> offset($reg2)' to 'sw $<reg>, offset($reg2);
diff --git a/llvm/test/MC/Mips/sw-add-bne.s b/llvm/test/MC/Mips/sw-add-bne.s
new file mode 100644
index 0000000000000..b4a739db7419b
--- /dev/null
+++ b/llvm/test/MC/Mips/sw-add-bne.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc -assemble -mcpu=mips32r6 -arch=mipsel -filetype=obj %s -o tmp.o
+# RUN: llvm-objdump -d tmp.o | FileCheck %s --check-prefix=MIPSELR6
+
+# MIPSELR6: 00000000 <xxx>:
+# MIPSELR6-NEXT: addiu $2, $2, 0x4 <xxx+0x4>
+# MIPSELR6-NEXT: sw $4, -0x4($2)
+# MIPSELR6-NEXT: bne $2, $3, 0x0 <xxx>
+# MIPSELR6-NEXT: nop <xxx>
+xxx:
+$BB0_1: # %for.body
+ sw $4, 0($2)
+ addiu $2, $2, 4
+ bne $2, $3, $BB0_1
|
1 similar comment
|
@wzssyqa Do we need to optimize this issue, could you help me confirm it again? |
We want to optimize
to
so that the sw can be placed into delay slot.
Fix #132685.