From db27fcb107a93cfe04950c116620f506b79a78ac Mon Sep 17 00:00:00 2001 From: hewei Date: Tue, 18 Mar 2025 16:21:40 +0800 Subject: [PATCH] Fix: Refactor constant folding Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IBUC3J Signed-off-by: hewei Change-Id: Ib4cef18b3e4afb1ac93e7b70a94cf2a2fffeee12 --- ecmascript/compiler/combined_pass_visitor.cpp | 2 + ecmascript/compiler/constant_folding.cpp | 259 +++++++++++++----- ecmascript/compiler/constant_folding.h | 130 +++++++-- ecmascript/compiler/gate_accessor.cpp | 5 + ecmascript/compiler/gate_accessor.h | 1 + ecmascript/compiler/lcr_opcodes.h | 2 +- ecmascript/compiler/mcr_lowering.cpp | 1 + .../compiler/number_speculative_retype.cpp | 33 +++ .../compiler/number_speculative_retype.h | 1 + 9 files changed, 345 insertions(+), 89 deletions(-) diff --git a/ecmascript/compiler/combined_pass_visitor.cpp b/ecmascript/compiler/combined_pass_visitor.cpp index 9b82770a61..0275965dbe 100644 --- a/ecmascript/compiler/combined_pass_visitor.cpp +++ b/ecmascript/compiler/combined_pass_visitor.cpp @@ -55,6 +55,7 @@ void CombinedPassVisitor::LogicallyReplaceGate(GateRef gate, GateRef replacement it = acc_.ReplaceIn(it, replacement); } } + void CombinedPassVisitor::RelaxStateAndDepend(GateRef gate) { ReplaceGate(gate, StateDepend {acc_.GetState(gate), acc_.GetDep(gate)}, gate); @@ -187,6 +188,7 @@ GateRef CombinedPassVisitor::VisitGate(GateRef gate) } return gate; } + // Reverse post-order void CombinedPassVisitor::VisitTopGate(Edge& current) { diff --git a/ecmascript/compiler/constant_folding.cpp b/ecmascript/compiler/constant_folding.cpp index a68fd29865..4458e247c9 100644 --- a/ecmascript/compiler/constant_folding.cpp +++ b/ecmascript/compiler/constant_folding.cpp @@ -21,106 +21,190 @@ GateRef ConstantFolding::VisitGate(GateRef gate) { auto op = acc_.GetOpCode(gate); switch (op) { - case OpCode::ADD: - return VisitADD(gate); - case OpCode::SUB: - return VisitSUB(gate); - case OpCode::MUL: - return VisitMUL(gate); - case OpCode::SMOD: - return VisitSMOD(gate); - case OpCode::UMOD: - return VisitUMOD(gate); - case OpCode::ZEXT: - return VisitZEXT(gate); + BINARY_OP_LIST(GEN_SWITCH_CASE) + UNARY_OP_LIST(GEN_SWITCH_CASE) default: return Circuit::NullGate(); } } -GateRef ConstantFolding::VisitZEXT(GateRef gate) +GateRef ConstantFolding::BinaryInt32Calculate(GateRef gate, std::function op) { - auto input = acc_.GetValueIn(gate, 0); - if (acc_.GetMachineType(gate) == acc_.GetMachineType(input)) { - AddFoldingCount(); - return input; + auto left = acc_.GetValueIn(gate, 0); + auto right = acc_.GetValueIn(gate, 1); + if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) { + return Circuit::NullGate(); } GateRef result = Circuit::NullGate(); - if (IsConstant(input) && IsInt32Type(input)) { - int value = acc_.GetInt32FromConstant(input); - auto machineType = acc_.GetMachineType(gate); - switch (machineType) { - case MachineType::I32: - result = Int32Constant(value); - break; - case MachineType::ARCH: - case MachineType::I64: - result = Int64Constant(value); - break; - default: - break; - } + if (acc_.IsConstant(left) && acc_.IsConstant(right)) { + AddFoldingCount(); + int lvalue = acc_.GetInt32FromConstant(left); + int rvalue = acc_.GetInt32FromConstant(right); + result = op(lvalue, rvalue); } return result; } -GateRef ConstantFolding::VisitSMOD(GateRef gate) +GateRef ConstantFolding::UnaryInt32Calculate(GateRef gate, std::function op) { - auto left = acc_.GetValueIn(gate, 0); - auto right = acc_.GetValueIn(gate, 1); - if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) { + auto valueIn = acc_.GetValueIn(gate, 0); + if (!IsInt32Type(gate) || !IsInt32Type(valueIn)) { return Circuit::NullGate(); } GateRef result = Circuit::NullGate(); - if (IsConstant(left) && IsConstant(right)) { - int lvalue = acc_.GetInt32FromConstant(left); - int rvalue = acc_.GetInt32FromConstant(right); - if (rvalue != 0) { - result = Int32Constant(lvalue % rvalue); - } + if (acc_.IsConstant(valueIn)) { + AddFoldingCount(); + int value = acc_.GetInt32FromConstant(valueIn); + result = op(value); } return result; } -GateRef ConstantFolding::VisitUMOD(GateRef gate) +GateRef ConstantFolding::BinaryF64Calculate(GateRef gate, std::function op) { auto left = acc_.GetValueIn(gate, 0); auto right = acc_.GetValueIn(gate, 1); - if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) { + if (!IsF64Type(gate) || !IsF64Type(left) || !IsF64Type(right)) { return Circuit::NullGate(); } GateRef result = Circuit::NullGate(); - if (IsConstant(left) && IsConstant(right)) { - int lvalue = acc_.GetInt32FromConstant(left); - int rvalue = acc_.GetInt32FromConstant(right); - if (rvalue != 0) { - result = Int32Constant(bit_cast(lvalue) % bit_cast(rvalue)); + if (acc_.IsConstant(left) && acc_.IsConstant(right)) { + AddFoldingCount(); + double lvalue = acc_.GetFloat64FromConstant(left); + double rvalue = acc_.GetFloat64FromConstant(right); + if (!std::isnan(lvalue) && !std::isnan(rvalue)) { + result = op(lvalue, rvalue); } } return result; } -GateRef ConstantFolding::VisitADD(GateRef gate) +GateRef ConstantFolding::UnaryF64Calculate(GateRef gate, std::function op) { - auto left = acc_.GetValueIn(gate, 0); - auto right = acc_.GetValueIn(gate, 1); - if (!IsInt32Type(gate) || !IsInt32Type(left) || !IsInt32Type(right)) { + auto valueIn = acc_.GetValueIn(gate, 0); + if (!IsF64Type(gate) || !IsF64Type(valueIn)) { return Circuit::NullGate(); } GateRef result = Circuit::NullGate(); - if (IsConstant(left) && IsConstant(right)) { - int lvalue = acc_.GetInt32FromConstant(left); - int rvalue = acc_.GetInt32FromConstant(right); - result = Int32Constant(lvalue + rvalue); + if (acc_.IsConstant(valueIn)) { + AddFoldingCount(); + double value = acc_.GetFloat64FromConstant(valueIn); + if (!std::isnan(value)) { + result = op(value); + } } return result; } +GateRef ConstantFolding::VisitADD(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { + if (lvalue > 0 && rvalue > INT_MAX - lvalue) { + return Circuit::NullGate(); + } + if (lvalue < 0 && rvalue < INT_MIN - lvalue) { + return Circuit::NullGate(); + } + return Int32Constant(lvalue + rvalue); + }); +} + GateRef ConstantFolding::VisitSUB(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { + if (rvalue > 0 && lvalue < INT_MIN + rvalue) { + return Circuit::NullGate(); + } + if (rvalue < 0 && lvalue > INT_MAX + rvalue) { + return Circuit::NullGate(); + } + return Int32Constant(lvalue - rvalue); + }); +} + +GateRef ConstantFolding::VisitMUL(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { + if (lvalue > 0 && rvalue > 0 && lvalue > INT_MAX / rvalue) { + return Circuit::NullGate(); + } + if (lvalue < 0 && rvalue < 0 && lvalue < INT_MAX / rvalue) { + return Circuit::NullGate(); + } + if (lvalue > 0 && rvalue < 0 && rvalue < INT_MIN / lvalue) { + return Circuit::NullGate(); + } + if (lvalue < 0 && rvalue > 0 && lvalue < INT_MIN / rvalue) { + return Circuit::NullGate(); + } + return Int32Constant(lvalue * rvalue); + }); +} + +GateRef ConstantFolding::VisitAND(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { return Int32Constant(lvalue & rvalue); }); +} + +GateRef ConstantFolding::VisitOR(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { return Int32Constant(lvalue | rvalue); }); +} + +GateRef ConstantFolding::VisitXOR(GateRef gate) +{ + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { return Int32Constant(lvalue ^ rvalue); }); +} + +GateRef ConstantFolding::VisitMAX(GateRef gate) +{ + if (IsInt32Type(gate)) { + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { + return Int32Constant(std::max(lvalue, rvalue)); + }); + } + return BinaryF64Calculate(gate, [this](double lvalue, double rvalue) { + return DoubleConstant(std::max(lvalue, rvalue)); + }); +} + +GateRef ConstantFolding::VisitMIN(GateRef gate) +{ + if (IsInt32Type(gate)) { + return BinaryInt32Calculate(gate, [this](int lvalue, int rvalue) { + return Int32Constant(std::min(lvalue, rvalue)); + }); + } + return BinaryF64Calculate(gate, [this](double lvalue, double rvalue) { + return DoubleConstant(std::min(lvalue, rvalue)); + }); +} + +GateRef ConstantFolding::VisitABS(GateRef gate) +{ + return UnaryInt32Calculate(gate, [this](int value) { return Int32Constant(std::abs(value)); }); +} + +GateRef ConstantFolding::VisitSQRT(GateRef gate) +{ + return UnaryF64Calculate(gate, [this](double value) { return DoubleConstant(std::sqrt(value)); }); +} + +GateRef ConstantFolding::VisitCEIL(GateRef gate) +{ + return UnaryF64Calculate(gate, [this](double value) { return DoubleConstant(std::ceil(value)); }); +} + +GateRef ConstantFolding::VisitFLOOR(GateRef gate) +{ + return UnaryF64Calculate(gate, [this](double value) { return DoubleConstant(std::floor(value)); }); +} + +GateRef ConstantFolding::VisitSMOD(GateRef gate) { auto left = acc_.GetValueIn(gate, 0); auto right = acc_.GetValueIn(gate, 1); @@ -129,15 +213,18 @@ GateRef ConstantFolding::VisitSUB(GateRef gate) } GateRef result = Circuit::NullGate(); - if (IsConstant(left) && IsConstant(right)) { + if (acc_.IsConstant(left) && acc_.IsConstant(right)) { + AddFoldingCount(); int lvalue = acc_.GetInt32FromConstant(left); int rvalue = acc_.GetInt32FromConstant(right); - result = Int32Constant(lvalue - rvalue); + if (rvalue != 0) { + result = Int32Constant(lvalue % rvalue); + } } return result; } -GateRef ConstantFolding::VisitMUL(GateRef gate) +GateRef ConstantFolding::VisitUMOD(GateRef gate) { auto left = acc_.GetValueIn(gate, 0); auto right = acc_.GetValueIn(gate, 1); @@ -146,33 +233,61 @@ GateRef ConstantFolding::VisitMUL(GateRef gate) } GateRef result = Circuit::NullGate(); - if (IsConstant(left) && IsConstant(right)) { + if (acc_.IsConstant(left) && acc_.IsConstant(right)) { + AddFoldingCount(); int lvalue = acc_.GetInt32FromConstant(left); int rvalue = acc_.GetInt32FromConstant(right); - result = Int32Constant(lvalue * rvalue); + if (rvalue != 0) { + result = Int32Constant(bit_cast(lvalue) % rvalue); + } } return result; } -GateRef ConstantFolding::Int32Constant(int32_t val) +GateRef ConstantFolding::VisitREV(GateRef gate) { - AddFoldingCount(); - GateRef result = builder_.Int32(val); + auto input = acc_.GetValueIn(gate); + if (!IsBoolType(gate) || !acc_.IsConstant(input) || !IsBoolType(input)) { + return Circuit::NullGate(); + } + + GateRef result = Circuit::NullGate(); + uint64_t rawValue = acc_.GetConstantValue(input); + if (acc_.GetGateType(gate).IsNJSValueType()) { + AddFoldingCount(); + result = BoolConstant(rawValue == 0); + } return result; } -GateRef ConstantFolding::Int64Constant(size_t val) +GateRef ConstantFolding::VisitZEXT(GateRef gate) { - AddFoldingCount(); - GateRef result = builder_.Int64(val); + auto input = acc_.GetValueIn(gate, 0); + if (acc_.GetMachineType(gate) == acc_.GetMachineType(input)) { + AddFoldingCount(); + return input; + } + + GateRef result = Circuit::NullGate(); + if (acc_.IsConstant(input) && IsInt32Type(input)) { + AddFoldingCount(); + int value = acc_.GetInt32FromConstant(input); + auto machineType = acc_.GetMachineType(gate); + switch (machineType) { + case MachineType::I32: + result = Int32Constant(value); + break; + case MachineType::ARCH: + case MachineType::I64: + result = Int64Constant(value); + break; + default: + break; + } + } return result; } -bool ConstantFolding::IsInt32Type(GateRef gate) const -{ - return acc_.GetMachineType(gate) == MachineType::I32; -} - void ConstantFolding::Print() const { if (IsLogEnabled()) { diff --git a/ecmascript/compiler/constant_folding.h b/ecmascript/compiler/constant_folding.h index c2a72aecac..7031f3d359 100644 --- a/ecmascript/compiler/constant_folding.h +++ b/ecmascript/compiler/constant_folding.h @@ -23,11 +23,60 @@ #include "ecmascript/compiler/combined_pass_visitor.h" #include "ecmascript/compiler/number_gate_info.h" - namespace panda::ecmascript::kungfu { - class ConstantFolding : public PassVisitor { -public: + +#define BINARY_OP_LIST(V) \ + V(ADD, VALID) \ + V(SUB, VALID) \ + V(MUL, VALID) \ + V(EXP, INVALID) \ + V(SDIV, INVALID) \ + V(SMOD, VALID) \ + V(UDIV, INVALID) \ + V(UMOD, VALID) \ + V(FDIV, INVALID) \ + V(FMOD, INVALID) \ + V(AND, VALID) \ + V(XOR, VALID) \ + V(OR, VALID) \ + V(LSL, INVALID) \ + V(LSR, INVALID) \ + V(ASR, INVALID) \ + V(MIN, VALID) \ + V(MAX, VALID) + +#define UNARY_OP_LIST(V) \ + V(ZEXT, VALID) \ + V(SEXT, INVALID) \ + V(DOUBLE_TRUNC, INVALID) \ + V(TRUNC, INVALID) \ + V(FEXT, INVALID) \ + V(FTRUNC, INVALID) \ + V(REV, VALID) \ + V(TAGGED_TO_INT64, INVALID) \ + V(INT64_TO_TAGGED, INVALID) \ + V(SIGNED_INT_TO_FLOAT, INVALID) \ + V(UNSIGNED_INT_TO_FLOAT, INVALID) \ + V(FLOAT_TO_SIGNED_INT, INVALID) \ + V(UNSIGNED_FLOAT_TO_INT, INVALID) \ + V(TRUNC_FLOAT_TO_INT64, INVALID) \ + V(TRUNC_FLOAT_TO_INT32, INVALID) \ + V(BITCAST, INVALID) \ + V(ABS, VALID) \ + V(SQRT, VALID) \ + V(CLZ32, INVALID) \ + V(CEIL, VALID) \ + V(FLOOR, VALID) + +#define GEN_SWITCH_CASE(op, flag) GEN_SWITCH_CASE_##flag(op) +#define GEN_SWITCH_CASE_VALID(op) \ + case OpCode::op: { \ + return Visit##op(gate); \ + } +#define GEN_SWITCH_CASE_INVALID(op) + + public: ConstantFolding(Circuit *circuit, RPOVisitor* visitor, CompilationConfig *cmpCfg, bool enableLog, const std::string& name, Chunk* chunk) : PassVisitor(circuit, chunk, visitor), circuit_(circuit), acc_(circuit), builder_(circuit, cmpCfg), @@ -36,38 +85,87 @@ public: void Print() const; GateRef VisitGate(GateRef gate); private: - GateRef VisitADD(GateRef gate); - GateRef VisitMUL(GateRef gate); - GateRef VisitZEXT(GateRef gate); - GateRef VisitSUB(GateRef gate); - GateRef VisitSMOD(GateRef gate); - GateRef VisitUMOD(GateRef gate); - GateRef Int32Constant(int32_t val); - GateRef Int64Constant(size_t val); - RangeInfo GetRange(GateRef gate) const; - bool IsInt32Type(GateRef gate) const; - - bool IsConstant(GateRef gate) const + +#define DECLARE_VISIT_OP(name, valid) \ + GateRef Visit##name(GateRef gate); + + BINARY_OP_LIST(DECLARE_VISIT_OP) + UNARY_OP_LIST(DECLARE_VISIT_OP) +#undef DECLARE_VISIT_BINARY_OP + + GateRef UnaryInt32Calculate(GateRef gate, std::function op); + GateRef UnaryF64Calculate(GateRef gate, std::function op); + GateRef BinaryInt32Calculate(GateRef gate, std::function op); + GateRef BinaryF64Calculate(GateRef gate, std::function op); + + inline GateRef BoolConstant(bool val) + { + AddFoldingCount(); + GateRef result = builder_.Boolean(val); + return result; + } + + inline GateRef Int32Constant(int32_t val) + { + AddFoldingCount(); + GateRef result = builder_.Int32(val); + return result; + } + + inline GateRef Int64Constant(size_t val) + { + AddFoldingCount(); + GateRef result = builder_.Int64(val); + return result; + } + + inline GateRef DoubleConstant(double val) + { + AddFoldingCount(); + GateRef result = builder_.Double(val); + return result; + } + + inline bool IsBoolType(GateRef gate) const + { + return acc_.GetMachineType(gate) == MachineType::I1; + } + + inline bool IsInt32Type(GateRef gate) const + { + return acc_.GetMachineType(gate) == MachineType::I32; + } + + inline bool IsInt64Type(GateRef gate) const + { + return acc_.GetMachineType(gate) == MachineType::I64; + } + + inline bool IsF64Type(GateRef gate) const { - return acc_.GetOpCode(gate) == OpCode::CONSTANT; + return acc_.GetMachineType(gate) == MachineType::F64; } bool IsLogEnabled() const { return enableLog_; } + std::string GetMethodName() const { return methodName_; } + void AddFoldingCount() { ++foldingCount_; } + int32_t GetFoldingCount() const { return foldingCount_; } + Circuit* circuit_; GateAccessor acc_; CircuitBuilder builder_; diff --git a/ecmascript/compiler/gate_accessor.cpp b/ecmascript/compiler/gate_accessor.cpp index 0a231ef6df..add28ace58 100644 --- a/ecmascript/compiler/gate_accessor.cpp +++ b/ecmascript/compiler/gate_accessor.cpp @@ -1003,6 +1003,11 @@ void GateAccessor::GetAllGates(std::vector& gates) const circuit_->GetAllGates(gates); } +bool GateAccessor::IsBoolType(GateRef gate) const +{ + return GetMachineType(gate) == MachineType::I1; +} + bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const { return circuit_->IsInGateNull(gate, idx); diff --git a/ecmascript/compiler/gate_accessor.h b/ecmascript/compiler/gate_accessor.h index 21caa678e7..f07c1d2c6f 100644 --- a/ecmascript/compiler/gate_accessor.h +++ b/ecmascript/compiler/gate_accessor.h @@ -496,6 +496,7 @@ public: GateRef GetInitialEnvGate(GateRef depend, GateRef jsFunc) const; double GetFloat64FromConstant(GateRef gate) const; int GetInt32FromConstant(GateRef gate) const; + bool IsBoolType(GateRef gate) const; bool IsInGateNull(GateRef gate, size_t idx) const; bool IsSelector(GateRef g) const; bool IsSimpleState(GateRef g) const; diff --git a/ecmascript/compiler/lcr_opcodes.h b/ecmascript/compiler/lcr_opcodes.h index e171bd571c..32ba93aec1 100644 --- a/ecmascript/compiler/lcr_opcodes.h +++ b/ecmascript/compiler/lcr_opcodes.h @@ -35,7 +35,6 @@ namespace panda::ecmascript::kungfu { V(Lsl, LSL, GateFlags::NONE_FLAG, 0, 0, 2) \ V(Lsr, LSR, GateFlags::NONE_FLAG, 0, 0, 2) \ V(Asr, ASR, GateFlags::NONE_FLAG, 0, 0, 2) \ - V(Sqrt, SQRT, GateFlags::NO_WRITE, 0, 0, 1) \ V(Min, MIN, GateFlags::NO_WRITE, 0, 0, 2) \ V(Max, MAX, GateFlags::NO_WRITE, 0, 0, 2) \ V(AddWithOverflow, ADD_WITH_OVERFLOW, GateFlags::NONE_FLAG, 0, 0, 2) \ @@ -60,6 +59,7 @@ namespace panda::ecmascript::kungfu { V(TruncFloatToInt64, TRUNC_FLOAT_TO_INT64, GateFlags::NONE_FLAG, 0, 0, 1) \ V(TruncFloatToInt32, TRUNC_FLOAT_TO_INT32, GateFlags::NONE_FLAG, 0, 0, 1) \ V(Bitcast, BITCAST, GateFlags::NONE_FLAG, 0, 0, 1) \ + V(Sqrt, SQRT, GateFlags::NO_WRITE, 0, 0, 1) \ V(Abs, ABS, GateFlags::NO_WRITE, 0, 0, 1) \ V(Clz32, CLZ32, GateFlags::NONE_FLAG, 0, 0, 1) \ V(Ceil, CEIL, GateFlags::NO_WRITE, 0, 0, 1) \ diff --git a/ecmascript/compiler/mcr_lowering.cpp b/ecmascript/compiler/mcr_lowering.cpp index 9aa482bd09..5ac1ac9f6e 100644 --- a/ecmascript/compiler/mcr_lowering.cpp +++ b/ecmascript/compiler/mcr_lowering.cpp @@ -130,6 +130,7 @@ GateRef MCRLowering::VisitGate(GateRef gate) break; case OpCode::STRING_ADD: LowerStringAdd(gate); + break; default: break; } diff --git a/ecmascript/compiler/number_speculative_retype.cpp b/ecmascript/compiler/number_speculative_retype.cpp index 7661539334..d5f57fe625 100644 --- a/ecmascript/compiler/number_speculative_retype.cpp +++ b/ecmascript/compiler/number_speculative_retype.cpp @@ -819,6 +819,7 @@ GateRef NumberSpeculativeRetype::VisitIsTrueOrFalse(GateRef gate) } else if (paramType.IsBooleanType()) { valueType = GateType::BooleanType(); } + auto input = CheckAndConvertToBool(value, valueType); ResizeAndSetTypeInfo(input, TypeInfo::INT1); acc_.ReplaceValueIn(gate, input, 0); @@ -981,8 +982,40 @@ GateRef NumberSpeculativeRetype::VisitWithConstantValue(GateRef gate, size_t ign return Circuit::NullGate(); } +GateRef NumberSpeculativeRetype::TryConvertConstantToBool(GateRef gate) +{ + if (acc_.GetOpCode(gate) != OpCode::CONSTANT) { + return Circuit::NullGate(); + } + + if (acc_.GetGateType(gate).IsNJSValueType()) { + uint64_t rawValue = acc_.GetConstantValue(gate); + if (rawValue == 0) { + return builder_.Boolean(false); + } else { + return builder_.Boolean(true); + } + } + + JSTaggedValue value(acc_.GetConstantValue(gate)); + if (value.IsInt()) { + int32_t rawValue = value.GetInt(); + if (rawValue == 0) { + return builder_.Boolean(false); + } else { + return builder_.Boolean(true); + } + } + return Circuit::NullGate(); +} + GateRef NumberSpeculativeRetype::CheckAndConvertToBool(GateRef gate, GateType gateType) { + auto input = TryConvertConstantToBool(gate); + if (input != Circuit::NullGate()) { + return input; + } + TypeInfo output = GetOutputTypeInfo(gate); switch (output) { case TypeInfo::INT1: diff --git a/ecmascript/compiler/number_speculative_retype.h b/ecmascript/compiler/number_speculative_retype.h index 1128db6273..f792ec1833 100644 --- a/ecmascript/compiler/number_speculative_retype.h +++ b/ecmascript/compiler/number_speculative_retype.h @@ -160,6 +160,7 @@ private: GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType, ConvertToNumber convert = ConvertToNumber::BOOL_ONLY); GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType, ConvertToNumber convert); + GateRef TryConvertConstantToBool(GateRef gate); GateRef CheckAndConvertToBool(GateRef gate, GateType gateType); GateRef ConvertToTagged(GateRef gate); GateRef TryConvertConstant(GateRef gate, bool needInt32); -- Gitee