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