[PATCH] D74303: [CFI] cfi directive insertion for callee-save-registers in CFIInstrInserter pass

Wei Mi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 9 22:01:12 PST 2020


wmi created this revision.
wmi added reviewers: thegameg, rnk.
Herald added a subscriber: hiraditya.
Herald added a project: LLVM.

https://reviews.llvm.org/D42848 handled CFA related cfi directives but didn't handle callee-save-registers (csr) related cfi directives like .cfi_offset and .cfi_restore. This patch adds that part.

Basically it reuses the framework created in D42848 <https://reviews.llvm.org/D42848>. For each basicblock, the patch tracks which csr set have been saved at its CFG predecessors's exits, and compare the csr set with the set at its previous basicblock's exit (The previous block is the block laid before the current block). If the saved csr set at its previous basicblock's exit is larger, .cfi_restore will be inserted.

It fixes the cfi information for the simple case below. The case is shrinkwrap optimized by llvm:

  --------------- 1.cc ----------------
  void goo();
    
  long foo(bool cond, long *a) {
    if (__builtin_expect(cond, 1)) {
      goo();
      return a[0] + a[1] + a[2];
    }
    return 0;
  }
  ------------------------------------
  
  clang_without_patch -O2 -fno-omit-frame-pointer -S 1.cc
  	.cfi_startproc
  # %bb.0:                                # %entry
  	testb	%dil, %dil
  	je	.LBB0_1
  # %bb.2:                                # %if.then
  	pushq	%rbp
  	.cfi_def_cfa_offset 16
  	.cfi_offset %rbp, -16
  	movq	%rsp, %rbp
  	.cfi_def_cfa_register %rbp
  	pushq	%rbx
  	pushq	%rax
  	.cfi_offset %rbx, -24
  	movq	%rsi, %rbx
  	callq	_Z3goov
  	movq	8(%rbx), %rax
  	addq	(%rbx), %rax
  	addq	16(%rbx), %rax
  	addq	$8, %rsp
  	popq	%rbx
  	popq	%rbp
  	.cfi_def_cfa %rsp, 8
  	retq
  .LBB0_1:
  	xorl	%eax, %eax          
  	retq
  .Lfunc_end0:
  	.size	_Z3foobPl, .Lfunc_end0-_Z3foobPl
  	.cfi_endproc
  
  clang_with_patch -O2 -fno-omit-frame-pointer -S 1.cc
  	.cfi_startproc
  # %bb.0:                                # %entry
  	testb	%dil, %dil
  	je	.LBB0_1
  # %bb.2:                                # %if.then
  	pushq	%rbp
  	.cfi_def_cfa_offset 16
  	.cfi_offset %rbp, -16
  	movq	%rsp, %rbp
  	.cfi_def_cfa_register %rbp
  	pushq	%rbx
  	pushq	%rax
  	.cfi_offset %rbx, -24
  	movq	%rsi, %rbx
  	callq	_Z3goov
  	movq	8(%rbx), %rax
  	addq	(%rbx), %rax
  	addq	16(%rbx), %rax
  	addq	$8, %rsp
  	popq	%rbx
  	popq	%rbp
  	.cfi_def_cfa %rsp, 8
  	retq
  .LBB0_1:
  	.cfi_restore %rbx          <==== .cfi_restore inserted.
  	.cfi_restore %rbp          <==== .cfi_restore inserted.
  	xorl	%eax, %eax           <==== without .cfi_restore above, here libunwind will erroneously think the values of %rbx and %rbp in last stack frame are saved in current stack frame.                                                           
  	retq
  .Lfunc_end0:
  	.size	_Z3foobPl, .Lfunc_end0-_Z3foobPl
  	.cfi_endproc


Repository:
  rL LLVM

https://reviews.llvm.org/D74303

Files:
  llvm/lib/CodeGen/CFIInstrInserter.cpp
  llvm/test/CodeGen/X86/cfi-inserter-callee-save-register.mir

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D74303.243473.patch
Type: text/x-patch
Size: 6960 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200210/e67f8a17/attachment.bin>


More information about the llvm-commits mailing list