Skip to content

Commit

Permalink
[X86] Always generate precise CFA adjustments.
Browse files Browse the repository at this point in the history
This removes the code path that generate "synchronous" (only correct at call site) CFA.
We will probably want to re-introduce it once we are capable of emitting different
.eh_frame and .debug_frame sections.

Differential Revision: http://reviews.llvm.org/D14948

llvm-svn: 254874
  • Loading branch information
Michael Kuperstein committed Dec 6, 2015
1 parent 076dfe5 commit 77ce9d3
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 25 deletions.
11 changes: 6 additions & 5 deletions llvm/include/llvm/CodeGen/MachineModuleInfo.h
Expand Up @@ -161,6 +161,12 @@ class MachineModuleInfo : public ImmutablePass {
bool CallsUnwindInit;
bool HasEHFunclets;

// TODO: Ideally, what we'd like is to have a switch that allows emitting
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
// even under this switch, we'd like .debug_frame to be precise when using.
// -g. At this moment, there's no way to specify that some CFI directives
// go into .eh_frame only, while others go into .debug_frame only.

/// DbgInfoAvailable - True if debugging information is available
/// in this module.
bool DbgInfoAvailable;
Expand Down Expand Up @@ -235,11 +241,6 @@ class MachineModuleInfo : public ImmutablePass {
bool hasDebugInfo() const { return DbgInfoAvailable; }
void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }

// Returns true if we need to generate precise CFI. Currently
// this is equivalent to hasDebugInfo(), but if we ever implement
// async EH, it will require precise CFI as well.
bool usePreciseUnwindInfo() const { return hasDebugInfo(); }

bool callsEHReturn() const { return CallsEHReturn; }
void setCallsEHReturn(bool b) { CallsEHReturn = b; }

Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/X86/X86CallFrameOptimization.cpp
Expand Up @@ -500,7 +500,8 @@ bool X86CallFrameOptimization::adjustCallSequence(MachineFunction &MF,

// For debugging, when using SP-based CFA, we need to adjust the CFA
// offset after each push.
if (!TFL->hasFP(MF) && MF.getMMI().usePreciseUnwindInfo())
// TODO: This is needed only if we require precise CFA.
if (!TFL->hasFP(MF))
TFL->BuildCFI(MBB, std::next(Push), DL,
MCCFIInstruction::createAdjustCfaOffset(nullptr, 4));

Expand Down
21 changes: 12 additions & 9 deletions llvm/lib/Target/X86/X86FrameLowering.cpp
Expand Up @@ -2524,10 +2524,10 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// (Pushes of argument for frame setup, callee pops for frame destroy)
Amount -= InternalAmt;

// If this is a callee-pop calling convention, and we're emitting precise
// SP-based CFI, emit a CFA adjust for the amount the callee popped.
if (isDestroy && InternalAmt && DwarfCFI && !hasFP(MF) &&
MMI.usePreciseUnwindInfo())
// TODO: This is needed only if we require precise CFA.
// If this is a callee-pop calling convention, emit a CFA adjust for
// the amount the callee popped.
if (isDestroy && InternalAmt && DwarfCFI && !hasFP(MF))
BuildCFI(MBB, I, DL,
MCCFIInstruction::createAdjustCfaOffset(nullptr, -InternalAmt));

Expand All @@ -2548,11 +2548,14 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// offset to be correct at each call site, while for debugging we want
// it to be more precise.
int CFAOffset = Amount;
if (!MMI.usePreciseUnwindInfo())
CFAOffset += InternalAmt;
CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
BuildCFI(MBB, I, DL,
MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
// TODO: When not using precise CFA, we also need to adjust for the
// InternalAmt here.

if (CFAOffset) {
CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
BuildCFI(MBB, I, DL,
MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
}
}

return;
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/X86/X86MCInstLower.cpp
Expand Up @@ -1143,8 +1143,10 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
const X86FrameLowering* FrameLowering =
MF->getSubtarget<X86Subtarget>().getFrameLowering();
bool hasFP = FrameLowering->hasFP(*MF);

bool NeedsDwarfCFI = MMI->usePreciseUnwindInfo();

// TODO: This is needed only if we require precise CFA.
bool NeedsDwarfCFI =
(MMI->hasDebugInfo() || MF->getFunction()->needsUnwindTableEntry());
int stackGrowth = -RI->getSlotSize();

if (NeedsDwarfCFI && !hasFP) {
Expand Down
37 changes: 29 additions & 8 deletions llvm/test/CodeGen/X86/push-cfi.ll
Expand Up @@ -6,17 +6,24 @@ declare void @good(i32 %a, i32 %b, i32 %c, i32 %d)
declare void @large(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f)
declare void @empty()

; When we use an invoke, and have FP, we expect a .cfi_escape GNU_ARGS_SIZE
; with size 16 before the invocation. Without FP, we expect.cfi_adjust_cfa_offset
; before and after.
; Darwin should not generate pushes in neither circumstance.
; When we use an invoke, we expect a .cfi_escape GNU_ARGS_SIZE
; with size 16 before the invocation. Without FP, we also expect
; .cfi_adjust_cfa_offset after each push.
; Darwin should not generate pushes in either circumstance.
; CHECK-LABEL: test1_nofp:
; LINUX: .cfi_escape 0x2e, 0x10
; LINUX: .cfi_adjust_cfa_offset 16
; LINUX-NEXT: pushl $4
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $3
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $2
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $1
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: call
; LINUX-NEXT: addl $16, %esp
; LINUX: .cfi_adjust_cfa_offset -16
Expand Down Expand Up @@ -62,11 +69,18 @@ cleanup:
; so darwin should not generate pushes.
; CHECK-LABEL: test2_nofp:
; LINUX-NOT: .cfi_escape
; LINUX: .cfi_adjust_cfa_offset 16
; LINUX-NEXT: pushl $4
; LINUX: pushl $4
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $3
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $2
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $1
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: call
; LINUX-NEXT: addl $16, %esp
; LINUX: .cfi_adjust_cfa_offset -16
Expand Down Expand Up @@ -170,11 +184,18 @@ cleanup:
; without parameters, but don't need to adjust the cfa offset
; CHECK-LABEL: test5_nofp:
; LINUX: .cfi_escape 0x2e, 0x10
; LINUX: .cfi_adjust_cfa_offset 16
; LINUX-NEXT: pushl $4
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $3
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $2
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: pushl $1
; LINUX-NEXT: Ltmp{{[0-9]+}}:
; LINUX-NEXT: .cfi_adjust_cfa_offset 4
; LINUX-NEXT: call
; LINUX-NEXT: addl $16, %esp
; LINUX: .cfi_adjust_cfa_offset -16
Expand Down
8 changes: 8 additions & 0 deletions llvm/test/CodeGen/X86/tls-pie.ll
Expand Up @@ -36,9 +36,13 @@ entry:
define i32 @f3() {
; X32-LABEL: f3:
; X32: calll .L{{[0-9]+}}$pb
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: .cfi_adjust_cfa_offset 4
; X32-NEXT: .L{{[0-9]+}}$pb:
; X32-NEXT: popl %eax
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: .cfi_adjust_cfa_offset -4
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp{{[0-9]+}}-.L{{[0-9]+}}$pb), %eax
; X32-NEXT: movl i2@GOTNTPOFF(%eax), %eax
; X32-NEXT: movl %gs:(%eax), %eax
Expand All @@ -56,9 +60,13 @@ entry:
define i32* @f4() {
; X32-LABEL: f4:
; X32: calll .L{{[0-9]+}}$pb
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: .cfi_adjust_cfa_offset 4
; X32-NEXT: .L{{[0-9]+}}$pb:
; X32-NEXT: popl %ecx
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: .cfi_adjust_cfa_offset -4
; X32-NEXT: .Ltmp{{[0-9]+}}:
; X32-NEXT: addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp{{[0-9]+}}-.L{{[0-9]+}}$pb), %ecx
; X32-NEXT: movl %gs:0, %eax
; X32-NEXT: addl i2@GOTNTPOFF(%ecx), %eax
Expand Down
4 changes: 4 additions & 0 deletions llvm/test/CodeGen/X86/win32-pic-jumptable.ll
@@ -1,8 +1,12 @@
; RUN: llc < %s -relocation-model=pic | FileCheck %s

; CHECK: calll L0$pb
; CHECK-NEXT: Ltmp{{[0-9]+}}:
; CHECK-NEXT: .cfi_adjust_cfa_offset 4
; CHECK-NEXT: L0$pb:
; CHECK-NEXT: popl %eax
; CHECK-NEXT: Ltmp{{[0-9]+}}:
; CHECK-NEXT: .cfi_adjust_cfa_offset -4
; CHECK-NEXT: addl LJTI0_0(,%ecx,4), %eax
; CHECK-NEXT: jmpl *%eax

Expand Down

0 comments on commit 77ce9d3

Please sign in to comment.