arkcompiler_ets_runtime/ecmascript/compiler/circuit_builder-inl.h
zhangyinlu efdee45a09 [CIR]短路求值整改
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAMPAW
Description:1:短路求值整改,修改BoolAnd/BoolOr为LogicAnd/LogicOr;2:为降低性能影响,部分确定无问题的场景,依然使用BoolAnd类接口,并修改其名称为BitAnd

Signed-off-by: zhangyinlu <zhangyinlu@huawei.com>
Change-Id: Ia7dc6f73322dc7588213c6a4c1a14f87104bf378
2024-09-06 10:36:38 +08:00

265 lines
6.3 KiB
C++

/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H
#define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H
#include "ecmascript/compiler/lcr_circuit_builder.h"
#include "ecmascript/compiler/mcr_circuit_builder.h"
#include "ecmascript/compiler/hcr_circuit_builder.h"
#include "ecmascript/compiler/circuit_builder.h"
#include "ecmascript/mem/region.h"
#include "ecmascript/method.h"
namespace panda::ecmascript::kungfu {
// constant
GateRef CircuitBuilder::True()
{
return Boolean(true);
}
GateRef CircuitBuilder::False()
{
return Boolean(false);
}
GateRef CircuitBuilder::Undefined()
{
return UndefineConstant();
}
GateRef CircuitBuilder::Hole()
{
return HoleConstant();
}
GateRef CircuitBuilder::DoubleIsINF(GateRef x)
{
GateRef infinity = Double(base::POSITIVE_INFINITY);
GateRef negativeInfinity = Double(-base::POSITIVE_INFINITY);
GateRef diff1 = DoubleEqual(x, infinity);
GateRef diff2 = DoubleEqual(x, negativeInfinity);
return BitOr(diff1, diff2);
}
GateRef CircuitBuilder::DoubleIsNanOrInf(GateRef x)
{
return BitOr(DoubleIsNAN(x), DoubleIsINF(x));
}
// Js World
// cast operation
GateRef CircuitBuilder::GetGlobalConstantOffset(ConstantIndex index)
{
return PtrMul(IntPtr(sizeof(JSTaggedValue)), IntPtr(static_cast<int>(index)));
}
GateRef CircuitBuilder::GetExpectedNumOfArgs(GateRef method)
{
GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
return Int64And(
Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1));
}
int CircuitBuilder::NextVariableId()
{
return env_->NextVariableId();
}
void CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit)
{
BRANCH_CIR2(Equal(result, ExceptionConstant()), fail, success);
Bind(fail);
{
Jump(exit);
}
}
void CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal)
{
BRANCH_CIR2(Equal(result, exceptionVal), fail, success);
Bind(fail);
{
Jump(exit);
}
}
void CircuitBuilder::SubCfgEntry(Label *entry)
{
ASSERT(env_ != nullptr);
env_->SubCfgEntry(entry);
}
void CircuitBuilder::SubCfgExit()
{
ASSERT(env_ != nullptr);
env_->SubCfgExit();
}
GateRef CircuitBuilder::Return(GateRef value)
{
auto control = GetCurrentLabel()->GetControl();
auto depend = GetCurrentLabel()->GetDepend();
return Return(control, depend, value);
}
GateRef CircuitBuilder::Return()
{
auto control = GetCurrentLabel()->GetControl();
auto depend = GetCurrentLabel()->GetDepend();
return ReturnVoid(control, depend);
}
void CircuitBuilder::Bind(Label *label)
{
label->Bind();
env_->SetCurrentLabel(label);
}
void CircuitBuilder::Bind(Label *label, bool justSlowPath)
{
if (!justSlowPath) {
label->Bind();
env_->SetCurrentLabel(label);
}
}
GateRef CircuitBuilder::GetState() const
{
return GetCurrentLabel()->GetControl();
}
GateRef CircuitBuilder::GetDepend() const
{
return GetCurrentLabel()->GetDepend();
}
StateDepend CircuitBuilder::GetStateDepend() const
{
return StateDepend(GetState(), GetDepend());
}
void CircuitBuilder::SetDepend(GateRef depend)
{
GetCurrentLabel()->SetDepend(depend);
}
void CircuitBuilder::SetState(GateRef state)
{
GetCurrentLabel()->SetControl(state);
}
Label *CircuitBuilder::GetCurrentLabel() const
{
return GetCurrentEnvironment()->GetCurrentLabel();
}
LogicAndBuilder::LogicAndBuilder(Environment *env)
: env_(env), builder_(env_->GetBuilder())
{
subentry_ = new Label(env_);
builder_->SubCfgEntry(subentry_);
result_ = new Variable(env_, VariableType::BOOL(), builder_->NextVariableId(), builder_->False());
exit_ = new Label(env_);
}
LogicAndBuilder::~LogicAndBuilder()
{
ASSERT(exit_ != nullptr);
delete exit_;
exit_ = nullptr;
ASSERT(result_ != nullptr);
delete result_;
result_ = nullptr;
ASSERT(subentry_ != nullptr);
delete subentry_;
subentry_ = nullptr;
for (auto &label : labels_) {
ASSERT(label != nullptr);
delete label;
label = nullptr;
}
}
LogicAndBuilder &LogicAndBuilder::And(GateRef check)
{
auto checkTrue = new Label(env_);
labels_.push_back(checkTrue);
builder_->Branch(check, checkTrue, exit_);
builder_->Bind(checkTrue);
return *this;
}
GateRef LogicAndBuilder::Done()
{
*result_ = builder_->True();
builder_->Jump(exit_);
builder_->Bind(exit_);
auto ret = **result_;
builder_->SubCfgExit();
return ret;
}
LogicOrBuilder::LogicOrBuilder(Environment *env)
: env_(env), builder_(env_->GetBuilder())
{
subentry_ = new Label(env_);
builder_->SubCfgEntry(subentry_);
result_ = new Variable(env_, VariableType::BOOL(), builder_->NextVariableId(), builder_->True());
exit_ = new Label(env_);
}
LogicOrBuilder::~LogicOrBuilder()
{
ASSERT(exit_ != nullptr);
delete exit_;
exit_ = nullptr;
ASSERT(result_ != nullptr);
delete result_;
result_ = nullptr;
ASSERT(subentry_ != nullptr);
delete subentry_;
subentry_ = nullptr;
for (auto &label : labels_) {
ASSERT(label != nullptr);
delete label;
label = nullptr;
}
}
LogicOrBuilder &LogicOrBuilder::Or(GateRef check)
{
auto checkFalse = new Label(env_);
labels_.push_back(checkFalse);
builder_->Branch(check, exit_, checkFalse);
builder_->Bind(checkFalse);
return *this;
}
GateRef LogicOrBuilder::Done()
{
*result_ = builder_->False();
builder_->Jump(exit_);
builder_->Bind(exit_);
auto ret = **result_;
builder_->SubCfgExit();
return ret;
}
} // namespace panda::ecmascript::kungfu
#endif