Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lld/MachO/Arch/ARM64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,16 @@ void ARM64::populateThunk(InputSection *thunk, Symbol *funcSym) {
/*offset=*/0, /*addend=*/0,
/*referent=*/funcSym);
}
// Just a single direct branch to the target function.
// Just a single direct branch to the target function and a nop.
// The nop will improve the debuggability.
//
// Debug lines in DWARF does not recognize one-instruction sequence, and this
// thunk will be merged into other sequences if it only had one instruction.
// Adding a nop after the branch has no runtime cost, and little size impact,
// but it would make DWARF linker and debuggers happier.
static constexpr uint32_t icfSafeThunkCode[] = {
0x14000000, // 08: b target
0xD503201F, // 0c: nop
};

void ARM64::initICFSafeThunkBody(InputSection *thunk, Symbol *targetSym) const {
Expand Down
237 changes: 157 additions & 80 deletions lld/test/MachO/icf-safe-thunks-dwarf.ll

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions lld/test/MachO/icf-safe-thunks.ll
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,15 @@
;
; CHECK-ARM64: _func_2identical_v2:
; CHECK-ARM64-NEXT: b _func_2identical_v1
; CHECK-ARM64-NEXT: nop
; CHECK-ARM64-NEXT: _func_3identical_v2:
; CHECK-ARM64-NEXT: b _func_3identical_v1
; CHECK-ARM64-NEXT: nop
; CHECK-ARM64-NEXT: _func_3identical_v3:
; CHECK-ARM64-NEXT: b _func_3identical_v1
; CHECK-ARM64-NEXT: nop


; Check the size of each functions. Thunks' size will change from 4-> 8 because of added nop.
; CHECK-ARM64-MAP: 0x00000010 [ 2] _func_unique_1
; CHECK-ARM64-MAP-NEXT: 0x00000010 [ 2] _func_2identical_v1
; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_unique_2_canmerge
Expand All @@ -57,9 +60,9 @@
; CHECK-ARM64-MAP-NEXT: 0x00000000 [ 2] _func_call_thunked_2_merge
; CHECK-ARM64-MAP-NEXT: 0x00000034 [ 2] _call_all_funcs
; CHECK-ARM64-MAP-NEXT: 0x00000050 [ 2] _take_func_addr
; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_2identical_v2
; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_3identical_v2
; CHECK-ARM64-MAP-NEXT: 0x00000004 [ 2] _func_3identical_v3
; CHECK-ARM64-MAP-NEXT: 0x00000008 [ 2] _func_2identical_v2
; CHECK-ARM64-MAP-NEXT: 0x00000008 [ 2] _func_3identical_v2
; CHECK-ARM64-MAP-NEXT: 0x00000008 [ 2] _func_3identical_v3

;--- a.cpp
#define ATTR __attribute__((noinline)) extern "C"
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/CodeGen/AsmPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
/// Return a unique ID for the current function.
unsigned getFunctionNumber() const;

/// Return the number of instructions printed for the current function.
unsigned getInstructionCount() const { return NumInstsInFunction; }

/// Return symbol for the function pseudo stack if the stack frame is not a
/// register based.
virtual const MCSymbol *getFunctionFrameSymbol() const { return nullptr; }
Expand Down Expand Up @@ -940,6 +943,9 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
mutable unsigned LastFn = 0;
mutable unsigned Counter = ~0U;

/// Number of instructions printed in the current function
unsigned NumInstsInFunction = 0;

bool DwarfUsesRelocationsAcrossSections = false;

/// This method emits the header for the current function.
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1913,7 +1913,6 @@ void AsmPrinter::emitFunctionBody() {

// Print out code for the function.
bool HasAnyRealCode = false;
int NumInstsInFunction = 0;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NumInstsInFunction was already calculated for debugging purposes. We just promote them as a class member to help us determine if DW_AT_LLVM_stmt_sequence should be emitted.

bool IsEHa = MMI->getModule()->getModuleFlag("eh-asynch");

const MCSubtargetInfo *STI = nullptr;
Expand Down Expand Up @@ -2909,6 +2908,9 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
this->MF = &MF;
const Function &F = MF.getFunction();

// Reset instruction counter for the new function
NumInstsInFunction = 0;

// Record that there are split-stack functions, so we will emit a special
// section to tell the linker.
if (MF.shouldSplitStack()) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,8 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP,
*DD->getCurrentFunction()))
addFlag(*SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr);

if (emitFuncLineTableOffsets() && LineTableSym) {
if (emitFuncLineTableOffsets() && LineTableSym &&
Asm->getInstructionCount() > 1) {
addSectionLabel(
*SPDie, dwarf::DW_AT_LLVM_stmt_sequence, LineTableSym,
Asm->getObjFileLowering().getDwarfLineSection()->getBeginSymbol());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
; We don't need a line table for an empty function
; CHECK-NO-OFF-NOT: DW_LNE_set_address

; CHECK-YES-OFF: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ({{.*}})
; CHECK-YES-OFF-NOT: DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset] ({{.*}})
; CHECK-YES-OFF: Address
; CHECK-YES-OFF-NEXT: ------------------
; CHECK-YES-OFF-NEXT: DW_LNE_set_address ({{.*}})
Expand Down
Loading