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