• 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 AArch64ScheduleProcessInfo : public ScheduleProcessInfo {
32 public:
AArch64ScheduleProcessInfo(uint32 size)33     explicit AArch64ScheduleProcessInfo(uint32 size) : ScheduleProcessInfo(size) {}
34     ~AArch64ScheduleProcessInfo() override = default;
35 
36     /* recover register type which is not recorded in live analysis */
37     static RegType GetRegisterType(const CGFunc &f, regno_t regNO);
38     void VaryLiveRegSet(const CGFunc &f, regno_t regNO, bool isInc);
39     void VaryFreeRegSet(const CGFunc &f, std::set<regno_t> regNOs, DepNode &node);
40 
GetFreeIntRegs(DepNode & node)41     uint32 GetFreeIntRegs(DepNode &node)
42     {
43         return (freeIntRegNodeSet.count(&node)) > 0 ? freeIntRegNodeSet.find(&node)->second : 0;
44     }
IncFreeIntRegNode(DepNode & node)45     void IncFreeIntRegNode(DepNode &node)
46     {
47         if (freeIntRegNodeSet.count(&node) == 0) {
48             freeIntRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1));
49         } else {
50             freeIntRegNodeSet.find(&node)->second++;
51         }
52     }
GetFreeIntRegNodeSet()53     const std::map<DepNode *, uint32> &GetFreeIntRegNodeSet() const
54     {
55         return freeIntRegNodeSet;
56     }
IncFreeFpRegNode(DepNode & node)57     void IncFreeFpRegNode(DepNode &node)
58     {
59         if (freeFpRegNodeSet.count(&node) == 0) {
60             freeFpRegNodeSet.emplace(std::pair<DepNode *, uint32>(&node, 1));
61         } else {
62             freeFpRegNodeSet.find(&node)->second++;
63         }
64     }
GetFreeFpRegs(DepNode & node)65     uint32 GetFreeFpRegs(DepNode &node)
66     {
67         return (freeFpRegNodeSet.count(&node)) > 0 ? freeFpRegNodeSet.find(&node)->second : 0;
68     }
GetFreeFpRegNodeSet()69     const std::map<DepNode *, uint32> &GetFreeFpRegNodeSet() const
70     {
71         return freeFpRegNodeSet;
72     }
73 
ClearALLFreeRegNodeSet()74     void ClearALLFreeRegNodeSet()
75     {
76         freeIntRegNodeSet.clear();
77         freeFpRegNodeSet.clear();
78     }
79 
FindIntLiveReg(regno_t reg)80     size_t FindIntLiveReg(regno_t reg) const
81     {
82         return intLiveRegSet.count(reg);
83     }
IncIntLiveRegSet(regno_t reg)84     void IncIntLiveRegSet(regno_t reg)
85     {
86         intLiveRegSet.emplace(reg);
87     }
DecIntLiveRegSet(regno_t reg)88     void DecIntLiveRegSet(regno_t reg)
89     {
90         intLiveRegSet.erase(reg);
91     }
FindFpLiveReg(regno_t reg)92     size_t FindFpLiveReg(regno_t reg) const
93     {
94         return fpLiveRegSet.count(reg);
95     }
IncFpLiveRegSet(regno_t reg)96     void IncFpLiveRegSet(regno_t reg)
97     {
98         fpLiveRegSet.emplace(reg);
99     }
DecFpLiveRegSet(regno_t reg)100     void DecFpLiveRegSet(regno_t reg)
101     {
102         fpLiveRegSet.erase(reg);
103     }
104 
SizeOfIntLiveRegSet()105     size_t SizeOfIntLiveRegSet() const
106     {
107         return intLiveRegSet.size();
108     }
109 
SizeOfCalleeSaveLiveRegister(bool isInt)110     size_t SizeOfCalleeSaveLiveRegister(bool isInt)
111     {
112         size_t num = 0;
113         if (isInt) {
114             for (auto regNO : intLiveRegSet) {
115                 if (regNO > static_cast<regno_t>(R19)) {
116                     num++;
117                 }
118             }
119         } else {
120             for (auto regNO : fpLiveRegSet) {
121                 if (regNO > static_cast<regno_t>(V16)) {
122                     num++;
123                 }
124             }
125         }
126         return num;
127     }
128 
SizeOfFpLiveRegSet()129     size_t SizeOfFpLiveRegSet() const
130     {
131         return fpLiveRegSet.size();
132     }
133 
134 private:
135     std::set<regno_t> intLiveRegSet;
136     std::set<regno_t> fpLiveRegSet;
137     std::map<DepNode *, uint32> freeIntRegNodeSet;
138     std::map<DepNode *, uint32> freeFpRegNodeSet;
139 };
140 
141 class AArch64Schedule : public Schedule {
142 public:
AArch64Schedule(CGFunc & func,MemPool & memPool,LiveAnalysis & live,const std::string & phaseName)143     AArch64Schedule(CGFunc &func, MemPool &memPool, LiveAnalysis &live, const std::string &phaseName)
144         : Schedule(func, memPool, live, phaseName)
145     {
146         intCalleeSaveThreshold = func.UseFP() ? intCalleeSaveThresholdBase : intCalleeSaveThresholdEnhance;
147     }
148     ~AArch64Schedule() override = default;
149 
150 protected:
151     void DumpDepGraph(const MapleVector<DepNode *> &nodes) const;
152     void DumpScheduleResult(const MapleVector<DepNode *> &nodes, SimulateType type) const;
153     void GenerateDot(const BB &bb, const MapleVector<DepNode *> &nodes) const;
154     void EraseNodeFromNodeList(const DepNode &target, MapleVector<DepNode *> &nodeList) override;
155     void FindAndCombineMemoryAccessPair(const std::vector<DepNode *> &memList) override;
156     void RegPressureScheduling(BB &bb, MapleVector<DepNode *> &nodes) override;
157 
158 private:
159     enum CSRResult : uint8 {
160         kNode1,
161         kNode2,
162         kDoCSP /* can do csp further */
163     };
164     void Init() override;
165     void MemoryAccessPairOpt() override;
166     void ClinitPairOpt() override;
167     uint32 DoSchedule() override;
168     uint32 DoBruteForceSchedule() override;
169     uint32 SimulateOnly() override;
170     void UpdateBruteForceSchedCycle() override;
171     void IterateBruteForce(DepNode &targetNode, MapleVector<DepNode *> &readyList, uint32 currCycle,
172                            MapleVector<DepNode *> &scheduledNodes, uint32 &maxCycleCount,
173                            MapleVector<DepNode *> &optimizedScheduledNodes) override;
174     bool CanCombine(const Insn &insn) const override;
175     void ListScheduling(bool beforeRA) override;
176     void BruteForceScheduling(const BB &bb);
177     void SimulateScheduling(const BB &bb);
178     void FinalizeScheduling(BB &bb, const DepAnalysis &depAnalysis) override;
179     uint32 ComputeEstart(uint32 cycle) override;
180     void ComputeLstart(uint32 maxEstart) override;
181     void UpdateELStartsOnCycle(uint32 cycle) override;
182     void RandomTest() override;
183     void EraseNodeFromReadyList(const DepNode &target) override;
184     uint32 GetNextSepIndex() const override;
185     void CountUnitKind(const DepNode &depNode, uint32 array[], const uint32 arraySize) const override;
186     static bool IfUseUnitKind(const DepNode &depNode, uint32 index);
187     void UpdateReadyList(DepNode &targetNode, MapleVector<DepNode *> &readyList, bool updateEStart) override;
188     void UpdateScheduleProcessInfo(AArch64ScheduleProcessInfo &info) const;
189     void UpdateAdvanceCycle(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &targetNode) const;
190     bool CheckSchedulable(AArch64ScheduleProcessInfo &info) const;
191     void SelectNode(AArch64ScheduleProcessInfo &scheduleInfo);
192     static void DumpDebugInfo(const ScheduleProcessInfo &scheduleInfo);
193     bool CompareDepNode(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const;
194     void CalculateMaxUnitKindCount(ScheduleProcessInfo &scheduleInfo) const;
195     void UpdateReleaseRegInfo(AArch64ScheduleProcessInfo &scheduleInfo);
196     std::set<regno_t> CanFreeRegister(const DepNode &node) const;
197     void UpdateLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo, const DepNode &node);
198     void InitLiveRegSet(AArch64ScheduleProcessInfo &scheduleInfo);
199     int CalSeriesCycles(const MapleVector<DepNode *> &nodes) const;
200     CSRResult DoCSR(DepNode &node1, DepNode &node2, AArch64ScheduleProcessInfo &scheduleInfo) const;
201     AArch64Schedule::CSRResult ScheduleCrossCall(const DepNode &node1, const DepNode &node2) const;
202     int intCalleeSaveThreshold = 0;
203 
204     static uint32 maxUnitIndex;
205     static int intRegPressureThreshold;
206     static int fpRegPressureThreshold;
207     static int intCalleeSaveThresholdBase;
208     static int intCalleeSaveThresholdEnhance;
209     static int fpCalleeSaveThreshold;
210 };
211 } /* namespace maplebe */
212 
213 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_SCHEDULE_H */
214