• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 ECMASCRIPT_COMPILER_CONSTANT_FOLDING_H
17 #define ECMASCRIPT_COMPILER_CONSTANT_FOLDING_H
18 
19 #include "ecmascript/compiler/circuit.h"
20 #include "ecmascript/compiler/circuit_builder.h"
21 #include "ecmascript/compiler/gate.h"
22 #include "ecmascript/compiler/share_gate_meta_data.h"
23 #include "ecmascript/compiler/combined_pass_visitor.h"
24 #include "ecmascript/compiler/number_gate_info.h"
25 
26 namespace panda::ecmascript::kungfu {
27 class ConstantFolding : public PassVisitor {
28 
29 #define BINARY_OP_LIST(V)                       \
30     V(ADD,          VALID)                      \
31     V(SUB,          VALID)                      \
32     V(MUL,          VALID)                      \
33     V(EXP,          INVALID)                    \
34     V(SDIV,         INVALID)                    \
35     V(SMOD,         VALID)                      \
36     V(UDIV,         INVALID)                    \
37     V(UMOD,         VALID)                      \
38     V(FDIV,         INVALID)                    \
39     V(FMOD,         INVALID)                    \
40     V(AND,          VALID)                      \
41     V(XOR,          VALID)                      \
42     V(OR,           VALID)                      \
43     V(LSL,          INVALID)                    \
44     V(LSR,          INVALID)                    \
45     V(ASR,          INVALID)                    \
46     V(MIN,          VALID)                      \
47     V(MAX,          VALID)
48 
49 #define UNARY_OP_LIST(V)                        \
50     V(ZEXT,                    VALID)           \
51     V(SEXT,                    INVALID)         \
52     V(DOUBLE_TRUNC,            INVALID)         \
53     V(TRUNC,                   INVALID)         \
54     V(FEXT,                    INVALID)         \
55     V(FTRUNC,                  INVALID)         \
56     V(REV,                     VALID)           \
57     V(TAGGED_TO_INT64,         INVALID)         \
58     V(INT64_TO_TAGGED,         INVALID)         \
59     V(SIGNED_INT_TO_FLOAT,     INVALID)         \
60     V(UNSIGNED_INT_TO_FLOAT,   INVALID)         \
61     V(FLOAT_TO_SIGNED_INT,     INVALID)         \
62     V(UNSIGNED_FLOAT_TO_INT,   INVALID)         \
63     V(TRUNC_FLOAT_TO_INT64,    INVALID)         \
64     V(TRUNC_FLOAT_TO_INT32,    INVALID)         \
65     V(BITCAST,                 INVALID)         \
66     V(ABS,                     VALID)           \
67     V(SQRT,                    VALID)           \
68     V(CLZ32,                   INVALID)         \
69     V(CEIL,                    VALID)           \
70     V(FLOOR,                   VALID)
71 
72 #define GEN_SWITCH_CASE(op, flag) GEN_SWITCH_CASE_##flag(op)
73 #define GEN_SWITCH_CASE_VALID(op)                                     \
74     case OpCode::op: {                                                \
75         return Visit##op(gate);                                       \
76     }
77 #define GEN_SWITCH_CASE_INVALID(op)
78 
79   public:
ConstantFolding(Circuit * circuit,RPOVisitor * visitor,CompilationConfig * cmpCfg,bool enableLog,const std::string & name,Chunk * chunk)80     ConstantFolding(Circuit *circuit, RPOVisitor* visitor, CompilationConfig *cmpCfg, bool enableLog,
81                     const std::string& name, Chunk* chunk)
82         : PassVisitor(circuit, chunk, visitor), circuit_(circuit), acc_(circuit), builder_(circuit, cmpCfg),
83           enableLog_(enableLog), methodName_(name) {}
84     ~ConstantFolding() = default;
85     void Print() const;
86     GateRef VisitGate(GateRef gate);
87 private:
88 
89 #define DECLARE_VISIT_OP(name, valid)           \
90     GateRef Visit##name(GateRef gate);
91 
92     BINARY_OP_LIST(DECLARE_VISIT_OP)
93     UNARY_OP_LIST(DECLARE_VISIT_OP)
94 #undef DECLARE_VISIT_BINARY_OP
95 
96     GateRef UnaryInt32Calculate(GateRef gate, std::function<GateRef(int)> op);
97     GateRef UnaryF64Calculate(GateRef gate, std::function<GateRef(double)> op);
98     GateRef BinaryInt32Calculate(GateRef gate, std::function<GateRef(int, int)> op);
99     GateRef BinaryF64Calculate(GateRef gate, std::function<GateRef(double, double)> op);
100 
BoolConstant(bool val)101     inline GateRef BoolConstant(bool val)
102     {
103         AddFoldingCount();
104         GateRef result = builder_.Boolean(val);
105         return result;
106     }
107 
Int32Constant(int32_t val)108     inline GateRef Int32Constant(int32_t val)
109     {
110         AddFoldingCount();
111         GateRef result = builder_.Int32(val);
112         return result;
113     }
114 
Int64Constant(size_t val)115     inline GateRef Int64Constant(size_t val)
116     {
117         AddFoldingCount();
118         GateRef result = builder_.Int64(val);
119         return result;
120     }
121 
DoubleConstant(double val)122     inline GateRef DoubleConstant(double val)
123     {
124         AddFoldingCount();
125         GateRef result = builder_.Double(val);
126         return result;
127     }
128 
IsBoolType(GateRef gate)129     inline bool IsBoolType(GateRef gate) const
130     {
131         return acc_.GetMachineType(gate) == MachineType::I1;
132     }
133 
IsInt32Type(GateRef gate)134     inline bool IsInt32Type(GateRef gate) const
135     {
136         return acc_.GetMachineType(gate) == MachineType::I32;
137     }
138 
IsInt64Type(GateRef gate)139     inline bool IsInt64Type(GateRef gate) const
140     {
141         return acc_.GetMachineType(gate) == MachineType::I64;
142     }
143 
IsF64Type(GateRef gate)144     inline bool IsF64Type(GateRef gate) const
145     {
146         return acc_.GetMachineType(gate) == MachineType::F64;
147     }
148 
IsLogEnabled()149     bool IsLogEnabled() const
150     {
151         return enableLog_;
152     }
153 
GetMethodName()154     std::string GetMethodName() const
155     {
156         return methodName_;
157     }
158 
AddFoldingCount()159     void AddFoldingCount()
160     {
161         ++foldingCount_;
162     }
163 
GetFoldingCount()164     int32_t GetFoldingCount() const
165     {
166         return foldingCount_;
167     }
168 
169     Circuit* circuit_;
170     GateAccessor acc_;
171     CircuitBuilder builder_;
172     bool enableLog_{false};
173     std::string methodName_;
174     int32_t foldingCount_{0};
175 };
176 
177 }   // namespace panda::ecmascript::kungfu
178 #endif  //ECMASCRIPT_COMPILER_CONSTANT_FOLDING_H