diff options
Diffstat (limited to 'lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r-- | lib/Target/X86/X86FrameLowering.cpp | 80 |
1 files changed, 48 insertions, 32 deletions
diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 984db12201ed..e310fe069117 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1,9 +1,8 @@ //===-- X86FrameLowering.cpp - X86 Frame Information ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -585,23 +584,23 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF, // registers. For the prolog expansion we use RAX, RCX and RDX. MachineRegisterInfo &MRI = MF.getRegInfo(); const TargetRegisterClass *RegClass = &X86::GR64RegClass; - const unsigned SizeReg = InProlog ? (unsigned)X86::RAX + const Register SizeReg = InProlog ? X86::RAX : MRI.createVirtualRegister(RegClass), - ZeroReg = InProlog ? (unsigned)X86::RCX + ZeroReg = InProlog ? X86::RCX : MRI.createVirtualRegister(RegClass), - CopyReg = InProlog ? (unsigned)X86::RDX + CopyReg = InProlog ? X86::RDX : MRI.createVirtualRegister(RegClass), - TestReg = InProlog ? (unsigned)X86::RDX + TestReg = InProlog ? X86::RDX : MRI.createVirtualRegister(RegClass), - FinalReg = InProlog ? (unsigned)X86::RDX + FinalReg = InProlog ? X86::RDX : MRI.createVirtualRegister(RegClass), - RoundedReg = InProlog ? (unsigned)X86::RDX + RoundedReg = InProlog ? X86::RDX : MRI.createVirtualRegister(RegClass), - LimitReg = InProlog ? (unsigned)X86::RCX + LimitReg = InProlog ? X86::RCX : MRI.createVirtualRegister(RegClass), - JoinReg = InProlog ? (unsigned)X86::RCX + JoinReg = InProlog ? X86::RCX : MRI.createVirtualRegister(RegClass), - ProbeReg = InProlog ? (unsigned)X86::RCX + ProbeReg = InProlog ? X86::RCX : MRI.createVirtualRegister(RegClass); // SP-relative offsets where we can save RCX and RDX. @@ -654,9 +653,10 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF, BuildMI(&MBB, DL, TII.get(X86::SUB64rr), TestReg) .addReg(CopyReg) .addReg(SizeReg); - BuildMI(&MBB, DL, TII.get(X86::CMOVB64rr), FinalReg) + BuildMI(&MBB, DL, TII.get(X86::CMOV64rr), FinalReg) .addReg(TestReg) - .addReg(ZeroReg); + .addReg(ZeroReg) + .addImm(X86::COND_B); // FinalReg now holds final stack pointer value, or zero if // allocation would overflow. Compare against the current stack @@ -673,7 +673,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF, .addReg(X86::GS); BuildMI(&MBB, DL, TII.get(X86::CMP64rr)).addReg(FinalReg).addReg(LimitReg); // Jump if the desired stack pointer is at or above the stack limit. - BuildMI(&MBB, DL, TII.get(X86::JAE_1)).addMBB(ContinueMBB); + BuildMI(&MBB, DL, TII.get(X86::JCC_1)).addMBB(ContinueMBB).addImm(X86::COND_AE); // Add code to roundMBB to round the final stack pointer to a page boundary. RoundMBB->addLiveIn(FinalReg); @@ -710,7 +710,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF, BuildMI(LoopMBB, DL, TII.get(X86::CMP64rr)) .addReg(RoundedReg) .addReg(ProbeReg); - BuildMI(LoopMBB, DL, TII.get(X86::JNE_1)).addMBB(LoopMBB); + BuildMI(LoopMBB, DL, TII.get(X86::JCC_1)).addMBB(LoopMBB).addImm(X86::COND_NE); MachineBasicBlock::iterator ContinueMBBI = ContinueMBB->getFirstNonPHI(); @@ -794,8 +794,8 @@ void X86FrameLowering::emitStackProbeCall(MachineFunction &MF, .addExternalSymbol(MF.createExternalSymbolName(Symbol)); } - unsigned AX = Is64Bit ? X86::RAX : X86::EAX; - unsigned SP = Is64Bit ? X86::RSP : X86::ESP; + unsigned AX = Uses64BitFramePtr ? X86::RAX : X86::EAX; + unsigned SP = Uses64BitFramePtr ? X86::RSP : X86::ESP; CI.addReg(AX, RegState::Implicit) .addReg(SP, RegState::Implicit) .addReg(AX, RegState::Define | RegState::Implicit) @@ -809,7 +809,7 @@ void X86FrameLowering::emitStackProbeCall(MachineFunction &MF, // adjusting %rsp. // All other platforms do not specify a particular ABI for the stack probe // function, so we arbitrarily define it to not adjust %esp/%rsp itself. - BuildMI(MBB, MBBI, DL, TII.get(getSUBrrOpcode(Is64Bit)), SP) + BuildMI(MBB, MBBI, DL, TII.get(getSUBrrOpcode(Uses64BitFramePtr)), SP) .addReg(SP) .addReg(AX); } @@ -872,6 +872,17 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB, MI->getOperand(3).setIsDead(); } +bool X86FrameLowering::has128ByteRedZone(const MachineFunction& MF) const { + // x86-64 (non Win64) has a 128 byte red zone which is guaranteed not to be + // clobbered by any interrupt handler. + assert(&STI == &MF.getSubtarget<X86Subtarget>() && + "MF used frame lowering for wrong subtarget"); + const Function &Fn = MF.getFunction(); + const bool IsWin64CC = STI.isCallingConvWin64(Fn.getCallingConv()); + return Is64Bit && !IsWin64CC && !Fn.hasFnAttribute(Attribute::NoRedZone); +} + + /// emitPrologue - Push callee-saved registers onto the stack, which /// automatically adjust the stack pointer. Adjust the stack pointer to allocate /// space for local variables. Also emit labels used by the exception handler to @@ -976,7 +987,6 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, MF.hasEHFunclets() && Personality == EHPersonality::CoreCLR; bool IsClrFunclet = IsFunclet && FnHasClrFunclet; bool HasFP = hasFP(MF); - bool IsWin64CC = STI.isCallingConvWin64(Fn.getCallingConv()); bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); bool NeedsWin64CFI = IsWin64Prologue && Fn.needsUnwindTableEntry(); // FIXME: Emit FPO data for EH funclets. @@ -1030,12 +1040,11 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, // pointer, calls, or dynamic alloca then we do not need to adjust the // stack pointer (we fit in the Red Zone). We also check that we don't // push and pop from the stack. - if (Is64Bit && !Fn.hasFnAttribute(Attribute::NoRedZone) && + if (has128ByteRedZone(MF) && !TRI->needsStackRealignment(MF) && !MFI.hasVarSizedObjects() && // No dynamic alloca. !MFI.adjustsStack() && // No calls. !UseStackProbe && // No stack probes. - !IsWin64CC && // Win64 has no Red Zone !MFI.hasCopyImplyingStackAdjustment() && // Don't push and pop. !MF.shouldSplitStack()) { // Regular stack uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); @@ -1774,6 +1783,15 @@ int X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); int64_t FPDelta = 0; + // In an x86 interrupt, remove the offset we added to account for the return + // address from any stack object allocated in the caller's frame. Interrupts + // do not have a standard return address. Fixed objects in the current frame, + // such as SSE register spills, should not get this treatment. + if (MF.getFunction().getCallingConv() == CallingConv::X86_INTR && + Offset >= 0) { + Offset += getOffsetOfLocalArea(); + } + if (IsWin64Prologue) { assert(!MFI.hasCalls() || (StackSize % 16) == 8); @@ -1888,8 +1906,7 @@ X86FrameLowering::getFrameIndexReferencePreferSP(const MachineFunction &MF, // If !hasReservedCallFrame the function might have SP adjustement in the // body. So, even though the offset is statically known, it depends on where // we are in the function. - const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); - if (!IgnoreSPUpdates && !TFI->hasReservedCallFrame(MF)) + if (!IgnoreSPUpdates && !hasReservedCallFrame(MF)) return getFrameIndexReference(MF, FI, FrameReg); // We don't handle tail calls, and shouldn't be seeing them either. @@ -2407,7 +2424,7 @@ void X86FrameLowering::adjustForSegmentedStacks( // This jump is taken if SP >= (Stacklet Limit + Stack Space required). // It jumps to normal execution of the function body. - BuildMI(checkMBB, DL, TII.get(X86::JA_1)).addMBB(&PrologueMBB); + BuildMI(checkMBB, DL, TII.get(X86::JCC_1)).addMBB(&PrologueMBB).addImm(X86::COND_A); // On 32 bit we first push the arguments size and then the frame size. On 64 // bit, we pass the stack frame size in r10 and the argument size in r11. @@ -2637,7 +2654,7 @@ void X86FrameLowering::adjustForHiPEPrologue( // SPLimitOffset is in a fixed heap location (pointed by BP). addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(CMPop)) .addReg(ScratchReg), PReg, false, SPLimitOffset); - BuildMI(stackCheckMBB, DL, TII.get(X86::JAE_1)).addMBB(&PrologueMBB); + BuildMI(stackCheckMBB, DL, TII.get(X86::JCC_1)).addMBB(&PrologueMBB).addImm(X86::COND_AE); // Create new MBB for IncStack: BuildMI(incStackMBB, DL, TII.get(CALLop)). @@ -2646,7 +2663,7 @@ void X86FrameLowering::adjustForHiPEPrologue( SPReg, false, -MaxStack); addRegOffset(BuildMI(incStackMBB, DL, TII.get(CMPop)) .addReg(ScratchReg), PReg, false, SPLimitOffset); - BuildMI(incStackMBB, DL, TII.get(X86::JLE_1)).addMBB(incStackMBB); + BuildMI(incStackMBB, DL, TII.get(X86::JCC_1)).addMBB(incStackMBB).addImm(X86::COND_LE); stackCheckMBB->addSuccessor(&PrologueMBB, {99, 100}); stackCheckMBB->addSuccessor(incStackMBB, {1, 100}); @@ -2802,7 +2819,7 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, StackAdjustment += mergeSPUpdates(MBB, InsertPos, false); if (StackAdjustment) { - if (!(F.optForMinSize() && + if (!(F.hasMinSize() && adjustStackWithPops(MBB, InsertPos, DL, StackAdjustment))) BuildStackAdjustment(MBB, InsertPos, DL, StackAdjustment, /*InEpilogue=*/false); @@ -3079,8 +3096,7 @@ void X86FrameLowering::orderFrameObjects( // Sort the objects using X86FrameSortingAlgorithm (see its comment for // info). - std::stable_sort(SortingObjects.begin(), SortingObjects.end(), - X86FrameSortingComparator()); + llvm::stable_sort(SortingObjects, X86FrameSortingComparator()); // Now modify the original list to represent the final order that // we want. The order will depend on whether we're going to access them @@ -3154,7 +3170,7 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized( MinFixedObjOffset -= std::abs(MinFixedObjOffset) % 8; int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize; int UnwindHelpFI = - MFI.CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false); + MFI.CreateFixedObject(SlotSize, UnwindHelpOffset, /*IsImmutable=*/false); EHInfo.UnwindHelpFrameIdx = UnwindHelpFI; // Store -2 into UnwindHelp on function entry. We have to scan forwards past |