• 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_LOOP_H
17 #define MAPLEBE_INCLUDE_CG_LOOP_H
18 
19 #include "cgfunc.h"
20 #include "cg_dominance.h"
21 #include "maple_phase.h"
22 
23 namespace maplebe {
24 class LoopDesc {
25 public:
26     struct LoopDescCmp {
operatorLoopDescCmp27         bool operator()(const LoopDesc *loop1, const LoopDesc *loop2) const
28         {
29             CHECK_NULL_FATAL(loop1);
30             CHECK_NULL_FATAL(loop2);
31             return (loop1->GetHeader().GetId() < loop2->GetHeader().GetId());
32         }
33     };
34 
LoopDesc(MapleAllocator & allocator,BB & head)35     LoopDesc(MapleAllocator &allocator, BB &head)
36         : alloc(allocator),
37           header(head),
38           loopBBs(alloc.Adapter()),
39           exitBBs(alloc.Adapter()),
40           backEdges(alloc.Adapter()),
41           childLoops(alloc.Adapter())
42     {
43     }
44 
45     ~LoopDesc() = default;
46 
47     void Dump() const;
48 
GetHeader()49     BB &GetHeader()
50     {
51         return header;
52     }
53 
GetHeader()54     const BB &GetHeader() const
55     {
56         return header;
57     }
58 
59     // get all bbIds in the loop
GetLoopBBs()60     const MapleSet<BBID> &GetLoopBBs() const
61     {
62         return loopBBs;
63     }
64 
65     // check whether the BB exists in the current loop
Has(const BB & bb)66     bool Has(const BB &bb) const
67     {
68         return loopBBs.find(bb.GetId()) != loopBBs.end();
69     }
70 
InsertLoopBBs(const BB & bb)71     void InsertLoopBBs(const BB &bb)
72     {
73         (void)loopBBs.insert(bb.GetId());
74     }
75 
GetExitBBs()76     const MapleSet<BBID> &GetExitBBs() const
77     {
78         return exitBBs;
79     }
80 
InsertExitBBs(const BB & bb)81     void InsertExitBBs(const BB &bb)
82     {
83         (void)exitBBs.insert(bb.GetId());
84     }
85 
InsertBackEdges(const BB & bb)86     void InsertBackEdges(const BB &bb)
87     {
88         (void)backEdges.insert(bb.GetId());
89     }
90 
91     // check whether from->to is the back edge of the current loop
IsBackEdge(const BB & from,const BB & to)92     bool IsBackEdge(const BB &from, const BB &to) const
93     {
94         return (to.GetId() == header.GetId()) && (backEdges.find(from.GetId()) != backEdges.end());
95     }
96 
97     // get the BBId of all back edges
GetBackEdges()98     const MapleSet<BBID> &GetBackEdges() const
99     {
100         return backEdges;
101     }
102 
GetParentLoop()103     const LoopDesc *GetParentLoop() const
104     {
105         return parentLoop;
106     }
107 
GetParentLoop()108     LoopDesc *GetParentLoop()
109     {
110         return parentLoop;
111     }
112 
SetParentLoop(LoopDesc & loop)113     void SetParentLoop(LoopDesc &loop)
114     {
115         parentLoop = &loop;
116     }
117 
GetNestDepth()118     uint32 GetNestDepth() const
119     {
120         return nestDepth;
121     }
122 
SetNestDepth(uint32 depth)123     void SetNestDepth(uint32 depth)
124     {
125         nestDepth = depth;
126     }
127 
GetChildLoops()128     const MapleSet<LoopDesc*, LoopDescCmp> &GetChildLoops() const
129     {
130         return childLoops;
131     }
132 
InsertChildLoops(LoopDesc & loop)133     void InsertChildLoops(LoopDesc &loop)
134     {
135         (void)childLoops.insert(&loop);
136     }
137 
138 private:
139     MapleAllocator &alloc;
140     BB &header;                      // BB's header
141     MapleSet<BBID> loopBBs;          // BBs in loop
142     MapleSet<BBID> exitBBs;          // loop exit BBs
143     MapleSet<BBID> backEdges;        // loop back edges, backBB -> headBB
144     LoopDesc *parentLoop = nullptr;  // points to its closest nesting loop
145     uint32 nestDepth = 1;            // the nesting depth
146     MapleSet<LoopDesc*, LoopDescCmp> childLoops;
147 };
148 
149 class LoopAnalysis : public AnalysisResult {
150 public:
LoopAnalysis(CGFunc & func,MemPool & memPool,DomAnalysis & domInfo)151     LoopAnalysis(CGFunc &func, MemPool &memPool, DomAnalysis &domInfo)
152         : AnalysisResult(&memPool),
153           alloc(&memPool),
154           cgFunc(func),
155           dom(domInfo),
156           loops(alloc.Adapter()),
157           bbLoopParent(cgFunc.GetAllBBSize(), nullptr, alloc.Adapter())
158     {
159     }
160 
161     ~LoopAnalysis() override = default;
162 
GetLoops()163     const MapleVector<LoopDesc*> &GetLoops() const
164     {
165         return loops;
166     }
167 
GetLoops()168     MapleVector<LoopDesc*> &GetLoops()
169     {
170         return loops;
171     }
172 
173     // get the loop to which the BB belong, null -> not in loop.
GetBBLoopParent(BBID bbID)174     LoopDesc *GetBBLoopParent(BBID bbID) const
175     {
176         if (bbID >= bbLoopParent.size()) {
177             return nullptr;
178         }
179         return bbLoopParent[bbID];
180     }
181 
182     // check whether from->to is the back edge
IsBackEdge(const BB & from,const BB & to)183     bool IsBackEdge(const BB &from, const BB &to) const
184     {
185         auto *loop = GetBBLoopParent(to.GetId());
186         if (loop && loop->IsBackEdge(from, to)) {
187             return true;
188         }
189         loop = GetBBLoopParent(from.GetId());
190         return loop && loop->IsBackEdge(from, to);
191     }
192 
193     void Analysis();
194 
Dump()195     void Dump() const
196     {
197         LogInfo::MapleLogger() << "Dump LoopAnalysis Result For Func " << cgFunc.GetName() << ":\n";
198         for (const auto *loop : loops) {
199             loop->Dump();
200         }
201         for (BBID bbId = 0; bbId < bbLoopParent.size(); ++bbId) {
202             if (bbLoopParent[bbId] == nullptr) {
203                 continue;
204             }
205             LogInfo::MapleLogger() << "BB " << bbId << " in loop " << bbLoopParent[bbId]->GetHeader().GetId() << "\n";
206         }
207     }
208 
IsLoopHeaderBB(const BB & bb)209     bool IsLoopHeaderBB(const BB &bb) const
210     {
211         if (GetBBLoopParent(bb.GetId()) == nullptr) {
212             return false;
213         } else if (GetBBLoopParent(bb.GetId())->GetHeader().GetId() == bb.GetId()) {
214             return true;
215         }
216         return false;
217     }
218 
219 private:
220     MapleAllocator alloc;
221     CGFunc &cgFunc;
222     DomAnalysis &dom;
223     MapleVector<LoopDesc*> loops;         // all loops in func
224     MapleVector<LoopDesc*> bbLoopParent;  // gives closest nesting loop for each bb
225 
226     LoopDesc *GetOrCreateLoopDesc(BB &headBB);
227     void SetLoopParent4BB(const BB &bb, LoopDesc &loopDesc);
228     void SetExitBBs(LoopDesc &loop) const;
229     void GenerateLoop(BB *bb);
230     void ProcessBB(BB &bb);
231 };
232 
233 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgLoopAnalysis, maplebe::CGFunc);
GetResult()234 LoopAnalysis *GetResult()
235 {
236     return loop;
237 }
238 LoopAnalysis *loop = nullptr;
239 OVERRIDE_DEPENDENCE
240 MAPLE_FUNC_PHASE_DECLARE_END
241 } /* namespace maplebe */
242 
243 #endif /* MAPLEBE_INCLUDE_CG_LOOP_H */
244