Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Call Frame Information (CFI) Handling for Basic Block Sections
This patch handles CFI with basic block sections, which unlike DebugInfo does not support ranges. The DWARF standard explicitly requires emitting separate CFI Frame Descriptor Entries for each contiguous fragment of a function. Thus, the CFI information for all callee-saved registers (possibly including the frame pointer, if necessary) have to be emitted along with redefining the Call Frame Address (CFA), viz. where the current frame starts. CFI directives are emitted in FDE’s in the object file with a low_pc, high_pc specification. So, a single FDE must point to a contiguous code region unlike debug info which has the support for ranges. This is what complicates CFI for basic block sections. Now, what happens when we start placing individual basic blocks in unique sections: * Basic block sections allow the linker to randomly reorder basic blocks in the address space such that a given basic block can become non-contiguous with the original function. * The different basic block sections can no longer share the cfi_startproc and cfi_endproc directives. So, each basic block section should emit this independently. * Each (cfi_startproc, cfi_endproc) directive will result in a new FDE that caters to that basic block section. * Now, this basic block section needs to duplicate the information from the entry block to compute the CFA as it is an independent entity. It cannot refer to the FDE of the original function and hence must duplicate all the stuff that is needed to compute the CFA on its own. * We are working on a de-duplication patch that can share common information in FDEs in a CIE (Common Information Entry) and we will present this as a follow up patch. This can significantly reduce the duplication overhead and is particularly useful when several basic block sections are created. * The CFI directives are emitted similarly for registers that are pushed onto the stack, like callee saved registers in the prologue. There are cfi directives that emit how to retrieve the value of the register at that point when the push happened. This has to be duplicated too in a basic block that is floated as a separate section. Differential Revision: https://reviews.llvm.org/D79978
- Loading branch information
Showing
10 changed files
with
241 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
; RUN: llc -O0 %s --basicblock-sections=all -mtriple=x86_64 -filetype=asm --frame-pointer=all -o - | FileCheck --check-prefix=SECTIONS_CFI %s | ||
; RUN: llc -O0 %s --basicblock-sections=all -mtriple=x86_64 -filetype=asm --frame-pointer=none -o - | FileCheck --check-prefix=SECTIONS_NOFP_CFI %s | ||
; RUN: llc -O0 %s --basicblock-sections=all -mtriple=x86_64 -filetype=obj --frame-pointer=all -o - | llvm-dwarfdump --eh-frame - | FileCheck --check-prefix=EH_FRAME %s | ||
|
||
;; void f1(); | ||
;; void f3(bool b) { | ||
;; if (b) | ||
;; f1(); | ||
;; } | ||
|
||
|
||
; SECTIONS_CFI: _Z2f3b: | ||
; SECTIONS_CFI: .cfi_startproc | ||
; SECTIONS_CFI: .cfi_def_cfa_offset 16 | ||
; SECTIONS_CFI: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_def_cfa_register %rbp | ||
; SECTIONS_CFI: .cfi_endproc | ||
|
||
; SECTIONS_CFI: _Z2f3b.1: | ||
; SECTIONS_CFI-NEXT: .cfi_startproc | ||
; SECTIONS_CFI-NEXT: .cfi_def_cfa %rbp, 16 | ||
; SECTIONS_CFI-NEXT: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_endproc | ||
|
||
; SECTIONS_CFI: _Z2f3b.2: | ||
; SECTIONS_CFI-NEXT: .cfi_startproc | ||
; SECTIONS_CFI-NEXT: .cfi_def_cfa %rbp, 16 | ||
; SECTIONS_CFI-NEXT: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_def_cfa | ||
; SECTIONS_CFI: .cfi_endproc | ||
|
||
|
||
; SECTIONS_NOFP_CFI: _Z2f3b: | ||
; SECTIONS_NOFP_CFI: .cfi_startproc | ||
; SECTIONS_NOFP_CFI: .cfi_def_cfa_offset 16 | ||
; SECTIONS_NOFP_CFI: .cfi_endproc | ||
|
||
; SECTIONS_NOFP_CFI: _Z2f3b.1: | ||
; SECTIONS_NOFP_CFI-NEXT: .cfi_startproc | ||
; SECTIONS_NOFP_CFI-NEXT: .cfi_def_cfa %rsp, 16 | ||
; SECTIONS_NOFP_CFI: .cfi_endproc | ||
|
||
; SECTIONS_NOFP_CFI: _Z2f3b.2: | ||
; SECTIONS_NOFP_CFI-NEXT: .cfi_startproc | ||
; SECTIONS_NOFP_CFI-NEXT: .cfi_def_cfa %rsp, 16 | ||
; SECTIONS_NOFP_CFI: .cfi_endproc | ||
|
||
|
||
;; There must be 1 CIE and 3 FDEs. | ||
|
||
; EH_FRAME: CIE | ||
; EH_FRAME: DW_CFA_def_cfa | ||
; EH_FRAME: DW_CFA_offset | ||
|
||
; EH_FRAME: FDE cie= | ||
; EH_FRAME: DW_CFA_def_cfa_offset | ||
; EH_FRAME: DW_CFA_offset | ||
; EH_FRAME: DW_CFA_def_cfa_register | ||
|
||
; EH_FRAME: FDE cie= | ||
; EH_FRAME: DW_CFA_def_cfa | ||
; EH_FRAME: DW_CFA_offset | ||
|
||
; EH_FRAME: FDE cie= | ||
; EH_FRAME: DW_CFA_def_cfa | ||
; EH_FRAME: DW_CFA_offset | ||
|
||
; Function Attrs: noinline optnone uwtable | ||
define dso_local void @_Z2f3b(i1 zeroext %b) { | ||
entry: | ||
%b.addr = alloca i8, align 1 | ||
%frombool = zext i1 %b to i8 | ||
store i8 %frombool, i8* %b.addr, align 1 | ||
%0 = load i8, i8* %b.addr, align 1 | ||
%tobool = trunc i8 %0 to i1 | ||
br i1 %tobool, label %if.then, label %if.end | ||
|
||
if.then: ; preds = %entry | ||
call void @_Z2f1v() | ||
br label %if.end | ||
|
||
if.end: ; preds = %if.then, %entry | ||
ret void | ||
} | ||
|
||
declare dso_local void @_Z2f1v() |
53 changes: 53 additions & 0 deletions
53
llvm/test/CodeGen/X86/cfi-inserter-basic-block-sections-callee-save-registers.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
;; This test checks if CFI instructions for all callee saved registers are emitted | ||
;; correctly with basic block sections. | ||
; RUN: llc %s -mtriple=x86_64 -filetype=asm --basicblock-sections=all --frame-pointer=all -o - | FileCheck --check-prefix=SECTIONS_CFI %s | ||
|
||
; SECTIONS_CFI: _Z3foob: | ||
; SECTIONS_CFI: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_offset [[RA:%r.+]], -56 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RB:%r.+]], -48 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RC:%r.+]], -40 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RD:%r.+]], -32 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RE:%r.+]], -24 | ||
|
||
; SECTIONS_CFI: _Z3foob.1: | ||
; SECTIONS_CFI: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_offset [[RA]], -56 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RB]], -48 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RC]], -40 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RD]], -32 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RE]], -24 | ||
|
||
; SECTIONS_CFI: _Z3foob.2: | ||
; SECTIONS_CFI: .cfi_offset %rbp, -16 | ||
; SECTIONS_CFI: .cfi_offset [[RA]], -56 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RB]], -48 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RC]], -40 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RD]], -32 | ||
; SECTIONS_CFI-NEXT: .cfi_offset [[RE]], -24 | ||
|
||
|
||
;; void foo(bool b) { | ||
;; if (b) // adds a basic block | ||
;; // clobber all callee-save registers to force them to be callee-saved and to | ||
;; // be described by cfi_offset directives. | ||
;; asm("nop" ::: "r12", "r13", "r14", "r15", "rbx"); | ||
;; } | ||
|
||
define dso_local void @_Z3foob(i1 zeroext %b) { | ||
entry: | ||
%b.addr = alloca i8, align 1 | ||
%frombool = zext i1 %b to i8 | ||
store i8 %frombool, i8* %b.addr, align 1 | ||
%0 = load i8, i8* %b.addr, align 1 | ||
%tobool = trunc i8 %0 to i1 | ||
br i1 %tobool, label %if.then, label %if.end | ||
|
||
if.then: ; preds = %entry | ||
call void asm sideeffect "nop", "~{r12},~{r13},~{r14},~{r15},~{rbx},~{dirflag},~{fpsr},~{flags}"() #1, !srcloc !2 | ||
br label %if.end | ||
|
||
if.end: ; preds = %if.then, %entry | ||
ret void | ||
} | ||
!2 = !{i32 38} |