• 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_MEEXPRUSEINFO_H
17 #define MAPLE_ME_INCLUDE_MEEXPRUSEINFO_H
18 #include "me_ir.h"
19 #include "me_function.h"
20 
21 #include <variant>
22 
23 namespace maple {
24 
25 class UseItem final {
26 public:
UseItem(MeStmt * useStmt)27     explicit UseItem(MeStmt *useStmt) : useNode(useStmt) {}
UseItem(MePhiNode * phi)28     explicit UseItem(MePhiNode *phi) : useNode(phi) {}
29 
GetUseBB()30     const BB *GetUseBB() const
31     {
32         return std::visit(
33             [this](auto &&arg) {
34                 using T = std::decay_t<decltype(arg)>;
35                 if constexpr (std::is_same_v<T, MeStmt *>) {
36                     return Get<MeStmt>()->GetBB();
37                 } else {
38                     return Get<MePhiNode>()->GetDefBB();
39                 }
40             },
41             useNode);
42     }
43 
IsUseByPhi()44     bool IsUseByPhi() const
45     {
46         return std::holds_alternative<MePhiNode *>(useNode);
47     }
48 
IsUseByStmt()49     bool IsUseByStmt() const
50     {
51         return std::holds_alternative<MeStmt *>(useNode);
52     }
53 
GetStmt()54     const MeStmt *GetStmt() const
55     {
56         return Get<MeStmt>();
57     }
GetStmt()58     MeStmt *GetStmt()
59     {
60         return Get<MeStmt>();
61     }
62 
GetPhi()63     const MePhiNode *GetPhi() const
64     {
65         return Get<MePhiNode>();
66     }
GetPhi()67     MePhiNode *GetPhi()
68     {
69         return Get<MePhiNode>();
70     }
71 
72     bool operator==(const UseItem &other) const
73     {
74         return useNode == other.useNode;
75     }
76     bool operator!=(const UseItem &other) const
77     {
78         return !(*this == other);
79     }
80 
81 private:
82     template <typename T>
Get()83     const T *Get() const
84     {
85         assert(std::holds_alternative<T *>(useNode) && "Invalid use type.");
86         return std::get<T *>(useNode);
87     }
88     template <typename T>
Get()89     T *Get()
90     {
91         assert(std::holds_alternative<T *>(useNode) && "Invalid use type.");
92         return std::get<T *>(useNode);
93     }
94 
95     std::variant<MeStmt *, MePhiNode *> useNode;
96 };
97 
98 enum MeExprUseInfoState {
99     kUseInfoInvalid = 0,
100     kUseInfoOfScalar = 1,
101     kUseInfoOfAllExpr = 3,
102 };
103 
104 using UseSitesType = MapleList<UseItem>;
105 using ExprUseInfoPair = std::pair<MeExpr *, UseSitesType *>;
106 class MeExprUseInfo final {
107 public:
MeExprUseInfo(MemPool * memPool)108     explicit MeExprUseInfo(MemPool *memPool) : allocator(memPool), useSites(nullptr), useInfoState(kUseInfoInvalid) {}
109 
~MeExprUseInfo()110     ~MeExprUseInfo() {}
111     void CollectUseInfoInFunc(IRMap *irMap, Dominance *domTree, MeExprUseInfoState state);
112     UseSitesType *GetUseSitesOfExpr(const MeExpr *expr) const;
GetUseSites()113     const MapleVector<ExprUseInfoPair> &GetUseSites() const
114     {
115         return *useSites;
116     }
117 
118     template <class T>
119     void AddUseSiteOfExpr(MeExpr *expr, T *useSite);
120 
121     void CollectUseInfoInExpr(MeExpr *expr, MeStmt *stmt);
122     void CollectUseInfoInStmt(MeStmt *stmt);
123     void CollectUseInfoInBB(BB *bb);
124 
125     // return true if use sites of scalarA all replaced by scalarB
126 
GetUseSites()127     MapleVector<ExprUseInfoPair> &GetUseSites()
128     {
129         return *useSites;
130     }
131 
SetUseSites(MapleVector<ExprUseInfoPair> * sites)132     void SetUseSites(MapleVector<ExprUseInfoPair> *sites)
133     {
134         useSites = sites;
135     }
136 
SetState(MeExprUseInfoState state)137     void SetState(MeExprUseInfoState state)
138     {
139         useInfoState = state;
140     }
141 
InvalidUseInfo()142     void InvalidUseInfo()
143     {
144         useInfoState = kUseInfoInvalid;
145     }
146 
IsInvalid()147     bool IsInvalid() const
148     {
149         return useInfoState == kUseInfoInvalid;
150     }
151 
UseInfoOfScalarIsValid()152     bool UseInfoOfScalarIsValid() const
153     {
154         return useInfoState >= kUseInfoOfScalar;
155     }
156 
UseInfoOfAllIsValid()157     bool UseInfoOfAllIsValid() const
158     {
159         return useInfoState == kUseInfoOfAllExpr;
160     }
161 
162 private:
163     MapleAllocator allocator;
164     MapleVector<ExprUseInfoPair> *useSites;  // index is exprId
165     MeExprUseInfoState useInfoState;
166 };
167 }  // namespace maple
168 #endif  // MAPLE_ME_INCLUDE_MEEXPRUSEINFO_H
169