File: RISCVRegisterInfo.h

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,245,064 kB
  • sloc: cpp: 7,619,731; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,676; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (162 lines) | stat: -rw-r--r-- 5,975 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//===-- RISCVRegisterInfo.h - RISC-V Register Information Impl --*- 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 file contains the RISC-V implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H
#define LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H

#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/TargetParser/RISCVTargetParser.h"

#define GET_REGINFO_HEADER
#include "RISCVGenRegisterInfo.inc"

namespace llvm {

namespace RISCVRI {
enum : uint8_t {
  // The IsVRegClass value of this RegisterClass.
  IsVRegClassShift = 0,
  IsVRegClassShiftMask = 0b1 << IsVRegClassShift,
  // The VLMul value of this RegisterClass. This value is valid iff IsVRegClass
  // is true.
  VLMulShift = IsVRegClassShift + 1,
  VLMulShiftMask = 0b11 << VLMulShift,

  // The NF value of this RegisterClass. This value is valid iff IsVRegClass is
  // true.
  NFShift = VLMulShift + 2,
  NFShiftMask = 0b111 << NFShift,
};

/// \returns the IsVRegClass for the register class.
static inline bool isVRegClass(uint8_t TSFlags) {
  return (TSFlags & IsVRegClassShiftMask) >> IsVRegClassShift;
}

/// \returns the LMUL for the register class.
static inline RISCVVType::VLMUL getLMul(uint8_t TSFlags) {
  return static_cast<RISCVVType::VLMUL>((TSFlags & VLMulShiftMask) >>
                                        VLMulShift);
}

/// \returns the NF for the register class.
static inline unsigned getNF(uint8_t TSFlags) {
  return static_cast<unsigned>((TSFlags & NFShiftMask) >> NFShift) + 1;
}
} // namespace RISCVRI

struct RISCVRegisterInfo : public RISCVGenRegisterInfo {

  RISCVRegisterInfo(unsigned HwMode);

  const uint32_t *getCallPreservedMask(const MachineFunction &MF,
                                       CallingConv::ID) const override;

  unsigned getCSRFirstUseCost() const override {
    // The cost will be compared against BlockFrequency where entry has the
    // value of 1 << 14. A value of 5 will choose to spill or split cold
    // path instead of using a callee-saved register.
    return 5;
  }

  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;

  const MCPhysReg *getIPRACSRegs(const MachineFunction *MF) const override;

  BitVector getReservedRegs(const MachineFunction &MF) const override;
  bool isAsmClobberable(const MachineFunction &MF,
                        MCRegister PhysReg) const override;

  const uint32_t *getNoPreservedMask() const override;

  // Update DestReg to have the value SrcReg plus an offset.  This is
  // used during frame layout, and we may need to ensure that if we
  // split the offset internally that the DestReg is always aligned,
  // assuming that source reg was.
  void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II,
                 const DebugLoc &DL, Register DestReg, Register SrcReg,
                 StackOffset Offset, MachineInstr::MIFlag Flag,
                 MaybeAlign RequiredAlign) const;

  bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
                           unsigned FIOperandNum,
                           RegScavenger *RS = nullptr) const override;

  bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;

  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;

  bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
                          int64_t Offset) const override;

  Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
                                        int64_t Offset) const override;

  void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
                         int64_t Offset) const override;

  int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
                                   int Idx) const override;

  void lowerVSPILL(MachineBasicBlock::iterator II) const;
  void lowerVRELOAD(MachineBasicBlock::iterator II) const;

  Register getFrameRegister(const MachineFunction &MF) const override;

  StringRef getRegAsmName(MCRegister Reg) const override;

  bool requiresRegisterScavenging(const MachineFunction &MF) const override {
    return true;
  }

  bool requiresFrameIndexScavenging(const MachineFunction &MF) const override {
    return true;
  }

  const TargetRegisterClass *
  getPointerRegClass(const MachineFunction &MF,
                     unsigned Kind = 0) const override {
    return &RISCV::GPRRegClass;
  }

  const TargetRegisterClass *
  getLargestLegalSuperClass(const TargetRegisterClass *RC,
                            const MachineFunction &) const override;

  void getOffsetOpcodes(const StackOffset &Offset,
                        SmallVectorImpl<uint64_t> &Ops) const override;

  unsigned getRegisterCostTableIndex(const MachineFunction &MF) const override;

  float getSpillWeightScaleFactor(const TargetRegisterClass *RC) const override;

  bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
                             SmallVectorImpl<MCPhysReg> &Hints,
                             const MachineFunction &MF, const VirtRegMap *VRM,
                             const LiveRegMatrix *Matrix) const override;

  static bool isVRRegClass(const TargetRegisterClass *RC) {
    return RISCVRI::isVRegClass(RC->TSFlags) &&
           RISCVRI::getNF(RC->TSFlags) == 1;
  }

  static bool isVRNRegClass(const TargetRegisterClass *RC) {
    return RISCVRI::isVRegClass(RC->TSFlags) && RISCVRI::getNF(RC->TSFlags) > 1;
  }

  static bool isRVVRegClass(const TargetRegisterClass *RC) {
    return RISCVRI::isVRegClass(RC->TSFlags);
  }
};
} // namespace llvm

#endif