• 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 "ecmascript/compiler/constant_folding.h"
17 
18 namespace panda::ecmascript::kungfu {
19 
VisitGate(GateRef gate)20 GateRef ConstantFolding::VisitGate(GateRef gate)
21 {
22     auto op = acc_.GetOpCode(gate);
23     switch (op) {
24         case OpCode::ADD:
25             return VisitADD(gate);
26         case OpCode::SUB:
27             return VisitSUB(gate);
28         case OpCode::MUL:
29             return VisitMUL(gate);
30         case OpCode::SMOD:
31             return VisitSMOD(gate);
32         case OpCode::UMOD:
33             return VisitUMOD(gate);
34         case OpCode::ZEXT:
35             return VisitZEXT(gate);
36         default:
37             return Circuit::NullGate();
38     }
39 }
40 
VisitZEXT(GateRef gate)41 GateRef ConstantFolding::VisitZEXT(GateRef gate)
42 {
43     auto input = acc_.GetValueIn(gate, 0);
44     if (acc_.GetMachineType(gate) == acc_.GetMachineType(input)) {
45         AddFoldingCount();
46         return input;
47     }
48 
49     GateRef result = Circuit::NullGate();
50     if (IsConstant(input) && IsInt32Type(input)) {
51         int value = acc_.GetInt32FromConstant(input);
52         auto machineType = acc_.GetMachineType(gate);
53         switch (machineType) {
54             case MachineType::I32:
55                 result = Int32Constant(value);
56                 break;
57             case MachineType::ARCH:
58             case MachineType::I64:
59                 result = Int64Constant(value);
60                 break;
61             default:
62                 break;
63         }
64     }
65     return result;
66 }
67 
VisitSMOD(GateRef gate)68 GateRef ConstantFolding::VisitSMOD(GateRef gate)
69 {
70     auto left = acc_.GetValueIn(gate, 0);
71     auto right = acc_.GetValueIn(gate, 1);
72     if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) {
73         return Circuit::NullGate();
74     }
75 
76     GateRef result = Circuit::NullGate();
77     if (IsConstant(left) && IsConstant(right)) {
78         int lvalue = acc_.GetInt32FromConstant(left);
79         int rvalue = acc_.GetInt32FromConstant(right);
80         if (rvalue != 0) {
81             result = Int32Constant(lvalue % rvalue);
82         }
83     }
84     return result;
85 }
86 
VisitUMOD(GateRef gate)87 GateRef ConstantFolding::VisitUMOD(GateRef gate)
88 {
89     auto left = acc_.GetValueIn(gate, 0);
90     auto right = acc_.GetValueIn(gate, 1);
91     if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) {
92         return Circuit::NullGate();
93     }
94 
95     GateRef result = Circuit::NullGate();
96     if (IsConstant(left) && IsConstant(right)) {
97         int lvalue = acc_.GetInt32FromConstant(left);
98         int rvalue = acc_.GetInt32FromConstant(right);
99         if (rvalue != 0) {
100             result = Int32Constant(bit_cast<uint32_t>(lvalue) % bit_cast<uint32_t>(rvalue));
101         }
102     }
103     return result;
104 }
105 
VisitADD(GateRef gate)106 GateRef ConstantFolding::VisitADD(GateRef gate)
107 {
108     auto left = acc_.GetValueIn(gate, 0);
109     auto right = acc_.GetValueIn(gate, 1);
110     if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) {
111         return Circuit::NullGate();
112     }
113 
114     GateRef result = Circuit::NullGate();
115     if (IsConstant(left) && IsConstant(right)) {
116         int lvalue = acc_.GetInt32FromConstant(left);
117         int rvalue = acc_.GetInt32FromConstant(right);
118         result = Int32Constant(lvalue + rvalue);
119     }
120     return result;
121 }
122 
VisitSUB(GateRef gate)123 GateRef ConstantFolding::VisitSUB(GateRef gate)
124 {
125     auto left = acc_.GetValueIn(gate, 0);
126     auto right = acc_.GetValueIn(gate, 1);
127     if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) {
128         return Circuit::NullGate();
129     }
130 
131     GateRef result = Circuit::NullGate();
132     if (IsConstant(left) && IsConstant(right)) {
133         int lvalue = acc_.GetInt32FromConstant(left);
134         int rvalue = acc_.GetInt32FromConstant(right);
135         result = Int32Constant(lvalue - rvalue);
136     }
137     return result;
138 }
139 
VisitMUL(GateRef gate)140 GateRef ConstantFolding::VisitMUL(GateRef gate)
141 {
142     auto left = acc_.GetValueIn(gate, 0);
143     auto right = acc_.GetValueIn(gate, 1);
144     if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) {
145         return Circuit::NullGate();
146     }
147 
148     GateRef result = Circuit::NullGate();
149     if (IsConstant(left) && IsConstant(right)) {
150         int lvalue = acc_.GetInt32FromConstant(left);
151         int rvalue = acc_.GetInt32FromConstant(right);
152         result = Int32Constant(lvalue * rvalue);
153     }
154     return result;
155 }
156 
Int32Constant(int32_t val)157 GateRef ConstantFolding::Int32Constant(int32_t val)
158 {
159     AddFoldingCount();
160     GateRef result = builder_.Int32(val);
161     return result;
162 }
163 
Int64Constant(size_t val)164 GateRef ConstantFolding::Int64Constant(size_t val)
165 {
166     AddFoldingCount();
167     GateRef result = builder_.Int64(val);
168     return result;
169 }
170 
IsInt32Type(GateRef gate) const171 bool ConstantFolding::IsInt32Type(GateRef gate) const
172 {
173     return acc_.GetMachineType(gate) == MachineType::I32;
174 }
175 
Print() const176 void ConstantFolding::Print() const
177 {
178     if (IsLogEnabled()) {
179         LOG_COMPILER(INFO) << "";
180         LOG_COMPILER(INFO) << "\033[34m"
181                            << "===================="
182                            << " After constant folding "
183                            << "[" << GetMethodName() << "]"
184                            << "===================="
185                            << "\033[0m";
186         circuit_->PrintAllGatesWithBytecode();
187         LOG_COMPILER(INFO) << "\033[34m" << "========================= End ==========================" << "\033[0m";
188 
189         LOG_COMPILER(INFO) << "Folding Count : " << GetFoldingCount();
190     }
191 }
192 }   // namespace panda::ecmascript::kungfu