• 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 MAPLE_PHASE_INCLUDE_MAPLE_PHASE_MANAGER_H
17 #define MAPLE_PHASE_INCLUDE_MAPLE_PHASE_MANAGER_H
18 #include "maple_phase.h"
19 #include "me_option.h"
20 #include "call_graph.h"
21 
22 namespace maple {
23 class MaplePhase;
24 using AnalysisMemKey = std::pair<uint32, MaplePhaseID>;
25 class AnalysisDataManager {
26 public:
AnalysisDataManager(MemPool & mempool)27     explicit AnalysisDataManager(MemPool &mempool)
28         : allocator(&mempool), analysisPhaseMemPool(allocator.Adapter()), availableAnalysisPhases(allocator.Adapter())
29     {
30         innerCtrler = &mempool.GetCtrler();
31     }
32 
33     ~AnalysisDataManager() = default;
34 
UseGlobalMpCtrler()35     bool UseGlobalMpCtrler() const
36     {
37         return useGlobalMpCtrler;
38     }
39 
CopyAnalysisResultFrom(const AnalysisDataManager & other)40     void CopyAnalysisResultFrom(const AnalysisDataManager &other)
41     {
42         analysisPhaseMemPool = other.analysisPhaseMemPool;
43         availableAnalysisPhases = other.availableAnalysisPhases;
44     }
45 
46     MemPool *ApplyMemPoolForAnalysisPhase(uint32 phaseKey, const MaplePhaseInfo &pi);
47     void AddAnalysisPhase(uint32 phaseKey, MaplePhase *p);
CheckAnalysisInfoEmpty()48     bool CheckAnalysisInfoEmpty() const
49     {
50         return analysisPhaseMemPool.empty() && availableAnalysisPhases.empty();
51     }
52     void EraseAnalysisPhase(uint32 phaseKey, MaplePhaseID pid);
53     void EraseAllAnalysisPhase();
54     void EraseAnalysisPhase(MapleMap<AnalysisMemKey, MaplePhase *>::iterator &anaPhaseMapIt);
55     void ClearInVaildAnalysisPhase(uint32 phaseKey, AnalysisDep &ADep);  // do after transform phase;
56     MaplePhase *GetVaildAnalysisPhase(uint32 phaseKey, MaplePhaseID pid);
57     bool IsAnalysisPhaseAvailable(uint32 phaseKey, MaplePhaseID pid);
58     void Dump();
59 
60 private:
61     MapleAllocator allocator;  // thread local
62     MemPoolCtrler *innerCtrler = nullptr;
63     MapleMap<AnalysisMemKey, MemPool *> analysisPhaseMemPool;
64     MapleMap<AnalysisMemKey, MaplePhase *> availableAnalysisPhases;
65     bool useGlobalMpCtrler = false;
66 };
67 
68 /* top level manager [manages phase managers/ immutable pass(not implement yet)] */
69 class MaplePhaseManager {
70 public:
MaplePhaseManager(MemPool & memPool)71     explicit MaplePhaseManager(MemPool &memPool)
72         : allocator(&memPool),
73           phasesSequence(allocator.Adapter()),
74           analysisDepMap(allocator.Adapter()),
75           threadMemPools(allocator.Adapter()),
76           analysisDataManagers(allocator.Adapter())
77     {
78     }
79 
~MaplePhaseManager()80     virtual ~MaplePhaseManager()
81     {
82         phaseTh = nullptr;
83     }
84 
GetManagerMemPool()85     MemPool *GetManagerMemPool()
86     {
87         return allocator.GetMemPool();
88     }
89 
ClearAllPhases()90     void ClearAllPhases()
91     {
92         phasesSequence.clear();
93     }
94 
95 #define ADDMAPLEPHASE(PhaseName, condition) AddPhase(PhaseName, condition)
96 #define ADDMAPLEMEPHASE(PhaseName, condition) \
97     if (!MeOption::IsSkipPhase(PhaseName)) {  \
98         AddPhase(PhaseName, condition);       \
99     }
100 #define ADDMODULEPHASE(PhaseName, condition)                  \
101     if (!Options::IsSkipPhase(PhaseName) && IsRunMpl2Mpl()) { \
102         AddPhase(PhaseName, condition);                       \
103     }
104     void AddPhase(const std::string &phaseName, bool condition);
105     AnalysisDep *FindAnalysisDep(const MaplePhase *phase);
106 
SetQuiet(bool value)107     void SetQuiet(bool value)
108     {
109         quiet = value;
110     }
111 
IsQuiet()112     bool IsQuiet() const
113     {
114         return quiet;
115     }
116 
LogDependence(const MaplePhaseInfo * curPhase,int depLev)117     void LogDependence(const MaplePhaseInfo *curPhase, int depLev)
118     {
119         std::string prefix = "";
120         while (depLev > 0) {
121             prefix += "  ";
122             depLev--;
123         }
124         if (!IsQuiet()) {
125             LogInfo::MapleLogger() << prefix << "  ++ trigger phase [ " << curPhase->PhaseName() << " ]\n";
126         }
127     }
128 
129     void SolveSkipFrom(const std::string &phaseName, size_t &i);
130     void SolveSkipAfter(const std::string &phaseName, size_t &i);
131 
132     /* phase time record */
133     void InitTimeHandler(uint32 threadNum = 1)
134     {
135         phaseTh = GetManagerMemPool()->New<PhaseTimeHandler>(*GetManagerMemPool(), threadNum);
136     }
137     void DumpPhaseTime();
138 
139     /* threadMP is given by thread local mempool */
140     AnalysisDataManager *ApplyAnalysisDataManager(const std::thread::id threadID, MemPool &threadMP);
141     AnalysisDataManager *GetAnalysisDataManager(const std::thread::id threadID, MemPool &threadMP);
142 
143     /* mempool */
144     std::unique_ptr<ThreadLocalMemPool> AllocateMemPoolInPhaseManager(const std::string &mempoolName);
UseGlobalMpCtrler()145     bool UseGlobalMpCtrler() const
146     {
147         return useGlobalMpCtrler;
148     }
149 
150     template <typename phaseT, typename IRTemplate>
151     void RunDependentPhase(const MaplePhase &phase, AnalysisDataManager &adm, IRTemplate &irUnit, int lev = 0);
152     template <typename phaseT, typename IRTemplate>
153     bool RunTransformPhase(const MaplePhaseInfo &phaseInfo, AnalysisDataManager &adm, IRTemplate &irUnit, int lev = 0);
154     template <typename phaseT, typename IRTemplate>
155     bool RunAnalysisPhase(const MaplePhaseInfo &phaseInfo, AnalysisDataManager &adm, IRTemplate &irUnit, int lev = 0);
156 
157 protected:
158     MapleAllocator allocator;
159     MapleVector<MaplePhaseID> phasesSequence;
160     // write in multithread once. read any time
161     MapleMap<MaplePhaseID, AnalysisDep *> analysisDepMap;
162     // thread mempool for analysisDataManger and analysis info hook
163     MapleUnorderedMap<std::thread::id, MemPool *> threadMemPools;
164 
165 private:
166     // in serial model. there is no analysisataManager.
167     MapleUnorderedMap<std::thread::id, AnalysisDataManager *> analysisDataManagers;
168     PhaseTimeHandler *phaseTh = nullptr;
169     bool skipFromFlag = false;
170     bool skipAfterFlag = false;
171     bool quiet = false;
172 
173     /*
174      * use global/local mempool controller to allocate mempool
175      * Use global mempool : memPoolCtrler  [reduce memory occupancy]
176      * Use local mempool : innerCtrler     [reduce compiling time]
177      * Can be deleted after testing
178      */
179     bool useGlobalMpCtrler = true;
180 };
181 
182 class AnalysisInfoHook {
183 public:
AnalysisInfoHook(MemPool & memPool,AnalysisDataManager & adm,MaplePhaseManager * bpm)184     AnalysisInfoHook(MemPool &memPool, AnalysisDataManager &adm, MaplePhaseManager *bpm)
185         : allocator(&memPool), adManager(adm), bindingPM(bpm), analysisPhasesData(allocator.Adapter())
186     {
187     }
188     virtual ~AnalysisInfoHook() = default;
AddAnalysisData(uint32 phaseKey,MaplePhaseID id,MaplePhase * phaseImpl)189     void AddAnalysisData(uint32 phaseKey, MaplePhaseID id, MaplePhase *phaseImpl)
190     {
191         (void)analysisPhasesData.emplace(
192             std::pair<AnalysisMemKey, MaplePhase *>(AnalysisMemKey(phaseKey, id), phaseImpl));
193     }
194 
FindAnalysisData(uint32 phaseKey,const MaplePhase * p,MaplePhaseID id)195     MaplePhase *FindAnalysisData(uint32 phaseKey, const MaplePhase *p, MaplePhaseID id)
196     {
197         auto anaPhaseInfoIt = analysisPhasesData.find(AnalysisMemKey(phaseKey, id));
198         if (anaPhaseInfoIt != analysisPhasesData.end()) {
199             return anaPhaseInfoIt->second;
200         } else {
201             /* fill all required analysis phase at first time */
202             AnalysisDep *anaDependence = bindingPM->FindAnalysisDep(p);
203             for (auto requiredAnaPhase : anaDependence->GetRequiredPhase()) {
204                 const MaplePhaseInfo *requiredPhase =
205                     MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(requiredAnaPhase);
206                 if (!requiredPhase->IsAnalysis()) {
207                     continue;
208                 }
209                 AddAnalysisData(phaseKey, requiredAnaPhase,
210                                 adManager.GetVaildAnalysisPhase(phaseKey, requiredAnaPhase));
211             }
212             DEBUG_ASSERT(analysisPhasesData.find(AnalysisMemKey(phaseKey, id)) != analysisPhasesData.end(),
213                          "Need Analysis Dependence info");
214             return analysisPhasesData[AnalysisMemKey(phaseKey, id)];
215         }
216     }
217 
218     /* Find analysis Data which is at higher IR level */
219     template <typename AIMPHASE, typename IRUnit>
GetOverIRAnalyisData(const IRUnit & u)220     MaplePhase *GetOverIRAnalyisData(const IRUnit &u)
221     {
222         MaplePhase *it = dynamic_cast<MaplePhase *>(bindingPM);
223         DEBUG_ASSERT(it != nullptr, "find Over IR info failed");
224         return it->GetAnalysisInfoHook()->FindAnalysisData(u.GetUniqueID(), it, &AIMPHASE::id);
225     }
226 
227     /* Find analysis Data which is at highest IR level */
228     template <typename AIMPHASE, typename IRUnit>
GetTopLevelAnalyisData(const IRUnit & u)229     MaplePhase *GetTopLevelAnalyisData(const IRUnit &u)
230     {
231         MaplePhase *curPhase = nullptr;
232         MaplePhase *upperPhase = dynamic_cast<MaplePhase *>(bindingPM);
233         DEBUG_ASSERT(upperPhase != nullptr, "find Over IR info failed");
234         AnalysisInfoHook *curHook = this;
235         AnalysisInfoHook *upperHook = upperPhase->GetAnalysisInfoHook();
236         while (upperHook != nullptr) {
237             curPhase = upperPhase;
238             curHook = upperHook;
239             upperPhase = dynamic_cast<MaplePhase *>(upperHook->bindingPM);
240             upperHook = upperPhase->GetAnalysisInfoHook();
241         }
242         return curHook->FindAnalysisData(u.GetUniqueID(), curPhase, &AIMPHASE::id);
243     }
244 
GetOverIRMempool()245     MemPool *GetOverIRMempool()
246     {
247         return bindingPM->GetManagerMemPool();
248     }
249 
250     /* Use In O2 carefully */
251     template <typename PHASEType, typename IRTemplate>
252     MaplePhase *ForceRunAnalysisPhase(MaplePhaseID anaPid, IRTemplate &irUnit, int depLev = 1)
253     {
254         const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(anaPid);
255         if (adManager.IsAnalysisPhaseAvailable(irUnit.GetUniqueID(), curPhase->GetPhaseID())) {
256             return adManager.GetVaildAnalysisPhase(irUnit.GetUniqueID(), anaPid);
257         }
258         bindingPM->LogDependence(curPhase, depLev);
259         (void)bindingPM->RunAnalysisPhase<PHASEType, IRTemplate>(*curPhase, adManager, irUnit, depLev);
260         return adManager.GetVaildAnalysisPhase(irUnit.GetUniqueID(), anaPid);
261     }
262 
263     template <typename PHASEType, typename IRTemplate>
264     void ForceRunTransFormPhase(MaplePhaseID anaPid, IRTemplate &irUnit, int depLev = 1)
265     {
266         const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(anaPid);
267         bindingPM->LogDependence(curPhase, depLev);
268         (void)bindingPM->RunTransformPhase<PHASEType, IRTemplate>(*curPhase, adManager, irUnit, depLev);
269     }
270 
271     /* Use In O2 carefully */
ForceEraseAnalysisPhase(uint32 phaseKey,MaplePhaseID anaPid)272     void ForceEraseAnalysisPhase(uint32 phaseKey, MaplePhaseID anaPid)
273     {
274         adManager.EraseAnalysisPhase(phaseKey, anaPid);
275     }
276 
277     /* Use In O2 carefully */
ForceEraseAllAnalysisPhase()278     void ForceEraseAllAnalysisPhase()
279     {
280         adManager.EraseAllAnalysisPhase();
281     }
282 
283 private:
284     MapleAllocator allocator;
285     AnalysisDataManager &adManager;
286     MaplePhaseManager *bindingPM;
287     MapleMap<AnalysisMemKey, MaplePhase *> analysisPhasesData;
288 };
289 
290 /* manages (module phases) & (funtion phase managers) */
291 class ModulePM : public MaplePhase, public MaplePhaseManager {
292 public:
ModulePM(MemPool * mp,MaplePhaseID id)293     ModulePM(MemPool *mp, MaplePhaseID id) : MaplePhase(kModulePM, id, *mp), MaplePhaseManager(*mp) {}
294     virtual ~ModulePM() = default;
295 };
296 
297 /* manages (function phases) & (loop/region phase managers) */
298 class FunctionPM : public MapleModulePhase, public MaplePhaseManager {
299 public:
FunctionPM(MemPool * mp,MaplePhaseID id)300     FunctionPM(MemPool *mp, MaplePhaseID id) : MapleModulePhase(id, mp), MaplePhaseManager(*mp) {}
301     virtual ~FunctionPM() = default;
302 };
303 
304 /* manages (scc phases) */
305 class SccPM : public MapleModulePhase, public MaplePhaseManager {
306 public:
SccPM(MemPool * mp,MaplePhaseID id)307     SccPM(MemPool *mp, MaplePhaseID id) : MapleModulePhase(id, mp), MaplePhaseManager(*mp) {}
308     virtual ~SccPM() = default;
309 };
310 
311 /* manages (function phases in function phase) */
312 template <typename IRType>
313 class FunctionPhaseGroup : public MapleFunctionPhase<IRType>, public MaplePhaseManager {
314 public:
FunctionPhaseGroup(MemPool * mp,MaplePhaseID id)315     FunctionPhaseGroup(MemPool *mp, MaplePhaseID id) : MapleFunctionPhase<IRType>(&id, mp), MaplePhaseManager(*mp) {}
316     virtual ~FunctionPhaseGroup() = default;
317 };
318 }  // namespace maple
319 #endif  // MAPLE_PHASE_MANAGER_H
320