14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_COMPILER_GATE_MATCHERS_H 164514f5e3Sopenharmony_ci#define ECMASCRIPT_COMPILER_GATE_MATCHERS_H 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder.h" 204514f5e3Sopenharmony_ci#include "utils/bit_utils.h" 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ci// Checks if value is in range [lowerLimit, higherLimit] using a single 264514f5e3Sopenharmony_ci// branch. 274514f5e3Sopenharmony_citemplate <typename T, typename U> inline constexpr bool IsValueInRange(T value, U lowerLimit, U higherLimit) 284514f5e3Sopenharmony_ci{ 294514f5e3Sopenharmony_ci static_assert(sizeof(U) <= sizeof(T)); 304514f5e3Sopenharmony_ci using unsigned_T = typename std::make_unsigned<T>::type; 314514f5e3Sopenharmony_ci // Use static_cast to support enum classes. 324514f5e3Sopenharmony_ci return static_cast<unsigned_T>(static_cast<unsigned_T>(value) - static_cast<unsigned_T>(lowerLimit)) <= 334514f5e3Sopenharmony_ci static_cast<unsigned_T>(static_cast<unsigned_T>(higherLimit) - static_cast<unsigned_T>(lowerLimit)); 344514f5e3Sopenharmony_ci} 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_ciclass GateMatcher { 374514f5e3Sopenharmony_cipublic: 384514f5e3Sopenharmony_ci explicit GateMatcher(GateRef gate, Circuit *circuit) : acc_(circuit), gate_(gate) 394514f5e3Sopenharmony_ci { 404514f5e3Sopenharmony_ci } 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ci GateRef Gate() const 434514f5e3Sopenharmony_ci { 444514f5e3Sopenharmony_ci return gate_; 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ci GateRef ValueIn(uint32_t index) 484514f5e3Sopenharmony_ci { 494514f5e3Sopenharmony_ci return acc_.GetValueIn(gate_, index); 504514f5e3Sopenharmony_ci } 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_ci OpCode Opcode() const 534514f5e3Sopenharmony_ci { 544514f5e3Sopenharmony_ci return acc_.GetOpCode(gate_); 554514f5e3Sopenharmony_ci } 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci MachineType MachineType() const 584514f5e3Sopenharmony_ci { 594514f5e3Sopenharmony_ci return acc_.GetMachineType(gate_); 604514f5e3Sopenharmony_ci } 614514f5e3Sopenharmony_ci GateRef InputAt(int index) const 624514f5e3Sopenharmony_ci { 634514f5e3Sopenharmony_ci return acc_.GetValueIn(gate_, index); 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci 664514f5e3Sopenharmony_ci#define DECLARE_IS_GATE(NAME, OP, R, S, D, V) \ 674514f5e3Sopenharmony_ci bool Is##NAME() const \ 684514f5e3Sopenharmony_ci { \ 694514f5e3Sopenharmony_ci return (Opcode() == (OpCode::OP)); \ 704514f5e3Sopenharmony_ci } 714514f5e3Sopenharmony_ci IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_IS_GATE) 724514f5e3Sopenharmony_ci GATE_META_DATA_LIST_WITH_BOOL(DECLARE_IS_GATE) 734514f5e3Sopenharmony_ci GATE_META_DATA_LIST_WITH_BOOL_VALUE_IN(DECLARE_IS_GATE) 744514f5e3Sopenharmony_ci GATE_META_DATA_LIST_WITH_SIZE(DECLARE_IS_GATE) 754514f5e3Sopenharmony_ci GATE_META_DATA_LIST_WITH_ONE_PARAMETER(DECLARE_IS_GATE) GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_IS_GATE) 764514f5e3Sopenharmony_ci GATE_META_DATA_LIST_FOR_CALL(DECLARE_IS_GATE) GATE_META_DATA_LIST_WITH_PC_OFFSET_FIXED_VALUE(DECLARE_IS_GATE) 774514f5e3Sopenharmony_ci GATE_META_DATA_LIST_FOR_NEW(DECLARE_IS_GATE) 784514f5e3Sopenharmony_ci#undef DECLARE_IS_GATE 794514f5e3Sopenharmony_ci 804514f5e3Sopenharmony_ci#define DECLARE_IS_INST(NAME, OPCODEID, MACHINETYPEID) \ 814514f5e3Sopenharmony_ci bool Ism##NAME() const \ 824514f5e3Sopenharmony_ci { \ 834514f5e3Sopenharmony_ci return Is##OPCODEID() && MachineType() == (MACHINETYPEID); \ 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(DECLARE_IS_INST) 864514f5e3Sopenharmony_ci UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(DECLARE_IS_INST) 874514f5e3Sopenharmony_ci#undef DECLARE_IS_INST 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_ci#define DECLARE_IS_INST(NAME, OPCODEID, CONDITION) \ 904514f5e3Sopenharmony_ci bool Ism##NAME() const \ 914514f5e3Sopenharmony_ci { \ 924514f5e3Sopenharmony_ci return Is##OPCODEID() && static_cast<uint64_t>(CONDITION) == ConditionValue(); \ 934514f5e3Sopenharmony_ci }; \ 944514f5e3Sopenharmony_ci BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(DECLARE_IS_INST) 954514f5e3Sopenharmony_ci#undef DECLARE_IS_INST 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ci bool Equals(const GateRef gate) 984514f5e3Sopenharmony_ci { 994514f5e3Sopenharmony_ci return gate == Gate(); 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci GateAccessor acc_; 1034514f5e3Sopenharmony_ci 1044514f5e3Sopenharmony_ci BitField ConditionValue() 1054514f5e3Sopenharmony_ci { 1064514f5e3Sopenharmony_ci ASSERT(IsFcmp() || IsIcmp()); 1074514f5e3Sopenharmony_ci return acc_.TryGetValue(Gate()); 1084514f5e3Sopenharmony_ci } 1094514f5e3Sopenharmony_ciprivate: 1104514f5e3Sopenharmony_ci GateRef gate_; 1114514f5e3Sopenharmony_ci}; 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_ci// A pattern matcher for abitrary value constants. 1144514f5e3Sopenharmony_ci// 1154514f5e3Sopenharmony_ci// Note that value identities on the input gate are skipped when matching. The 1164514f5e3Sopenharmony_ci// resolved value may not be a parameter of the input gate. The Gate() method 1174514f5e3Sopenharmony_ci// returns the unmodified input gate. This is by design, as reducers may wish to 1184514f5e3Sopenharmony_ci// match value constants but delay reducing the gate until a later phase. 1194514f5e3Sopenharmony_citemplate <typename T, OpCode kOpcode, MachineType kMachineType> struct ValueMatcher : public GateMatcher { 1204514f5e3Sopenharmony_ci using ValueType = T; 1214514f5e3Sopenharmony_ci 1224514f5e3Sopenharmony_ci explicit ValueMatcher(GateRef gate, Circuit *circuit) 1234514f5e3Sopenharmony_ci : GateMatcher(gate, circuit), resolvedValue_(), hasResolvedValue_(false) 1244514f5e3Sopenharmony_ci { 1254514f5e3Sopenharmony_ci if (acc_.GetOpCode(gate) == kOpcode && acc_.GetMachineType(gate) == kMachineType) { 1264514f5e3Sopenharmony_ci hasResolvedValue_ = true; 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci 1294514f5e3Sopenharmony_ci if (hasResolvedValue_) { 1304514f5e3Sopenharmony_ci if (kMachineType == F64) { 1314514f5e3Sopenharmony_ci resolvedValue_ = acc_.GetFloat64FromConstant(gate); 1324514f5e3Sopenharmony_ci } else if (kMachineType == I32) { 1334514f5e3Sopenharmony_ci resolvedValue_ = acc_.GetInt32FromConstant(gate); 1344514f5e3Sopenharmony_ci } else if (kMachineType == I64) { 1354514f5e3Sopenharmony_ci resolvedValue_ = acc_.GetConstantValue(gate); 1364514f5e3Sopenharmony_ci } else { 1374514f5e3Sopenharmony_ci hasResolvedValue_ = false; 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci } 1404514f5e3Sopenharmony_ci } 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_ci bool HasResolvedValue() const 1434514f5e3Sopenharmony_ci { 1444514f5e3Sopenharmony_ci return hasResolvedValue_; 1454514f5e3Sopenharmony_ci } 1464514f5e3Sopenharmony_ci const T &ResolvedValue() const 1474514f5e3Sopenharmony_ci { 1484514f5e3Sopenharmony_ci ASSERT(HasResolvedValue()); 1494514f5e3Sopenharmony_ci return resolvedValue_; 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci 1524514f5e3Sopenharmony_ciprivate: 1534514f5e3Sopenharmony_ci T resolvedValue_; 1544514f5e3Sopenharmony_ci bool hasResolvedValue_; 1554514f5e3Sopenharmony_ci}; 1564514f5e3Sopenharmony_ci 1574514f5e3Sopenharmony_ci// A pattern matcher for integer constants. 1584514f5e3Sopenharmony_citemplate <typename T, OpCode kOpcode, MachineType kMachineType> 1594514f5e3Sopenharmony_cistruct IntMatcher final : public ValueMatcher<T, kOpcode, kMachineType> { 1604514f5e3Sopenharmony_ci explicit IntMatcher(GateRef gate, Circuit *circuit) : ValueMatcher<T, kOpcode, kMachineType>(gate, circuit) 1614514f5e3Sopenharmony_ci { 1624514f5e3Sopenharmony_ci } 1634514f5e3Sopenharmony_ci 1644514f5e3Sopenharmony_ci bool Is(const T &value) const 1654514f5e3Sopenharmony_ci { 1664514f5e3Sopenharmony_ci return this->HasResolvedValue() && this->ResolvedValue() == value; 1674514f5e3Sopenharmony_ci } 1684514f5e3Sopenharmony_ci 1694514f5e3Sopenharmony_ci bool IsInRange(const T &low, const T &high) const 1704514f5e3Sopenharmony_ci { 1714514f5e3Sopenharmony_ci return this->HasResolvedValue() && IsValueInRange(this->ResolvedValue(), low, high); 1724514f5e3Sopenharmony_ci } 1734514f5e3Sopenharmony_ci bool IsMultipleOf(T n) const 1744514f5e3Sopenharmony_ci { 1754514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 1764514f5e3Sopenharmony_ci return false; 1774514f5e3Sopenharmony_ci } 1784514f5e3Sopenharmony_ci return (this->ResolvedValue() % n) == 0; 1794514f5e3Sopenharmony_ci } 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_ci bool IsPowerOf2() const 1824514f5e3Sopenharmony_ci { 1834514f5e3Sopenharmony_ci if (!this->HasResolvedValue() || this->ResolvedValue() <= 0) { 1844514f5e3Sopenharmony_ci return false; 1854514f5e3Sopenharmony_ci } 1864514f5e3Sopenharmony_ci using unsigned_type = typename std::make_unsigned<T>::type; 1874514f5e3Sopenharmony_ci const unsigned_type resolvedValue = static_cast<unsigned_type>(this->ResolvedValue()); 1884514f5e3Sopenharmony_ci return (resolvedValue & (resolvedValue - 1)) == 0; 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_ci bool IsNegativePowerOf2() const 1924514f5e3Sopenharmony_ci { 1934514f5e3Sopenharmony_ci if (!this->HasResolvedValue() || this->ResolvedValue() >= 0) { 1944514f5e3Sopenharmony_ci return false; 1954514f5e3Sopenharmony_ci } 1964514f5e3Sopenharmony_ci return ((this->ResolvedValue() == std::numeric_limits<T>::min()) || 1974514f5e3Sopenharmony_ci (-this->ResolvedValue() & (-this->ResolvedValue() - 1)) == 0); 1984514f5e3Sopenharmony_ci } 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_ci bool IsNegative() const 2014514f5e3Sopenharmony_ci { 2024514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2034514f5e3Sopenharmony_ci return false; 2044514f5e3Sopenharmony_ci } 2054514f5e3Sopenharmony_ci return this->ResolvedValue() < 0; 2064514f5e3Sopenharmony_ci } 2074514f5e3Sopenharmony_ci}; 2084514f5e3Sopenharmony_ci 2094514f5e3Sopenharmony_ciusing Int32Matcher = IntMatcher<int32_t, OpCode::CONSTANT, MachineType::I32>; 2104514f5e3Sopenharmony_ciusing Uint32Matcher = IntMatcher<uint32_t, OpCode::CONSTANT, MachineType::I32>; 2114514f5e3Sopenharmony_ciusing Int64Matcher = IntMatcher<int64_t, OpCode::CONSTANT, MachineType::I64>; 2124514f5e3Sopenharmony_ciusing Uint64Matcher = IntMatcher<uint64_t, OpCode::CONSTANT, MachineType::I64>; 2134514f5e3Sopenharmony_ci 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_ci// A pattern matcher for floating point constants. 2164514f5e3Sopenharmony_citemplate <typename T, OpCode kOpcode, MachineType kMachineType> 2174514f5e3Sopenharmony_cistruct FloatMatcher final : public ValueMatcher<T, kOpcode, kMachineType> { 2184514f5e3Sopenharmony_ci explicit FloatMatcher(GateRef gate, Circuit *circuit) : ValueMatcher<T, kOpcode, kMachineType>(gate, circuit) 2194514f5e3Sopenharmony_ci { 2204514f5e3Sopenharmony_ci } 2214514f5e3Sopenharmony_ci 2224514f5e3Sopenharmony_ci bool Is(const T &value) const 2234514f5e3Sopenharmony_ci { 2244514f5e3Sopenharmony_ci return this->HasResolvedValue() && this->ResolvedValue() == value; 2254514f5e3Sopenharmony_ci } 2264514f5e3Sopenharmony_ci bool IsInRange(const T &low, const T &high) const 2274514f5e3Sopenharmony_ci { 2284514f5e3Sopenharmony_ci return this->HasResolvedValue() && low <= this->ResolvedValue() && this->ResolvedValue() <= high; 2294514f5e3Sopenharmony_ci } 2304514f5e3Sopenharmony_ci bool IsMinusZero() const 2314514f5e3Sopenharmony_ci { 2324514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2334514f5e3Sopenharmony_ci return false; 2344514f5e3Sopenharmony_ci } 2354514f5e3Sopenharmony_ci return this->Is(0.0) && std::signbit(this->ResolvedValue()); 2364514f5e3Sopenharmony_ci } 2374514f5e3Sopenharmony_ci 2384514f5e3Sopenharmony_ci bool IsNegative() const 2394514f5e3Sopenharmony_ci { 2404514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2414514f5e3Sopenharmony_ci return false; 2424514f5e3Sopenharmony_ci } 2434514f5e3Sopenharmony_ci return this->ResolvedValue() < 0.0; 2444514f5e3Sopenharmony_ci } 2454514f5e3Sopenharmony_ci 2464514f5e3Sopenharmony_ci bool IsNaN() const 2474514f5e3Sopenharmony_ci { 2484514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2494514f5e3Sopenharmony_ci return false; 2504514f5e3Sopenharmony_ci } 2514514f5e3Sopenharmony_ci return std::isnan(this->ResolvedValue()); 2524514f5e3Sopenharmony_ci } 2534514f5e3Sopenharmony_ci 2544514f5e3Sopenharmony_ci bool IsZero() const 2554514f5e3Sopenharmony_ci { 2564514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2574514f5e3Sopenharmony_ci return false; 2584514f5e3Sopenharmony_ci } 2594514f5e3Sopenharmony_ci return this->Is(0.0) && !std::signbit(this->ResolvedValue()); 2604514f5e3Sopenharmony_ci } 2614514f5e3Sopenharmony_ci 2624514f5e3Sopenharmony_ci bool IsNormal() const 2634514f5e3Sopenharmony_ci { 2644514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2654514f5e3Sopenharmony_ci return false; 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci return std::isnormal(this->ResolvedValue()); 2684514f5e3Sopenharmony_ci } 2694514f5e3Sopenharmony_ci 2704514f5e3Sopenharmony_ci bool IsInteger() const 2714514f5e3Sopenharmony_ci { 2724514f5e3Sopenharmony_ci if (!this->HasResolvedValue()) { 2734514f5e3Sopenharmony_ci return false; 2744514f5e3Sopenharmony_ci } 2754514f5e3Sopenharmony_ci return std::nearbyint(this->ResolvedValue()) == this->ResolvedValue(); 2764514f5e3Sopenharmony_ci } 2774514f5e3Sopenharmony_ci}; 2784514f5e3Sopenharmony_ci 2794514f5e3Sopenharmony_ciusing Float32Matcher = FloatMatcher<float, OpCode::CONSTANT, MachineType::F32>; 2804514f5e3Sopenharmony_ciusing Float64Matcher = FloatMatcher<double, OpCode::CONSTANT, MachineType::F64>; 2814514f5e3Sopenharmony_ci 2824514f5e3Sopenharmony_ci 2834514f5e3Sopenharmony_ci// For shorter pattern matching code, this struct matches both the left and 2844514f5e3Sopenharmony_ci// right hand sides of a binary operation and can put constants on the right 2854514f5e3Sopenharmony_ci// if they appear on the left hand side of a commutative operation. 2864514f5e3Sopenharmony_citemplate <typename LeftExpr, typename RightExpr, MachineType rep> struct BinopMatcher : public GateMatcher { 2874514f5e3Sopenharmony_ci explicit BinopMatcher(GateRef gate, Circuit *circuit) 2884514f5e3Sopenharmony_ci : GateMatcher(gate, circuit), left_(InputAt(0), circuit), right_(InputAt(1), circuit) 2894514f5e3Sopenharmony_ci { 2904514f5e3Sopenharmony_ci if (IsCommutative(Opcode())) { 2914514f5e3Sopenharmony_ci PutConstantOnRight(); 2924514f5e3Sopenharmony_ci } 2934514f5e3Sopenharmony_ci } 2944514f5e3Sopenharmony_ci 2954514f5e3Sopenharmony_ci BinopMatcher(GateRef gate, bool allowInputSwap, Circuit *circuit) 2964514f5e3Sopenharmony_ci : GateMatcher(gate, circuit), left_(InputAt(0), circuit), right_(InputAt(1), circuit) 2974514f5e3Sopenharmony_ci { 2984514f5e3Sopenharmony_ci if (allowInputSwap) { 2994514f5e3Sopenharmony_ci PutConstantOnRight(); 3004514f5e3Sopenharmony_ci } 3014514f5e3Sopenharmony_ci } 3024514f5e3Sopenharmony_ci 3034514f5e3Sopenharmony_ci using LeftMatcher = LeftExpr; 3044514f5e3Sopenharmony_ci using RightMatcher = RightExpr; 3054514f5e3Sopenharmony_ci 3064514f5e3Sopenharmony_ci // static constexpr MachineType representation = rep; 3074514f5e3Sopenharmony_ci 3084514f5e3Sopenharmony_ci const LeftExpr &Left() const 3094514f5e3Sopenharmony_ci { 3104514f5e3Sopenharmony_ci return left_; 3114514f5e3Sopenharmony_ci } 3124514f5e3Sopenharmony_ci 3134514f5e3Sopenharmony_ci const RightExpr &Right() const 3144514f5e3Sopenharmony_ci { 3154514f5e3Sopenharmony_ci return right_; 3164514f5e3Sopenharmony_ci } 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ci void SetLeft(GateRef left, Circuit* circuit) 3194514f5e3Sopenharmony_ci { 3204514f5e3Sopenharmony_ci left_ = LeftExpr(left, circuit); 3214514f5e3Sopenharmony_ci } 3224514f5e3Sopenharmony_ci 3234514f5e3Sopenharmony_ci void SetRight(GateRef right, Circuit* circuit) 3244514f5e3Sopenharmony_ci { 3254514f5e3Sopenharmony_ci right_ = RightExpr(right, circuit); 3264514f5e3Sopenharmony_ci } 3274514f5e3Sopenharmony_ci 3284514f5e3Sopenharmony_ci bool IsFoldable() const 3294514f5e3Sopenharmony_ci { 3304514f5e3Sopenharmony_ci return Left().HasResolvedValue() && Right().HasResolvedValue(); 3314514f5e3Sopenharmony_ci } 3324514f5e3Sopenharmony_ci bool LeftEqualsRight() const 3334514f5e3Sopenharmony_ci { 3344514f5e3Sopenharmony_ci return Left().Gate() == Right().Gate(); 3354514f5e3Sopenharmony_ci } 3364514f5e3Sopenharmony_ci 3374514f5e3Sopenharmony_ci bool OwnsInput(GateRef input) 3384514f5e3Sopenharmony_ci { 3394514f5e3Sopenharmony_ci auto use = acc_.Uses(input); 3404514f5e3Sopenharmony_ci for (auto it = use.begin(); it != use.end(); it++) { 3414514f5e3Sopenharmony_ci if (*it != Gate()) { 3424514f5e3Sopenharmony_ci return false; 3434514f5e3Sopenharmony_ci } 3444514f5e3Sopenharmony_ci } 3454514f5e3Sopenharmony_ci return true; 3464514f5e3Sopenharmony_ci } 3474514f5e3Sopenharmony_ci 3484514f5e3Sopenharmony_ciprotected: 3494514f5e3Sopenharmony_ci void SwapInputs() 3504514f5e3Sopenharmony_ci { 3514514f5e3Sopenharmony_ci std::swap(left_, right_); 3524514f5e3Sopenharmony_ci acc_.ReplaceValueIn(Gate(), Left().Gate(), 0); 3534514f5e3Sopenharmony_ci acc_.ReplaceValueIn(Gate(), Right().Gate(), 1); 3544514f5e3Sopenharmony_ci } 3554514f5e3Sopenharmony_ci 3564514f5e3Sopenharmony_ciprivate: 3574514f5e3Sopenharmony_ci void PutConstantOnRight() 3584514f5e3Sopenharmony_ci { 3594514f5e3Sopenharmony_ci if (Left().HasResolvedValue() && !Right().HasResolvedValue()) { 3604514f5e3Sopenharmony_ci SwapInputs(); 3614514f5e3Sopenharmony_ci } 3624514f5e3Sopenharmony_ci } 3634514f5e3Sopenharmony_ci static bool IsCommutative(OpCode opcode) 3644514f5e3Sopenharmony_ci { 3654514f5e3Sopenharmony_ci switch (opcode) { 3664514f5e3Sopenharmony_ci case OpCode::ADD: 3674514f5e3Sopenharmony_ci case OpCode::AND: 3684514f5e3Sopenharmony_ci case OpCode::OR: 3694514f5e3Sopenharmony_ci case OpCode::XOR: 3704514f5e3Sopenharmony_ci case OpCode::MUL: 3714514f5e3Sopenharmony_ci case OpCode::ADD_WITH_OVERFLOW: 3724514f5e3Sopenharmony_ci case OpCode::MUL_WITH_OVERFLOW: 3734514f5e3Sopenharmony_ci return true; 3744514f5e3Sopenharmony_ci default: 3754514f5e3Sopenharmony_ci return false; 3764514f5e3Sopenharmony_ci } 3774514f5e3Sopenharmony_ci return false; 3784514f5e3Sopenharmony_ci } 3794514f5e3Sopenharmony_ci LeftExpr left_; 3804514f5e3Sopenharmony_ci RightExpr right_; 3814514f5e3Sopenharmony_ci}; 3824514f5e3Sopenharmony_ci 3834514f5e3Sopenharmony_ciusing Int32BinopMatcher = BinopMatcher<Int32Matcher, Int32Matcher, MachineType::I32>; 3844514f5e3Sopenharmony_ciusing Uint32BinopMatcher = BinopMatcher<Uint32Matcher, Uint32Matcher, MachineType::I32>; 3854514f5e3Sopenharmony_ciusing Int64BinopMatcher = BinopMatcher<Int64Matcher, Int64Matcher, MachineType::I64>; 3864514f5e3Sopenharmony_ciusing Uint64BinopMatcher = BinopMatcher<Uint64Matcher, Uint64Matcher, MachineType::I64>; 3874514f5e3Sopenharmony_ciusing Float32BinopMatcher = BinopMatcher<Float32Matcher, Float32Matcher, MachineType::F32>; 3884514f5e3Sopenharmony_ciusing Float64BinopMatcher = BinopMatcher<Float64Matcher, Float64Matcher, MachineType::F64>; 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ci 3914514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 3924514f5e3Sopenharmony_ci#endif // ECMASCRIPT_COMPILER_GATE_MATCHERS_H