• 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_REGCOALESCE_H
17 #define MAPLEBE_INCLUDE_CG_REGCOALESCE_H
18 #include "live.h"
19 
20 namespace maplebe {
21 
22 using posPair = std::pair<uint32, uint32>;
23 class LiveInterval {
24 public:
LiveInterval(MapleAllocator & allocator)25     explicit LiveInterval(MapleAllocator &allocator)
26         : ranges(allocator.Adapter()),
27           conflict(allocator.Adapter()),
28           defPoints(allocator.Adapter()),
29           usePoints(allocator.Adapter()),
30           alloc(allocator)
31     {
32     }
33 
IncNumCall()34     void IncNumCall()
35     {
36         ++numCall;
37     }
38 
GetRanges()39     MapleMap<uint32, MapleVector<posPair>> GetRanges()
40     {
41         return ranges;
42     }
43 
AddRange(uint32 bbid,uint32 end,bool alreadLive)44     void AddRange(uint32 bbid, uint32 end, bool alreadLive)
45     {
46         auto it = ranges.find(bbid);
47         if (it == ranges.end()) {
48             MapleVector<posPair> posVec(alloc.Adapter());
49             posVec.emplace_back(std::pair(end, end));
50             ranges.emplace(bbid, posVec);
51         } else {
52             MapleVector<posPair> &posVec = it->second;
53             if (alreadLive) {
54                 CHECK_FATAL(posVec.size() > 0, "must not be zero");
55                 posPair lastPos = posVec[posVec.size() - 1];
56                 posVec[posVec.size() - 1] = std::pair(end, lastPos.second);
57             } else {
58                 posVec.emplace_back(std::pair(end, end));
59             }
60         }
61     }
62 
MergeRanges(LiveInterval & lr)63     void MergeRanges(LiveInterval &lr)
64     {
65         auto lrDestRanges = lr.GetRanges();
66         for (auto destRange : lrDestRanges) {
67             uint32 bbid = destRange.first;
68             auto &destPosVec = destRange.second;
69             auto it = ranges.find(bbid);
70             if (it == ranges.end()) {
71                 /* directly add it */
72                 MapleVector<posPair> posVec(alloc.Adapter());
73                 for (auto pos : destPosVec) {
74                     posVec.emplace_back(std::pair(pos.first, pos.second));
75                 }
76                 ranges.emplace(bbid, posVec);
77             } else {
78                 /* merge it simply, so that subpos may overlap. */
79                 auto &srcPosVec = it->second;
80                 for (auto pos1 : destPosVec) {
81                     bool merged = false;
82                     for (auto &pos2 : srcPosVec) {
83                         if (!((pos1.first < pos2.first && pos1.second < pos2.first) ||
84                               (pos2.first < pos1.second && pos2.second < pos1.first))) {
85                             uint32 bgn = pos1.first < pos2.first ? pos1.first : pos2.first;
86                             uint32 end = pos1.second > pos2.second ? pos1.second : pos2.second;
87                             pos2 = std::pair(bgn, end);
88                             merged = true;
89                         }
90                     }
91                     /* add it directly when no overlap*/
92                     if (!merged) {
93                         srcPosVec.emplace_back(std::pair(pos1.first, pos1.second));
94                     }
95                 }
96             }
97         }
98     }
99 
MergeConflict(LiveInterval & lr)100     void MergeConflict(LiveInterval &lr)
101     {
102         for (auto reg : lr.conflict) {
103             conflict.insert(reg);
104         }
105     }
106 
MergeRefPoints(LiveInterval & lr)107     void MergeRefPoints(LiveInterval &lr)
108     {
109         if (lr.GetDefPoint().size() != k1ByteSize) {
110             for (auto insn : lr.defPoints) {
111                 defPoints.insert(insn);
112             }
113         }
114         for (auto insn : lr.usePoints) {
115             usePoints.insert(insn);
116         }
117     }
118 
AddConflict(regno_t val)119     void AddConflict(regno_t val)
120     {
121         conflict.insert(val);
122     }
123 
GetConflict()124     MapleSet<uint32> GetConflict()
125     {
126         return conflict;
127     }
128 
AddRefPoint(Insn * val,bool isDef)129     void AddRefPoint(Insn *val, bool isDef)
130     {
131         if (isDef) {
132             defPoints.insert(val);
133         } else {
134             usePoints.insert(val);
135         }
136     }
137 
GetDefPoint()138     InsnMapleSet &GetDefPoint()
139     {
140         return defPoints;
141     }
142 
GetUsePoint()143     InsnMapleSet &GetUsePoint()
144     {
145         return usePoints;
146     }
147 
IsConflictWith(regno_t val)148     bool IsConflictWith(regno_t val)
149     {
150         return conflict.find(val) != conflict.end();
151     }
152 
GetRegType()153     RegType GetRegType() const
154     {
155         return regType;
156     }
157 
SetRegType(RegType val)158     void SetRegType(RegType val)
159     {
160         this->regType = val;
161     }
162 
GetRegNO()163     regno_t GetRegNO() const
164     {
165         return regno;
166     }
167 
SetRegNO(regno_t val)168     void SetRegNO(regno_t val)
169     {
170         this->regno = val;
171     }
172 
Dump()173     void Dump()
174     {
175         std::cout << "R" << regno << ": ";
176         for (auto range : ranges) {
177             uint32 bbid = range.first;
178             std::cout << "BB" << bbid << ": < ";
179             for (auto pos : range.second) {
180                 std::cout << "[" << pos.first << ", " << pos.second << ") ";
181             }
182             std::cout << " > ";
183         }
184         std::cout << "\n";
185     }
DumpDefs()186     void DumpDefs()
187     {
188         std::cout << "R" << regno << ": ";
189         for (auto def : defPoints) {
190             def->Dump();
191         }
192         std::cout << "\n";
193     }
DumpUses()194     void DumpUses()
195     {
196         std::cout << "R" << regno << ": ";
197         for (auto def : usePoints) {
198             def->Dump();
199         }
200         std::cout << "\n";
201     }
202 
203 private:
204     MapleMap<uint32, MapleVector<posPair>> ranges;
205     MapleSet<uint32> conflict;
206     InsnMapleSet defPoints;
207     InsnMapleSet usePoints;
208     uint32 numCall = 0;
209     RegType regType = kRegTyUndef;
210     regno_t regno = 0;
211     MapleAllocator &alloc;
212 };
213 
214 class LiveIntervalAnalysis {
215 public:
LiveIntervalAnalysis(CGFunc & func,MemPool & memPool)216     LiveIntervalAnalysis(CGFunc &func, MemPool &memPool)
217         : cgFunc(&func), memPool(&memPool), alloc(&memPool), vregIntervals(alloc.Adapter())
218     {
219     }
220 
~LiveIntervalAnalysis()221     virtual ~LiveIntervalAnalysis()
222     {
223         cgFunc = nullptr;
224         memPool = nullptr;
225         bfs = nullptr;
226     }
227 
228     virtual void CoalesceRegisters() = 0;
229     void Run();
230     void Analysis();
231     void DoAnalysis();
232     void ClearBFS();
233     void Dump();
234     void CoalesceLiveIntervals(LiveInterval &lrDest, LiveInterval &lrSrc);
GetLiveInterval(regno_t regno)235     LiveInterval *GetLiveInterval(regno_t regno)
236     {
237         auto it = vregIntervals.find(regno);
238         if (it == vregIntervals.end()) {
239             return nullptr;
240         } else {
241             return it->second;
242         }
243     }
244 
245 protected:
246     CGFunc *cgFunc;
247     MemPool *memPool;
248     MapleAllocator alloc;
249     MapleMap<regno_t, LiveInterval *> vregIntervals;
250     Bfs *bfs = nullptr;
251     bool runAnalysis = false;
252 };
253 
MAPLE_FUNC_PHASE_DECLARE(CgRegCoalesce,maplebe::CGFunc)254 MAPLE_FUNC_PHASE_DECLARE(CgRegCoalesce, maplebe::CGFunc)
255 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CGliveIntervalAnalysis, maplebe::CGFunc)
256 LiveIntervalAnalysis *GetResult()
257 {
258     return liveInterval;
259 }
260 LiveIntervalAnalysis *liveInterval = nullptr;
261 OVERRIDE_DEPENDENCE
262 MAPLE_FUNC_PHASE_DECLARE_END
263 } /* namespace maplebe */
264 
265 #endif /* MAPLEBE_INCLUDE_CG_REGCOALESCE_H */
266