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 #include "ecmascript/ts_types/ts_manager.h" 27 28 namespace panda::ecmascript::kungfu { 29 class NumberSpeculativeRetype { 30 public: 31 enum class State { 32 Retype, 33 Convert, 34 }; NumberSpeculativeRetype(Circuit * circuit,Chunk * chunk,ChunkVector<TypeInfo> & typeInfos)35 NumberSpeculativeRetype(Circuit* circuit, Chunk* chunk, ChunkVector<TypeInfo>& typeInfos) 36 : circuit_(circuit), acc_(circuit), builder_(circuit), 37 typeInfos_(typeInfos), chunk_(chunk) {} 38 GateRef VisitGate(GateRef gate); 39 void setState(NumberSpeculativeRetype::State state); 40 41 private: 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 VisitStringBinaryOp(GateRef gate); 67 GateRef VisitUndefinedEqualCompareOrUndefinedNotEqualCompare(GateRef gate); 68 GateRef VisitTypedUnaryOp(GateRef gate); 69 70 GateRef VisitNumberMonocular(GateRef gate); 71 GateRef VisitNumberNot(GateRef gate); 72 GateRef VisitTypedConditionJump(GateRef gate); 73 74 GateRef VisitIntMonocular(GateRef gate); 75 GateRef VisitDoubleMonocular(GateRef gate); 76 77 GateRef VisitNumberCalculate(GateRef gate); 78 GateRef VisitNumberCompare(GateRef gate); 79 GateRef VisitNumberShiftAndLogical(GateRef gate); 80 GateRef VisitNumberMod(GateRef gate); 81 GateRef VisitBooleanJump(GateRef gate); 82 GateRef VisitRangeCheckPredicate(GateRef gate); 83 GateRef VisitIndexCheck(GateRef gate); 84 GateRef VisitLoadArrayLength(GateRef gate); 85 GateRef VisitLoadStringLength(GateRef gate); 86 GateRef VisitLoadElement(GateRef gate); 87 GateRef VisitStoreElement(GateRef gate); 88 GateRef VisitStoreProperty(GateRef gate); 89 GateRef VisitLoadProperty(GateRef gate); 90 GateRef VisitNumberRelated(GateRef gate); 91 GateRef VisitCallBuiltins(GateRef gate); 92 GateRef VisitOthers(GateRef gate); 93 GateRef VisitTypeConvert(GateRef gate); 94 GateRef VisitFrameState(GateRef gate); 95 GateRef VisitIsTrueOrFalse(GateRef gate); 96 GateRef VisitWithConstantValue(GateRef gate, size_t ignoreIndex); 97 GateRef VisitIntermediateValue(GateRef gate); 98 GateRef VisitEqualCompareOrNotEqualCompare(GateRef gate); 99 100 GateRef VisitStringCompare(GateRef gate); 101 GateRef VisitStringAdd(GateRef gate); 102 GateRef VisitMonoLoadPropertyOnProto(GateRef gate); 103 GateRef VisitMonoCallGetterOnProto(GateRef gate); 104 GateRef VisitMonoStoreProperty(GateRef gate); 105 106 void ConvertForBinaryOp(GateRef gate); 107 void ConvertForCompareOp(GateRef gate); 108 void ConvertForIntOperator(GateRef gate, GateType leftType, GateType rightType); 109 void ConvertForShiftAndLogicalOperator(GateRef gate, GateType leftType, GateType rightType); 110 void ConvertForDoubleOperator(GateRef gate, GateType leftType, GateType rightType); 111 112 GateRef CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE, 113 OpType type = OpType::NORMAL); 114 GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE); 115 GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType); 116 GateRef CheckAndConvertToBool(GateRef gate, GateType gateType); 117 GateRef ConvertToTagged(GateRef gate); 118 GateRef TryConvertConstant(GateRef gate, bool needInt32); 119 GateRef ConvertTaggedToNJSValue(GateRef gate, TypeInfo output); 120 TypeInfo GetOuputForPhi(GateRef gate, bool ignoreConstant); 121 GetOutputTypeInfo(GateRef gate)122 TypeInfo GetOutputTypeInfo(GateRef gate) const 123 { 124 auto index = acc_.GetId(gate); 125 ASSERT(index < typeInfos_.size()); 126 return typeInfos_[index]; 127 } 128 SetOutputTypeInfo(GateRef gate,TypeInfo info)129 void SetOutputTypeInfo(GateRef gate, TypeInfo info) 130 { 131 auto index = acc_.GetId(gate); 132 ASSERT(index < typeInfos_.size()); 133 typeInfos_[index] = info; 134 } 135 ResizeAndSetTypeInfo(GateRef gate,TypeInfo info)136 void ResizeAndSetTypeInfo(GateRef gate, TypeInfo info) 137 { 138 auto index = acc_.GetId(gate); 139 if (index >= typeInfos_.size()) { 140 // +1: for size 141 typeInfos_.resize(index + 1, TypeInfo::NONE); 142 } 143 typeInfos_[index] = info; 144 } 145 146 static constexpr size_t PROPERTY_LOOKUP_RESULT_INDEX = 1; 147 static constexpr size_t HCLASS_INDEX = 2; 148 Circuit *circuit_ {nullptr}; 149 GateAccessor acc_; 150 CircuitBuilder builder_; 151 ChunkVector<TypeInfo>& typeInfos_; 152 State state_ {0}; 153 [[maybe_unused]] Chunk *chunk_ {nullptr}; 154 }; 155 156 class NumberSpeculativeRetypeManager : public PassVisitor { 157 public: NumberSpeculativeRetypeManager(Circuit * circuit,RPOVisitor * visitor,Chunk * chunk,NumberSpeculativeRetype * retype,NumberSpeculativeRetype::State state)158 NumberSpeculativeRetypeManager(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk, 159 NumberSpeculativeRetype* retype, NumberSpeculativeRetype::State state) 160 : PassVisitor(circuit, chunk, visitor), retype_(retype), state_(state) {} 161 GateRef VisitGate(GateRef gate) override; 162 private: 163 NumberSpeculativeRetype* retype_; 164 NumberSpeculativeRetype::State state_; 165 }; 166 167 } // panda::ecmascript::kungfu 168 #endif // ECMASCRIPT_COMPILER_NUMBER_SPECULATIVE_RETYPE_H 169