[llvm-dev] Providing correct unwind info in function epilogue
Reid Kleckner via llvm-dev
llvm-dev at lists.llvm.org
Mon Jan 11 10:27:42 PST 2016
A late pass that adds CFI after block layout sounds like the right approach.
On Mon, Jan 11, 2016 at 8:04 AM, Violeta Vukobrat <
violeta.vukobrat at rt-rk.com> wrote:
> Hi all,
>
> We have been working on a solution for the problem of incorrect unwind
> info in function epilogue, reported in:
> http://lists.llvm.org/pipermail/llvm-dev/2015-August/089378.html.
> The cause of the problem are missing CFI instructions that update the rule
> for calculating CFA in the epilogue. We added the instructions for updating
> the CFA calculation rule in the X86FrameLowering::emitEpilogue() method:
> - for the case without FP, we added a cfi_def_cfa_offset instruction each
> time the stack pointer is changed
> - and for the case when FP is used, we added a cfi_def_cfa instruction
> when frame pointer is 'pop'-ed (to use stack pointer register and initial
> offset for CFA calculation from then on).
> These changes enabled the generation of correct unwind info for the
> function epilogue, for the case when epilogue is the last basic block in a
> function.
>
> However, there are a few cases that cause problems with this solution, and
> all of them have epilogue somewhere in the middle of the function, and not
> as the last basic block:
> 1. Problem when there are EH instructions below the epilogue.
> Example: a few tests in test-suite that have EH that physically comes
> after epilogue block. In the following example:
>
> 0: 53 push %rbx
> 1: 0f b6 05 00 00 00 00 movzbl 0x0(%rip),%eax # 8
> <_Z6throwsv+0x8>
> 8: 83 e0 01 and $0x1,%eax
> b: 83 f8 01 cmp $0x1,%eax
> e: 74 07 je 17 <_Z6throwsv+0x17>
> 10: b8 7b 00 00 00 mov $0x7b,%eax
> 15: 5b pop %rbx
> 16: c3 retq
> 17: bf 04 00 00 00 mov $0x4,%edi
> 1c: e8 00 00 00 00 callq 21 <_Z6throwsv+0x21>
> 21: c7 00 07 00 00 00 movl $0x7,(%rax)
> 27: be 00 00 00 00 mov $0x0,%esi
> ...
>
> code after 'retq' instruction (location 16) has the CFA calculation
> rule set after the 'pop' instruction at (location 15). However, it should
> have the CFA calculation rule set by the prologue ('push' instruction at
> location 0), and not by the epilogue.
> 2. Problems that shrink wrapping pass can potentially cause:
> 2.1. Place prologue and epilogue somewhere in the middle of the
> function (not as the first/last blocks)
> 2.2. Separate the 'return' instruction from the rest of the epilogue.
> Its physical position in the function can be above or below the epilogue.
> 2.3. After inserting prologue and epilogue code, some of the later
> passes can reorder them and merge them with other basic blocks.
> 3. Problem when multiple epilogues exist in a function.
>
> In order to solve the described problems, and provide correct rules for
> calculating CFA at each instruction in the function, we started
> implementing a new pass. This pass should run after all basic block merging
> and reordering are done (once basic blocks are in their final order).
> The pass goes through all basic blocks in the function and sets the
> correct cfi_def_cfa_offset at the beginning of each basic block. Because
> this introduces excess cfi instructions, the ones that are not necessary
> are eliminated (e.g. consecutive cfi_def_cfa_offset instructions with same
> offset value).
> This is a work in progress, as we still need to add support for setting
> correct register at the beginning of each basic block (that is needed
> because we use cfi_def_cfa instruction for the case when FP is used).
> We plan to upload a patch for review once we have a working solution,
> but for now, we wanted to see if anyone has any ideas or comments. Do you
> agree that this pass implementation is a right way to solve this issue?
>
> --
> Violeta Vukobrat
> Software Engineer
> RT-RK Computer Based Systems LLC
> www.rt-rk.com
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160111/a1bc7ec7/attachment.html>
More information about the llvm-dev
mailing list