summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86FrameLowering.cpp
diff options
context:
space:
mode:
authorMichael Kuperstein <michael.m.kuperstein@intel.com>2015-11-03 08:17:25 +0000
committerMichael Kuperstein <michael.m.kuperstein@intel.com>2015-11-03 08:17:25 +0000
commit73dc85293f003c0e81b1f3e6a255a24f1f8b6db6 (patch)
treed47c802239005955de6518927110703828608564 /llvm/lib/Target/X86/X86FrameLowering.cpp
parent4ec5abffae8cd3957f69d247b92212ae92a43036 (diff)
downloadbcm5719-llvm-73dc85293f003c0e81b1f3e6a255a24f1f8b6db6.tar.gz
bcm5719-llvm-73dc85293f003c0e81b1f3e6a255a24f1f8b6db6.zip
[X86] Generate .cfi_adjust_cfa_offset correctly when pushing arguments
When push instructions are being used to pass function arguments on the stack, and either EH or debugging are enabled, we need to generate .cfi_adjust_cfa_offset directives appropriately. For (synch) EH, it is enough for the CFA offset to be correct at every call site, while for debugging we want to be correct after every push. Darwin does not support this well, so don't use pushes whenever it would be required. Differential Revision: http://reviews.llvm.org/D13767 llvm-svn: 251904
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 95cb76094ec..7b7f0daf12b 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -2105,18 +2105,23 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
unsigned StackAlign = getStackAlignment();
Amount = RoundUpToAlignment(Amount, StackAlign);
+ MachineModuleInfo &MMI = MF.getMMI();
+ const Function *Fn = MF.getFunction();
+ bool WindowsCFI = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
+ bool DwarfCFI = !WindowsCFI &&
+ (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry());
+
// If we have any exception handlers in this function, and we adjust
- // the SP before calls, we may need to indicate this to the unwinder,
- // using GNU_ARGS_SIZE. Note that this may be necessary
- // even when Amount == 0, because the preceding function may have
- // set a non-0 GNU_ARGS_SIZE.
+ // the SP before calls, we may need to indicate this to the unwinder
+ // using GNU_ARGS_SIZE. Note that this may be necessary even when
+ // Amount == 0, because the preceding function may have set a non-0
+ // GNU_ARGS_SIZE.
// TODO: We don't need to reset this between subsequent functions,
// if it didn't change.
- bool HasDwarfEHHandlers =
- !MF.getTarget().getMCAsmInfo()->usesWindowsCFI() &&
- !MF.getMMI().getLandingPads().empty();
+ bool HasDwarfEHHandlers = !WindowsCFI &&
+ !MF.getMMI().getLandingPads().empty();
- if (HasDwarfEHHandlers && !isDestroy &&
+ if (HasDwarfEHHandlers && !isDestroy &&
MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences())
BuildCFI(MBB, I, DL,
MCCFIInstruction::createGnuArgsSize(nullptr, Amount));
@@ -2128,15 +2133,37 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// (Pushes of argument for frame setup, callee pops for frame destroy)
Amount -= InternalAmt;
+ // If this is a callee-pop calling convention, and we're emitting precise
+ // SP-based CFI, emit a CFA adjust for the amount the callee popped.
+ if (isDestroy && InternalAmt && DwarfCFI && !hasFP(MF) &&
+ MMI.usePreciseUnwindInfo())
+ BuildCFI(MBB, I, DL,
+ MCCFIInstruction::createAdjustCfaOffset(nullptr, -InternalAmt));
+
if (Amount) {
// Add Amount to SP to destroy a frame, and subtract to setup.
int Offset = isDestroy ? Amount : -Amount;
- if (!(MF.getFunction()->optForMinSize() &&
+ if (!(Fn->optForMinSize() &&
adjustStackWithPops(MBB, I, DL, Offset)))
BuildStackAdjustment(MBB, I, DL, Offset, /*InEpilogue=*/false);
}
+ if (DwarfCFI && !hasFP(MF)) {
+ // If we don't have FP, but need to generate unwind information,
+ // we need to set the correct CFA offset after the stack adjustment.
+ // How much we adjust the CFA offset depends on whether we're emitting
+ // CFI only for EH purposes or for debugging. EH only requires the CFA
+ // offset to be correct at each call site, while for debugging we want
+ // it to be more precise.
+ int CFAOffset = Amount;
+ if (!MMI.usePreciseUnwindInfo())
+ CFAOffset += InternalAmt;
+ CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
+ BuildCFI(MBB, I, DL,
+ MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
+ }
+
return;
}
OpenPOWER on IntegriCloud