[Darwin] Change compact unwind encoding generation to support CFI instructions in epilogue

Hi all,

I have a question concerning compact unwind encoding generation. I am working on adding support for providing unwind info in function epilogue for X86: http://reviews.llvm.org/D18046, which means I am adding CFI instructions to a function. The instructions important to mention here are cfi_def_cfa_offset and cfi_def_cfa being added to the epilogue. During testing I found that these newly added instructions change the generated compact unwind encoding, more specifically, I located the source of the problem to be in generateCompactUnwindEncodingImpl() function. These are the changes that I made:

diff --git a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index def1b94..8076946 100644
--- a/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -542,9 +542,12 @@ protected:
          // L0:
          // .cfi_def_cfa_offset 80
- PrevStackSize = StackSize;
- StackSize = std::abs(Inst.getOffset()) / StackDivide;
- ++NumDefCFAOffsets;
+ // Find the maximum def_cfa_offset that is set in a function
+ if ((std::abs(Inst.getOffset()) / StackDivide) > StackSize) {
+ PrevStackSize = StackSize;
+ StackSize = std::abs(Inst.getOffset()) / StackDivide;
+ ++NumDefCFAOffsets;
+ }
        case MCCFIInstruction::OpOffset: {
@@ -571,6 +574,9 @@ protected:
          InstrOffset += PushInstrSize(Reg);
+ case MCCFIInstruction::OpDefCfa: {
+ break;
+ }

The first change is for the OpDefCfaOffset instruction type, where I changed the code to have the StackSize variable set to the highest offset that is found (it was set to be the last one found, which, in case when there are only CFI instructions in prologue, also was the one with the highest offset, but, when CFI instructions are added in epilogue, that is not the case anymore (because the offset decreases in epilogue)).
The second change is for the OpDefCfa instruction type. What I wanted here was to prevent the return from the function in case of OpDefCfa, however, I wasn't sure how or if that should impact the encoding generation.
My question is: do these changes make sense? If not, what is the right way to handle this?

Hi Violeta,

My question is: do these changes make sense? If not, what is the right way
to handle this?

If it was me, I'd try to make the changes depend on
FrameSetup/FrameDestroy tags (adding them if necessary). The Darwin
compact unwinder is never going to learn anything to its benefit from
a CFI instruction in the epilogue.