brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · f9be80f Raw
226 lines · c
1//=- RISCVMachineFunctionInfo.h - RISC-V machine function info ----*- C++ -*-=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares RISCV-specific per-machine-function information.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H14#define LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H15 16#include "RISCVSubtarget.h"17#include "llvm/CodeGen/MIRYamlMapping.h"18#include "llvm/CodeGen/MachineFrameInfo.h"19#include "llvm/CodeGen/MachineFunction.h"20 21namespace llvm {22 23class RISCVMachineFunctionInfo;24 25namespace yaml {26struct RISCVMachineFunctionInfo final : public yaml::MachineFunctionInfo {27  int VarArgsFrameIndex;28  int VarArgsSaveSize;29 30  RISCVMachineFunctionInfo() = default;31  RISCVMachineFunctionInfo(const llvm::RISCVMachineFunctionInfo &MFI);32 33  void mappingImpl(yaml::IO &YamlIO) override;34  ~RISCVMachineFunctionInfo() override = default;35};36 37template <> struct MappingTraits<RISCVMachineFunctionInfo> {38  static void mapping(IO &YamlIO, RISCVMachineFunctionInfo &MFI) {39    YamlIO.mapOptional("varArgsFrameIndex", MFI.VarArgsFrameIndex);40    YamlIO.mapOptional("varArgsSaveSize", MFI.VarArgsSaveSize);41  }42};43} // end namespace yaml44 45/// RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo46/// and contains private RISCV-specific information for each MachineFunction.47class RISCVMachineFunctionInfo : public MachineFunctionInfo {48private:49  /// FrameIndex for start of varargs area50  int VarArgsFrameIndex = 0;51  /// Size of the save area used for varargs52  int VarArgsSaveSize = 0;53  /// FrameIndex used for transferring values between 64-bit FPRs and a pair54  /// of 32-bit GPRs via the stack.55  int MoveF64FrameIndex = -1;56  /// FrameIndex of the spill slot for the scratch register in BranchRelaxation.57  int BranchRelaxationScratchFrameIndex = -1;58  /// Size of any opaque stack adjustment due to save/restore libcalls.59  unsigned LibCallStackSize = 0;60  /// Size of RVV stack.61  uint64_t RVVStackSize = 0;62  /// Alignment of RVV stack.63  Align RVVStackAlign;64  /// Padding required to keep RVV stack aligned within the main stack.65  uint64_t RVVPadding = 0;66  /// Size of stack frame to save callee saved registers67  unsigned CalleeSavedStackSize = 0;68  /// Is there any vector argument or return?69  bool IsVectorCall = false;70 71  /// Registers that have been sign extended from i32.72  SmallVector<Register, 8> SExt32Registers;73 74  /// Size of stack frame for Zcmp PUSH/POP75  unsigned RVPushStackSize = 0;76  unsigned RVPushRegs = 0;77 78  /// Size of any opaque stack adjustment due to QCI Interrupt instructions.79  unsigned QCIInterruptStackSize = 0;80 81  /// Store Frame Indexes for Interrupt-Related CSR Spills.82  SmallVector<int, 2> InterruptCSRFrameIndexes;83 84  int64_t StackProbeSize = 0;85 86  /// Does it probe the stack for a dynamic allocation?87  bool HasDynamicAllocation = false;88 89public:90  RISCVMachineFunctionInfo(const Function &F, const RISCVSubtarget *STI);91 92  MachineFunctionInfo *93  clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,94        const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)95      const override;96 97  int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }98  void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }99 100  unsigned getVarArgsSaveSize() const { return VarArgsSaveSize; }101  void setVarArgsSaveSize(int Size) { VarArgsSaveSize = Size; }102 103  int getMoveF64FrameIndex(MachineFunction &MF) {104    if (MoveF64FrameIndex == -1)105      MoveF64FrameIndex =106          MF.getFrameInfo().CreateStackObject(8, Align(8), false);107    return MoveF64FrameIndex;108  }109 110  int getBranchRelaxationScratchFrameIndex() const {111    return BranchRelaxationScratchFrameIndex;112  }113  void setBranchRelaxationScratchFrameIndex(int Index) {114    BranchRelaxationScratchFrameIndex = Index;115  }116 117  unsigned getReservedSpillsSize() const {118    return LibCallStackSize + RVPushStackSize + QCIInterruptStackSize;119  }120 121  unsigned getLibCallStackSize() const { return LibCallStackSize; }122  void setLibCallStackSize(unsigned Size) { LibCallStackSize = Size; }123 124  bool useSaveRestoreLibCalls(const MachineFunction &MF) const {125    // We cannot use fixed locations for the callee saved spill slots if the126    // function uses a varargs save area, or is an interrupt handler.127    return !isPushable(MF) &&128           MF.getSubtarget<RISCVSubtarget>().enableSaveRestore() &&129           VarArgsSaveSize == 0 && !MF.getFrameInfo().hasTailCall() &&130           !MF.getFunction().hasFnAttribute("interrupt");131  }132 133  uint64_t getRVVStackSize() const { return RVVStackSize; }134  void setRVVStackSize(uint64_t Size) { RVVStackSize = Size; }135 136  Align getRVVStackAlign() const { return RVVStackAlign; }137  void setRVVStackAlign(Align StackAlign) { RVVStackAlign = StackAlign; }138 139  uint64_t getRVVPadding() const { return RVVPadding; }140  void setRVVPadding(uint64_t Padding) { RVVPadding = Padding; }141 142  unsigned getCalleeSavedStackSize() const { return CalleeSavedStackSize; }143  void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; }144 145  enum class PushPopKind { None = 0, StdExtZcmp, VendorXqccmp };146 147  PushPopKind getPushPopKind(const MachineFunction &MF) const;148 149  bool isPushable(const MachineFunction &MF) const {150    return getPushPopKind(MF) != PushPopKind::None;151  }152 153  unsigned getRVPushRegs() const { return RVPushRegs; }154  void setRVPushRegs(unsigned Regs) { RVPushRegs = Regs; }155 156  unsigned getRVPushStackSize() const { return RVPushStackSize; }157  void setRVPushStackSize(unsigned Size) { RVPushStackSize = Size; }158 159  enum class InterruptStackKind {160    None = 0,161    QCINest,162    QCINoNest,163    SiFiveCLICPreemptible,164    SiFiveCLICStackSwap,165    SiFiveCLICPreemptibleStackSwap166  };167 168  InterruptStackKind getInterruptStackKind(const MachineFunction &MF) const;169 170  bool useQCIInterrupt(const MachineFunction &MF) const {171    InterruptStackKind Kind = getInterruptStackKind(MF);172    return Kind == InterruptStackKind::QCINest ||173           Kind == InterruptStackKind::QCINoNest;174  }175 176  unsigned getQCIInterruptStackSize() const { return QCIInterruptStackSize; }177  void setQCIInterruptStackSize(unsigned Size) { QCIInterruptStackSize = Size; }178 179  bool useSiFiveInterrupt(const MachineFunction &MF) const {180    InterruptStackKind Kind = getInterruptStackKind(MF);181    return Kind == InterruptStackKind::SiFiveCLICPreemptible ||182           Kind == InterruptStackKind::SiFiveCLICStackSwap ||183           Kind == InterruptStackKind::SiFiveCLICPreemptibleStackSwap;184  }185 186  bool isSiFivePreemptibleInterrupt(const MachineFunction &MF) const {187    InterruptStackKind Kind = getInterruptStackKind(MF);188    return Kind == InterruptStackKind::SiFiveCLICPreemptible ||189           Kind == InterruptStackKind::SiFiveCLICPreemptibleStackSwap;190  }191 192  bool isSiFiveStackSwapInterrupt(const MachineFunction &MF) const {193    InterruptStackKind Kind = getInterruptStackKind(MF);194    return Kind == InterruptStackKind::SiFiveCLICStackSwap ||195           Kind == InterruptStackKind::SiFiveCLICPreemptibleStackSwap;196  }197 198  void pushInterruptCSRFrameIndex(int FI) {199    InterruptCSRFrameIndexes.push_back(FI);200  }201  int getInterruptCSRFrameIndex(size_t Idx) const {202    return InterruptCSRFrameIndexes[Idx];203  }204 205  // Some Stack Management Variants automatically update FP in a frame-pointer206  // convention compatible way - which means we don't need to manually update207  // the FP, but we still need to emit the correct CFI information for208  // calculating the CFA based on FP.209  bool hasImplicitFPUpdates(const MachineFunction &MF) const;210 211  void initializeBaseYamlFields(const yaml::RISCVMachineFunctionInfo &YamlMFI);212 213  void addSExt32Register(Register Reg);214  bool isSExt32Register(Register Reg) const;215 216  bool isVectorCall() const { return IsVectorCall; }217  void setIsVectorCall() { IsVectorCall = true; }218 219  bool hasDynamicAllocation() const { return HasDynamicAllocation; }220  void setDynamicAllocation() { HasDynamicAllocation = true; }221};222 223} // end namespace llvm224 225#endif // LLVM_LIB_TARGET_RISCV_RISCVMACHINEFUNCTIONINFO_H226