Skip to content

Commit

Permalink
[X86][Darwin] Emit compact-unwind for register-sized stack adjustments
Browse files Browse the repository at this point in the history
For stack frames on the size of a register in x86, a code size optimization
emits "push rax/eax" instead of "sub" for stack allocation. For example:

foo:
  .cfi_startproc
BB#0:
  pushq %rax
Ltmp0:
  .cfi_def_cfa_offset 16
  ...
  .cfi_endproc

However, we are falling back to DWARF in this case because we cannot
encode %rax as a saved register.

This requirement is wrong, since we don't care about the contents of
%rax, it is the equivalent of a sub.

In order to specify that we care about the contents of %rax, we would
need a .cfi_offset %rax, <offset>.

It's also overzealous in the case where there are pushes for callee saved
registers followed by a "push rax/eax" instead of "sub", in which case we should
also be able to encode the callee saved regs and everything else using compact
unwind.

Patch authored by Bruno Cardoso Lopes.

Differential Revision: https://reviews.llvm.org/D13793

llvm-svn: 350623
  • Loading branch information
francisvm committed Jan 8, 2019
1 parent f605e82 commit 7a6d767
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
10 changes: 0 additions & 10 deletions llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
Expand Up @@ -635,16 +635,6 @@ class DarwinX86AsmBackend : public X86AsmBackend {
CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
} else {
// If the amount of the stack allocation is the size of a register, then
// we "push" the RAX/EAX register onto the stack instead of adjusting the
// stack pointer with a SUB instruction. We don't support the push of the
// RAX/EAX register with compact unwind. So we check for that situation
// here.
if ((NumDefCFAOffsets == SavedRegIdx + 1 &&
StackSize - PrevStackSize == 1) ||
(Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2))
return CU::UNWIND_MODE_DWARF;

SubtractInstrIdx += InstrOffset;
++StackAdjust;

Expand Down
18 changes: 18 additions & 0 deletions llvm/test/MC/X86/compact-unwind.s
Expand Up @@ -64,6 +64,24 @@ Ltmp14:
retq
.cfi_endproc

# Check that a adjustment through a push %rax is the same as a sub.

# CHECK: Entry at offset 0x40:
# CHECK-NEXT: start: 0x2a _testrax
# CHECK-NEXT: length: 0x5
# CHECK-NEXT: compact encoding: 0x02020000
.globl _testrax
_testrax: ## @testrax
.cfi_startproc
## %bb.0: ## %entry
pushq %rax
Ltmp15:
.cfi_def_cfa_offset 16
xorl %eax, %eax
popq %rax
retq
.cfi_endproc

.section __TEXT,__cstring,cstring_literals
L_.str: ## @.str
.asciz "%d\n"
Expand Down

0 comments on commit 7a6d767

Please sign in to comment.