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_INCLUDE_CG_DOM_H
17 #define MAPLEBE_INCLUDE_CG_DOM_H
18
19 #include "cg_phase.h"
20 #include "insn.h"
21 #include "cgbb.h"
22 #include "datainfo.h"
23 #include "maple_phase.h"
24
25 namespace maplebe {
26 class DominanceBase : public AnalysisResult {
27 public:
DominanceBase(CGFunc & func,MemPool & memPool,MemPool & tmpPool,MapleVector<BB * > & bbVec,BB & commonEntryBB,BB & commonExitBB)28 DominanceBase(CGFunc &func, MemPool &memPool, MemPool &tmpPool, MapleVector<BB *> &bbVec, BB &commonEntryBB,
29 BB &commonExitBB)
30 : AnalysisResult(&memPool),
31 domAllocator(&memPool),
32 tmpAllocator(&tmpPool),
33 bbVec(bbVec),
34 cgFunc(func),
35 commonEntryBB(commonEntryBB),
36 commonExitBB(commonExitBB)
37 {
38 }
39
40 ~DominanceBase() override = default;
41
GetCommonEntryBB()42 BB &GetCommonEntryBB() const
43 {
44 return commonEntryBB;
45 }
46
GetCommonExitBB()47 BB &GetCommonExitBB() const
48 {
49 return commonExitBB;
50 }
51
52 protected:
53 bool CommonEntryBBIsPred(const BB &bb) const;
54 MapleAllocator domAllocator; // stores the analysis results
55 MapleAllocator tmpAllocator; // can be freed after dominator computation
56 MapleVector<BB *> &bbVec;
57 CGFunc &cgFunc;
58 BB &commonEntryBB;
59 BB &commonExitBB;
60 };
61
62 class DomAnalysis : public DominanceBase {
63 public:
DomAnalysis(CGFunc & func,MemPool & memPool,MemPool & tmpPool,MapleVector<BB * > & bbVec,BB & commonEntryBB,BB & commonExitBB)64 DomAnalysis(CGFunc &func, MemPool &memPool, MemPool &tmpPool, MapleVector<BB *> &bbVec, BB &commonEntryBB,
65 BB &commonExitBB)
66 : DominanceBase(func, memPool, tmpPool, bbVec, commonEntryBB, commonExitBB),
67 postOrderIDVec(bbVec.size() + 1, -1, tmpAllocator.Adapter()),
68 reversePostOrder(tmpAllocator.Adapter()),
69 doms(bbVec.size() + 1, nullptr, domAllocator.Adapter()),
70 domFrontier(bbVec.size() + 1, MapleVector<uint32>(domAllocator.Adapter()), domAllocator.Adapter()),
71 domChildren(bbVec.size() + 1, MapleVector<uint32>(domAllocator.Adapter()), domAllocator.Adapter()),
72 iterDomFrontier(bbVec.size() + 1, MapleUnorderedSet<uint32>(domAllocator.Adapter()), domAllocator.Adapter()),
73 dtPreOrder(bbVec.size() + 1, 0, domAllocator.Adapter()),
74 dtDfn(bbVec.size() + 1, -1, domAllocator.Adapter()),
75 dtDfnOut(bbVec.size() + 1, -1, domAllocator.Adapter())
76 {
77 }
78 ~DomAnalysis() override = default;
79
80 void Compute();
81 void Dump();
82
83 void GenPostOrderID();
84 void ComputeDominance();
85 void ComputeDomFrontiers();
86 void ComputeDomChildren();
87 void GetIterDomFrontier(const BB *bb, MapleUnorderedSet<uint32> *dfset, uint32 bbidMarker,
88 std::vector<bool> &visitedMap);
89 void ComputeIterDomFrontiers();
90 uint32 ComputeDtPreorder(const BB &bb, uint32 &num);
91 bool Dominate(const BB &bb1, const BB &bb2); // true if bb1 dominates bb2
92
GetReversePostOrder()93 MapleVector<BB *> &GetReversePostOrder()
94 {
95 return reversePostOrder;
96 }
97
GetDtPreOrder()98 MapleVector<uint32> &GetDtPreOrder()
99 {
100 return dtPreOrder;
101 }
102
GetDtPreOrderItem(size_t idx)103 uint32 GetDtPreOrderItem(size_t idx) const
104 {
105 return dtPreOrder[idx];
106 }
107
GetDtPreOrderSize()108 size_t GetDtPreOrderSize() const
109 {
110 return dtPreOrder.size();
111 }
112
GetDtDfnItem(size_t idx)113 uint32 GetDtDfnItem(size_t idx) const
114 {
115 return dtDfn[idx];
116 }
117
GetDtDfnSize()118 size_t GetDtDfnSize() const
119 {
120 return dtDfn.size();
121 }
122
GetDom(uint32 id)123 BB *GetDom(uint32 id)
124 {
125 DEBUG_ASSERT(id < doms.size(), "bbid out of range");
126 return doms[id];
127 }
SetDom(uint32 id,BB * bb)128 void SetDom(uint32 id, BB *bb)
129 {
130 DEBUG_ASSERT(id < doms.size(), "bbid out of range");
131 doms[id] = bb;
132 }
GetDomsSize()133 size_t GetDomsSize() const
134 {
135 return doms.size();
136 }
137
GetDomFrontier(size_t idx)138 auto &GetDomFrontier(size_t idx)
139 {
140 return domFrontier[idx];
141 }
HasDomFrontier(uint32 id,uint32 frontier)142 bool HasDomFrontier(uint32 id, uint32 frontier) const
143 {
144 return std::find(domFrontier[id].begin(), domFrontier[id].end(), frontier) != domFrontier[id].end();
145 }
146
GetDomFrontierSize()147 size_t GetDomFrontierSize() const
148 {
149 return domFrontier.size();
150 }
151
GetDomChildren()152 auto &GetDomChildren()
153 {
154 return domChildren;
155 }
156
GetDomChildren(size_t idx)157 auto &GetDomChildren(size_t idx)
158 {
159 return domChildren[idx];
160 }
161
GetIdomFrontier(uint32 idx)162 auto &GetIdomFrontier(uint32 idx)
163 {
164 return iterDomFrontier[idx];
165 }
166
GetDomChildrenSize()167 size_t GetDomChildrenSize() const
168 {
169 return domChildren.size();
170 }
171
172 private:
173 void PostOrderWalk(const BB &bb, int32 &pid, MapleVector<bool> &visitedMap);
174 BB *Intersect(BB &bb1, const BB &bb2);
175
176 MapleVector<int32> postOrderIDVec; // index is bb id
177 MapleVector<BB *> reversePostOrder; // an ordering of the BB in reverse postorder
178 MapleVector<BB *> doms; // index is bb id; immediate dominator for each BB
179 MapleVector<MapleVector<uint32>> domFrontier; // index is bb id
180 MapleVector<MapleVector<uint32>> domChildren; // index is bb id; for dom tree
181 MapleVector<MapleUnorderedSet<uint32>> iterDomFrontier;
182 MapleVector<uint32> dtPreOrder; // ordering of the BBs in a preorder traversal of the dominator tree
183 MapleVector<uint32> dtDfn; // gives position of each BB in dt_preorder
184 MapleVector<uint32> dtDfnOut; // max position of all nodes in the sub tree of each BB in dt_preorder
185 };
186
187 MAPLE_FUNC_PHASE_DECLARE_BEGIN(CgDomAnalysis, maplebe::CGFunc);
GetResult()188 DomAnalysis *GetResult()
189 {
190 return domAnalysis;
191 }
192 DomAnalysis *domAnalysis = nullptr;
193 MAPLE_FUNC_PHASE_DECLARE_END
194 } /* namespace maplebe */
195
196 #endif /* MAPLEBE_INCLUDE_CG_DOM_H */
197