Skip to content

Commit 5f7d6ac

Browse files
committedAug 23, 2019
[mips] Reduce number of instructions used for loading a global symbol's value
Now `lw/sw $reg, sym+offset` pseudo instructions for global symbol `sym` are lowering into the following three instructions. ``` lw $reg, %got(symbol)($gp) addiu $reg, $reg, offset lw/sw $reg, 0($reg) ``` It's possible to reduce the number of instructions by taking the offset in account in the final `lw/sw` command. This patch implements that optimization. ``` lw $reg, %got(symbol)($gp) lw/sw $reg, offset($reg) ``` Differential Revision: https://reviews.llvm.org/D66553 llvm-svn: 369756
1 parent 58492b1 commit 5f7d6ac

File tree

3 files changed

+41
-39
lines changed

3 files changed

+41
-39
lines changed
 

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

+13-5
Original file line numberDiff line numberDiff line change
@@ -3655,17 +3655,25 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
36553655
if (inPicMode()) {
36563656
// FIXME:
36573657
// a) Fix lw/sw $reg, symbol($reg) instruction expanding.
3658-
// b) If expression includes offset (sym + number), do not
3659-
// encode the offset into a relocation. Take it in account
3660-
// in the last load/store instruction.
36613658
// c) Check that immediates of R_MIPS_GOT16/R_MIPS_LO16 relocations
36623659
// do not exceed 16-bit.
36633660
// d) Use R_MIPS_GOT_PAGE/R_MIPS_GOT_OFST relocations instead
36643661
// of R_MIPS_GOT_DISP in appropriate cases to reduce number
36653662
// of GOT entries.
3666-
loadAndAddSymbolAddress(OffsetOp.getExpr(), TmpReg, Mips::NoRegister,
3663+
MCValue Res;
3664+
if (!OffsetOp.getExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) {
3665+
Error(IDLoc, "expected relocatable expression");
3666+
return;
3667+
}
3668+
if (Res.getSymB() != nullptr) {
3669+
Error(IDLoc, "expected relocatable expression with only one symbol");
3670+
return;
3671+
}
3672+
3673+
loadAndAddSymbolAddress(Res.getSymA(), TmpReg, Mips::NoRegister,
36673674
!ABI.ArePtrs64bit(), IDLoc, Out, STI);
3668-
TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, 0, IDLoc, STI);
3675+
TOut.emitRRI(Inst.getOpcode(), DstReg, TmpReg, Res.getConstant(), IDLoc,
3676+
STI);
36693677
} else {
36703678
const MCExpr *ExprOffset = OffsetOp.getExpr();
36713679
MCOperand LoOperand = MCOperand::createExpr(

‎llvm/test/MC/Mips/mips-expansions.s

+16-18
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,17 @@
122122
# CHECK-LE: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
123123

124124
lw $8, 1f+8
125-
# CHECK-LE: lw $8, %got(($tmp0)+8)($gp) # encoding: [A,A,0x88,0x8f]
126-
# CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
127-
# CHECK-LE: addiu $8, $8, %lo(($tmp0)+8) # encoding: [A,A,0x08,0x25]
128-
# CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
129-
# CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
125+
# CHECK-LE: lw $8, %got($tmp0)($gp) # encoding: [A,A,0x88,0x8f]
126+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
127+
# CHECK-LE-NEXT: addiu $8, $8, %lo($tmp0) # encoding: [A,A,0x08,0x25]
128+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
129+
# CHECK-LE-NEXT: lw $8, 8($8) # encoding: [0x08,0x00,0x08,0x8d]
130130
sw $8, 1f+8
131-
# CHECK-LE: lw $1, %got(($tmp0)+8)($gp) # encoding: [A,A,0x81,0x8f]
132-
# CHECK-LE: # fixup A - offset: 0, value: %got(($tmp0)+8), kind: fixup_Mips_GOT
133-
# CHECK-LE: addiu $1, $1, %lo(($tmp0)+8) # encoding: [A,A,0x21,0x24]
134-
# CHECK-LE: # fixup A - offset: 0, value: %lo(($tmp0)+8), kind: fixup_Mips_LO16
135-
# CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
131+
# CHECK-LE: lw $1, %got($tmp0)($gp) # encoding: [A,A,0x81,0x8f]
132+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
133+
# CHECK-LE-NEXT: addiu $1, $1, %lo($tmp0) # encoding: [A,A,0x21,0x24]
134+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
135+
# CHECK-LE-NEXT: sw $8, 8($1) # encoding: [0x08,0x00,0x28,0xac]
136136

137137
lw $10, 655483($4)
138138
# CHECK-LE: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
@@ -144,15 +144,13 @@
144144
# CHECK-LE: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
145145

146146
lw $8, symbol+8
147-
# CHECK-LE: lw $8, %got(symbol)($gp) # encoding: [A,A,0x88,0x8f]
148-
# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
149-
# CHECK-LE: addiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x25]
150-
# CHECK-LE: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
147+
# CHECK-LE: lw $8, %got(symbol)($gp) # encoding: [A,A,0x88,0x8f]
148+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
149+
# CHECK-LE-NEXT: lw $8, 8($8) # encoding: [0x08,0x00,0x08,0x8d]
151150
sw $8, symbol+8
152-
# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
153-
# CHECK-LE: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
154-
# CHECK-LE: addiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x24]
155-
# CHECK-LE: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
151+
# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]
152+
# CHECK-LE-NEXT: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
153+
# CHECK-LE-NEXT: sw $8, 8($1) # encoding: [0x08,0x00,0x28,0xac]
156154

157155
ldc1 $f0, symbol
158156
# CHECK-LE: lw $1, %got(symbol)($gp) # encoding: [A,A,0x81,0x8f]

‎llvm/test/MC/Mips/mips64-expansions.s

+12-16
Original file line numberDiff line numberDiff line change
@@ -481,15 +481,13 @@ sym:
481481
# CHECK: sw $10, 0($1) # encoding: [0x00,0x00,0x2a,0xac]
482482

483483
lw $8, sym+8
484-
# CHECK: ld $8, %got_disp(sym)($gp) # encoding: [A,A,0x88,0xdf]
485-
# CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
486-
# CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
487-
# CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
484+
# CHECK: ld $8, %got_disp(sym)($gp) # encoding: [A,A,0x88,0xdf]
485+
# CHECK-NEXT: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
486+
# CHECK-NEXT: lw $8, 8($8) # encoding: [0x08,0x00,0x08,0x8d]
488487
sw $8, sym+8
489-
# CHECK: ld $1, %got_disp(sym)($gp) # encoding: [A,A,0x81,0xdf]
490-
# CHECK: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
491-
# CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
492-
# CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
488+
# CHECK: ld $1, %got_disp(sym)($gp) # encoding: [A,A,0x81,0xdf]
489+
# CHECK-NEXT: # fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
490+
# CHECK-NEXT: sw $8, 8($1) # encoding: [0x08,0x00,0x28,0xac]
493491

494492
lw $10, 655483($4)
495493
# CHECK: lui $10, 10 # encoding: [0x0a,0x00,0x0a,0x3c]
@@ -501,15 +499,13 @@ sym:
501499
# CHECK: sw $10, -7616($1) # encoding: [0x40,0xe2,0x2a,0xac]
502500

503501
lw $8, symbol+8
504-
# CHECK: ld $8, %got_disp(symbol)($gp) # encoding: [A,A,0x88,0xdf]
505-
# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
506-
# CHECK: daddiu $8, $8, 8 # encoding: [0x08,0x00,0x08,0x65]
507-
# CHECK: lw $8, 0($8) # encoding: [0x00,0x00,0x08,0x8d]
502+
# CHECK: ld $8, %got_disp(symbol)($gp) # encoding: [A,A,0x88,0xdf]
503+
# CHECK-NEXT: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
504+
# CHECK-NEXT: lw $8, 8($8) # encoding: [0x08,0x00,0x08,0x8d]
508505
sw $8, symbol+8
509-
# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
510-
# CHECK: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
511-
# CHECK: daddiu $1, $1, 8 # encoding: [0x08,0x00,0x21,0x64]
512-
# CHECK: sw $8, 0($1) # encoding: [0x00,0x00,0x28,0xac]
506+
# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
507+
# CHECK-NEXT: # fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
508+
# CHECK-NEXT: sw $8, 8($1) # encoding: [0x08,0x00,0x28,0xac]
513509

514510
ldc1 $f0, symbol
515511
# CHECK: ld $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]

0 commit comments

Comments
 (0)
Please sign in to comment.