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 ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_LOWERING_H
17#define ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_LOWERING_H
18
19#include "ecmascript/compiler/circuit_builder-inl.h"
20#include "ecmascript/compiler/gate_accessor.h"
21#include "ecmascript/compiler/share_gate_meta_data.h"
22#include "ecmascript/compiler/number_gate_info.h"
23#include "ecmascript/compiler/type.h"
24#include "ecmascript/mem/chunk_containers.h"
25
26namespace panda::ecmascript::kungfu {
27class NumberSpeculativeLowering {
28public:
29    NumberSpeculativeLowering(Circuit* circuit, Chunk* chunk, ChunkVector<TypeInfo>& typeInfos,
30        ChunkVector<RangeInfo>& rangeInfos)
31        : circuit_(circuit), acc_(circuit), builder_(circuit), typeInfos_(typeInfos),
32          rangeInfos_(rangeInfos), rangeGuardGates_(chunk) {}
33    void Run();
34
35private:
36    void VisitGate(GateRef gate);
37    void VisitTypedBinaryOp(GateRef gate);
38    void VisitNumberBinaryOp(GateRef gate);
39    void VisitStringBinaryOp(GateRef gate);
40    void VisitTypedUnaryOp(GateRef gate);
41    void VisitNumberNot(GateRef gate);
42    void VisitTypedConditionJump(GateRef gate);
43    void VisitConstant(GateRef gate);
44    void VisitPhi(GateRef gate);
45    void VisitUndefinedStrictEqOrUndefinedStrictNotEq(GateRef gate);
46    void VisitUndefinedEqOrUndefinedNotEq(GateRef gate);
47    void VisitEqualOrNotEqual(GateRef gate);
48    void VisitRangeGuard(GateRef gate);
49    void VisitRangeCheckPredicate(GateRef gate);
50    void VisitIndexCheck(GateRef gate);
51    void VisitLoadArrayLength(GateRef gate);
52    void VisitLoadStringLength(GateRef gate);
53    void VisitLoadMapSize(GateRef gate);
54    void VisitLoadElement(GateRef gate);
55    void VisitLoadProperty(GateRef gate);
56    void VisitLoadPropertyOnProto(GateRef gate);
57    void VisitRound(GateRef gate);
58    void VisitFRound(GateRef gate);
59
60    template<TypedBinOp Op>
61    void VisitNumberCalculate(GateRef gate);
62    template<TypedBinOp Op>
63    void VisitNumberCompare(GateRef gate);
64    template<TypedBinOp Op>
65    void VisitNumberShift(GateRef gate);
66    template<TypedBinOp Op>
67    void VisitNumberLogical(GateRef gate);
68    template<TypedUnOp Op>
69    void VisitNumberMonocular(GateRef gate);
70    void VisitNumberDiv(GateRef gate);
71    template<TypedBinOp Op>
72    void VisitNumberMod(GateRef gate);
73    void VisitBooleanJump(GateRef gate);
74    void VisitIsTrueOrFalse(GateRef gate, bool flag);
75    void VisitStrictEqualOrStrictNotEqual(GateRef gate);
76
77    template<TypedBinOp Op>
78    void VisitStringCompare(GateRef gate);
79    template<TypedBinOp Op>
80    void VisitStringAdd(GateRef gate);
81
82    template<TypedBinOp Op>
83    GateRef CalculateInts(GateRef left, GateRef right);
84    template<TypedBinOp Op>
85    GateRef CalculateDoubles(GateRef left, GateRef right);
86    template<TypedBinOp Op>
87    GateRef CompareInts(GateRef left, GateRef right);
88    template<TypedBinOp Op>
89    GateRef CompareDoubles(GateRef left, GateRef right);
90    template<TypedBinOp Op>
91    GateRef ShiftInts(GateRef left, GateRef right);
92    template<TypedBinOp Op>
93    GateRef LogicalInts(GateRef left, GateRef right);
94    template<TypedUnOp Op>
95    GateRef MonocularInt(GateRef value);
96    template<TypedUnOp Op>
97    GateRef MonocularDouble(GateRef value);
98
99    TypeInfo GetOutputType(GateRef gate) const
100    {
101        auto index = acc_.GetId(gate);
102        ASSERT(index < typeInfos_.size());
103        return typeInfos_[index];
104    }
105
106    void UpdateRange(GateRef gate, const RangeInfo& range);
107    RangeInfo GetRange(GateRef gate) const;
108    GateRef GetConstInt32(int32_t v);
109    GateRef GetConstDouble(double v);
110
111    Circuit* circuit_;
112    GateAccessor acc_;
113    CircuitBuilder builder_;
114    ChunkVector<TypeInfo>& typeInfos_;
115    ChunkVector<RangeInfo>& rangeInfos_;
116    ChunkVector<GateRef> rangeGuardGates_;
117};
118}  // panda::ecmascript::kungfu
119#endif  // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_LOWERING_H
120