• 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 #include "ext_constantfold.h"
17 #include <climits>
18 
19 namespace maple {
20 // This class is designed to further identify simplification
21 // patterns that have not been covered in ConstantFold.
22 
ExtSimplify(StmtNode * node)23 StmtNode *ExtConstantFold::ExtSimplify(StmtNode *node)
24 {
25     CHECK_NULL_FATAL(node);
26     switch (node->GetOpCode()) {
27         case OP_block:
28             return ExtSimplifyBlock(static_cast<BlockNode *>(node));
29         case OP_if:
30             return ExtSimplifyIf(static_cast<IfStmtNode *>(node));
31         case OP_dassign:
32             return ExtSimplifyDassign(static_cast<DassignNode *>(node));
33         case OP_iassign:
34             return ExtSimplifyIassign(static_cast<IassignNode *>(node));
35         case OP_dowhile:
36         case OP_while:
37             return ExtSimplifyWhile(static_cast<WhileStmtNode *>(node));
38         default:
39             return node;
40     }
41 }
42 
DispatchFold(BaseNode * node)43 BaseNode *ExtConstantFold::DispatchFold(BaseNode *node)
44 {
45     // Not trying all possiblities.
46     // For simplicity, stop looking further down the expression once OP_OP_cior/OP_cand (etc) are seen
47     CHECK_NULL_FATAL(node);
48     switch (node->GetOpCode()) {
49         case OP_cior:
50         case OP_lior:
51         case OP_cand:
52         case OP_land:
53         case OP_abs:
54         case OP_bnot:
55         case OP_lnot:
56         case OP_neg:
57         case OP_recip:
58         case OP_sqrt:
59             return ExtFoldUnary(static_cast<UnaryNode *>(node));
60         case OP_add:
61         case OP_ashr:
62         case OP_band:
63         case OP_bior:
64         case OP_bxor:
65         case OP_div:
66         case OP_lshr:
67         case OP_max:
68         case OP_min:
69         case OP_mul:
70         case OP_rem:
71         case OP_shl:
72         case OP_sub:
73         case OP_eq:
74         case OP_ne:
75         case OP_ge:
76         case OP_gt:
77         case OP_le:
78         case OP_lt:
79         case OP_cmp:
80             return ExtFoldBinary(static_cast<BinaryNode *>(node));
81         case OP_select:
82             return ExtFoldTernary(static_cast<TernaryNode *>(node));
83         default:
84             return node;
85     }
86 }
87 
ExtFoldUnary(UnaryNode * node)88 BaseNode *ExtConstantFold::ExtFoldUnary(UnaryNode *node)
89 {
90     CHECK_NULL_FATAL(node);
91     BaseNode *result = nullptr;
92     result = DispatchFold(node->Opnd(0));
93     if (result != node->Opnd(0)) {
94         node->SetOpnd(result, 0);
95     }
96     return node;
97 }
98 
ExtFoldBinary(BinaryNode * node)99 BaseNode *ExtConstantFold::ExtFoldBinary(BinaryNode *node)
100 {
101     CHECK_NULL_FATAL(node);
102     BaseNode *result = nullptr;
103     result = DispatchFold(node->Opnd(0));
104     if (result != node->Opnd(0)) {
105         node->SetOpnd(result, 0);
106     }
107     result = DispatchFold(node->Opnd(1));
108     if (result != node->Opnd(1)) {
109         node->SetOpnd(result, 1);
110     }
111     return node;
112 }
113 
ExtFoldTernary(TernaryNode * node)114 BaseNode *ExtConstantFold::ExtFoldTernary(TernaryNode *node)
115 {
116     CHECK_NULL_FATAL(node);
117     BaseNode *result = nullptr;
118     result = DispatchFold(node->Opnd(kFirstOpnd));
119     if (result != node->Opnd(kFirstOpnd)) {
120         node->SetOpnd(result, kFirstOpnd);
121     }
122     result = DispatchFold(node->Opnd(kSecondOpnd));
123     if (result != node->Opnd(kSecondOpnd)) {
124         node->SetOpnd(result, kSecondOpnd);
125     }
126     result = DispatchFold(node->Opnd(kThirdOpnd));
127     if (result != node->Opnd(kThirdOpnd)) {
128         node->SetOpnd(result, kThirdOpnd);
129     }
130     return node;
131 }
132 
ExtFold(BaseNode * node)133 BaseNode *ExtConstantFold::ExtFold(BaseNode *node)
134 {
135     if (node == nullptr || kOpcodeInfo.IsStmt(node->GetOpCode())) {
136         return nullptr;
137     }
138     return DispatchFold(node);
139 }
140 
ExtSimplifyBlock(BlockNode * node)141 StmtNode *ExtConstantFold::ExtSimplifyBlock(BlockNode *node)
142 {
143     CHECK_NULL_FATAL(node);
144     if (node->GetFirst() == nullptr) {
145         return node;
146     }
147     StmtNode *s = node->GetFirst();
148     do {
149         (void)ExtSimplify(s);
150         s = s->GetNext();
151         ;
152     } while (s != nullptr);
153     return node;
154 }
155 
ExtSimplifyIf(IfStmtNode * node)156 StmtNode *ExtConstantFold::ExtSimplifyIf(IfStmtNode *node)
157 {
158     CHECK_NULL_FATAL(node);
159     (void)ExtSimplify(node->GetThenPart());
160     if (node->GetElsePart()) {
161         (void)ExtSimplify(node->GetElsePart());
162     }
163     BaseNode *origTest = node->Opnd();
164     BaseNode *returnValue = ExtFold(node->Opnd());
165     if (returnValue != origTest) {
166         node->SetOpnd(returnValue, 0);
167     }
168     return node;
169 }
170 
ExtSimplifyDassign(DassignNode * node)171 StmtNode *ExtConstantFold::ExtSimplifyDassign(DassignNode *node)
172 {
173     CHECK_NULL_FATAL(node);
174     BaseNode *returnValue = ExtFold(node->GetRHS());
175     if (returnValue != node->GetRHS()) {
176         node->SetRHS(returnValue);
177     }
178     return node;
179 }
180 
ExtSimplifyIassign(IassignNode * node)181 StmtNode *ExtConstantFold::ExtSimplifyIassign(IassignNode *node)
182 {
183     CHECK_NULL_FATAL(node);
184     BaseNode *returnValue = ExtFold(node->GetRHS());
185     if (returnValue != node->GetRHS()) {
186         node->SetRHS(returnValue);
187     }
188     return node;
189 }
190 
ExtSimplifyWhile(WhileStmtNode * node)191 StmtNode *ExtConstantFold::ExtSimplifyWhile(WhileStmtNode *node)
192 {
193     CHECK_NULL_FATAL(node);
194     if (node->Opnd(0) == nullptr) {
195         return node;
196     }
197     BaseNode *returnValue = ExtFold(node->Opnd(0));
198     if (returnValue != node->Opnd(0)) {
199         node->SetOpnd(returnValue, 0);
200     }
201     return node;
202 }
203 }  // namespace maple
204