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/combined_pass_visitor.h" 21 #include "ecmascript/compiler/gate_accessor.h" 22 #include "ecmascript/compiler/share_gate_meta_data.h" 23 #include "ecmascript/compiler/number_gate_info.h" 24 #include "ecmascript/compiler/type.h" 25 #include "ecmascript/mem/chunk_containers.h" 26 27 namespace panda::ecmascript::kungfu { 28 class NumberSpeculativeRetype { 29 public: 30 enum class State { 31 Retype, 32 Convert, 33 }; NumberSpeculativeRetype(Circuit * circuit,Chunk * chunk,ChunkVector<TypeInfo> & typeInfos)34 NumberSpeculativeRetype(Circuit* circuit, Chunk* chunk, ChunkVector<TypeInfo>& typeInfos) 35 : circuit_(circuit), acc_(circuit), builder_(circuit), 36 typeInfos_(typeInfos), chunk_(chunk) {} 37 GateRef VisitGate(GateRef gate); 38 void setState(NumberSpeculativeRetype::State state); 39 void ConvertMonoAccessorValueIn(GateRef gate); 40 41 private: 42 43 enum class OpType { 44 NORMAL, 45 SHIFT_AND_LOGICAL, 46 }; 47 48 enum class ConvertToNumber { 49 DISABLE, 50 BOOL_ONLY, 51 ALL 52 }; 53 ToConvertSupport(ConvertToNumber convert)54 ConvertSupport ToConvertSupport(ConvertToNumber convert) 55 { 56 return convert == ConvertToNumber::DISABLE ? ConvertSupport::DISABLE : ConvertSupport::ENABLE; 57 } 58 IsRetype()59 bool IsRetype() const 60 { 61 return state_ == State::Retype; 62 } 63 IsConvert()64 bool IsConvert() const 65 { 66 return state_ == State::Convert; 67 } 68 69 GateRef SetOutputType(GateRef gate, GateType type); 70 GateRef SetOutputType(GateRef gate, ParamType type); 71 GateRef SetOutputType(GateRef gate, Representation rep); 72 GateRef SetOutputType(GateRef gate, TypeInfo type); 73 TypeInfo GetNumberTypeInfo(GateRef gate); 74 GateRef VisitPhi(GateRef gate); 75 GateRef VisitArrayFindOrFindIndex(GateRef gate); 76 GateRef VisitConstant(GateRef gate); 77 GateRef VisitTypedBinaryOp(GateRef gate); 78 GateRef VisitNumberBinaryOp(GateRef gate); 79 GateRef VisitStringBinaryOp(GateRef gate); 80 GateRef VisitUndefinedEqualCompareOrUndefinedNotEqualCompare(GateRef gate); 81 GateRef VisitTypedUnaryOp(GateRef gate); 82 83 GateRef VisitNumberMonocular(GateRef gate); 84 GateRef VisitNumberNot(GateRef gate); 85 GateRef VisitTypedConditionJump(GateRef gate); 86 87 GateRef VisitIntMonocular(GateRef gate); 88 GateRef VisitDoubleMonocular(GateRef gate); 89 90 GateRef VisitNumberCalculate(GateRef gate); 91 GateRef VisitNumberCompare(GateRef gate); 92 GateRef VisitNumberShiftAndLogical(GateRef gate); 93 GateRef VisitNumberToString(GateRef gate); 94 GateRef VisitNumberParseFloat(GateRef gate); 95 GateRef VisitNumberParseInt(GateRef gate); 96 GateRef VisitMathDoubleParamsBuiltin(GateRef gate); 97 const GateMetaData *GetNewMeta(OpCode op, TypeInfo type); 98 void UpdateMeta(GateRef gate, TypeInfo newType, const GateMetaData *meta); 99 GateRef VisitMathTaggedNumberParamsBuiltin(GateRef gate); 100 GateRef VisitClz32Builtin(GateRef gate); 101 GateRef VisitMathTrunc(GateRef gate); 102 GateRef VisitMathImul(GateRef gate); 103 template <bool IS_NAN> 104 GateRef VisitNumberOrGlobalBuiltin(GateRef gate); 105 GateRef VisitNumberIsInteger(GateRef gate); 106 GateRef VisitBigIntAsIntN(GateRef gate); 107 GateRef VisitBooleanJump(GateRef gate); 108 GateRef VisitRangeCheckPredicate(GateRef gate); 109 GateRef VisitIndexCheck(GateRef gate); 110 GateRef VisitLoadArrayLength(GateRef gate); 111 GateRef VisitLoadStringLength(GateRef gate); 112 GateRef VisitLoadMapSize(GateRef gate); 113 GateRef VisitLoadElement(GateRef gate); 114 GateRef VisitStoreElement(GateRef gate); 115 GateRef VisitStoreProperty(GateRef gate); 116 GateRef VisitLoadProperty(GateRef gate); 117 GateRef VisitNumberRelated(GateRef gate, ParamType paramType); 118 GateRef VisitDataViewGet(GateRef gate); 119 GateRef VisitDataViewSet(GateRef gate); 120 GateRef VisitOthers(GateRef gate, GateType outputType = GateType::AnyType()); 121 GateRef VisitOthersWithoutConvert(GateRef gate, GateType outputType = GateType::AnyType()); 122 GateRef VisitBigIntConstructor(GateRef gate); 123 GateRef VisitTypeConvert(GateRef gate); 124 GateRef VisitFrameState(GateRef gate); 125 GateRef VisitIsTrueOrFalse(GateRef gate); 126 GateRef VisitWithConstantValue(GateRef gate, size_t ignoreIndex); 127 GateRef VisitIntermediateValue(GateRef gate); 128 GateRef VisitEqualCompareOrNotEqualCompare(GateRef gate); 129 130 GateRef VisitStringCompare(GateRef gate); 131 GateRef VisitStringAdd(GateRef gate); 132 GateRef VisitMonoLoadPropertyOnProto(GateRef gate); 133 GateRef VisitMonoCallGetterOnProto(GateRef gate); 134 GateRef VisitMonoStoreProperty(GateRef gate); 135 GateRef VisitDateGetTime(GateRef gate); 136 GateRef VisitDateNow(GateRef gate); 137 GateRef VisitArrayIncludesIndexOf(GateRef gate); 138 GateRef VisitStringCharCodeAt(GateRef gate); 139 GateRef VisitString(GateRef gate); 140 141 void ConvertForNumberBinaryOp(GateRef gate); 142 void ConvertForNumberCompareOp(GateRef gate); 143 void ConvertForNumberShiftAndLogicalOperator(GateRef gate); 144 145 void ConvertForIntOperator(GateRef gate, GateType leftType, GateType rightType); 146 void ConvertForShiftAndLogicalOperator(GateRef gate, GateType leftType, GateType rightType); 147 void ConvertForDoubleOperator(GateRef gate, GateType leftType, GateType rightType); 148 149 template<bool BOOL_AS_INT = true> 150 TypeInfo GetNumberInputTypeInfo(GateRef gate, bool skipTagged = false); 151 void SetNewInputForMathImul(GateRef gate, int idx); 152 double GetDoubleValueFromConst(GateRef gate); 153 154 GateRef CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE, 155 OpType type = OpType::NORMAL, bool needCheckFloat64 = true); 156 GateRef CheckTaggedAndConvertToInt32(GateRef gate, GateType gateType, OpType type); 157 GateRef CheckBoundAndConvertToInt32(GateRef gate, 158 ConvertSupport support = ConvertSupport::ENABLE, 159 OpType type = OpType::NORMAL); 160 GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType, 161 ConvertToNumber convert = ConvertToNumber::BOOL_ONLY); 162 GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType, ConvertToNumber convert); 163 GateRef CheckAndConvertToBool(GateRef gate, GateType gateType); 164 GateRef ConvertToTagged(GateRef gate); 165 GateRef TryConvertConstant(GateRef gate, bool needInt32); 166 GateRef TryConvertConstantToInt32(GateRef gate); 167 GateRef ConvertTaggedToNJSValue(GateRef gate, TypeInfo output); 168 TypeInfo GetOutputForPhi(GateRef gate, bool ignoreConstant); 169 GetOutputTypeInfo(GateRef gate)170 TypeInfo GetOutputTypeInfo(GateRef gate) const 171 { 172 auto index = acc_.GetId(gate); 173 ASSERT(index < typeInfos_.size()); 174 return typeInfos_[index]; 175 } 176 SetOutputTypeInfo(GateRef gate,TypeInfo info)177 void SetOutputTypeInfo(GateRef gate, TypeInfo info) 178 { 179 auto index = acc_.GetId(gate); 180 ASSERT(index < typeInfos_.size()); 181 typeInfos_[index] = info; 182 } 183 ResizeAndSetTypeInfo(GateRef gate,TypeInfo info)184 void ResizeAndSetTypeInfo(GateRef gate, TypeInfo info) 185 { 186 auto index = acc_.GetId(gate); 187 if (index >= typeInfos_.size()) { 188 // +1: for size 189 typeInfos_.resize(index + 1, TypeInfo::NONE); 190 } 191 typeInfos_[index] = info; 192 } 193 194 static constexpr size_t PROPERTY_LOOKUP_RESULT_INDEX = 1; 195 static constexpr size_t HCLASS_INDEX = 2; 196 Circuit *circuit_ {nullptr}; 197 GateAccessor acc_; 198 CircuitBuilder builder_; 199 ChunkVector<TypeInfo>& typeInfos_; 200 State state_ {0}; 201 [[maybe_unused]] Chunk *chunk_ {nullptr}; 202 }; 203 204 class NumberSpeculativeRetypeManager : public PassVisitor { 205 public: NumberSpeculativeRetypeManager(Circuit * circuit,RPOVisitor * visitor,Chunk * chunk,NumberSpeculativeRetype * retype,NumberSpeculativeRetype::State state)206 NumberSpeculativeRetypeManager(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk, 207 NumberSpeculativeRetype* retype, NumberSpeculativeRetype::State state) 208 : PassVisitor(circuit, chunk, visitor), retype_(retype), state_(state) {} 209 GateRef VisitGate(GateRef gate) override; 210 private: 211 NumberSpeculativeRetype* retype_; 212 NumberSpeculativeRetype::State state_; 213 }; 214 215 } // panda::ecmascript::kungfu 216 #endif // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_RETYPE_H 217