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_ME_INCLUDE_ME_FUNCTION_H
17 #define MAPLE_ME_INCLUDE_ME_FUNCTION_H
18 #include "mir_parser.h"
19 #include "mir_function.h"
20 #include "opcode_info.h"
21 #include "me_option.h"
22 #include "mempool.h"
23 #include "mempool_allocator.h"
24 #include "ver_symbol.h"
25 #include "bb.h"
26 #include "ssa_tab.h"
27 #include "func_emit.h"
28 #include "me_ir.h"
29 #include "profile.h"
30 #include "pme_function.h"
31
32 namespace maple {
33 class MeCFG; // circular dependency exists, no other choice
34 class MeIRMap; // circular dependency exists, no other choice
35 #if DEBUG
36 extern MIRModule *globalMIRModule;
37 extern MeFunction *globalFunc;
38 extern MeIRMap *globalIRMap;
39 extern SSATab *globalSSATab;
40 #endif
41
42 template <typename Iterator>
43 class FilterIterator {
44 public:
45 using FilterFunc = std::function<bool(Iterator)>;
46 using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
47 using value_type = typename std::iterator_traits<Iterator>::value_type;
48 using difference_type = typename std::iterator_traits<Iterator>::difference_type;
49 using pointer = typename std::iterator_traits<Iterator>::pointer;
50 using reference = typename std::iterator_traits<Iterator>::reference;
51 using const_pointer = typename std::add_const<pointer>::type;
52 using const_reference = typename std::add_const<reference>::type;
53
FilterIterator(Iterator it)54 explicit FilterIterator(Iterator it) : iterator(it) {}
55
FilterIterator(Iterator it,FilterFunc func)56 FilterIterator(Iterator it, FilterFunc func) : iterator(it), func(func)
57 {
58 while (!func(iterator)) {
59 ++iterator;
60 }
61 }
62
63 ~FilterIterator() = default;
64
base()65 Iterator base() const
66 {
67 return iterator;
68 }
69
70 reference operator*() const
71 {
72 return *iterator;
73 }
74
75 pointer operator->() const
76 {
77 return iterator.operator->();
78 }
79
80 FilterIterator &operator++()
81 {
82 ++iterator;
83 return func(iterator) ? *this : ++(*this);
84 }
85
86 FilterIterator &operator--()
87 {
88 --iterator;
89 return func(iterator) ? *this : --(*this);
90 }
91
92 const FilterIterator operator++(int)
93 {
94 FilterIterator it = *this;
95 ++(*this);
96 return it;
97 }
98
99 const FilterIterator operator--(int)
100 {
101 FilterIterator it = *this;
102 --(*this);
103 return it;
104 }
105
106 bool operator==(const FilterIterator &it) const
107 {
108 return this->iterator == it.iterator;
109 }
110
111 bool operator!=(const FilterIterator &it) const
112 {
113 return !(*this == it);
114 }
115
116 bool operator==(const Iterator &it) const
117 {
118 return this->iterator == it;
119 }
120
121 bool operator!=(const Iterator &it) const
122 {
123 return !(*this == it);
124 }
125
126 private:
FilterNone(Iterator)127 static bool FilterNone(Iterator)
128 {
129 return true;
130 }
131 Iterator iterator;
132 FilterFunc func = FilterIterator::FilterNone;
133 };
134
135 template <typename Iterator>
136 inline auto build_filter_iterator(Iterator it) -> FilterIterator<Iterator>
137 {
138 return FilterIterator<Iterator>(it);
139 }
140
141 template <typename Iterator, typename _Func>
142 inline auto build_filter_iterator(Iterator it, _Func func) -> FilterIterator<Iterator>
143 {
144 return FilterIterator<Iterator>(it, std::function<bool(Iterator)>(func));
145 }
146
147 template <typename Iterator>
148 inline auto build_filter_iterator(Iterator it, std::function<bool(Iterator)> func) -> FilterIterator<Iterator>
149 {
150 return FilterIterator<Iterator>(it, func);
151 }
152
153 template <typename Iterator>
FilterNullPtr(Iterator it,Iterator endIt)154 bool FilterNullPtr(Iterator it, Iterator endIt)
155 {
156 return it == endIt || *it != nullptr;
157 }
158
159 enum MeFuncHint {
160 kReserved = 0x00, // reserved
161 kPlacementRCed = 0x01, // method processed by placementrc
162 kAnalyzeRCed = 0x02, // method processed by analyzerc
163 kRcLowered = 0x04, // method lowered by rclowering
164 };
165
166 class MeFunction : public FuncEmit {
167 public:
MeFunction(MIRModule * mod,MIRFunction * func,MemPool * memPool,StackMemPool & funcStackMP,MemPool * versMemPool,const std::string & fileName)168 MeFunction(MIRModule *mod, MIRFunction *func, MemPool *memPool, StackMemPool &funcStackMP, MemPool *versMemPool,
169 const std::string &fileName)
170 : memPool(memPool),
171 stackMP(funcStackMP),
172 alloc(memPool),
173 versMemPool(versMemPool),
174 versAlloc(versMemPool),
175 mirModule(*mod),
176 mirFunc(func),
177 laidOutBBVec(alloc.Adapter()),
178 fileName(fileName, memPool),
179 preMeFunc(nullptr),
180 preMeMp(nullptr)
181 {
182 }
183
184 ~MeFunction() override = default;
185 void Verify() const;
GetName()186 const std::string &GetName() const
187 {
188 return mirFunc->GetName();
189 }
190
GetVerSt(size_t veridx)191 VersionSt *GetVerSt(size_t veridx) const
192 {
193 return meSSATab->GetVerSt(veridx);
194 }
195
196 /* get or create label for bb */
197 LabelIdx GetOrCreateBBLabel(BB &bb);
198
IsEmpty()199 bool IsEmpty() const
200 {
201 return mirFunc->IsEmpty();
202 }
203
HasException()204 bool HasException() const
205 {
206 return hasEH;
207 }
208
GetAlloc()209 MapleAllocator &GetAlloc()
210 {
211 return alloc;
212 }
GetVersAlloc()213 MapleAllocator &GetVersAlloc()
214 {
215 return versAlloc;
216 }
GetVersMp()217 MemPool *GetVersMp()
218 {
219 // version mempool may be release if invalid
220 if (versMemPool == nullptr) {
221 versMemPool = new ThreadLocalMemPool(memPoolCtrler, "verst mempool");
222 versAlloc.SetMemPool(versMemPool);
223 }
224 return versMemPool;
225 }
226
ReleaseVersMemory()227 void ReleaseVersMemory()
228 {
229 if (versMemPool) {
230 memPoolCtrler.DeleteMemPool(versMemPool);
231 versMemPool = nullptr;
232 versAlloc.SetMemPool(nullptr);
233 }
234 }
235
GetLaidOutBBs()236 const MapleVector<BB *> &GetLaidOutBBs() const
237 {
238 return laidOutBBVec;
239 }
240
SetLaidOutBBs(const MapleVector<BB * > & laidout)241 void SetLaidOutBBs(const MapleVector<BB *> &laidout)
242 {
243 laidOutBBVec = laidout;
244 }
245
HasLaidOut()246 bool HasLaidOut() const
247 {
248 return !laidOutBBVec.empty();
249 }
250
ClearLayout()251 void ClearLayout()
252 {
253 if (laidOutBBVec.empty()) {
254 return;
255 }
256 laidOutBBVec.clear();
257 }
258
GetMeSSATab()259 SSATab *GetMeSSATab()
260 {
261 return meSSATab;
262 }
SetMeSSATab(SSATab * currMessaTab)263 void SetMeSSATab(SSATab *currMessaTab)
264 {
265 meSSATab = currMessaTab;
266 }
267
GetMirFunc()268 MIRFunction *GetMirFunc()
269 {
270 return mirFunc;
271 }
272
GetMIRModule()273 MIRModule &GetMIRModule() const
274 {
275 return mirModule;
276 }
277
GetIRMap()278 MeIRMap *GetIRMap()
279 {
280 return irmap;
281 }
282
SetIRMap(MeIRMap * currIRMap)283 void SetIRMap(MeIRMap *currIRMap)
284 {
285 irmap = currIRMap;
286 }
287
GetCfg()288 MeCFG *GetCfg() const
289 {
290 return theCFG;
291 }
292
SetTheCfg(MeCFG * currTheCfg)293 void SetTheCfg(MeCFG *currTheCfg)
294 {
295 theCFG = currTheCfg;
296 }
297
GetRegNum()298 uint32 GetRegNum() const
299 {
300 return regNum;
301 }
302
SetRegNum(uint32 num)303 void SetRegNum(uint32 num)
304 {
305 regNum = num;
306 }
307
GetHints()308 uint32 GetHints() const
309 {
310 return hints;
311 }
312
SetHints(uint32 num)313 void SetHints(uint32 num)
314 {
315 hints = num;
316 }
317
GetMemPool()318 MemPool *GetMemPool()
319 {
320 return memPool;
321 }
322
GetStackMemPool()323 StackMemPool &GetStackMemPool()
324 {
325 return stackMP;
326 }
327
AddProfileDesc(uint64 hash,uint32 start,uint32 end)328 void AddProfileDesc(uint64 hash, uint32 start, uint32 end)
329 {
330 mirFunc->AddProfileDesc(hash, start, end);
331 }
332
GetProfInf()333 const IRProfileDesc *GetProfInf()
334 {
335 if (profileDesc == nullptr) {
336 // return profileDesc with default value
337 profileDesc = memPool->New<IRProfileDesc>();
338 }
339 return profileDesc;
340 }
IsIRProfValid()341 bool IsIRProfValid() const
342 {
343 return profValid;
344 }
345
SetProfValid(bool val)346 void SetProfValid(bool val)
347 {
348 profValid = val;
349 }
350
GetFrequency()351 uint32 GetFrequency() const
352 {
353 return frequency;
354 }
355
SetFrequency(uint32 f)356 void SetFrequency(uint32 f)
357 {
358 frequency = f;
359 }
360
SetHasWriteInputAsmNode()361 void SetHasWriteInputAsmNode()
362 {
363 hasWriteInputAsmNode = true;
364 };
365
HasWriteInputAsmNode()366 bool HasWriteInputAsmNode() const
367 {
368 return hasWriteInputAsmNode;
369 }
370
GetUniqueID()371 uint32 GetUniqueID() const
372 {
373 return mirFunc->GetPuidx();
374 }
375
IsUnSafe()376 bool IsUnSafe() const
377 {
378 return !mirFunc->GetAttr(FUNCATTR_safed) || mirFunc->GetAttr(FUNCATTR_unsafed);
379 }
380
IsSafe()381 bool IsSafe() const
382 {
383 return mirFunc->GetAttr(FUNCATTR_safed);
384 }
385
386 void PartialInit();
387
388 void Release();
389
CurFunction()390 MIRFunction *CurFunction() const
391 {
392 return mirModule.CurFunction();
393 }
SetPreMeFunc(PreMeFunction * lfoF)394 void SetPreMeFunc(PreMeFunction *lfoF)
395 {
396 preMeFunc = lfoF;
397 }
GetPreMeFunc()398 PreMeFunction *GetPreMeFunc()
399 {
400 return preMeFunc;
401 }
SetPmeMempool(MemPool * mp)402 void SetPmeMempool(MemPool *mp)
403 {
404 preMeMp = mp;
405 }
GetPmeMempool()406 MemPool *GetPmeMempool()
407 {
408 return preMeMp;
409 }
IsLfo()410 bool IsLfo() const
411 {
412 return isLfo;
413 }
SetLfo(bool islfo)414 void SetLfo(bool islfo)
415 {
416 isLfo = islfo;
417 }
IsPme()418 bool IsPme() const
419 {
420 return isPme;
421 }
SetPme(bool set)422 void SetPme(bool set)
423 {
424 isPme = set;
425 }
IsTopLevelSSAValid()426 bool IsTopLevelSSAValid() const
427 {
428 return static_cast<bool>(state & kSSATopLevel);
429 }
IsAddrTakenSSAValid()430 bool IsAddrTakenSSAValid() const
431 {
432 return static_cast<bool>(state & kSSAAddrTaken);
433 }
IsMemSSAValid()434 bool IsMemSSAValid()
435 {
436 return IsTopLevelSSAValid() && IsAddrTakenSSAValid();
437 }
IsMeIRAvailable()438 bool IsMeIRAvailable() const
439 {
440 return static_cast<bool>(state & kSSAHSSA);
441 }
IsMplIRAvailable()442 bool IsMplIRAvailable() const
443 {
444 return !static_cast<bool>(state & kSSAHSSA);
445 }
446
ResetMeFuncState(uint8 s)447 void ResetMeFuncState(uint8 s)
448 {
449 state &= ~s;
450 }
451
SetMeFuncState(uint8 s)452 void SetMeFuncState(uint8 s)
453 {
454 state |= s;
455 }
456
457 private:
458 MemPool *memPool;
459 StackMemPool &stackMP;
460 MapleAllocator alloc;
461 MemPool *versMemPool;
462 MapleAllocator versAlloc;
463 MIRModule &mirModule;
464 MIRFunction *mirFunc;
465 /* mempool */
466 MapleVector<BB *> laidOutBBVec;
467 MeCFG *theCFG = nullptr;
468 SSATab *meSSATab = nullptr;
469 MeIRMap *irmap = nullptr;
470 /* input */
471 MapleString fileName;
472 uint32 regNum = 0; // count virtual registers
473 uint32 hints = 0;
474 bool hasEH = false; /* current has try statement */
475 bool hasWriteInputAsmNode = false; /* set when ssa tab build */
476 bool profValid = false;
477 IRProfileDesc *profileDesc = nullptr;
478 uint32 frequency = 0;
479 // lfo
480 bool isLfo = false;
481 // during pme processing
482 bool isPme = false;
483 PreMeFunction *preMeFunc;
484 MemPool *preMeMp; // used for lfo function
485 uint8 state = 0; // current state : ssa level and ir flavor
486 public:
487 uint32 dseRuns = 0; // number of times dse phase has been run
488 uint32 hdseRuns = 0; // number of times hdse phase has been run
489 uint32 hpropRuns = 0; // number of times hprop phase has been run
490 uint32 vrpRuns = 0; // number of times vrp phase has been run
491 bool genLMBC = false; // whether outputing lmbc (low maple bytecode)
492 };
493 } // namespace maple
494 #endif // MAPLE_ME_INCLUDE_ME_FUNCTION_H
495