* 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_GATE_H
#define ECMASCRIPT_COMPILER_GATE_H
#include <array>
#include <iostream>
#include <map>
#include <optional>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/compiler/hcr_gate_meta_data.h"
#include "ecmascript/compiler/mcr_gate_meta_data.h"
#include "ecmascript/compiler/lcr_gate_meta_data.h"
#include "ecmascript/compiler/type.h"
#include "libpandabase/macros.h"
namespace panda::ecmascript::kungfu {
using BitField = uint64_t;
using GateRef = int32_t;
using GateId = uint32_t;
using GateOp = uint8_t;
using GateMark = uint8_t;
using TimeStamp = uint8_t;
using SecondaryOp = uint8_t;
using OutIdx = uint32_t;
class Gate;
class BytecodeCircuitBuilder;
enum MarkCode : GateMark {
NO_MARK = 0,
PREVISIT,
VISITED,
FINISHED,
};
class Out {
public:
Out() = default;
void SetNextOut(const Out *ptr);
[[nodiscard]] Out *GetNextOut();
[[nodiscard]] const Out *GetNextOutConst() const;
void SetPrevOut(const Out *ptr);
[[nodiscard]] Out *GetPrevOut();
[[nodiscard]] const Out *GetPrevOutConst() const;
void SetIndex(OutIdx idx);
[[nodiscard]] OutIdx GetIndex() const;
[[nodiscard]] Gate *GetGate();
[[nodiscard]] const Gate *GetGateConst() const;
void SetPrevOutNull();
[[nodiscard]] bool IsPrevOutNull() const;
void SetNextOutNull();
[[nodiscard]] bool IsNextOutNull() const;
[[nodiscard]] bool IsStateEdge() const;
~Out() = default;
private:
GateRef nextOut_;
GateRef prevOut_;
OutIdx idx_;
};
class In {
public:
In() = default;
void SetGate(const Gate *ptr);
[[nodiscard]] Gate *GetGate();
[[nodiscard]] const Gate *GetGateConst() const;
void SetGateNull();
[[nodiscard]] bool IsGateNull() const;
~In() = default;
private:
GateRef gatePtr_;
};
class Gate {
public:
Gate(const GateMetaData* meta, GateId id, Gate *inList[], MachineType machineType, GateType type);
static size_t GetGateSize(size_t numIns)
{
numIns = (numIns == 0) ? 1 : numIns;
return numIns * (sizeof(In) + sizeof(Out)) + sizeof(Gate);
}
static size_t GetOutListSize(size_t numIns)
{
numIns = (numIns == 0) ? 1 : numIns;
return numIns * sizeof(Out);
}
void NewIn(size_t idx, Gate *in);
void ModifyIn(size_t idx, Gate *in);
void DeleteIn(size_t idx);
void DeleteGate();
static constexpr GateRef InvalidGateRef = -1;
[[nodiscard]] Out *GetOut(size_t idx);
[[nodiscard]] Out *GetFirstOut();
[[nodiscard]] const Out *GetOutConst(size_t idx) const;
[[nodiscard]] const Out *GetFirstOutConst() const;
void SetFirstOut(const Out *firstOut);
void SetFirstOutNull();
[[nodiscard]] bool IsFirstOutNull() const;
[[nodiscard]] In *GetIn(size_t idx);
[[nodiscard]] const In *GetInConst(size_t idx) const;
[[nodiscard]] Gate *GetInGate(size_t idx);
[[nodiscard]] const Gate *GetInGateConst(size_t idx) const;
[[nodiscard]] bool IsInGateNull(size_t idx) const;
[[nodiscard]] OpCode GetOpCode() const;
[[nodiscard]] GateId GetId() const;
[[nodiscard]] size_t GetNumIns() const;
[[nodiscard]] size_t GetStateCount() const;
[[nodiscard]] size_t GetDependCount() const;
[[nodiscard]] size_t GetInValueCount() const;
[[nodiscard]] size_t GetInFrameStateCount() const;
[[nodiscard]] size_t GetInValueStarts() const;
[[nodiscard]] size_t GetRootCount() const;
[[nodiscard]] size_t GetInFrameStateStarts() const;
void Print(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1,
std::string_view comment = "") const;
std::string ToString(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1,
std::string_view comment = "") const;
void ShortPrint(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const;
size_t PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx,
std::ostringstream &log, bool isEnd = false) const;
void PrintGateWithAdditionOp(std::string additionOp, std::string_view comment) const;
void PrintWithBytecode(std::string_view comment) const;
void CheckNullInput() const;
void CheckStateInput() const;
void CheckValueInput(bool isArch64) const;
void CheckDependInput() const;
void CheckRootInput() const;
void CheckFrameStateInput() const;
void CheckStateOutput(const std::string& methodName) const;
std::string GetValueInAndOut(bool inListPreview = false, size_t highlightIdx = -1) const;
void CheckBranchOutput() const;
void CheckNOP() const;
void CheckSelector() const;
void CheckRelay() const;
void Verify(bool isArch64, const std::string& methodName) const;
[[nodiscard]] MarkCode GetMark(TimeStamp stamp) const;
void SetMark(MarkCode mark, TimeStamp stamp);
MachineType GetMachineType() const
{
return machineType_;
}
void SetMachineType(MachineType machineType)
{
machineType_ = machineType;
}
GateType GetGateType() const
{
return type_;
}
void SetGateType(GateType type)
{
type_ = type;
}
const GateMetaData* GetMetaData() const
{
return meta_;
}
const OneParameterMetaData* GetOneParameterMetaData() const
{
return OneParameterMetaData::Cast(meta_);
}
const StringMetaData* GetStringMetaData() const
{
ASSERT(meta_->IsStringType());
return static_cast<const StringMetaData*>(meta_);
}
const JSBytecodeMetaData* GetJSBytecodeMetaData() const
{
return JSBytecodeMetaData::Cast(meta_);
}
const BoolMetaData* GetBoolMetaData() const
{
return BoolMetaData::Cast(meta_);
}
const TypedCallMetaData* GetTypedCallMetaData() const
{
return TypedCallMetaData::Cast(meta_);
}
const NewConstructMetaData* GetNewConstructMetaData() const
{
return NewConstructMetaData::Cast(meta_);
}
std::string MachineTypeStr(MachineType machineType) const;
std::string GateTypeStr(GateType gateType) const;
~Gate() = default;
private:
friend class Circuit;
friend class GateAccessor;
void CheckInputOpcode(size_t idx, OpCode expected) const;
void CheckInputMachineType(size_t idx, MachineType expected, bool isArch64) const;
void CheckNotInputMachineType(size_t idx, MachineType notExpected) const;
void CheckState(size_t idx) const;
void CheckGeneralState(size_t idx) const;
void CheckFailed(std::string errorString, size_t highlightIdx) const;
void SetMetaData(const GateMetaData* meta)
{
meta_ = meta;
}
uint64_t TryGetValue() const
{
if (meta_->IsOneParameterKind()) {
return GetOneParameterMetaData()->GetValue();
}
return 0;
}
void DumpHeader(std::ostringstream &oss, const std::string& additionOp) const;
void DumpInputs(std::ostringstream &oss, bool inListPreview, size_t highlightIdx) const;
void DumpOutputs(std::ostringstream &oss, bool inListPreview) const;
std::string GetBytecodeStr() const;
const GateMetaData *meta_ { nullptr };
GateId id_ { 0 };
GateType type_ { GateType::Empty() };
MachineType machineType_ { MachineType::NOVALUE };
TimeStamp stamp_ { 0 };
MarkCode mark_ { MarkCode::NO_MARK };
uint8_t bitField_ { 0 };
GateRef firstOut_ { 0 };
};
}
#endif