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_RETYPE_H 17 #define ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_RETYPE_H 18 19 #include "ecmascript/compiler/circuit_builder.h" 20 #include "ecmascript/compiler/gate_accessor.h" 21 #include "ecmascript/compiler/gate_meta_data.h" 22 #include "ecmascript/compiler/graph_visitor.h" 23 #include "ecmascript/compiler/number_gate_info.h" 24 #include "ecmascript/compiler/type.h" 25 #include "ecmascript/mem/chunk_containers.h" 26 #include "ecmascript/ts_types/ts_manager.h" 27 28 namespace panda::ecmascript::kungfu { 29 class NumberSpeculativeRetype : public GraphVisitor { 30 public: NumberSpeculativeRetype(Circuit * circuit,Chunk * chunk,ChunkVector<TypeInfo> & typeInfos)31 NumberSpeculativeRetype(Circuit *circuit, Chunk* chunk, ChunkVector<TypeInfo>& typeInfos) 32 : GraphVisitor(circuit, chunk), acc_(circuit), builder_(circuit), 33 typeInfos_(typeInfos) {} 34 void Run(); 35 GateRef VisitGate(GateRef gate); 36 37 private: 38 enum class State { 39 Retype, 40 Convert, 41 }; 42 43 enum class OpType { 44 NORMAL, 45 SHIFT_AND_LOGICAL, 46 }; 47 IsRetype()48 bool IsRetype() const 49 { 50 return state_ == State::Retype; 51 } 52 IsConvert()53 bool IsConvert() const 54 { 55 return state_ == State::Convert; 56 } 57 58 GateRef SetOutputType(GateRef gate, PGOSampleType type); 59 GateRef SetOutputType(GateRef gate, GateType type); 60 GateRef SetOutputType(GateRef gate, Representation rep); 61 GateRef SetOutputType(GateRef gate, TypeInfo type); 62 GateRef VisitPhi(GateRef gate); 63 GateRef VisitConstant(GateRef gate); 64 GateRef VisitTypedBinaryOp(GateRef gate); 65 GateRef VisitNumberBinaryOp(GateRef gate); 66 GateRef VisitUndefinedStrictEq(GateRef gate); 67 GateRef VisitTypedUnaryOp(GateRef gate); 68 69 GateRef VisitNumberMonocular(GateRef gate); 70 GateRef VisitNumberNot(GateRef gate); 71 GateRef VisitTypedConditionJump(GateRef gate); 72 73 GateRef VisitIntMonocular(GateRef gate); 74 GateRef VisitDoubleMonocular(GateRef gate); 75 76 GateRef VisitNumberCalculate(GateRef gate); 77 GateRef VisitNumberCompare(GateRef gate); 78 GateRef VisitNumberShiftAndLogical(GateRef gate); 79 GateRef VisitNumberMod(GateRef gate); 80 GateRef VisitBooleanJump(GateRef gate); 81 GateRef VisitIndexCheck(GateRef gate); 82 GateRef VisitLoadArrayLength(GateRef gate); 83 GateRef VisitLoadElement(GateRef gate); 84 GateRef VisitStoreElement(GateRef gate); 85 GateRef VisitStoreProperty(GateRef gate); 86 GateRef VisitLoadProperty(GateRef gate); 87 GateRef VisitNumberRelated(GateRef gate); 88 GateRef VisitCallBuiltins(GateRef gate); 89 GateRef VisitOthers(GateRef gate); 90 GateRef VisitTypeConvert(GateRef gate); 91 GateRef VisitFrameState(GateRef gate); 92 GateRef VisitIsTrueOrFalse(GateRef gate); 93 GateRef VisitWithConstantValue(GateRef gate, size_t ignoreIndex); 94 GateRef VisitIntermediateValue(GateRef gate); 95 96 void ConvertForBinaryOp(GateRef gate); 97 void ConvertForCompareOp(GateRef gate); 98 void ConvertForIntOperator(GateRef gate, GateType leftType, GateType rightType); 99 void ConvertForShiftAndLogicalOperator(GateRef gate, GateType leftType, GateType rightType); 100 void ConvertForDoubleOperator(GateRef gate, GateType leftType, GateType rightType); 101 102 GateRef CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE, 103 OpType type = OpType::NORMAL); 104 GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE); 105 GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType); 106 GateRef CheckAndConvertToBool(GateRef gate, GateType gateType); 107 GateRef ConvertToTagged(GateRef gate); 108 GateRef TryConvertConstant(GateRef gate, bool needInt32); 109 GateRef ConvertTaggedToNJSValue(GateRef gate, TypeInfo output); 110 TypeInfo GetOuputForPhi(GateRef gate, bool ignoreConstant); 111 GetOutputTypeInfo(GateRef gate)112 TypeInfo GetOutputTypeInfo(GateRef gate) const 113 { 114 auto index = acc_.GetId(gate); 115 ASSERT(index < typeInfos_.size()); 116 return typeInfos_[index]; 117 } 118 SetOutputTypeInfo(GateRef gate,TypeInfo info)119 void SetOutputTypeInfo(GateRef gate, TypeInfo info) 120 { 121 auto index = acc_.GetId(gate); 122 ASSERT(index < typeInfos_.size()); 123 typeInfos_[index] = info; 124 } 125 ResizeAndSetTypeInfo(GateRef gate,TypeInfo info)126 void ResizeAndSetTypeInfo(GateRef gate, TypeInfo info) 127 { 128 auto index = acc_.GetId(gate); 129 if (index >= typeInfos_.size()) { 130 // +1: for size 131 typeInfos_.resize(index + 1, TypeInfo::NONE); 132 } 133 typeInfos_[index] = info; 134 } 135 136 static constexpr size_t PROPERTY_LOOKUP_RESULT_INDEX = 1; 137 GateAccessor acc_; 138 CircuitBuilder builder_; 139 ChunkVector<TypeInfo>& typeInfos_; 140 State state_ {0}; 141 }; 142 } // panda::ecmascript::kungfu 143 #endif // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_RETYPE_H 144