summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86FrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp39
1 files changed, 26 insertions, 13 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 89fa44142a4..c9b29b59c95 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -378,11 +378,16 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 ||
Opc == X86::ADD32ri || Opc == X86::ADD32ri8) &&
PI->getOperand(0).getReg() == StackPtr){
+ assert(PI->getOperand(1).getReg() == StackPtr);
Offset += PI->getOperand(2).getImm();
MBB.erase(PI);
if (!doMergeWithPrevious) MBBI = NI;
} else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
- PI->getOperand(0).getReg() == StackPtr) {
+ PI->getOperand(0).getReg() == StackPtr &&
+ PI->getOperand(1).getReg() == StackPtr &&
+ PI->getOperand(2).getImm() == 1 &&
+ PI->getOperand(3).getReg() == X86::NoRegister &&
+ PI->getOperand(5).getReg() == X86::NoRegister) {
// For LEAs we have: def = lea SP, FI, noreg, Offset, noreg.
Offset += PI->getOperand(4).getImm();
MBB.erase(PI);
@@ -390,6 +395,7 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
} else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
Opc == X86::SUB32ri || Opc == X86::SUB32ri8) &&
PI->getOperand(0).getReg() == StackPtr) {
+ assert(PI->getOperand(1).getReg() == StackPtr);
Offset -= PI->getOperand(2).getImm();
MBB.erase(PI);
if (!doMergeWithPrevious) MBBI = NI;
@@ -2533,13 +2539,22 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
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;
+ // Add Amount to SP to destroy a frame, or subtract to setup.
+ int64_t StackAdjustment = isDestroy ? Amount : -Amount;
+
+ if (StackAdjustment) {
+ // Merge with any previous or following adjustment instruction.
+ StackAdjustment += mergeSPUpdates(MBB, I, true);
+ StackAdjustment += mergeSPUpdates(MBB, I, false);
+
+ if (!StackAdjustment) {
+ // This and the merged instruction canceled out each other.
+ return I;
+ }
- if (!(Fn->optForMinSize() &&
- adjustStackWithPops(MBB, I, DL, Offset)))
- BuildStackAdjustment(MBB, I, DL, Offset, /*InEpilogue=*/false);
+ if (!(Fn->optForMinSize() &&
+ adjustStackWithPops(MBB, I, DL, StackAdjustment)))
+ BuildStackAdjustment(MBB, I, DL, StackAdjustment, /*InEpilogue=*/false);
}
if (DwarfCFI && !hasFP(MF)) {
@@ -2549,14 +2564,12 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
// 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;
+
// TODO: When not using precise CFA, we also need to adjust for the
// InternalAmt here.
-
- if (CFAOffset) {
- CFAOffset = isDestroy ? -CFAOffset : CFAOffset;
- BuildCFI(MBB, I, DL,
- MCCFIInstruction::createAdjustCfaOffset(nullptr, CFAOffset));
+ if (StackAdjustment) {
+ BuildCFI(MBB, I, DL, MCCFIInstruction::createAdjustCfaOffset(
+ nullptr, -StackAdjustment));
}
}
OpenPOWER on IntegriCloud