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