
PEI previously used fake frame indices for these callee saved registers. These fake frame indices are not register with MachineFrameInfo. This required them to be deleted form CalleeSavedInfo after PEI to avoid breaking later passes. See #79535 Unfortunately, removing the registers from CalleeSavedInfo pessimizes Interprocedural Register Allocation. The RegUsageInfoCollector pass runs after PEI and uses CalleeSavedInfo. This patch replaces #79535 by properly creating fixed stack objects through MachineFrameInfo. This changes the stack size and offsets returned by MachineFrameInfo which requires changes to how RISCVFrameLowering uses that information. In addition to the individual object for each register, I've also create a single large fixed object that covers the entire stack area covered by cm.push or the libcalls. cm.push must always push a multiple of 16 bytes and the save restore libcall pushes a multiple of stack align. I think this leaves holes in the stack where we could spill other registers, but it matches what we did previously. Maybe we can optimize this in the future. The only test changes are due to stack alignment handling after the callee save registers. Since we now have the fixed objects, on the stack the offset is non-zero when an aligned object is processed so the offset gets rounded up, increasing the stack size. I suspect we might need some more updates for RVV related code. There is very little or maybe even no testing of RVV mixed with Zcmp and save-restore.
96 lines
3.9 KiB
C++
96 lines
3.9 KiB
C++
//===-- RISCVFrameLowering.h - Define frame lowering for RISC-V -*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class implements RISC-V specific bits of TargetFrameLowering class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
|
|
#define LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
|
|
|
|
#include "llvm/CodeGen/TargetFrameLowering.h"
|
|
#include "llvm/Support/TypeSize.h"
|
|
|
|
namespace llvm {
|
|
class RISCVSubtarget;
|
|
|
|
class RISCVFrameLowering : public TargetFrameLowering {
|
|
public:
|
|
explicit RISCVFrameLowering(const RISCVSubtarget &STI);
|
|
|
|
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
|
|
uint64_t getStackSizeWithRVVPadding(const MachineFunction &MF) const;
|
|
|
|
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
|
|
Register &FrameReg) const override;
|
|
|
|
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
|
RegScavenger *RS) const override;
|
|
|
|
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
|
|
RegScavenger *RS) const override;
|
|
|
|
bool hasFP(const MachineFunction &MF) const override;
|
|
|
|
bool hasBP(const MachineFunction &MF) const;
|
|
|
|
bool hasReservedCallFrame(const MachineFunction &MF) const override;
|
|
MachineBasicBlock::iterator
|
|
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI) const override;
|
|
|
|
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
|
|
const TargetRegisterInfo *TRI,
|
|
std::vector<CalleeSavedInfo> &CSI,
|
|
unsigned &MinCSFrameIndex,
|
|
unsigned &MaxCSFrameIndex) const override;
|
|
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI,
|
|
ArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
bool
|
|
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI,
|
|
MutableArrayRef<CalleeSavedInfo> CSI,
|
|
const TargetRegisterInfo *TRI) const override;
|
|
|
|
// Get the first stack adjustment amount for SplitSPAdjust.
|
|
// Return 0 if we don't want to split the SP adjustment in prologue and
|
|
// epilogue.
|
|
uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;
|
|
|
|
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
|
|
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override;
|
|
|
|
bool enableShrinkWrapping(const MachineFunction &MF) const override;
|
|
|
|
bool isSupportedStackID(TargetStackID::Value ID) const override;
|
|
TargetStackID::Value getStackIDForScalableVectors() const override;
|
|
|
|
bool isStackIdSafeForLocalArea(unsigned StackId) const override {
|
|
// We don't support putting RISC-V Vector objects into the pre-allocated
|
|
// local frame block at the moment.
|
|
return StackId != TargetStackID::ScalableVector;
|
|
}
|
|
|
|
protected:
|
|
const RISCVSubtarget &STI;
|
|
|
|
private:
|
|
void determineFrameLayout(MachineFunction &MF) const;
|
|
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
|
|
int64_t Amount, MachineInstr::MIFlag Flag) const;
|
|
std::pair<int64_t, Align>
|
|
assignRVVStackObjectOffsets(MachineFunction &MF) const;
|
|
};
|
|
} // namespace llvm
|
|
#endif
|