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 #include "meexpr_use_info.h"
17 #include "irmap.h"
18 #include "dominance.h"
19
20 namespace maple {
21 template <class T>
AddUseSiteOfExpr(MeExpr * expr,T * useSite)22 void MeExprUseInfo::AddUseSiteOfExpr(MeExpr *expr, T *useSite)
23 {
24 if (expr->GetExprID() == kInvalidExprID) {
25 return;
26 }
27
28 auto uintExprID = static_cast<uint32>(expr->GetExprID());
29 if (useSites->size() <= uintExprID) {
30 constexpr uint32 bufferSize = 50;
31 useSites->insert(useSites->end(), uintExprID + bufferSize, {nullptr, nullptr});
32 }
33 if ((*useSites)[uintExprID].second == nullptr) {
34 auto *newList = allocator.New<MapleList<UseItem>>(allocator.Adapter());
35 newList->emplace_front(UseItem(useSite));
36 (*useSites)[uintExprID] = {expr, newList};
37 return;
38 }
39 UseItem use(useSite);
40 if ((*useSites)[uintExprID].second->front() != use) {
41 (*useSites)[uintExprID].second->emplace_front(use);
42 }
43 }
44
GetUseSitesOfExpr(const MeExpr * expr) const45 MapleList<UseItem> *MeExprUseInfo::GetUseSitesOfExpr(const MeExpr *expr) const
46 {
47 if (IsInvalid()) {
48 CHECK_FATAL(false, "Expr use info is invalid");
49 } else if (!expr->IsScalar()) {
50 CHECK_FATAL(useInfoState == kUseInfoOfAllExpr, "expr is not scalar, use info has not been collected");
51 }
52
53 if (expr->GetExprID() == kInvalidExprID) {
54 return nullptr;
55 }
56
57 auto uintExprID = static_cast<uint32>(expr->GetExprID());
58 if (useSites->size() <= uintExprID) {
59 return nullptr;
60 }
61 return (*useSites)[uintExprID].second;
62 }
63
CollectUseInfoInExpr(MeExpr * expr,MeStmt * stmt)64 void MeExprUseInfo::CollectUseInfoInExpr(MeExpr *expr, MeStmt *stmt)
65 {
66 if (expr == nullptr) {
67 return;
68 }
69 if (expr->IsScalar()) {
70 AddUseSiteOfExpr(static_cast<ScalarMeExpr *>(expr), stmt);
71 return;
72 }
73
74 if (useInfoState == kUseInfoOfAllExpr) {
75 AddUseSiteOfExpr(expr, stmt);
76 }
77
78 if (expr->GetMeOp() == kMeOpIvar) {
79 for (auto *mu : static_cast<IvarMeExpr *>(expr)->GetMuList()) {
80 AddUseSiteOfExpr(mu, stmt);
81 }
82 }
83
84 for (size_t opndId = 0; opndId < expr->GetNumOpnds(); ++opndId) {
85 auto opnd = expr->GetOpnd(opndId);
86 CollectUseInfoInExpr(opnd, stmt);
87 }
88 }
89
CollectUseInfoInStmt(MeStmt * stmt)90 void MeExprUseInfo::CollectUseInfoInStmt(MeStmt *stmt)
91 {
92 for (size_t opndId = 0; opndId < stmt->NumMeStmtOpnds(); ++opndId) {
93 auto *opnd = stmt->GetOpnd(opndId);
94 CollectUseInfoInExpr(opnd, stmt);
95 }
96
97 auto *muList = stmt->GetMuList();
98 if (muList != nullptr) {
99 for (const auto &ost2mu : *muList) {
100 AddUseSiteOfExpr(ost2mu.second, stmt);
101 }
102 }
103 }
104
CollectUseInfoInBB(BB * bb)105 void MeExprUseInfo::CollectUseInfoInBB(BB *bb)
106 {
107 if (bb == nullptr) {
108 return;
109 }
110
111 auto &phiList = bb->GetMePhiList();
112 for (const auto &ost2phi : phiList) {
113 auto *phi = ost2phi.second;
114 if (!phi->GetIsLive()) {
115 continue;
116 }
117 for (size_t id = 0; id < phi->GetOpnds().size(); ++id) {
118 auto *opnd = phi->GetOpnd(id);
119 AddUseSiteOfExpr(opnd, phi);
120 }
121 }
122
123 for (auto &stmt : bb->GetMeStmts()) {
124 CollectUseInfoInStmt(&stmt);
125 }
126 }
127
CollectUseInfoInFunc(IRMap * irMap,Dominance * domTree,MeExprUseInfoState state)128 void MeExprUseInfo::CollectUseInfoInFunc(IRMap *irMap, Dominance *domTree, MeExprUseInfoState state)
129 {
130 if (!IsInvalid() && (state <= this->useInfoState)) {
131 return;
132 }
133 if (useSites != nullptr) {
134 for (auto &useSite : *useSites) {
135 if (useSite.second != nullptr) {
136 useSite.second->clear();
137 }
138 }
139 useSites->clear();
140 }
141
142 allocator.SetMemPool(irMap->GetIRMapAlloc().GetMemPool());
143 useSites = irMap->New<MapleVector<ExprUseInfoPair>>(allocator.Adapter());
144 if (irMap->GetExprID() >= 0) {
145 useSites->resize(static_cast<size_t>(irMap->GetExprID() + 1));
146 }
147 useInfoState = state;
148
149 for (auto bb : domTree->GetReversePostOrder()) {
150 CollectUseInfoInBB(irMap->GetBB(BBId(bb->GetID())));
151 }
152 }
153 } // namespace maple
154