• 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_AARCH64_AARCH64_SCHEDULE_H
17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_SCHEDULE_H
18 
19 #include "schedule.h"
20 #include "aarch64_operand.h"
21 
22 namespace maplebe {
23 enum RegisterType : uint8 {
24     kRegisterUndef,
25     kRegisterInt,
26     kRegisterFloat,
27     kRegisterCc,
28     kRegisterLast,
29 };
30 
31 class ScheduleProcessInfo {
32 public:
ScheduleProcessInfo(uint32 size)33     explicit ScheduleProcessInfo(uint32 size)
34     {
35         availableReadyList.reserve(size);
36         scheduledNodes.reserve(size);
37     }
38 
39     virtual ~ScheduleProcessInfo() = default;
40 
GetLastUpdateCycle()41     uint32 GetLastUpdateCycle() const
42     {
43         return lastUpdateCycle;
44     }
45 
SetLastUpdateCycle(uint32 updateCycle)46     void SetLastUpdateCycle(uint32 updateCycle)
47     {
48         lastUpdateCycle = updateCycle;
49     }
50 
GetCurrCycle()51     uint32 GetCurrCycle() const
52     {
53         return currCycle;
54     }
55 
IncCurrCycle()56     void IncCurrCycle()
57     {
58         ++currCycle;
59     }
60 
DecAdvanceCycle()61     void DecAdvanceCycle()
62     {
63         advanceCycle--;
64     }
65 
GetAdvanceCycle()66     uint32 GetAdvanceCycle() const
67     {
68         return advanceCycle;
69     }
70 
SetAdvanceCycle(uint32 cycle)71     void SetAdvanceCycle(uint32 cycle)
72     {
73         advanceCycle = cycle;
74     }
75 
ClearAvailableReadyList()76     void ClearAvailableReadyList()
77     {
78         availableReadyList.clear();
79     }
80 
PushElemIntoAvailableReadyList(DepNode * node)81     void PushElemIntoAvailableReadyList(DepNode *node)
82     {
83         availableReadyList.emplace_back(node);
84     }
85 
SizeOfAvailableReadyList()86     size_t SizeOfAvailableReadyList() const
87     {
88         return availableReadyList.size();
89     }
90 
AvailableReadyListIsEmpty()91     bool AvailableReadyListIsEmpty() const
92     {
93         return availableReadyList.empty();
94     }
95 
SetAvailableReadyList(const std::vector<DepNode * > & tempReadyList)96     void SetAvailableReadyList(const std::vector<DepNode *> &tempReadyList)
97     {
98         availableReadyList = tempReadyList;
99     }
100 
GetAvailableReadyList()101     const std::vector<DepNode *> &GetAvailableReadyList() const
102     {
103         return availableReadyList;
104     }
105 
GetAvailableReadyList()106     const std::vector<DepNode *> &GetAvailableReadyList()
107     {
108         return availableReadyList;
109     }
110 
PushElemIntoScheduledNodes(DepNode * node)111     void PushElemIntoScheduledNodes(DepNode *node)
112     {
113         node->SetState(kScheduled);
114         node->SetSchedCycle(currCycle);
115         node->OccupyUnits();
116         scheduledNodes.emplace_back(node);
117     }
118 
IsFirstSeparator()119     bool IsFirstSeparator() const
120     {
121         return isFirstSeparator;
122     }
123 
ResetIsFirstSeparator()124     void ResetIsFirstSeparator()
125     {
126         isFirstSeparator = false;
127     }
128 
SizeOfScheduledNodes()129     size_t SizeOfScheduledNodes() const
130     {
131         return scheduledNodes.size();
132     }
133 
GetScheduledNodes()134     const std::vector<DepNode *> &GetScheduledNodes() const
135     {
136         return scheduledNodes;
137     }
138 
139 private:
140     std::vector<DepNode *> availableReadyList;
141     std::vector<DepNode *> scheduledNodes;
142     uint32 lastUpdateCycle = 0;
143     uint32 currCycle = 0;
144     uint32 advanceCycle = 0;
145     bool isFirstSeparator = true;
146 };
147 
148 class AArch64ScheduleProcessInfo : public ScheduleProcessInfo {
149 public:
AArch64ScheduleProcessInfo(uint32 size)150     explicit AArch64ScheduleProcessInfo(uint32 size) : ScheduleProcessInfo(size) {}
151     ~AArch64ScheduleProcessInfo() override = default;
152 
153     /* recover register type which is not recorded in live analysis */
154     static RegType GetRegisterType(CGFunc &f, regno_t regNO);
155     void VaryLiveRegSet(CGFunc &f, regno_t regNO, bool isInc);
156     void VaryFreeRegSet(CGFunc &f, std::set<regno_t> regNOs, DepNode &node);
157 
GetFreeIntRegs(DepNode & node)158     uint32 GetFreeIntRegs(DepNode &node)
159     {
160         return freeIntRegNodeSet.count(&node) ? freeIntRegNodeSet.find(&node)->second : 0;
161     }
IncFreeIntRegNode(DepNode & node)162     void IncFreeIntRegNode(DepNode &node)
163     {
164         if (!freeIntRegNodeSet.count(&node)) {
165             freeIntRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1));
166         } else {
167             freeIntRegNodeSet.find(&node)->second++;
168         }
169     }
GetFreeIntRegNodeSet()170     const std::map<DepNode *, uint32> &GetFreeIntRegNodeSet() const
171     {
172         return freeIntRegNodeSet;
173     }
IncFreeFpRegNode(DepNode & node)174     void IncFreeFpRegNode(DepNode &node)
175     {
176         if (!freeFpRegNodeSet.count(&node)) {
177             freeFpRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1));
178         } else {
179             freeFpRegNodeSet.find(&node)->second++;
180         }
181     }
GetFreeFpRegs(DepNode & node)182     uint32 GetFreeFpRegs(DepNode &node)
183     {
184         return freeFpRegNodeSet.count(&node) ? freeFpRegNodeSet.find(&node)->second : 0;
185     }
GetFreeFpRegNodeSet()186     const std::map<DepNode *, uint32> &GetFreeFpRegNodeSet() const
187     {
188         return freeFpRegNodeSet;
189     }
190 
ClearALLFreeRegNodeSet()191     void ClearALLFreeRegNodeSet()
192     {
193         freeIntRegNodeSet.clear();
194         freeFpRegNodeSet.clear();
195     }
196 
FindIntLiveReg(regno_t reg)197     size_t FindIntLiveReg(regno_t reg) const
198     {
199         return intLiveRegSet.count(reg);
200     }
IncIntLiveRegSet(regno_t reg)201     void IncIntLiveRegSet(regno_t reg)
202     {
203         intLiveRegSet.emplace(reg);
204     }
DecIntLiveRegSet(regno_t reg)205     void DecIntLiveRegSet(regno_t reg)
206     {
207         intLiveRegSet.erase(reg);
208     }
FindFpLiveReg(regno_t reg)209     size_t FindFpLiveReg(regno_t reg) const
210     {
211         return fpLiveRegSet.count(reg);
212     }
IncFpLiveRegSet(regno_t reg)213     void IncFpLiveRegSet(regno_t reg)
214     {
215         fpLiveRegSet.emplace(reg);
216     }
DecFpLiveRegSet(regno_t reg)217     void DecFpLiveRegSet(regno_t reg)
218     {
219         fpLiveRegSet.erase(reg);
220     }
221 
SizeOfIntLiveRegSet()222     size_t SizeOfIntLiveRegSet() const
223     {
224         return intLiveRegSet.size();
225     }
226 
SizeOfCalleeSaveLiveRegister(bool isInt)227     size_t SizeOfCalleeSaveLiveRegister(bool isInt)
228     {
229         size_t num = 0;
230         if (isInt) {
231             for (auto regNO : intLiveRegSet) {
232                 if (regNO > static_cast<regno_t>(R19)) {
233                     num++;
234                 }
235             }
236         } else {
237             for (auto regNO : fpLiveRegSet) {
238                 if (regNO > static_cast<regno_t>(V16)) {
239                     num++;
240                 }
241             }
242         }
243         return num;
244     }
245 
SizeOfFpLiveRegSet()246     size_t SizeOfFpLiveRegSet() const
247     {
248         return fpLiveRegSet.size();
249     }
250 
251 private:
252     std::set<regno_t> intLiveRegSet;
253     std::set<regno_t> fpLiveRegSet;
254     std::map<DepNode *, uint32> freeIntRegNodeSet;
255     std::map<DepNode *, uint32> freeFpRegNodeSet;
256 };
257 
258 class AArch64Schedule : public Schedule {
259 public:
AArch64Schedule(CGFunc & func,MemPool & memPool,LiveAnalysis & live,const std::string & phaseName)260     AArch64Schedule(CGFunc &func, MemPool &memPool, LiveAnalysis &live, const std::string &phaseName)
261         : Schedule(func, memPool, live, phaseName)
262     {
263         intCalleeSaveThreshold = func.UseFP() ? intCalleeSaveThresholdBase : intCalleeSaveThresholdEnhance;
264     }
265     ~AArch64Schedule() override = default;
266 
267 protected:
268     void DumpDepGraph(const MapleVector<DepNode *> &nodes) const;
269     void DumpScheduleResult(const MapleVector<DepNode *> &nodes, SimulateType type) const;
270     void GenerateDot(const BB &bb, const MapleVector<DepNode *> &nodes) const;
271     void EraseNodeFromNodeList(const DepNode &target, MapleVector<DepNode *> &nodeList) override;
272     void FindAndCombineMemoryAccessPair(const std::vector<DepNode *> &memList) override;
273     void RegPressureScheduling(BB &bb, MapleVector<DepNode *> &nodes) override;
274 
275 private:
276     enum CSRResult : uint8 {
277         kNode1,
278         kNode2,
279         kDoCSP /* can do csp further */
280     };
281     void Init() override;
282     void MemoryAccessPairOpt() override;
283     void ClinitPairOpt() override;
284     uint32 DoSchedule() override;
285     uint32 DoBruteForceSchedule() override;
286     uint32 SimulateOnly() override;
287     void UpdateBruteForceSchedCycle() override;
288     void IterateBruteForce(DepNode &targetNode, MapleVector<DepNode *> &readyList, uint32 currCycle,
289                            MapleVector<DepNode *> &scheduledNodes, uint32 &maxCycleCount,
290                            MapleVector<DepNode *> &optimizedScheduledNodes) override;
291     bool CanCombine(const Insn &insn) const override;
292     void ListScheduling(bool beforeRA) override;
293     void BruteForceScheduling(const BB &bb);
294     void SimulateScheduling(const BB &bb);
295     void FinalizeScheduling(BB &bb, const DepAnalysis &depAnalysis) override;
296     uint32 ComputeEstart(uint32 cycle) override;
297     void ComputeLstart(uint32 maxEstart) override;
298     void UpdateELStartsOnCycle(uint32 cycle) override;
299     void RandomTest() override;
300     void EraseNodeFromReadyList(const DepNode &target) override;
301     uint32 GetNextSepIndex() const override;
302     void CountUnitKind(const DepNode &depNode, uint32 array[], const uint32 arraySize) const override;
303     static bool IfUseUnitKind(const DepNode &depNode, uint32 index);
304     void UpdateReadyList(DepNode &targetNode, MapleVector<DepNode *> &readyList, bool updateEStart) override;
305     void UpdateScheduleProcessInfo(AArch64ScheduleProcessInfo &info);
306     void UpdateAdvanceCycle(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &targetNode);
307     bool CheckSchedulable(AArch64ScheduleProcessInfo &info) const;
308     void SelectNode(AArch64ScheduleProcessInfo &scheduleInfo);
309     static void DumpDebugInfo(const ScheduleProcessInfo &scheduleInfo);
310     bool CompareDepNode(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const;
311     void CalculateMaxUnitKindCount(ScheduleProcessInfo &scheduleInfo);
312     void UpdateReleaseRegInfo(AArch64ScheduleProcessInfo &scheduleInfo);
313     std::set<regno_t> CanFreeRegister(const DepNode &node) const;
314     void UpdateLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &node);
315     void InitLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo);
316     int CalSeriesCycles(const MapleVector<DepNode *> &nodes);
317     CSRResult DoCSR(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const;
318     AArch64Schedule::CSRResult ScheduleCrossCall(const DepNode &node1, const DepNode &node2) const;
319     int intCalleeSaveThreshold = 0;
320 
321     static uint32 maxUnitIndex;
322     static int intRegPressureThreshold;
323     static int fpRegPressureThreshold;
324     static int intCalleeSaveThresholdBase;
325     static int intCalleeSaveThresholdEnhance;
326     static int fpCalleeSaveThreshold;
327 };
328 } /* namespace maplebe */
329 
330 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_SCHEDULE_H */
331