forked from OSchip/llvm-project
[lld-macho] Emit REBASE_OPCODE_ADD_ADDR_IMM_SCALED if possible
An ADD_ADDR rebase opcode's argument can be encoded as an immediate if the offset is less than 15 * word size. This change reduces the size of chromium_framework by 100+ KiB. Differential Revision: https://reviews.llvm.org/D128798
This commit is contained in:
parent
017c068f78
commit
8d29f0fdb9
|
@ -202,8 +202,18 @@ static void encodeRebase(const OutputSection *osec, uint64_t outSecOff,
|
|||
lastRebase.offset = offset;
|
||||
} else {
|
||||
assert(lastRebase.offset != offset);
|
||||
os << static_cast<uint8_t>(REBASE_OPCODE_ADD_ADDR_ULEB);
|
||||
encodeULEB128(offset - lastRebase.offset, os);
|
||||
uint64_t delta = offset - lastRebase.offset;
|
||||
// For unknown reasons, ld64 checks if the scaled offset is strictly less
|
||||
// than REBASE_IMMEDIATE_MASK instead of allowing equality. We match this
|
||||
// behavior as a precaution.
|
||||
if ((delta % target->wordSize == 0) &&
|
||||
(delta / target->wordSize < REBASE_IMMEDIATE_MASK)) {
|
||||
os << static_cast<uint8_t>(REBASE_OPCODE_ADD_ADDR_IMM_SCALED |
|
||||
(delta / target->wordSize));
|
||||
} else {
|
||||
os << static_cast<uint8_t>(REBASE_OPCODE_ADD_ADDR_ULEB);
|
||||
encodeULEB128(delta, os);
|
||||
}
|
||||
lastRebase.offset = offset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
||||
# RUN: %lld -dylib %t.o -o %t.dylib
|
||||
# RUN: obj2yaml %t.dylib | FileCheck %s
|
||||
|
||||
## Test that:
|
||||
## 1/ Consecutive rebases are encoded as REBASE_OPCODE_DO_REBASE_IMM_TIMES.
|
||||
## 2/ Gaps smaller than 15 words are encoded as REBASE_OPCODE_ADD_ADDR_IMM_SCALED.
|
||||
## 3/ Gaps larger than that become REBASE_OPCODE_ADD_ADDR_ULEB.
|
||||
## FIXME: The last rebase could be transformed into a REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB.
|
||||
|
||||
# CHECK: RebaseOpcodes:
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_SET_TYPE_IMM
|
||||
# CHECK-NEXT: Imm: 1
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
|
||||
# CHECK-NEXT: Imm: 1
|
||||
# CHECK-NEXT: ExtraData: [ 0x0 ]
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES
|
||||
# CHECK-NEXT: Imm: 1
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_ADD_ADDR_IMM_SCALED
|
||||
# CHECK-NEXT: Imm: 14
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES
|
||||
# CHECK-NEXT: Imm: 3
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_ADD_ADDR_ULEB
|
||||
# CHECK-NEXT: Imm: 0
|
||||
# CHECK-NEXT: ExtraData: [ 0x78 ]
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_DO_REBASE_IMM_TIMES
|
||||
# CHECK-NEXT: Imm: 1
|
||||
# CHECK-NEXT: Opcode: REBASE_OPCODE_DONE
|
||||
# CHECK-NEXT: Imm: 0
|
||||
|
||||
|
||||
.text
|
||||
.globl _foo
|
||||
_foo:
|
||||
|
||||
.data
|
||||
.quad _foo
|
||||
.space 112
|
||||
.quad _foo
|
||||
.quad _foo
|
||||
.quad _foo
|
||||
.space 120
|
||||
.quad _foo
|
Loading…
Reference in New Issue