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