• 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 #include "maple_phase_manager.h"
17 #include "cgfunc.h"
18 #include "mpl_timer.h"
19 #include "me_function.h"
20 
21 namespace maple {
22 using meFuncOptTy = MapleFunctionPhase<MeFunction>;
23 using cgFuncOptTy = MapleFunctionPhase<maplebe::CGFunc>;
ApplyMemPoolForAnalysisPhase(uint32 phaseKey,const MaplePhaseInfo & pi)24 MemPool *AnalysisDataManager::ApplyMemPoolForAnalysisPhase(uint32 phaseKey, const MaplePhaseInfo &pi)
25 {
26     std::string mempoolName = pi.PhaseName() + " memPool";
27     MemPool *phaseMempool = nullptr;
28     if (UseGlobalMpCtrler()) {
29         phaseMempool = memPoolCtrler.NewMemPool(mempoolName, true);
30     } else {
31         phaseMempool = innerCtrler->NewMemPool(mempoolName, true);
32     }
33     (void)analysisPhaseMemPool.emplace(
34         std::pair<AnalysisMemKey, MemPool *>(AnalysisMemKey(phaseKey, pi.GetPhaseID()), phaseMempool));
35     return phaseMempool;
36 }
37 
AddAnalysisPhase(uint32 phaseKey,MaplePhase * p)38 void AnalysisDataManager::AddAnalysisPhase(uint32 phaseKey, MaplePhase *p)
39 {
40     CHECK_FATAL(p != nullptr, "invalid phase when AddAnalysisPhase");  // change to assert after testing
41     (void)availableAnalysisPhases.emplace(
42         std::pair<AnalysisMemKey, MaplePhase *>(AnalysisMemKey(phaseKey, p->GetPhaseID()), p));
43 }
44 
45 // Erase phase at O2
46 // This is for the actully phase
EraseAnalysisPhase(uint32 phaseKey,MaplePhaseID pid)47 void AnalysisDataManager::EraseAnalysisPhase(uint32 phaseKey, MaplePhaseID pid)
48 {
49     auto it = analysisPhaseMemPool.find(AnalysisMemKey(phaseKey, pid));
50     auto itanother = availableAnalysisPhases.find(AnalysisMemKey(phaseKey, pid));
51     if (it != analysisPhaseMemPool.end() && itanother != availableAnalysisPhases.end()) {
52         auto resultanother = availableAnalysisPhases.erase(AnalysisMemKey(phaseKey, pid));
53         CHECK_FATAL(resultanother, "Release Failed");
54         delete it->second;
55         it->second = nullptr;
56         auto result = analysisPhaseMemPool.erase(AnalysisMemKey(phaseKey, pid));  // erase to release mempool ?
57         CHECK_FATAL(result, "Release Failed");
58     }
59 }
60 
61 // Erase all safely
EraseAllAnalysisPhase()62 void AnalysisDataManager::EraseAllAnalysisPhase()
63 {
64     for (auto it = availableAnalysisPhases.begin(); it != availableAnalysisPhases.end();) {
65         EraseAnalysisPhase(it);
66     }
67 }
68 
69 // Erase safely
EraseAnalysisPhase(MapleMap<AnalysisMemKey,MaplePhase * >::iterator & anaPhaseMapIt)70 void AnalysisDataManager::EraseAnalysisPhase(MapleMap<AnalysisMemKey, MaplePhase *>::iterator &anaPhaseMapIt)
71 {
72     auto it = analysisPhaseMemPool.find(anaPhaseMapIt->first);
73     if (it != analysisPhaseMemPool.end()) {
74         anaPhaseMapIt = availableAnalysisPhases.erase(anaPhaseMapIt);
75         delete it->second;
76         it->second = nullptr;
77 #ifdef DEBUG
78         bool result = analysisPhaseMemPool.erase(it->first);  // erase to release mempool
79 #else
80         (void)analysisPhaseMemPool.erase(it->first);
81 #endif
82         DEBUG_ASSERT(result, "Release Failed");
83 #ifdef DEBUG
84     } else {
85         DEBUG_ASSERT(false, "cannot delete phase which is not exist  &&  mempool is not create TOO");
86 #endif
87     }
88 }
89 
ClearInVaildAnalysisPhase(uint32 phaseKey,AnalysisDep & ADep)90 void AnalysisDataManager::ClearInVaildAnalysisPhase(uint32 phaseKey, AnalysisDep &ADep)
91 {
92     if (!ADep.GetPreservedAll()) {
93         // delete phases which are not preserved
94         if (ADep.GetPreservedPhase().empty()) {
95             for (auto it = availableAnalysisPhases.begin(); it != availableAnalysisPhases.end();) {
96                 if (it->first.first == phaseKey) {
97                     EraseAnalysisPhase(it);
98                 } else {
99                     ++it;
100                 }
101             }
102         }
103         for (auto it = availableAnalysisPhases.begin(); it != availableAnalysisPhases.end();) {
104             if (!ADep.FindIsPreserved((it->first).second) && it->first.first == phaseKey) {
105                 EraseAnalysisPhase(it);
106             } else {
107                 ++it;
108             }
109         }
110     } else {
111         if (!ADep.GetPreservedExceptPhase().empty()) {
112             for (auto exceptPhaseID : ADep.GetPreservedExceptPhase()) {
113                 auto it = availableAnalysisPhases.find(AnalysisMemKey(phaseKey, exceptPhaseID));
114                 if (it != availableAnalysisPhases.end()) {
115                     EraseAnalysisPhase(it);
116                 }
117             }
118         }
119     }
120 }
121 
GetVaildAnalysisPhase(uint32 phaseKey,MaplePhaseID pid)122 MaplePhase *AnalysisDataManager::GetVaildAnalysisPhase(uint32 phaseKey, MaplePhaseID pid)
123 {
124     auto it = availableAnalysisPhases.find(AnalysisMemKey(phaseKey, pid));
125     if (it == availableAnalysisPhases.end()) {
126         LogInfo::MapleLogger() << "Required "
127                                << MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(pid)->PhaseName()
128                                << " running before \n";
129         CHECK_FATAL(false, "find analysis phase failed");
130         return nullptr;
131     } else {
132         return it->second;
133     }
134 }
135 
IsAnalysisPhaseAvailable(uint32 phaseKey,MaplePhaseID pid)136 bool AnalysisDataManager::IsAnalysisPhaseAvailable(uint32 phaseKey, MaplePhaseID pid)
137 {
138     auto it = availableAnalysisPhases.find(AnalysisMemKey(phaseKey, pid));
139     return it != availableAnalysisPhases.end();
140 }
141 
Dump()142 void AnalysisDataManager::Dump()
143 {
144     LogInfo::MapleLogger() << "availableAnalysisPhases: \n";
145     for (auto &it : availableAnalysisPhases) {
146         LogInfo::MapleLogger()
147             << "<" << it.first.first << ", "
148             << MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(it.first.second)->PhaseName()
149             << "> : " << it.second << "\n";
150     }
151     LogInfo::MapleLogger() << "analysisPhaseMemPool: \n";
152     for (auto &it : analysisPhaseMemPool) {
153         LogInfo::MapleLogger()
154             << "<" << it.first.first << ", "
155             << MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(it.first.second)->PhaseName()
156             << "> : " << it.second << "\n";
157     }
158 }
159 
AddPhase(const std::string & phaseName,bool condition)160 void MaplePhaseManager::AddPhase(const std::string &phaseName, bool condition)
161 {
162     if (!condition) {
163         return;
164     }
165     bool found = false;
166     for (auto &it : MaplePhaseRegister::GetMaplePhaseRegister()->GetAllPassInfo()) {
167         if (it.second->PhaseName() == phaseName) {
168             phasesSequence.emplace_back(it.first);
169             found = true;
170             break;
171         }
172     }
173     if (!found) {
174         CHECK_FATAL(false, "%s not found !", phaseName.c_str());
175     }
176 }
177 
DumpPhaseTime()178 void MaplePhaseManager::DumpPhaseTime()
179 {
180     if (phaseTh != nullptr) {
181         phaseTh->DumpPhasesTime();
182     }
183 }
184 
SolveSkipFrom(const std::string & phaseName,size_t & i)185 void MaplePhaseManager::SolveSkipFrom(const std::string &phaseName, size_t &i)
186 {
187     const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]);
188     if (!skipFromFlag && curPhase->PhaseName() == phaseName) {
189         CHECK_FATAL(curPhase->CanSkip(), "%s cannot be skipped!", phaseName.c_str());
190         skipFromFlag = true;
191     }
192     if (skipFromFlag) {
193         while (curPhase->CanSkip() && (++i != phasesSequence.size())) {
194             curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]);
195             CHECK_FATAL(curPhase != nullptr, "null ptr check ");
196         }
197     }
198     skipFromFlag = false;
199 }
200 
SolveSkipAfter(const std::string & phaseName,size_t & i)201 void MaplePhaseManager::SolveSkipAfter(const std::string &phaseName, size_t &i)
202 {
203     const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]);
204     if (!skipAfterFlag && curPhase->PhaseName() == phaseName) {
205         skipAfterFlag = true;
206     }
207     if (skipAfterFlag) {
208         while (++i != phasesSequence.size()) {
209             curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(phasesSequence[i]);
210             CHECK_FATAL(curPhase != nullptr, "null ptr check ");
211             if (!curPhase->CanSkip()) {
212                 break;
213             }
214         }
215         --i; /* restore iterator */
216     }
217     skipAfterFlag = false;
218 }
219 
FindAnalysisDep(const MaplePhase * phase)220 AnalysisDep *MaplePhaseManager::FindAnalysisDep(const MaplePhase *phase)
221 {
222     AnalysisDep *anDependence = nullptr;
223     auto anDepIt = analysisDepMap.find(phase->GetPhaseID());
224     if (anDepIt != analysisDepMap.end()) {
225         anDependence = anDepIt->second;
226     } else {
227         anDependence = allocator.New<AnalysisDep>(*GetManagerMemPool());
228         phase->AnalysisDepInit(*anDependence);
229         (void)analysisDepMap.emplace(std::pair<MaplePhaseID, AnalysisDep *>(phase->GetPhaseID(), anDependence));
230     }
231     return anDependence;
232 }
233 
ApplyAnalysisDataManager(const std::thread::id threadID,MemPool & threadMP)234 AnalysisDataManager *MaplePhaseManager::ApplyAnalysisDataManager(const std::thread::id threadID, MemPool &threadMP)
235 {
236     auto *adm = threadMP.New<AnalysisDataManager>(threadMP);
237 #ifdef DEBUG
238     auto result = analysisDataManagers.emplace(std::pair<std::thread::id, AnalysisDataManager *>(threadID, adm));
239 #else
240     (void)analysisDataManagers.emplace(std::pair<std::thread::id, AnalysisDataManager *>(threadID, adm));
241 #endif
242     DEBUG_ASSERT(adm != nullptr && result.second, "apply AnalysisDataManager failed");
243     return adm;
244 }
245 
GetAnalysisDataManager(const std::thread::id threadID,MemPool & threadMP)246 AnalysisDataManager *MaplePhaseManager::GetAnalysisDataManager(const std::thread::id threadID, MemPool &threadMP)
247 {
248     auto admIt = analysisDataManagers.find(threadID);
249     if (admIt != analysisDataManagers.end()) {
250         return admIt->second;
251     } else {
252         return ApplyAnalysisDataManager(threadID, threadMP);
253     }
254 }
255 
AllocateMemPoolInPhaseManager(const std::string & mempoolName)256 std::unique_ptr<ThreadLocalMemPool> MaplePhaseManager::AllocateMemPoolInPhaseManager(const std::string &mempoolName)
257 {
258     if (!UseGlobalMpCtrler()) {
259         LogInfo::MapleLogger() << " Inner Ctrler has not been supported yet \n";
260     }
261     return std::make_unique<ThreadLocalMemPool>(memPoolCtrler, mempoolName);
262 }
263 
264 template <typename phaseT, typename IRTemplate>
RunDependentPhase(const MaplePhase & phase,AnalysisDataManager & adm,IRTemplate & irUnit,int lev)265 void MaplePhaseManager::RunDependentPhase(const MaplePhase &phase, AnalysisDataManager &adm, IRTemplate &irUnit,
266                                           int lev)
267 {
268     AnalysisDep *anaDependence = FindAnalysisDep(&phase);
269     for (auto requiredPhase : anaDependence->GetRequiredPhase()) {
270         const MaplePhaseInfo *curPhase = MaplePhaseRegister::GetMaplePhaseRegister()->GetPhaseByID(requiredPhase);
271         if (adm.IsAnalysisPhaseAvailable(irUnit.GetUniqueID(), curPhase->GetPhaseID())) {
272             continue;
273         }
274         LogDependence(curPhase, lev);
275         if (curPhase->IsAnalysis()) {
276             (void)RunAnalysisPhase<phaseT, IRTemplate>(*curPhase, adm, irUnit, lev);
277         } else {
278             (void)RunTransformPhase<phaseT, IRTemplate>(*curPhase, adm, irUnit, lev);
279         }
280     }
281 }
282 
283 /* live range of a phase should be short than mempool */
284 template <typename phaseT, typename IRTemplate>
RunTransformPhase(const MaplePhaseInfo & phaseInfo,AnalysisDataManager & adm,IRTemplate & irUnit,int lev)285 bool MaplePhaseManager::RunTransformPhase(const MaplePhaseInfo &phaseInfo, AnalysisDataManager &adm, IRTemplate &irUnit,
286                                           int lev)
287 {
288     bool result = false;
289     auto transformPhaseMempool = AllocateMemPoolInPhaseManager(phaseInfo.PhaseName() + "'s mempool");
290     auto *phase = static_cast<phaseT *>(phaseInfo.GetConstructor()(transformPhaseMempool.get()));
291     phase->SetAnalysisInfoHook(transformPhaseMempool->New<AnalysisInfoHook>(*(transformPhaseMempool.get()), adm, this));
292     RunDependentPhase<phaseT, IRTemplate>(*phase, adm, irUnit, lev + 1);
293     if (phaseTh != nullptr) {
294         phaseTh->RunBeforePhase(phaseInfo);
295         result = phase->PhaseRun(irUnit);
296         phaseTh->RunAfterPhase(phaseInfo);
297     } else {
298         result = phase->PhaseRun(irUnit);
299     }
300     phase->ClearTempMemPool();
301     adm.ClearInVaildAnalysisPhase(irUnit.GetUniqueID(), *FindAnalysisDep(phase));
302     return result;
303 }
304 
305 template <typename phaseT, typename IRTemplate>
RunAnalysisPhase(const MaplePhaseInfo & phaseInfo,AnalysisDataManager & adm,IRTemplate & irUnit,int lev)306 bool MaplePhaseManager::RunAnalysisPhase(const MaplePhaseInfo &phaseInfo, AnalysisDataManager &adm, IRTemplate &irUnit,
307                                          int lev)
308 {
309     bool result = false;
310     phaseT *phase = nullptr;
311     if (adm.IsAnalysisPhaseAvailable(irUnit.GetUniqueID(), phaseInfo.GetPhaseID())) {
312         return result;
313     }
314     MemPool *anasPhaseMempool = adm.ApplyMemPoolForAnalysisPhase(irUnit.GetUniqueID(), phaseInfo);
315     phase = static_cast<phaseT *>(phaseInfo.GetConstructor()(anasPhaseMempool));
316     // change analysis info hook mempool from ADM Allocator to phase allocator?
317     phase->SetAnalysisInfoHook(anasPhaseMempool->New<AnalysisInfoHook>(*anasPhaseMempool, adm, this));
318     RunDependentPhase<phaseT, IRTemplate>(*phase, adm, irUnit, lev + 1);
319     if (phaseTh != nullptr) {
320         phaseTh->RunBeforePhase(phaseInfo);
321         result = phase->PhaseRun(irUnit);
322         phaseTh->RunAfterPhase(phaseInfo);
323     } else {
324         result = phase->PhaseRun(irUnit);
325     }
326     phase->ClearTempMemPool();
327     adm.AddAnalysisPhase(irUnit.GetUniqueID(), phase);
328     return result;
329 }
330 
331 // declaration for functionPhase (template only)
332 template bool MaplePhaseManager::RunTransformPhase<MapleModulePhase, MIRModule>(const MaplePhaseInfo &phaseInfo,
333                                                                                 AnalysisDataManager &adm,
334                                                                                 MIRModule &irUnit, int lev);
335 template bool MaplePhaseManager::RunTransformPhase<MapleSccPhase<SCCNode<CGNode>>, SCCNode<CGNode>>(
336     const MaplePhaseInfo &phaseInfo, AnalysisDataManager &adm, SCCNode<CGNode> &irUnit, int lev);
337 template bool MaplePhaseManager::RunAnalysisPhase<MapleModulePhase, MIRModule>(const MaplePhaseInfo &phaseInfo,
338                                                                                AnalysisDataManager &adm,
339                                                                                MIRModule &irUnit, int lev);
340 template bool MaplePhaseManager::RunTransformPhase<meFuncOptTy, MeFunction>(const MaplePhaseInfo &phaseInfo,
341                                                                             AnalysisDataManager &adm,
342                                                                             MeFunction &irUnit, int lev);
343 template bool MaplePhaseManager::RunAnalysisPhase<meFuncOptTy, MeFunction>(const MaplePhaseInfo &phaseInfo,
344                                                                            AnalysisDataManager &adm, MeFunction &irUnit,
345                                                                            int lev);
346 template bool MaplePhaseManager::RunTransformPhase<cgFuncOptTy, maplebe::CGFunc>(const MaplePhaseInfo &phaseInfo,
347                                                                                  AnalysisDataManager &adm,
348                                                                                  maplebe::CGFunc &irUnit, int lev);
349 template bool MaplePhaseManager::RunAnalysisPhase<cgFuncOptTy, maplebe::CGFunc>(const MaplePhaseInfo &phaseInfo,
350                                                                                 AnalysisDataManager &adm,
351                                                                                 maplebe::CGFunc &irUnit, int lev);
352 }  // namespace maple
353