• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef MAPLEBE_INCLUDE_CG_REG_INFO_H
17 #define MAPLEBE_INCLUDE_CG_REG_INFO_H
18 
19 #include "isa.h"
20 #include "insn.h"
21 
22 namespace maplebe {
23 constexpr size_t kSpillMemOpndNum = 4;
24 constexpr uint32 kBaseVirtualRegNO = 200; /* avoid conflicts between virtual and physical */
25 constexpr uint32 kRegIncrStepLen = 80;    /* reg number increate step length */
26 
27 class VirtualRegNode {
28 public:
29     VirtualRegNode() = default;
30 
VirtualRegNode(RegType type,uint32 size)31     VirtualRegNode(RegType type, uint32 size) : regType(type), size(size), regNO(kInvalidRegNO) {}
32 
33     virtual ~VirtualRegNode() = default;
34 
AssignPhysicalRegister(regno_t phyRegNO)35     void AssignPhysicalRegister(regno_t phyRegNO)
36     {
37         regNO = phyRegNO;
38     }
39 
GetType()40     RegType GetType() const
41     {
42         return regType;
43     }
44 
GetSize()45     uint32 GetSize() const
46     {
47         return size;
48     }
49 
50 private:
51     RegType regType = kRegTyUndef;
52     uint32 size = 0;               /* size in bytes */
53     regno_t regNO = kInvalidRegNO; /* physical register assigned by register allocation */
54 };
55 
56 class VregInfo {
57 public:
58     /* Only one place to allocate vreg within cg.
59        'static' can be removed and initialized here if only allocation is from only one source.  */
60     static uint32 virtualRegCount;
61     static uint32 maxRegCount;
62     static std::vector<VirtualRegNode> vRegTable;
63     static std::unordered_map<regno_t, RegOperand *> vRegOperandTable;
64     static bool initialized;
65 
VregInfo()66     VregInfo()
67     {
68         if (initialized) {
69             initialized = false;
70             return;
71         }
72         initialized = true;
73         virtualRegCount = kBaseVirtualRegNO;
74         maxRegCount = kBaseVirtualRegNO;
75         vRegTable.clear();
76         vRegOperandTable.clear();
77     }
78 
79     ~VregInfo() = default;
80 
GetNextVregNO(RegType type,uint32 size)81     uint32 GetNextVregNO(RegType type, uint32 size)
82     {
83         /* when vReg reach to maxRegCount, maxRegCount limit adds 80 every time */
84         /* and vRegTable increases 80 elements. */
85         if (virtualRegCount >= maxRegCount) {
86             DEBUG_ASSERT(virtualRegCount < maxRegCount + 1, "MAINTAIN FAILED");
87             maxRegCount += kRegIncrStepLen;
88             VRegTableResize(maxRegCount);
89         }
90 #if TARGAARCH64 || TARGX86_64 || TARGRISCV64
91         if (size < k4ByteSize) {
92             size = k4ByteSize;
93         }
94         if (Triple::GetTriple().IsAarch64BeOrLe()) {
95             /* cannot handle 128 size register */
96             if (type == kRegTyInt && size > k8ByteSize) {
97                 size = k8ByteSize;
98             }
99         }
100         DEBUG_ASSERT(size == k4ByteSize || size == k8ByteSize || size == k16ByteSize, "check size");
101 #endif
102         VRegTableValuesSet(virtualRegCount, type, size);
103 
104         uint32 temp = virtualRegCount;
105         ++virtualRegCount;
106         return temp;
107     }
Inc(uint32 v)108     void Inc(uint32 v) const
109     {
110         virtualRegCount += v;
111     }
GetCount()112     uint32 GetCount() const
113     {
114         return virtualRegCount;
115     }
SetCount(uint32 v)116     void SetCount(uint32 v) const
117     {
118         /* Vreg number can only increase. */
119         if (virtualRegCount < v) {
120             virtualRegCount = v;
121         }
122     }
123 
124     /* maxRegCount related stuff */
GetMaxRegCount()125     uint32 GetMaxRegCount() const
126     {
127         return maxRegCount;
128     }
SetMaxRegCount(uint32 num)129     void SetMaxRegCount(uint32 num)
130     {
131         maxRegCount = num;
132     }
IncMaxRegCount(uint32 num)133     void IncMaxRegCount(uint32 num) const
134     {
135         maxRegCount += num;
136     }
137 
138     /* vRegTable related stuff */
VRegTableResize(uint32 sz)139     void VRegTableResize(uint32 sz)
140     {
141         vRegTable.resize(sz);
142     }
VRegTableSize()143     uint32 VRegTableSize() const
144     {
145         return static_cast<uint32>(vRegTable.size());
146     }
VRegTableGetSize(uint32 idx)147     uint32 VRegTableGetSize(uint32 idx) const
148     {
149         return vRegTable[idx].GetSize();
150     }
VRegTableGetType(uint32 idx)151     RegType VRegTableGetType(uint32 idx) const
152     {
153         return vRegTable[idx].GetType();
154     }
VRegTableElementGet(uint32 idx)155     VirtualRegNode &VRegTableElementGet(uint32 idx) const
156     {
157         return vRegTable[idx];
158     }
VRegTableElementSet(uint32 idx,VirtualRegNode * node)159     void VRegTableElementSet(uint32 idx, VirtualRegNode *node)
160     {
161         vRegTable[idx] = *node;
162     }
VRegTableValuesSet(uint32 idx,RegType rt,uint32 sz)163     void VRegTableValuesSet(uint32 idx, RegType rt, uint32 sz) const
164     {
165         new (&vRegTable[idx]) VirtualRegNode(rt, sz);
166     }
VRegOperandTableSet(regno_t regNO,RegOperand * rp)167     void VRegOperandTableSet(regno_t regNO, RegOperand *rp) const
168     {
169         vRegOperandTable[regNO] = rp;
170     }
171 };
172 using VRegNo = regno_t;
173 using PRegNo = regno_t;
174 using RegNoPair = std::pair<VRegNo, PRegNo>;
175 
176 class RegisterInfo {
177 public:
RegisterInfo(MapleAllocator & mallocator)178     explicit RegisterInfo(MapleAllocator &mallocator)
179         : allIntRegs(mallocator.Adapter()), allFpRegs(mallocator.Adapter()), allregs(mallocator.Adapter())
180     {
181     }
182 
~RegisterInfo()183     virtual ~RegisterInfo()
184     {
185         cgFunc = nullptr;
186     }
187 
188     virtual void Init() = 0;
189     virtual void Fini() = 0;
AddToAllRegs(regno_t regNo)190     void AddToAllRegs(regno_t regNo)
191     {
192         (void)allregs.insert(regNo);
193     }
GetAllRegs()194     const MapleSet<regno_t> &GetAllRegs() const
195     {
196         return allregs;
197     }
AddToIntRegs(regno_t regNo)198     void AddToIntRegs(regno_t regNo)
199     {
200         (void)allIntRegs.insert(regNo);
201     }
GetIntRegs()202     const MapleSet<regno_t> &GetIntRegs() const
203     {
204         return allIntRegs;
205     }
AddToFpRegs(regno_t regNo)206     void AddToFpRegs(regno_t regNo)
207     {
208         (void)allFpRegs.insert(regNo);
209     }
GetFpRegs()210     const MapleSet<regno_t> &GetFpRegs() const
211     {
212         return allFpRegs;
213     }
SetCurrFunction(CGFunc & func)214     void SetCurrFunction(CGFunc &func)
215     {
216         cgFunc = &func;
217     }
GetCurrFunction()218     CGFunc *GetCurrFunction() const
219     {
220         return cgFunc;
221     }
222     // When some registers are allocated to the callee, the caller stores a part of the registers
223     // and the callee stores another part of the registers.
224     // For these registers, it is a better choice to assign them as caller-save registers.
IsPrefCallerSaveRegs(RegType type,uint32 size)225     virtual bool IsPrefCallerSaveRegs(RegType type, uint32 size) const
226     {
227         return false;
228     }
IsCallerSavePartRegister(regno_t regNO,uint32 size)229     virtual bool IsCallerSavePartRegister(regno_t regNO, uint32 size) const
230     {
231         return false;
232     }
233     virtual RegOperand *GetOrCreatePhyRegOperand(regno_t regNO, uint32 size, RegType kind, uint32 flag = 0) = 0;
234     virtual bool IsGPRegister(regno_t regNO) const = 0;
235     virtual uint32 GetIntParamRegIdx(regno_t regNO) const = 0;
236     virtual uint32 GetFpParamRegIdx(regno_t regNO) const = 0;
237     virtual bool IsAvailableReg(regno_t regNO) const = 0;
238     virtual bool IsCalleeSavedReg(regno_t regno) const = 0;
239     virtual bool IsYieldPointReg(regno_t regNO) const = 0;
240     virtual bool IsUnconcernedReg(regno_t regNO) const = 0;
241     virtual bool IsVirtualRegister(const RegOperand &regOpnd) = 0;
242     virtual bool IsVirtualRegister(regno_t regno) = 0;
243     virtual uint32 GetIntRegsParmsNum() = 0;
244     virtual uint32 GetIntRetRegsNum() = 0;
245     virtual uint32 GetFpRetRegsNum() = 0;
246     virtual uint32 GetFloatRegsParmsNum() = 0;
247     virtual regno_t GetLastParamsIntReg() = 0;
248     virtual regno_t GetLastParamsFpReg() = 0;
249     virtual regno_t GetIntRetReg(uint32 idx) = 0;
250     virtual regno_t GetFpRetReg(uint32 idx) = 0;
251     virtual uint32 GetReservedSpillReg() = 0;
252     virtual uint32 GetSecondReservedSpillReg() = 0;
253     virtual uint32 GetAllRegNum() = 0;
254     virtual uint32 GetNormalUseOperandNum() = 0;
255     virtual regno_t GetInvalidReg() = 0;
256     virtual bool IsSpillRegInRA(regno_t regNO, bool has3RegOpnd) = 0;
257     virtual Insn *BuildStrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd) = 0;
258     virtual Insn *BuildLdrInsn(uint32 regSize, PrimType stype, RegOperand &phyOpnd, MemOperand &memOpnd) = 0;
259     virtual bool IsMovFromRegtoReg(MOperator mOp, Insn &insn) = 0;
260     virtual MemOperand *GetOrCreatSpillMem(regno_t vrNum, uint32 bitSize) = 0;
261     virtual MemOperand *AdjustMemOperandIfOffsetOutOfRange(MemOperand *memOpnd, const RegNoPair &regNoPair, bool isDest,
262                                                            Insn &insn, bool &isOutOfRange) = 0;
263     virtual void FreeSpillRegMem(regno_t vrNum) = 0;
264 
265 private:
266     MapleSet<regno_t> allIntRegs;
267     MapleSet<regno_t> allFpRegs;
268     MapleSet<regno_t> allregs;
269     CGFunc *cgFunc = nullptr;
270 };
271 } /* namespace maplebe */
272 
273 #endif /* MAPLEBE_INCLUDE_CG_REG_INFO_H */
274