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