On SystemZ, the outgoing argument area which is big enough for all calls in the function is created once during the prolog, as opposed to adjusting the stack around each call. The call-sequence instructions are therefore not really useful any more than to compute the maximum call frame size, which has so far been done by PEI, but can just as well be done at an earlier point. This patch removes the mapping of the CallFrameSetupOpcode and CallFrameDestroyOpcode and instead computes the MaxCallFrameSize directly after instruction selection and then removes the ADJCALLSTACK pseudos. This removes the confusing pseudos and also avoids the problem of having to keep the call frame size accurate when creating new MBBs. This fixes #76618 which exposed the need to maintain the call frame size when splitting blocks (which was not done).
140 lines
5.7 KiB
C++
140 lines
5.7 KiB
C++
//===-- SystemZFrameLowering.h - Frame lowering for SystemZ -----*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
|
|
#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H
|
|
|
|
#include "MCTargetDesc/SystemZMCTargetDesc.h"
|
|
#include "SystemZInstrBuilder.h"
|
|
#include "SystemZMachineFunctionInfo.h"
|
|
#include "llvm/ADT/IndexedMap.h"
|
|
#include "llvm/CodeGen/TargetFrameLowering.h"
|
|
#include "llvm/Support/TypeSize.h"
|
|
|
|
namespace llvm {
|
|
class SystemZSubtarget;
|
|
|
|
class SystemZFrameLowering : public TargetFrameLowering {
|
|
public:
|
|
SystemZFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl,
|
|
bool StackReal);
|
|
|
|
static std::unique_ptr<SystemZFrameLowering>
|
|
create(const SystemZSubtarget &STI);
|
|
|
|
// Override TargetFrameLowering.
|
|
bool allocateScavengingFrameIndexesNearIncomingSP(
|
|
const MachineFunction &MF) const override {
|
|
// SystemZ wants normal register scavenging slots, as close to the stack or
|
|
// frame pointer as possible.
|
|
// The default implementation assumes an x86-like layout, where the frame
|
|
// pointer is at the opposite end of the frame from the stack pointer.
|
|
// This meant that when frame pointer elimination was disabled,
|
|
// the slots ended up being as close as possible to the incoming
|
|
// stack pointer, which is the opposite of what we want on SystemZ.
|
|
return false;
|
|
}
|
|
|
|
bool hasReservedCallFrame(const MachineFunction &MF) const override;
|
|
};
|
|
|
|
class SystemZELFFrameLowering : public SystemZFrameLowering {
|
|
IndexedMap<unsigned> RegSpillOffsets;
|
|
|
|
public:
|
|
SystemZELFFrameLowering();
|
|
|
|
// Override TargetFrameLowering.
|
|
bool
|
|
assignCalleeSavedSpillSlots(MachineFunction &MF,
|
|
const TargetRegisterInfo *TRI,
|
|
std::vector<CalleeSavedInfo> &CSI) const override;
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS) const override;
|
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBI,
|
|
ArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
bool
|
|
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBII,
|
|
MutableArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
|
|
RegScavenger *RS) const override;
|
|
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
void inlineStackProbe(MachineFunction &MF,
|
|
MachineBasicBlock &PrologMBB) const override;
|
|
bool hasFP(const MachineFunction &MF) const override;
|
|
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
|
|
Register &FrameReg) const override;
|
|
void
|
|
orderFrameObjects(const MachineFunction &MF,
|
|
SmallVectorImpl<int> &ObjectsToAllocate) const override;
|
|
|
|
// Return the byte offset from the incoming stack pointer of Reg's
|
|
// ABI-defined save slot. Return 0 if no slot is defined for Reg. Adjust
|
|
// the offset in case MF has packed-stack.
|
|
unsigned getRegSpillOffset(MachineFunction &MF, Register Reg) const;
|
|
|
|
bool usePackedStack(MachineFunction &MF) const;
|
|
|
|
// Return the offset of the backchain.
|
|
unsigned getBackchainOffset(MachineFunction &MF) const {
|
|
// The back chain is stored topmost with packed-stack.
|
|
return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
|
|
}
|
|
|
|
// Get or create the frame index of where the old frame pointer is stored.
|
|
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
|
|
};
|
|
|
|
class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
|
|
IndexedMap<unsigned> RegSpillOffsets;
|
|
|
|
public:
|
|
SystemZXPLINKFrameLowering();
|
|
|
|
bool
|
|
assignCalleeSavedSpillSlots(MachineFunction &MF,
|
|
const TargetRegisterInfo *TRI,
|
|
std::vector<CalleeSavedInfo> &CSI) const override;
|
|
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS) const override;
|
|
|
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBI,
|
|
ArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
|
|
bool
|
|
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBII,
|
|
MutableArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
|
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
|
|
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
|
|
void inlineStackProbe(MachineFunction &MF,
|
|
MachineBasicBlock &PrologMBB) const override;
|
|
|
|
bool hasFP(const MachineFunction &MF) const override;
|
|
|
|
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
|
|
RegScavenger *RS) const override;
|
|
|
|
void determineFrameLayout(MachineFunction &MF) const;
|
|
};
|
|
} // end namespace llvm
|
|
|
|
#endif
|