[PATCH] D87371: [MC] [Win64EH] Try to generate packed unwind info where possible

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 00:33:56 PDT 2020


mstorsjo added a comment.

In D87371#2264423 <https://reviews.llvm.org/D87371#2264423>, @efriedma wrote:

>> Unfortunately, in practice, this isn't ever matched by the code generated by LLVM
>
> Are you planning this as a followup?

Originally I didn't, I was just trying to fulfill my curiosity regarding this (that has ended up taking way much longer than I originally anticipated), but we'll see if I end up nerd-sniping myself into it in the end.

I'm also toying with a relaxed version of this patch, that just checks whether the layout of stored registers on the stack is right, even though the exact sequence of operations isn't the expected one. E.g. in one case, llvm generates

  sub sp, sp, #32
  stp x19, x20, [sp, #16]

which generates the same stack layout as

  stp x19, x20, [sp, #-16]!
  sub sp, sp, #16

which is possible to describe with packed unwind info. As long as unwinding doesn't happen within prologues/epilogues, it should be equal. Not sure if one wants to do that for real (the length of the synthesized canonical prologue might differ a little from the actual one maybe), but it's at least interesting to play with, to see how big gains there potentially could be by tweaking the frame lowering.



================
Comment at: llvm/lib/MC/MCWin64EH.cpp:933
 
+  if (PackedEpilogOffset == 0 && !info->HandlesExceptions &&
+      FuncLength <= 0x7ff && TryPacked) {
----------------
efriedma wrote:
> Is it always exactly zero?  Spec says in some cases "No instruction corresponding to mov x29,sp is present in the epilog"
I'm not entirely sure how to interpret that clause.

I'm looking at one case, where MSVC generates the following prologue:
```
       0: fd 7b bb a9   stp     x29, x30, [sp, #-80]!
       4: fd 03 00 91   mov     x29, sp
       8: ff 43 00 d1   sub     sp, sp, #16
```
However, the final `sub sp, sp, #16` isn't part of the canonical prologue, and this is described as packed unwind info RegI=0, CR=3, FrameSize=80, which llvm-readobj prints as
```
    Prologue [
      mov x29, sp
      stp x29, lr, [sp, #-80]!
      end
    ]
```
However the actual epilogue of the generated code looks like this:
```
      dc: ff 43 00 91   add     sp, sp, #16
      e0: fd 7b c5 a8   ldp     x29, x30, [sp], #80
```

(Here, instead of `mov sp, x29` it has `add sp, sp #16`, but it doesn't matter as they're equivalent here.)

So if unwinding from the body, the prologue is executed, and it starts off by reversing `mov x29, sp` from the prologue. But if choosing to execute the epilogue instead of the prologue, it has to execute that instruction, to get the right stack pointer.

>From testing the unwinder behaviour with RtlVirtualUnwind, it does look like it does execute `mov sp, x29` as part of the epilogue for these cases though, which would make sense.


So I guess it should be ok to generate packed data if the epilogue is an exact match of the prologue, except for the final `set_fp` opcode - but that wording actually makes me worry more about the cases where the epilogue does contain that opcode (and rely on it). And the docs say

> Packed unwind data can't be used if a function requires restoration of sp from x29.

But I'd say that the code generated by MSVC that I quoted does seem to rely on it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87371/new/

https://reviews.llvm.org/D87371



More information about the llvm-commits mailing list