-
Notifications
You must be signed in to change notification settings - Fork 14.2k
[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
Open
yingopq
wants to merge
1
commit into
llvm:main
Choose a base branch
from
yingopq:Fix_bug_issue_132685
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[Mips][ASM] Optimize SW+ADDIU #144997
+135
−2
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We want to optimize
to
so that the sw can be placed into delay slot.
Fix #132685.