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_H
17 #define MAPLE_PHASE_INCLUDE_MAPLE_PHASE_H
18 #include "maple_phase_support.h"
19 namespace maple {
20 class MaplePhase;
21 class AnalysisInfoHook;
22 class MIRModule;
23 enum MaplePhaseKind : uint8_t { kModulePM, kModulePhase, kFunctionPM, kFunctionPhase, kSccPhasePM, kSccPhase };
24 
25 class MaplePhase {
26 public:
MaplePhase(MaplePhaseKind kind, MaplePhaseID id, MemPool &mp)27     MaplePhase(MaplePhaseKind kind, MaplePhaseID id, MemPool &mp)
28         : phaseAllocator(&mp), phaseKind(kind), phaseID(id), tempMemPools(phaseAllocator.Adapter())
29     {
30     }
~MaplePhase()31     virtual ~MaplePhase()
32     {
33         if (analysisInfo != nullptr) {
34             analysisInfo = nullptr;
35         }
36     };
Dump() const37     void Dump() const
38     {
39         LogInfo::MapleLogger() << "this is Phase : " << PhaseName() << " Kind : " << phaseKind << " ID : " << phaseID
40                                << "\n";
41     }
GetPhaseID() const42     MaplePhaseID GetPhaseID() const
43     {
44         return phaseID;
45     }
SetPhaseID(MaplePhaseID id)46     void SetPhaseID(MaplePhaseID id)
47     {
48         phaseID = id;
49     }
50     virtual std::string PhaseName() const = 0;
51     void SetAnalysisInfoHook(AnalysisInfoHook *hook);
52     AnalysisInfoHook *GetAnalysisInfoHook();
53 
54     void AnalysisDepInit(AnalysisDep &aDep) const;
GetPhaseAllocator()55     MapleAllocator *GetPhaseAllocator()
56     {
57         return &phaseAllocator;
58     }
GetPhaseMemPool()59     MemPool *GetPhaseMemPool()
60     {
61         return phaseAllocator.GetMemPool();
62     }
63 
64     MemPool *ApplyTempMemPool();
65     void ClearTempMemPool();
66 
67 private:
68     MapleAllocator phaseAllocator;  //  mempool for phase
69     AnalysisInfoHook *analysisInfo = nullptr;
70     virtual void GetAnalysisDependence(AnalysisDep &aDep) const;
71     MaplePhaseKind phaseKind;
72     MaplePhaseID phaseID;
73     MapleVector<MemPool *> tempMemPools;  // delete after phase Run  [Thread Local]
74 };
75 
76 class MapleModulePhase : public MaplePhase {
77 public:
MapleModulePhase(MaplePhaseID id, MemPool *mp)78     MapleModulePhase(MaplePhaseID id, MemPool *mp) : MaplePhase(kModulePhase, id, *mp) {}
79     ~MapleModulePhase() override = default;
80 
81     virtual bool PhaseRun(MIRModule &m) = 0;
82 };
83 
84 template <class funcT>
85 class MapleFunctionPhase : public MaplePhase {
86 public:
MapleFunctionPhase(MaplePhaseID id, MemPool *mp)87     MapleFunctionPhase(MaplePhaseID id, MemPool *mp) : MaplePhase(kFunctionPhase, id, *mp) {}
88     ~MapleFunctionPhase() override = default;
89     virtual bool PhaseRun(funcT &f) = 0;
90 };
91 
92 template <class SccT>
93 class MapleSccPhase : public MaplePhase {
94 public:
MapleSccPhase(MaplePhaseID id, MemPool *mp)95     MapleSccPhase(MaplePhaseID id, MemPool *mp) : MaplePhase(kSccPhase, id, *mp) {}
96     ~MapleSccPhase() override = default;
97     virtual bool PhaseRun(SccT &scc) = 0;
98     template <class funcT>
99     void Dump(funcT &f, const std::string phaseName);
100 };
101 
102 class MaplePhaseRegister {
103 public:
104     MaplePhaseRegister() = default;
105     ~MaplePhaseRegister() = default;
106 
107     static MaplePhaseRegister *GetMaplePhaseRegister();
108     void RegisterPhase(const MaplePhaseInfo &PI);
109     const MaplePhaseInfo *GetPhaseByID(MaplePhaseID id);
GetAllPassInfo() const110     const auto &GetAllPassInfo() const
111     {
112         return passInfoMap;
113     }
114 
115 private:
116     std::map<MaplePhaseID, const MaplePhaseInfo *> passInfoMap;
117 };
118 
119 template <typename phaseNameT>
120 class RegisterPhase : public MaplePhaseInfo {
121 public:
RegisterPhase(const std::string name, bool isAnalysis = false, bool CFGOnly = false, bool canSkip = false)122     RegisterPhase(const std::string name, bool isAnalysis = false, bool CFGOnly = false, bool canSkip = false)
123         : MaplePhaseInfo(name, &phaseNameT::id, isAnalysis, CFGOnly, canSkip)
124     {
125         SetConstructor(phaseNameT::CreatePhase);
126         auto globalRegistry = maple::MaplePhaseRegister::GetMaplePhaseRegister();
127         globalRegistry->RegisterPhase(*this);
128     }
129     ~RegisterPhase() = default;
130 };
131 
132 #define PHASECONSTRUCTOR(PHASENAME)                   \
133     static unsigned int id;                           \
134     static MaplePhase *CreatePhase(MemPool *createMP) \
135     {                                                 \
136         return createMP->New<PHASENAME>(createMP);    \
137     }
138 
139 #define OVERRIDE_DEPENDENCE \
140 private:                    \
141     void GetAnalysisDependence(maple::AnalysisDep &aDep) const override;
142 
143 #define MAPLE_FUNC_PHASE_DECLARE_BEGIN(PHASENAME, IRTYPE)                        \
144     class PHASENAME : public MapleFunctionPhase<IRTYPE> {                        \
145     public:                                                                      \
146         explicit PHASENAME(MemPool *mp) : MapleFunctionPhase<IRTYPE>(&id, mp) {} \
147         ~PHASENAME() override = default;                                         \
148         std::string PhaseName() const override;                                  \
149         static unsigned int id;                                                  \
150         static MaplePhase *CreatePhase(MemPool *createMP)                        \
151         {                                                                        \
152             return createMP->New<PHASENAME>(createMP);                           \
153         }                                                                        \
154         bool PhaseRun(IRTYPE &func) override;
155 
156 #define MAPLE_FUNC_PHASE_DECLARE_END \
157     }                                \
158     ;
159 
160 #define MAPLE_SCC_PHASE_DECLARE_BEGIN(PHASENAME, IRTYPE)                    \
161     class PHASENAME : public MapleSccPhase<IRTYPE> {                        \
162     public:                                                                 \
163         explicit PHASENAME(MemPool *mp) : MapleSccPhase<IRTYPE>(&id, mp) {} \
164         ~PHASENAME() override = default;                                    \
165         std::string PhaseName() const override;                             \
166         static unsigned int id;                                             \
167         static MaplePhase *CreatePhase(MemPool *createMP)                   \
168         {                                                                   \
169             return createMP->New<PHASENAME>(createMP);                      \
170         }                                                                   \
171         bool PhaseRun(IRTYPE &scc) override;
172 
173 #define MAPLE_SCC_PHASE_DECLARE_END \
174     }                               \
175     ;
176 
177 #define MAPLE_FUNC_PHASE_DECLARE(PHASENAME, IRTYPE)   \
178     MAPLE_FUNC_PHASE_DECLARE_BEGIN(PHASENAME, IRTYPE) \
179     OVERRIDE_DEPENDENCE                               \
180     MAPLE_FUNC_PHASE_DECLARE_END
181 
182 #define MAPLE_MODULE_PHASE_DECLARE_BEGIN(PHASENAME)                    \
183     class PHASENAME : public MapleModulePhase {                        \
184     public:                                                            \
185         explicit PHASENAME(MemPool *mp) : MapleModulePhase(&id, mp) {} \
186         ~PHASENAME() override = default;                               \
187         std::string PhaseName() const override;                        \
188         static unsigned int id;                                        \
189         static MaplePhase *CreatePhase(MemPool *createMP)              \
190         {                                                              \
191             return createMP->New<PHASENAME>(createMP);                 \
192         }                                                              \
193         bool PhaseRun(MIRModule &m) override;
194 
195 #define MAPLE_MODULE_PHASE_DECLARE_END \
196     }                                  \
197     ;
198 
199 #define MAPLE_MODULE_PHASE_DECLARE(PHASENAME)   \
200     MAPLE_MODULE_PHASE_DECLARE_BEGIN(PHASENAME) \
201     OVERRIDE_DEPENDENCE                         \
202     MAPLE_MODULE_PHASE_DECLARE_END
203 
204 #define MAPLE_ANALYSIS_PHASE_REGISTER(CLASSNAME, PHASENAME) \
205     unsigned int CLASSNAME::id = 0;                         \
206     std::string CLASSNAME::PhaseName() const                \
207     {                                                       \
208         return #PHASENAME;                                  \
209     }                                                       \
210     static RegisterPhase<CLASSNAME> MAPLEPHASE_##PHASENAME(#PHASENAME, true);
211 
212 #define MAPLE_TRANSFORM_PHASE_REGISTER(CLASSNAME, PHASENAME) \
213     unsigned int CLASSNAME::id = 0;                          \
214     std::string CLASSNAME::PhaseName() const                 \
215     {                                                        \
216         return #PHASENAME;                                   \
217     }                                                        \
218     static RegisterPhase<CLASSNAME> MAPLEPHASE_##PHASENAME(#PHASENAME, false);
219 
220 #define MAPLE_ANALYSIS_PHASE_REGISTER_CANSKIP(CLASSNAME, PHASENAME) \
221     unsigned int CLASSNAME::id = 0;                                 \
222     std::string CLASSNAME::PhaseName() const                        \
223     {                                                               \
224         return #PHASENAME;                                          \
225     }                                                               \
226     static RegisterPhase<CLASSNAME> MAPLEPHASE_##PHASENAME(#PHASENAME, true, false, true);
227 
228 #define MAPLE_TRANSFORM_PHASE_REGISTER_CANSKIP(CLASSNAME, PHASENAME) \
229     unsigned int CLASSNAME::id = 0;                                  \
230     std::string CLASSNAME::PhaseName() const                         \
231     {                                                                \
232         return #PHASENAME;                                           \
233     }                                                                \
234     static RegisterPhase<CLASSNAME> MAPLEPHASE_##PHASENAME(#PHASENAME, false, false, true);
235 
236 #define GET_ANALYSIS(PHASENAME, PHASEKEY)                                                                             \
237     static_cast<PHASENAME *>(GetAnalysisInfoHook()->FindAnalysisData((PHASEKEY).GetUniqueID(), this, &PHASENAME::id)) \
238         ->GetResult()
239 
240 #define FORCE_GET(PHASENAME)                                                                                           \
241     static_cast<PHASENAME *>(GetAnalysisInfoHook()->ForceRunAnalysisPhase<meFuncOptTy, MeFunction>(&PHASENAME::id, f)) \
242         ->GetResult()
243 
244 #define FORCE_INVALID(PHASENAME, PHASEKEY) \
245     GetAnalysisInfoHook()->ForceEraseAnalysisPhase(PHASEKEY.GetUniqueID(), &PHASENAME::id)
246 }  // namespace maple
247 
248 #endif  // MAPLE_ME_INCLUDE_ME_PHASE_MANAGER_H
249