arkcompiler_ets_runtime/ecmascript/compiler/share_gate_meta_data.cpp
liuzhijie f15f4fcb24 Optimize AOT NewObjRange
Issues: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9H3R6?from=project-issue
Signed-off-by: liuzhijie <liuzhijie9@huawei.com>

Change-Id: I6cfb557949befdd22343f3d9a5ed69bd9eb8a1fb
2024-04-28 11:07:38 +08:00

369 lines
14 KiB
C++

/*
* Copyright (c) 2023 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.
*/
#include "ecmascript/compiler/gate.h"
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/compiler/gate_meta_data_builder.h"
namespace panda::ecmascript::kungfu {
std::string GateMetaData::Str(OpCode opcode)
{
const std::map<OpCode, const char *> strMap = {
#define GATE_NAME_MAP(NAME, OP, R, S, D, V) { OpCode::OP, #OP },
IMMUTABLE_META_DATA_CACHE_LIST(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_BOOL(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_BOOL_VALUE_IN(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_SIZE(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_ONE_PARAMETER(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_PC_OFFSET(GATE_NAME_MAP)
GATE_META_DATA_LIST_FOR_CALL(GATE_NAME_MAP)
GATE_META_DATA_LIST_FOR_NEW(GATE_NAME_MAP)
GATE_META_DATA_LIST_WITH_PC_OFFSET_FIXED_VALUE(GATE_NAME_MAP)
#undef GATE_NAME_MAP
#define GATE_NAME_MAP(OP) { OpCode::OP, #OP },
GATE_OPCODE_LIST(GATE_NAME_MAP)
#undef GATE_NAME_MAP
};
if (strMap.count(opcode) > 0) {
return strMap.at(opcode);
}
return "OP-" + std::to_string(static_cast<uint8_t>(opcode));
}
bool GateMetaData::IsRoot() const
{
switch (opcode_) {
case OpCode::CIRCUIT_ROOT:
case OpCode::DEPEND_ENTRY:
case OpCode::ARG_LIST:
case OpCode::STATE_ENTRY:
case OpCode::RETURN_LIST:
return true;
default:
return false;
}
}
bool GateMetaData::IsProlog() const
{
return (opcode_ == OpCode::ARG || opcode_ == OpCode::INITVREG);
}
bool GateMetaData::IsFixed() const
{
switch (opcode_) {
case OpCode::VALUE_SELECTOR:
case OpCode::DEPEND_SELECTOR:
case OpCode::DEPEND_RELAY:
case OpCode::LOOP_EXIT_DEPEND:
case OpCode::LOOP_EXIT_VALUE:
return true;
default:
return false;
}
}
bool GateMetaData::IsSchedulable() const
{
ASSERT(!IsNop());
#ifndef NDEBUG
if (GetStateCount() == 0) {
ASSERT(!IsFixed());
}
#endif
return (!IsProlog()) && (!IsRoot()) && (GetStateCount() == 0);
}
bool GateMetaData::IsState() const
{
ASSERT(!IsNop());
#ifndef NDEBUG
if (GetStateCount() > 0) {
ASSERT(!IsProlog());
ASSERT(!IsRoot());
}
#endif
return (!IsVirtualState()) && (!IsFixed()) && (GetStateCount() > 0);
}
bool GateMetaData::IsGeneralState() const
{
switch (opcode_) {
case OpCode::IF_BRANCH:
case OpCode::SWITCH_BRANCH:
case OpCode::IF_TRUE:
case OpCode::IF_FALSE:
case OpCode::IF_SUCCESS:
case OpCode::IF_EXCEPTION:
case OpCode::SWITCH_CASE:
case OpCode::DEFAULT_CASE:
case OpCode::MERGE:
case OpCode::LOOP_BEGIN:
case OpCode::LOOP_BACK:
case OpCode::LOOP_EXIT:
case OpCode::ORDINARY_BLOCK:
case OpCode::STATE_ENTRY:
case OpCode::DEOPT_CHECK:
case OpCode::RETURN:
case OpCode::RETURN_VOID:
return true;
default:
return false;
}
}
bool GateMetaData::IsTerminalState() const
{
switch (opcode_) {
case OpCode::RETURN:
case OpCode::THROW:
case OpCode::RETURN_VOID:
case OpCode::GET_EXCEPTION:
case OpCode::STATE_SPLIT:
return true;
default:
return false;
}
}
bool GateMetaData::IsVirtualState() const
{
switch (opcode_) {
case OpCode::GET_EXCEPTION:
case OpCode::STATE_SPLIT:
return true;
default:
return false;
}
}
bool GateMetaData::IsCFGMerge() const
{
return (opcode_ == OpCode::MERGE) || (opcode_ == OpCode::LOOP_BEGIN);
}
bool GateMetaData::IsControlCase() const
{
ASSERT(HasFlag(GateFlags::CONTROL));
// should add relay
switch (opcode_) {
case OpCode::IF_BRANCH:
case OpCode::SWITCH_BRANCH:
case OpCode::IF_TRUE:
case OpCode::IF_FALSE:
case OpCode::SWITCH_CASE:
case OpCode::DEFAULT_CASE:
return true;
default:
return false;
}
}
bool GateMetaData::IsIfOrSwitchRelated() const
{
switch (opcode_) {
case OpCode::IF_TRUE:
case OpCode::IF_FALSE:
case OpCode::SWITCH_CASE:
case OpCode::DEFAULT_CASE:
case OpCode::IF_SUCCESS:
case OpCode::IF_EXCEPTION:
return true;
default:
return false;
}
}
bool GateMetaData::IsLoopHead() const
{
return (opcode_ == OpCode::LOOP_BEGIN);
}
bool GateMetaData::IsNop() const
{
return (opcode_ == OpCode::NOP || opcode_ == OpCode::DEAD);
}
bool GateMetaData::IsDead() const
{
return opcode_ == OpCode::DEAD;
}
bool GateMetaData::IsConstant() const
{
return (opcode_ == OpCode::CONSTANT);
}
bool GateMetaData::IsDependSelector() const
{
return (opcode_ == OpCode::DEPEND_SELECTOR);
}
GateMetaBuilder::GateMetaBuilder(Chunk* chunk)
: cache_(), chunk_(chunk) {}
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME() \
{ \
return &cache_.cached##NAME##_; \
}
IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(bool value) \
{ \
auto meta = new (chunk_) BoolMetaData(OpCode::OP, R, S, D, V, value); \
return meta; \
}
GATE_META_DATA_LIST_WITH_BOOL(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META_WITH_BOOL_VALUE_IN(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(size_t value, bool flag) \
{ \
auto meta = new (chunk_) BoolMetaData(OpCode::OP, R, S, D, V, flag); \
return meta; \
}
GATE_META_DATA_LIST_WITH_BOOL_VALUE_IN(DECLARE_GATE_META_WITH_BOOL_VALUE_IN)
#undef DECLARE_GATE_META_WITH_BOOL_VALUE_IN
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(size_t value) \
{ \
switch (value) { \
case GateMetaDataChache::ONE_VALUE: \
return &cache_.cached##NAME##1_; \
case GateMetaDataChache::TWO_VALUE: \
return &cache_.cached##NAME##2_; \
case GateMetaDataChache::THREE_VALUE: \
return &cache_.cached##NAME##3_; \
case GateMetaDataChache::FOUR_VALUE: \
return &cache_.cached##NAME##4_; \
case GateMetaDataChache::FIVE_VALUE: \
return &cache_.cached##NAME##5_; \
default: \
break; \
} \
auto meta = new (chunk_) GateMetaData(OpCode::OP, R, S, D, V); \
meta->SetKind(GateMetaData::Kind::MUTABLE_WITH_SIZE); \
return meta; \
}
GATE_META_DATA_LIST_WITH_SIZE(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t value) \
{ \
switch (value) { \
case GateMetaDataChache::ONE_VALUE: \
return &cache_.cached##NAME##1_; \
case GateMetaDataChache::TWO_VALUE: \
return &cache_.cached##NAME##2_; \
case GateMetaDataChache::THREE_VALUE: \
return &cache_.cached##NAME##3_; \
case GateMetaDataChache::FOUR_VALUE: \
return &cache_.cached##NAME##4_; \
case GateMetaDataChache::FIVE_VALUE: \
return &cache_.cached##NAME##5_; \
default: \
break; \
} \
auto meta = new (chunk_) OneParameterMetaData(OpCode::OP, R, S, D, V, value); \
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER); \
return meta; \
}
GATE_META_DATA_LIST_WITH_VALUE(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t value) \
{ \
auto meta = new (chunk_) OneParameterMetaData(OpCode::OP, R, S, D, V, value); \
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER); \
return meta; \
}
GATE_META_DATA_LIST_WITH_GATE_TYPE(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t value, uint64_t pcOffset) \
{ \
auto meta = new (chunk_) OneParameterMetaData(OpCode::OP, R, S, D, value, pcOffset); \
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER); \
return meta; \
}
GATE_META_DATA_LIST_WITH_PC_OFFSET(DECLARE_GATE_META)
#undef DECLARE_GATE_META
#define DECLARE_GATE_META_FOR_CALL(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t value, uint64_t pcOffset, bool noGC) \
{ \
auto meta = new (chunk_) TypedCallMetaData(OpCode::OP, R, S, D, value, pcOffset, noGC); \
meta->SetKind(GateMetaData::Kind::TYPED_CALL); \
return meta; \
}
GATE_META_DATA_LIST_FOR_CALL(DECLARE_GATE_META_FOR_CALL)
#undef DECLARE_GATE_META_FOR_CALL
#define DECLARE_GATE_META_FOR_NEW(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t value, uint64_t pcOffset, \
bool isFastCall) \
{ \
auto meta = new (chunk_) NewConstructMetaData(OpCode::OP, R, S, D, value, \
pcOffset, isFastCall); \
meta->SetKind(GateMetaData::Kind::CALL_NEW); \
return meta; \
}
GATE_META_DATA_LIST_FOR_NEW(DECLARE_GATE_META_FOR_NEW)
#undef DECLARE_GATE_META_FOR_NEW
#define DECLARE_GATE_META(NAME, OP, R, S, D, V) \
const GateMetaData* GateMetaBuilder::NAME(uint64_t pcOffset) const \
{ \
auto meta = new (chunk_) OneParameterMetaData(OpCode::OP, R, S, D, V, pcOffset); \
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER); \
return meta; \
}
GATE_META_DATA_LIST_WITH_PC_OFFSET_FIXED_VALUE(DECLARE_GATE_META)
#undef DECLARE_GATE_META
const GateMetaData* GateMetaBuilder::Arg(uint64_t value)
{
switch (value) {
#define DECLARE_CACHED_VALUE_CASE(VALUE) \
case VALUE: { \
return &cache_.cachedArg##VALUE##_; \
}
CACHED_ARG_LIST(DECLARE_CACHED_VALUE_CASE)
#undef DECLARE_CACHED_VALUE_CASE
default:
break;
}
auto meta = new (chunk_) OneParameterMetaData(OpCode::ARG, GateFlags::HAS_ROOT, 0, 0, 0, value);
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER);
return meta;
}
const GateMetaData* GateMetaBuilder::InitVreg(uint64_t value)
{
auto meta = new (chunk_) OneParameterMetaData(OpCode::INITVREG, GateFlags::HAS_ROOT, 0, 0, 0, value);
meta->SetKind(GateMetaData::Kind::MUTABLE_ONE_PARAMETER);
return meta;
}
} // namespace panda::ecmascript::kungfu