• 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 MAPLEBE_CG_INCLUDE_CGOCCUR_H
17 #define MAPLEBE_CG_INCLUDE_CGOCCUR_H
18 #include "cg_dominance.h"
19 
20 // the data structures that represent occurrences and work candidates for PRE
21 namespace maplebe {
22 enum OccType {
23     kOccUndef,
24     kOccReal,
25     kOccDef,
26     kOccStore,
27     kOccPhiocc,
28     kOccPhiopnd,
29     kOccExit,
30     kOccUse,     // for use appearances when candidate is dassign
31     kOccMembar,  // for representing occurrence of memory barriers (use CgRealOcc)
32 };
33 
34 class CgOccur {
35 public:
CgOccur(OccType ty,BB * bb,Insn * insn,Operand * opnd)36     CgOccur(OccType ty, BB *bb, Insn *insn, Operand *opnd) : occTy(ty), cgBB(bb), insn(insn), opnd(opnd) {}
37 
CgOccur(OccType ty,int cId,BB & bb,CgOccur * df)38     CgOccur(OccType ty, int cId, BB &bb, CgOccur *df) : occTy(ty), classID(cId), cgBB(&bb), def(df) {}
39     virtual ~CgOccur() = default;
40 
41     bool IsDominate(DomAnalysis &dom, CgOccur &occ);
GetBB()42     const BB *GetBB() const
43     {
44         return cgBB;
45     }
46 
GetBB()47     BB *GetBB()
48     {
49         return cgBB;
50     }
51 
SetBB(BB & bb)52     void SetBB(BB &bb)
53     {
54         cgBB = &bb;
55     }
56 
GetOccType()57     OccType GetOccType() const
58     {
59         return occTy;
60     }
61 
GetClassID()62     int GetClassID() const
63     {
64         return classID;
65     }
66 
SetClassID(int id)67     void SetClassID(int id)
68     {
69         classID = id;
70     }
71 
GetDef()72     const CgOccur *GetDef() const
73     {
74         return def;
75     }
76 
GetDef()77     CgOccur *GetDef()
78     {
79         return def;
80     }
81 
SetDef(CgOccur * define)82     void SetDef(CgOccur *define)
83     {
84         def = define;
85     }
86 
GetInsn()87     const Insn *GetInsn() const
88     {
89         return insn;
90     }
91 
GetInsn()92     Insn *GetInsn()
93     {
94         return insn;
95     }
96 
GetOperand()97     const Operand *GetOperand() const
98     {
99         return opnd;
100     }
101 
GetOperand()102     Operand *GetOperand()
103     {
104         return opnd;
105     }
106 
Processed()107     bool Processed() const
108     {
109         return processed;
110     }
111 
SetProcessed(bool val)112     void SetProcessed(bool val)
113     {
114         processed = val;
115     }
116 
GetPrevVersionOccur()117     virtual CgOccur *GetPrevVersionOccur()
118     {
119         CHECK_FATAL(false, "has no prev version occur");
120     }
121 
SetPrevVersionOccur(CgOccur *)122     virtual void SetPrevVersionOccur(CgOccur *)
123     {
124         CHECK_FATAL(false, "has no prev version occur");
125     }
126 
Dump()127     virtual void Dump() const
128     {
129         if (occTy == kOccExit) {
130             LogInfo::MapleLogger() << "ExitOcc at bb " << GetBB()->GetId() << std::endl;
131         }
132     };
133 
134 private:
135     OccType occTy = kOccUndef;  // kinds of occ
136     int classID = 0;            // class id
137     BB *cgBB = nullptr;         // the BB it occurs in
138     Insn *insn = nullptr;
139     Operand *opnd = nullptr;
140     CgOccur *def = nullptr;
141     bool processed = false;
142 };
143 
144 class CgUseOcc : public CgOccur {
145 public:
CgUseOcc(BB * bb,Insn * insn,Operand * opnd)146     CgUseOcc(BB *bb, Insn *insn, Operand *opnd) : CgOccur(kOccUse, bb, insn, opnd), needReload(false) {}
147 
148     ~CgUseOcc() = default;
149 
Reload()150     bool Reload() const
151     {
152         return needReload;
153     }
154 
SetReload(bool val)155     void SetReload(bool val)
156     {
157         needReload = val;
158     }
159 
GetPrevVersionOccur()160     CgOccur *GetPrevVersionOccur() override
161     {
162         return prevVersion;
163     }
164 
SetPrevVersionOccur(CgOccur * val)165     void SetPrevVersionOccur(CgOccur *val) override
166     {
167         prevVersion = val;
168     }
169 
Dump()170     void Dump() const override
171     {
172         LogInfo::MapleLogger() << "UseOcc " << GetClassID() << " at bb " << GetBB()->GetId() << ": "
173                                << (needReload ? "need-reload, " : "not need-reload, ") << "\n";
174     }
175 
176 private:
177     bool needReload = false;
178     CgOccur *prevVersion = nullptr;
179 };
180 
181 class CgStoreOcc : public CgOccur {
182 public:
CgStoreOcc(BB * bb,Insn * insn,Operand * opnd)183     CgStoreOcc(BB *bb, Insn *insn, Operand *opnd) : CgOccur(kOccStore, bb, insn, opnd) {}
184     ~CgStoreOcc() = default;
185 
Reload()186     bool Reload() const
187     {
188         return needReload;
189     }
190 
SetReload(bool val)191     void SetReload(bool val)
192     {
193         needReload = val;
194     }
195 
GetPrevVersionOccur()196     CgOccur *GetPrevVersionOccur() override
197     {
198         return prevVersion;
199     }
200 
SetPrevVersionOccur(CgOccur * val)201     void SetPrevVersionOccur(CgOccur *val) override
202     {
203         prevVersion = val;
204     }
205 
Dump()206     void Dump() const override
207     {
208         LogInfo::MapleLogger() << "StoreOcc " << GetClassID() << " at bb " << GetBB()->GetId() << ": "
209                                << (needReload ? "reload, " : "not reload, ") << "\n";
210     }
211 
212 private:
213     bool needReload = false;
214     CgOccur *prevVersion = nullptr;
215 };
216 
217 class CgDefOcc : public CgOccur {
218 public:
CgDefOcc(BB * bb,Insn * insn,Operand * opnd)219     CgDefOcc(BB *bb, Insn *insn, Operand *opnd) : CgOccur(kOccDef, bb, insn, opnd) {}
220     ~CgDefOcc() = default;
221 
Loaded()222     bool Loaded() const
223     {
224         return needStore;
225     }
226 
SetLoaded(bool val)227     void SetLoaded(bool val)
228     {
229         needStore = val;
230     }
231 
GetPrevVersionOccur()232     CgOccur *GetPrevVersionOccur() override
233     {
234         return prevVersion;
235     }
236 
SetPrevVersionOccur(CgOccur * val)237     void SetPrevVersionOccur(CgOccur *val) override
238     {
239         prevVersion = val;
240     }
241 
Dump()242     void Dump() const override
243     {
244         LogInfo::MapleLogger() << "DefOcc " << GetClassID() << " at bb " << GetBB()->GetId() << ": "
245                                << (needStore ? "store" : "not store") << "\n";
246     }
247 
248 private:
249     bool needStore = false;
250     CgOccur *prevVersion = nullptr;
251 };
252 
253 class CgPhiOpndOcc;
254 enum AvailState { kFullyAvailable, kPartialAvailable, kNotAvailable };
255 class CgPhiOcc : public CgOccur {
256 public:
CgPhiOcc(BB & bb,Operand * opnd,MapleAllocator & alloc)257     CgPhiOcc(BB &bb, Operand *opnd, MapleAllocator &alloc)
258         : CgOccur(kOccPhiocc, 0, bb, nullptr), regOpnd(opnd), isDownSafe(!bb.IsCatch()), phiOpnds(alloc.Adapter())
259     {
260     }
261 
262     virtual ~CgPhiOcc() = default;
263 
IsDownSafe()264     bool IsDownSafe() const
265     {
266         return isDownSafe;
267     }
268 
SetIsDownSafe(bool downSafe)269     void SetIsDownSafe(bool downSafe)
270     {
271         isDownSafe = downSafe;
272     }
273 
GetPhiOpnds()274     const MapleVector<CgPhiOpndOcc *> &GetPhiOpnds() const
275     {
276         return phiOpnds;
277     }
278 
GetPhiOpnds()279     MapleVector<CgPhiOpndOcc *> &GetPhiOpnds()
280     {
281         return phiOpnds;
282     }
283 
GetOpnd()284     Operand *GetOpnd()
285     {
286         return regOpnd;
287     }
288 
GetPhiOpnd(size_t idx)289     CgPhiOpndOcc *GetPhiOpnd(size_t idx)
290     {
291         DEBUG_ASSERT(idx < phiOpnds.size(), "out of range in CgPhiOcc::GetPhiOpnd");
292         return phiOpnds.at(idx);
293     }
294 
GetPhiOpnd(size_t idx)295     const CgPhiOpndOcc *GetPhiOpnd(size_t idx) const
296     {
297         DEBUG_ASSERT(idx < phiOpnds.size(), "out of range in CgPhiOcc::GetPhiOpnd");
298         return phiOpnds.at(idx);
299     }
300 
AddPhiOpnd(CgPhiOpndOcc & opnd)301     void AddPhiOpnd(CgPhiOpndOcc &opnd)
302     {
303         phiOpnds.push_back(&opnd);
304     }
305 
GetPrevVersionOccur()306     CgOccur *GetPrevVersionOccur() override
307     {
308         return prevVersion;
309     }
310 
SetPrevVersionOccur(CgOccur * val)311     void SetPrevVersionOccur(CgOccur *val) override
312     {
313         prevVersion = val;
314     }
315 
IsFullyAvailable()316     bool IsFullyAvailable() const
317     {
318         return availState == kFullyAvailable;
319     }
320 
IsPartialAvailable()321     bool IsPartialAvailable() const
322     {
323         return availState == kPartialAvailable;
324     }
325 
IsNotAvailable()326     bool IsNotAvailable() const
327     {
328         return availState == kNotAvailable;
329     }
330 
SetAvailability(AvailState val)331     void SetAvailability(AvailState val)
332     {
333         availState = val;
334     }
335 
Dump()336     void Dump() const override
337     {
338         LogInfo::MapleLogger() << "PhiOcc " << GetClassID() << " at bb " << GetBB()->GetId() << ": "
339                                << (isDownSafe ? "downsafe, " : "not downsafe, ")
340                                << (availState == kNotAvailable
341                                        ? "not avail"
342                                        : (availState == kPartialAvailable ? "part avail" : "fully avail"))
343                                << "\n";
344     }
345 
346 private:
347     Operand *regOpnd;
348     bool isDownSafe = true;  // default is true
349     AvailState availState = kFullyAvailable;
350     MapleVector<CgPhiOpndOcc *> phiOpnds;
351     CgOccur *prevVersion = nullptr;
352 };
353 
354 class CgPhiOpndOcc : public CgOccur {
355 public:
CgPhiOpndOcc(BB * bb,Operand * opnd,CgPhiOcc * defPhi)356     CgPhiOpndOcc(BB *bb, Operand *opnd, CgPhiOcc *defPhi)
357         : CgOccur(kOccPhiopnd, bb, nullptr, opnd), hasRealUse(false), phiOcc(defPhi)
358     {
359     }
360 
361     ~CgPhiOpndOcc() = default;
362 
HasRealUse()363     bool HasRealUse() const
364     {
365         return hasRealUse;
366     }
367 
SetHasRealUse(bool realUse)368     void SetHasRealUse(bool realUse)
369     {
370         hasRealUse = realUse;
371     }
372 
GetPhiOcc()373     const CgPhiOcc *GetPhiOcc() const
374     {
375         return phiOcc;
376     }
377 
GetPhiOcc()378     CgPhiOcc *GetPhiOcc()
379     {
380         return phiOcc;
381     }
382 
SetPhiOcc(CgPhiOcc & occ)383     void SetPhiOcc(CgPhiOcc &occ)
384     {
385         phiOcc = &occ;
386     }
387 
Reload()388     bool Reload() const
389     {
390         return reload;
391     }
SetReload(bool val)392     void SetReload(bool val)
393     {
394         reload = val;
395     }
396 
Dump()397     void Dump() const override
398     {
399         LogInfo::MapleLogger() << "PhiOpndOcc " << GetClassID() << " at bb " << GetBB()->GetId() << ": "
400                                << (hasRealUse ? "hasRealUse, " : "not hasRealUse, ")
401                                << (reload ? "reload" : "not reload") << std::endl;
402     }
403 
404 private:
405     bool hasRealUse;
406     bool reload = false;
407     CgPhiOcc *phiOcc = nullptr;  // its lhs
408 };
409 
410 // each singly linked list represents each bucket in workCandHashTable
411 class PreWorkCand {
412 public:
PreWorkCand(MapleAllocator & alloc,Operand * curOpnd,PUIdx pIdx)413     PreWorkCand(MapleAllocator &alloc, Operand *curOpnd, PUIdx pIdx)
414         : next(nullptr),
415           allOccs(alloc.Adapter()),
416           realOccs(alloc.Adapter()),
417           phiOccs(alloc.Adapter()),
418           theOperand(curOpnd),
419           puIdx(pIdx),
420           redo2HandleCritEdges(false)
421     {
422         DEBUG_ASSERT(pIdx != 0, "PreWorkCand: initial puIdx cannot be 0");
423     }
424 
425     virtual ~PreWorkCand() = default;
426 
AddRealOccAsLast(CgOccur & occ,PUIdx pIdx)427     void AddRealOccAsLast(CgOccur &occ, PUIdx pIdx)
428     {
429         realOccs.push_back(&occ);  // add as last
430         DEBUG_ASSERT(pIdx != 0, "puIdx of realocc cannot be 0");
431         if (pIdx != puIdx) {
432             puIdx = 0;
433         }
434     }
435 
GetNext()436     const PreWorkCand *GetNext() const
437     {
438         return next;
439     }
440 
GetNext()441     PreWorkCand *GetNext()
442     {
443         return next;
444     }
445 
SetNext(PreWorkCand & workCand)446     void SetNext(PreWorkCand &workCand)
447     {
448         next = &workCand;
449     }
450 
GetIndex()451     int32 GetIndex() const
452     {
453         return index;
454     }
455 
SetIndex(int idx)456     void SetIndex(int idx)
457     {
458         index = idx;
459     }
460 
GetRealOccs()461     const MapleVector<CgOccur *> &GetRealOccs() const
462     {
463         return realOccs;
464     }
465 
GetRealOccs()466     MapleVector<CgOccur *> &GetRealOccs()
467     {
468         return realOccs;
469     }
470 
GetRealOcc(size_t idx)471     const CgOccur *GetRealOcc(size_t idx) const
472     {
473         DEBUG_ASSERT(idx < realOccs.size(), "out of range in PreWorkCand::GetRealOccAt");
474         return realOccs.at(idx);
475     }
476 
GetRealOcc(size_t idx)477     CgOccur *GetRealOcc(size_t idx)
478     {
479         DEBUG_ASSERT(idx < realOccs.size(), "out of range in PreWorkCand::GetRealOccAt");
480         return realOccs.at(idx);
481     }
482 
PhiOccs()483     const MapleVector<CgPhiOcc *> &PhiOccs() const
484     {
485         return phiOccs;
486     }
487 
PhiOccs()488     MapleVector<CgPhiOcc *> &PhiOccs()
489     {
490         return phiOccs;
491     }
492 
GetTheOperand()493     const Operand *GetTheOperand() const
494     {
495         return theOperand;
496     }
497 
GetTheOperand()498     Operand *GetTheOperand()
499     {
500         return theOperand;
501     }
502 
SetTheOperand(Operand & expr)503     void SetTheOperand(Operand &expr)
504     {
505         theOperand = &expr;
506     }
507 
GetPUIdx()508     PUIdx GetPUIdx() const
509     {
510         return puIdx;
511     }
512 
SetPUIdx(PUIdx idx)513     void SetPUIdx(PUIdx idx)
514     {
515         puIdx = idx;
516     }
517 
Redo2HandleCritEdges()518     bool Redo2HandleCritEdges() const
519     {
520         return redo2HandleCritEdges;
521     }
522 
SetRedo2HandleCritEdges(bool redo)523     void SetRedo2HandleCritEdges(bool redo)
524     {
525         redo2HandleCritEdges = redo;
526     }
527 
528 private:
529     PreWorkCand *next;
530     int32 index = 0;
531     MapleVector<CgOccur *> allOccs;
532     MapleVector<CgOccur *> realOccs;  // maintained in order of dt_preorder
533     MapleVector<CgPhiOcc *> phiOccs;
534     Operand *theOperand;  // the expression of this workcand
535     PUIdx puIdx;          // if 0, its occ span multiple PUs; initial value must
536     // puIdx cannot be 0 if hasLocalOpnd is true
537     bool redo2HandleCritEdges : 1;  // redo to make critical edges affect canbevail
538 };
539 
540 class PreWorkCandHashTable {
541 public:
542     static const uint32 workCandHashLength = 229;
543     static uint32 ComputeWorkCandHashIndex(const Operand &opnd);
544     static uint32 ComputeStmtWorkCandHashIndex(const Insn &insn);
545 
546     PreWorkCandHashTable() = default;
547     ~PreWorkCandHashTable() = default;
548 
GetWorkcandHashTable()549     std::array<PreWorkCand *, workCandHashLength> &GetWorkcandHashTable()
550     {
551         return workCandHashTable;
552     }
553 
GetWorkcandFromIndex(size_t idx)554     PreWorkCand *GetWorkcandFromIndex(size_t idx)
555     {
556         return workCandHashTable[idx];
557     }
558 
SetWorkCandAt(size_t idx,PreWorkCand & workCand)559     void SetWorkCandAt(size_t idx, PreWorkCand &workCand)
560     {
561         workCandHashTable[idx] = &workCand;
562     }
563 
564 private:
565     std::array<PreWorkCand *, workCandHashLength> workCandHashTable;
566 };
567 }  // namespace maplebe
568 #endif  // MAPLEBE_CG_INCLUDE_CGOCCUR_H
569