This patch proposes how to deal with RISC-V vector frame objects. The layout of RISC-V vector frame will look like |---------------------------------| | scalar callee-saved registers | |---------------------------------| | scalar local variables | |---------------------------------| | scalar outgoing arguments | |---------------------------------| | RVV local variables && | | RVV outgoing arguments | |---------------------------------| <- end of frame (sp) If there is realignment or variable length array in the stack, we will use frame pointer to access fixed objects and stack pointer to access non-fixed objects. |---------------------------------| <- frame pointer (fp) | scalar callee-saved registers | |---------------------------------| | scalar local variables | |---------------------------------| | ///// realignment ///// | |---------------------------------| | scalar outgoing arguments | |---------------------------------| | RVV local variables && | | RVV outgoing arguments | |---------------------------------| <- end of frame (sp) If there are both realignment and variable length array in the stack, we will use frame pointer to access fixed objects and base pointer to access non-fixed objects. |---------------------------------| <- frame pointer (fp) | scalar callee-saved registers | |---------------------------------| | scalar local variables | |---------------------------------| | ///// realignment ///// | |---------------------------------| <- base pointer (bp) | RVV local variables && | | RVV outgoing arguments | |---------------------------------| | /////////////////////////////// | | variable length array | | /////////////////////////////// | |---------------------------------| <- end of frame (sp) | scalar outgoing arguments | |---------------------------------| In this version, we do not save the addresses of RVV objects in the stack. We access them directly through the polynomial expression (a x VLENB + b). We do not reserve frame pointer when there is any RVV object in the stack. So, we also access the scalar frame objects through the polynomial expression (a x VLENB + b) if the access across RVV stack area. Differential Revision: https://reviews.llvm.org/D94465
86 lines
3.5 KiB
C++
86 lines
3.5 KiB
C++
//===-- RISCVFrameLowering.h - Define frame lowering for RISCV -*- 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 RISCV-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)
|
|
: TargetFrameLowering(StackGrowsDown,
|
|
/*StackAlignment=*/Align(16),
|
|
/*LocalAreaOffset=*/0),
|
|
STI(STI) {}
|
|
|
|
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
|
|
|
|
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 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 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 isSupportedStackID(TargetStackID::Value ID) const override;
|
|
TargetStackID::Value getStackIDForScalableVectors() const override;
|
|
|
|
protected:
|
|
const RISCVSubtarget &STI;
|
|
|
|
private:
|
|
void determineFrameLayout(MachineFunction &MF) const;
|
|
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
|
|
const DebugLoc &DL, Register DestReg, Register SrcReg,
|
|
int64_t Val, MachineInstr::MIFlag Flag) const;
|
|
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
|
|
int64_t Amount) const;
|
|
int64_t assignRVVStackObjectOffsets(MachineFrameInfo &MFI) const;
|
|
};
|
|
}
|
|
#endif
|