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