• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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