!267 js bytecode to CFG

Merge pull request !267 from wanyanglan/master
This commit is contained in:
openharmony_ci 2022-01-26 08:27:57 +00:00 committed by Gitee
commit 6e5d6b8739
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
31 changed files with 3913 additions and 1219 deletions

View File

@ -32,6 +32,7 @@ group("ark_js_host_linux_tools_packages") {
if (is_standard_system) {
deps += [
"//ark/js_runtime/ecmascript/compiler:ark_stub_opt(${host_toolchain})",
"//ark/js_runtime/ecmascript/compiler:ark_ts_aot(${host_toolchain})",
]
}
}

View File

@ -23,6 +23,7 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_DEBUG_MODE 0
#define ECMASCRIPT_ENABLE_ARK_CONTAINER 0
#define ECMASCRIPT_ENABLE_RUNTIME_STAT 1 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ECMASCRIPT_ENABLE_TS_AOT_PRINT 1
/*
* 1. close ic

View File

@ -45,11 +45,20 @@ JSHandle<Program> PandaFileTranslator::TranslatePandaFile(EcmaVM *vm, const pand
const CString &methodName)
{
PandaFileTranslator translator(vm);
translator.TranslateClasses(pf, methodName);
std::vector<BytecodeTranslationInfo> infoList {};
translator.TranslateClasses(pf, methodName, infoList);
auto result = translator.GenerateProgram(pf);
return JSHandle<Program>(translator.thread_, result);
}
void PandaFileTranslator::TranslateAndCollectPandaFile(EcmaVM *vm, const panda_file::File &pf,
const CString &methodName,
std::vector<BytecodeTranslationInfo> &infoList)
{
PandaFileTranslator translator(vm);
translator.TranslateClasses(pf, methodName, infoList);
}
template<class T, class... Args>
static T *InitializeMemory(T *mem, Args... args)
{
@ -67,7 +76,8 @@ const JSMethod *PandaFileTranslator::FindMethods(uint32_t offset) const
return nullptr;
}
void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const CString &methodName)
void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const CString &methodName,
std::vector<BytecodeTranslationInfo> &infoList)
{
RegionFactory *factory = ecmaVm_->GetRegionFactory();
Span<const uint32_t> classIndexes = pf.GetClasses();
@ -94,7 +104,7 @@ void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const CSt
continue;
}
panda_file::ClassDataAccessor cda(pf, classId);
cda.EnumerateMethods([this, &sd, &methods, &methodIdx, &pf](panda_file::MethodDataAccessor &mda) {
cda.EnumerateMethods([this, &sd, &methods, &methodIdx, &pf, &infoList](panda_file::MethodDataAccessor &mda) {
auto codeId = mda.GetCodeId();
ASSERT(codeId.has_value());
@ -114,7 +124,7 @@ void PandaFileTranslator::TranslateClasses(const panda_file::File &pf, const CSt
const uint8_t *insns = codeDataAccessor.GetInstructions();
if (this->translated_code_.find(insns) == this->translated_code_.end()) {
this->translated_code_.insert(insns);
this->TranslateBytecode(codeSize, insns, pf, method);
this->TranslateBytecode(codeSize, insns, pf, method, infoList);
}
});
}
@ -466,10 +476,12 @@ void PandaFileTranslator::FixInstructionId32(const BytecodeInstruction &inst, [[
}
void PandaFileTranslator::TranslateBytecode(uint32_t insSz, const uint8_t *insArr, const panda_file::File &pf,
const JSMethod *method)
const JSMethod *method, std::vector<BytecodeTranslationInfo> &infoList)
{
auto bcIns = BytecodeInstruction(insArr);
auto bcInsLast = bcIns.JumpTo(insSz);
infoList.push_back(BytecodeTranslationInfo{{}, &pf, method});
auto &pcArray = infoList.back().pcArray;
while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
if (bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) &&
@ -535,6 +547,12 @@ void PandaFileTranslator::TranslateBytecode(uint32_t insSz, const uint8_t *insAr
bcIns = bcIns.GetNext();
FixOpcode(pc);
UpdateICOffset(const_cast<JSMethod *>(method), pc);
if (ecmaVm_->GetJSOptions().IsEnableTsAot()) {
pcArray.emplace_back(pc);
}
}
if (ecmaVm_->GetJSOptions().IsEnableTsAot()) {
pcArray.emplace_back(const_cast<uint8_t *>(bcInsLast.GetAddress()));
}
}

View File

@ -24,6 +24,12 @@
#include "utils/bit_field.h"
namespace panda::ecmascript {
struct BytecodeTranslationInfo {
std::vector<uint8_t *> pcArray {};
const panda_file::File *file {nullptr};
const JSMethod *method {nullptr};
};
class JSThread;
class Program;
@ -37,6 +43,8 @@ public:
NO_MOVE_SEMANTIC(PandaFileTranslator);
static JSHandle<Program> TranslatePandaFile(EcmaVM *vm, const panda_file::File &pf,
const CString &methodName);
static void TranslateAndCollectPandaFile(EcmaVM *vm, const panda_file::File &pf, const CString &methodName,
std::vector<BytecodeTranslationInfo> &infoList);
JSHandle<JSFunction> DefineMethodInLiteral(JSThread *thread, uint32_t methodId, FunctionKind kind,
uint16_t length) const;
@ -92,8 +100,10 @@ private:
uint32_t GetOrInsertConstantPool(ConstPoolType type, uint32_t offset);
const JSMethod *FindMethods(uint32_t offset) const;
Program *GenerateProgram(const panda_file::File &pf);
void TranslateClasses(const panda_file::File &pf, const CString &methodName);
void TranslateBytecode(uint32_t insSz, const uint8_t *insArr, const panda_file::File &pf, const JSMethod *method);
void TranslateClasses(const panda_file::File &pf, const CString &methodName,
std::vector<BytecodeTranslationInfo> &infoList);
void TranslateBytecode(uint32_t insSz, const uint8_t *insArr, const panda_file::File &pf, const JSMethod *method,
std::vector<BytecodeTranslationInfo> &infoList);
void FixInstructionId32(const BytecodeInstruction &inst, uint32_t index, uint32_t fixOrder = 0) const;
void FixOpcode(uint8_t *pc) const;
void UpdateICOffset(JSMethod *method, uint8_t *pc) const;

View File

@ -41,6 +41,7 @@ config("ark_jsruntime_compiler_config") {
source_set("libark_jsoptimizer_static") {
sources = [
"bytecode_circuit_builder.cpp",
"circuit.cpp",
"circuit_builder.cpp",
"circuit_builder_helper.cpp",
@ -214,3 +215,30 @@ ohos_executable("ark_stub_opt") {
output_name = "ark_stub_opt"
subsystem_name = "ark"
}
ohos_executable("ark_ts_aot") {
sources = [ "ts_aot_compiler.cpp" ]
configs = [
":include_llvm",
":ark_jsruntime_compiler_config",
"//ark/js_runtime:ark_jsruntime_public_config",
"$ark_root/runtime:arkruntime_public_config",
]
deps = [
"$ark_root/libpandabase:libarkbase",
"//ark/js_runtime:libark_jsruntime",
"//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer",
]
if (!is_standard_system) {
deps += [ "$ark_root/runtime:libarkruntime" ]
}
part_name = "ark_js_runtime"
install_enable = false
output_name = "ark_ts_aot"
subsystem_name = "ark"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,183 @@
/*
* 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_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
#define ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
#include <numeric>
#include <tuple>
#include <utility>
#include <vector>
#include "circuit.h"
#include "ecmascript/interpreter/interpreter-inl.h"
#include "ecmascript/js_method.h"
namespace panda::ecmascript::kungfu {
using VRegIDType = uint16_t;
enum class SplitKind : uint8_t {
DEFAULT,
START,
END
};
struct CfgInfo {
uint8_t *pc {nullptr};
SplitKind splitKind {SplitKind::DEFAULT};
std::vector<uint8_t *> succs {};
CfgInfo(uint8_t *startOrEndPc, SplitKind kind, std::vector<uint8_t *> successors)
: pc(startOrEndPc), splitKind(kind), succs(successors) {};
bool operator<(const CfgInfo &rhs) const
{
if (this->pc != rhs.pc) {
return this->pc < rhs.pc;
} else {
return this->splitKind < rhs.splitKind;
}
}
bool operator==(const CfgInfo &rhs) const
{
return this->pc == rhs.pc && this->splitKind == rhs.splitKind;
}
};
struct BytecodeRegion {
int32_t id {-1};
uint8_t *start {nullptr};
uint8_t *end {nullptr};
std::vector<BytecodeRegion *> preds {}; // List of predessesor blocks
std::vector<BytecodeRegion *> succs {}; // List of successors blocks
std::vector<BytecodeRegion *> trys {}; // List of trys blocks
std::vector<BytecodeRegion *> catchs {}; // List of catches blocks
std::vector<BytecodeRegion *> immDomBlocks {}; // List of dominated blocks
BytecodeRegion *iDominator {nullptr}; // Block that dominates the current block
std::vector<BytecodeRegion *> domFrontiers {}; // List of dominace frontiers
bool isDead {false};
std::set<uint16_t> phi {}; // phi node
bool phiAcc {false};
int32_t numOfStatePreds {0};
int32_t statePredIndex {0};
std::vector<std::tuple<size_t, uint8_t *, bool>> expandedPreds {};
kungfu::GateRef stateStart {kungfu::Circuit::NullGate()};
kungfu::GateRef dependStart {kungfu::Circuit::NullGate()};
std::map<uint16_t, kungfu::GateRef> vregToValSelectorGate {}; // corresponding ValueSelector gates of vregs
kungfu::GateRef valueSelectorAccGate {kungfu::Circuit::NullGate()};
bool operator <(const BytecodeRegion &target) const
{
return id < target.id;
}
};
struct BytecodeInfo {
std::vector<VRegIDType> vregIn {}; // read register
std::vector<VRegIDType> vregOut {}; // write register
bool accIn {false}; // read acc
bool accOut {false}; // write acc
uint8_t opcode {0};
uint16_t offset {0};
};
struct BytecodeGraph {
std::vector<BytecodeRegion> graph {};
const JSMethod *method;
};
enum BytecodeOffset {
ONE = 1,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
TEN
};
class BytecodeCircuitBuilder {
public:
explicit BytecodeCircuitBuilder() = default;
~BytecodeCircuitBuilder() = default;
NO_COPY_SEMANTIC(BytecodeCircuitBuilder);
NO_MOVE_SEMANTIC(BytecodeCircuitBuilder);
void PUBLIC_API BytecodeToCircuit(const std::vector<uint8_t *> &pcArray, const panda_file::File &pf,
const JSMethod *method);
[[nodiscard]] kungfu::Circuit GetCircuit() const
{
return circuit_;
}
[[nodiscard]] std::map<kungfu::GateRef, std::pair<size_t, uint8_t *>> GetGateToBytecode() const
{
return jsgateToBytecode_;
}
[[nodiscard]] std::map<uint8_t *, kungfu::GateRef> GetBytecodeToGate() const
{
return byteCodeToJSGate_;
}
[[nodiscard]] std::string GetBytecodeStr(kungfu::GateRef gate) const
{
auto pc = jsgateToBytecode_.at(gate).second;
return GetEcmaOpcodeStr(static_cast<EcmaOpcode>(*pc));
}
private:
void PUBLIC_API CollectBytecodeBlockInfo(uint8_t* pc, std::vector<CfgInfo> &bytecodeBlockInfos);
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> CollectTryCatchBlockInfo(
const panda_file::File &file, const JSMethod *method, std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc,
std::vector<CfgInfo> &bytecodeBlockInfos);
void CompleteBytecodeBlockInfo(std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc,
std::vector<CfgInfo> &bytecodeBlockInfos);
void BuildBasicBlocks(const JSMethod *method,
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> &exception,
std::vector<CfgInfo> &bytecodeBlockInfo,
std::map<uint8_t *, uint8_t*> &byteCodeCurPrePc);
void ComputeDominatorTree(BytecodeGraph &byteCodeGraph);
void BuildImmediateDominator(std::vector<size_t> &immDom, BytecodeGraph &byteCodeGraph);
void ComputeDomFrontiers(std::vector<size_t> &immDom, BytecodeGraph &byteCodeGraph);
BytecodeInfo GetBytecodeInfo(uint8_t *pc);
void RemoveDeadRegions(const std::map<size_t, size_t> &dfsTimestamp, BytecodeGraph &byteCodeGraph);
void InsertPhi(BytecodeGraph &byteCodeGraph);
void UpdateCFG(BytecodeGraph &byteCodeGraph);
void BuildCircuit(BytecodeGraph &byteCodeGraph);
void PrintCollectBlockInfo(std::vector<CfgInfo> &bytecodeBlockInfos);
void PrintGraph(std::vector<BytecodeRegion> &graph);
void PrintBytecodeInfo(std::vector<BytecodeRegion> &graph);
void PrintBBInfo(std::vector<BytecodeRegion> &graph);
static bool IsJump(EcmaOpcode opcode);
static bool IsCondJump(EcmaOpcode opcode);
static bool IsMov(EcmaOpcode opcode);
static bool IsReturn(EcmaOpcode opcode);
static bool IsThrow(EcmaOpcode opcode);
static bool IsGeneral(EcmaOpcode opcode);
kungfu::Circuit circuit_;
std::map<kungfu::GateRef, std::pair<size_t, uint8_t *>> jsgateToBytecode_;
std::map<uint8_t *, kungfu::GateRef> byteCodeToJSGate_;
std::map<int32_t, BytecodeRegion *> bbIdToBasicBlock_;
};
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H

View File

@ -15,50 +15,51 @@
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/compiler_macros.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
namespace panda::ecmascript::kungfu {
Circuit::Circuit() : space({}), circuitSize(0), gateCounter(0), time(1), dataSection({})
Circuit::Circuit() : space_(), circuitSize_(0), gateCount_(0), time_(1), dataSection_()
{
this->NewGate(OpCode(OpCode::CIRCUIT_ROOT), 0, {}, TypeCode::NOTYPE); // circuit root
NewGate(OpCode(OpCode::CIRCUIT_ROOT), 0, {}, TypeCode::NOTYPE); // circuit root
auto circuitRoot = Circuit::GetCircuitRoot(OpCode(OpCode::CIRCUIT_ROOT));
this->NewGate(OpCode(OpCode::STATE_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::DEPEND_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::FRAMESTATE_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::RETURN_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::THROW_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::CONSTANT_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::ALLOCA_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
this->NewGate(OpCode(OpCode::ARG_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::STATE_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::DEPEND_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::FRAMESTATE_ENTRY), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::RETURN_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::THROW_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::CONSTANT_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::ALLOCA_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
NewGate(OpCode(OpCode::ARG_LIST), 0, {circuitRoot}, TypeCode::NOTYPE);
}
uint8_t *Circuit::AllocateSpace(size_t gateSize)
{
this->circuitSize += gateSize;
if (UNLIKELY(this->GetSpaceDataSize() == 0)) {
this->SetSpaceDataSize(INITIAL_SPACE);
circuitSize_ += gateSize;
if (UNLIKELY(GetSpaceDataSize() == 0)) {
SetSpaceDataSize(INITIAL_SPACE);
}
while (UNLIKELY(this->GetSpaceDataSize() < this->circuitSize)) {
this->SetSpaceDataSize(this->GetSpaceDataSize() * SCALE_RATE);
while (UNLIKELY(GetSpaceDataSize() < circuitSize_)) {
SetSpaceDataSize(GetSpaceDataSize() * SCALE_RATE);
}
if (UNLIKELY(this->GetSpaceDataSize() > MAX_SPACE)) {
if (UNLIKELY(GetSpaceDataSize() > MAX_SPACE)) {
return nullptr; // abort compilation
}
if (UNLIKELY(this->GetSpaceDataStartPtrConst() == nullptr)) {
if (UNLIKELY(GetSpaceDataStartPtrConst() == nullptr)) {
return nullptr; // abort compilation
}
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return this->GetDataPtr(this->circuitSize - gateSize);
return GetDataPtr(circuitSize_ - gateSize);
}
Gate *Circuit::AllocateGateSpace(size_t numIns)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return reinterpret_cast<Gate *>(this->AllocateSpace(Gate::GetGateSize(numIns)) + Gate::GetOutListSize(numIns));
return reinterpret_cast<Gate *>(AllocateSpace(Gate::GetGateSize(numIns)) + Gate::GetOutListSize(numIns));
}
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
GateRef Circuit::NewGate(
OpCode opcode, BitField bitfield, size_t numIns, const GateRef inList[], TypeCode type, MarkCode mark)
GateRef Circuit::NewGate(OpCode opcode, ValueCode bitValue, BitField bitfield, size_t numIns, const GateRef inList[],
TypeCode type, MarkCode mark)
{
#ifndef NDEBUG
if (numIns != opcode.GetOpCodeNumIns(bitfield)) {
@ -70,30 +71,74 @@ GateRef Circuit::NewGate(
}
#endif
std::vector<Gate *> inPtrList(numIns);
auto gateSpace = this->AllocateGateSpace(numIns);
auto gateSpace = AllocateGateSpace(numIns);
for (size_t idx = 0; idx < numIns; idx++) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
inPtrList[idx] = (inList[idx] == Circuit::NullGate()) ? nullptr : this->LoadGatePtr(inList[idx]);
inPtrList[idx] = (inList[idx] == Circuit::NullGate()) ? nullptr : LoadGatePtr(inList[idx]);
}
auto newGate = new (gateSpace) Gate(this->gateCounter, opcode, bitfield, inPtrList.data(), type, mark);
this->gateCounter++;
return this->SaveGatePtr(newGate);
ASSERT(opcode.GetValueCode() == ValueCode::FLEX);
auto newGate = new (gateSpace) Gate(gateCount_, opcode, bitValue, bitfield, inPtrList.data(), type, mark);
gateCount_++;
return SaveGatePtr(newGate);
}
GateRef Circuit::NewGate(
OpCode opcode, BitField bitfield, const std::vector<GateRef> &inList, TypeCode type, MarkCode mark)
GateRef Circuit::NewGate(OpCode opcode, ValueCode bitValue, BitField bitfield, const std::vector<GateRef> &inList,
TypeCode type, MarkCode mark)
{
return this->NewGate(opcode, bitfield, inList.size(), inList.data(), type, mark);
return NewGate(opcode, bitValue, bitfield, inList.size(), inList.data(), type, mark);
}
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
GateRef Circuit::NewGate(OpCode opcode, BitField bitfield, size_t numIns, const GateRef inList[], TypeCode type,
MarkCode mark)
{
#ifndef NDEBUG
if (numIns != opcode.GetOpCodeNumIns(bitfield)) {
std::cerr << "Invalid input list!"
<< " op=" << opcode.Str() << " bitfield=" << bitfield
<< " expected_num_in=" << opcode.GetOpCodeNumIns(bitfield) << " actual_num_in=" << numIns
<< std::endl;
UNREACHABLE();
}
#endif
std::vector<Gate *> inPtrList(numIns);
auto gateSpace = AllocateGateSpace(numIns);
for (size_t idx = 0; idx < numIns; idx++) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
inPtrList[idx] = (inList[idx] == Circuit::NullGate()) ? nullptr : LoadGatePtr(inList[idx]);
}
ASSERT(opcode.GetValueCode() != ValueCode::FLEX);
auto newGate = new (gateSpace) Gate(gateCount_, opcode, opcode.GetValueCode(), bitfield, inPtrList.data(), type,
mark);
gateCount_++;
return SaveGatePtr(newGate);
}
GateRef Circuit::NewGate(OpCode opcode, BitField bitfield, const std::vector<GateRef> &inList, TypeCode type,
MarkCode mark)
{
return NewGate(opcode, bitfield, inList.size(), inList.data(), type, mark);
}
void Circuit::PrintAllGates() const
{
#if ECMASCRIPT_ENABLE_COMPILER_LOG
const auto &gateList = this->GetAllGates();
for (auto &gate : gateList) {
this->LoadGatePtrConst(gate)->Print();
const auto &gateList = GetAllGates();
for (const auto &gate : gateList) {
LoadGatePtrConst(gate)->Print();
}
}
void Circuit::PrintAllGates(BytecodeCircuitBuilder &builder) const
{
const auto &gateList = GetAllGates();
for (const auto &gate : gateList) {
if (LoadGatePtrConst(gate)->GetOpCode() == OpCode::JS_BYTECODE) {
auto bytecodeStr = builder.GetBytecodeStr(gate);
LoadGatePtrConst(gate)->PrintByteCode(bytecodeStr);
} else {
LoadGatePtrConst(gate)->Print();
}
}
#endif
}
std::vector<GateRef> Circuit::GetAllGates() const
@ -101,12 +146,10 @@ std::vector<GateRef> Circuit::GetAllGates() const
std::vector<GateRef> gateList;
gateList.push_back(0);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
for (size_t out = sizeof(Gate); out < this->circuitSize;
out += Gate::GetGateSize(
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
reinterpret_cast<const Out *>(this->LoadGatePtrConst(GateRef(out)))->GetIndex() + 1)) {
gateList.push_back(
this->SaveGatePtr(reinterpret_cast<const Out *>(this->LoadGatePtrConst(GateRef(out)))->GetGateConst()));
for (size_t out = sizeof(Gate); out < circuitSize_;
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
out += Gate::GetGateSize(reinterpret_cast<const Out *>(LoadGatePtrConst(GateRef(out)))->GetIndex() + 1)) {
gateList.push_back(SaveGatePtr(reinterpret_cast<const Out *>(LoadGatePtrConst(GateRef(out)))->GetGateConst()));
}
return gateList;
}
@ -114,19 +157,19 @@ std::vector<GateRef> Circuit::GetAllGates() const
GateRef Circuit::SaveGatePtr(const Gate *gate) const
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return static_cast<GateRef>(reinterpret_cast<const uint8_t *>(gate) - this->GetDataPtrConst(0));
return static_cast<GateRef>(reinterpret_cast<const uint8_t *>(gate) - GetDataPtrConst(0));
}
Gate *Circuit::LoadGatePtr(GateRef shift)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return reinterpret_cast<Gate *>(this->GetDataPtr(shift));
return reinterpret_cast<Gate *>(GetDataPtr(shift));
}
const Gate *Circuit::LoadGatePtrConst(GateRef shift) const
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return reinterpret_cast<const Gate *>(this->GetDataPtrConst(shift));
return reinterpret_cast<const Gate *>(GetDataPtrConst(shift));
}
GateRef Circuit::GetCircuitRoot(OpCode opcode)
@ -159,40 +202,40 @@ Circuit::~Circuit() {}
void Circuit::AdvanceTime() const
{
auto &time = const_cast<TimeStamp &>(this->time);
time++;
if (time == 0) {
time = 1;
this->ResetAllGateTimeStamps();
auto &curTime = const_cast<TimeStamp &>(time_);
curTime++;
if (curTime == 0) {
curTime = 1;
ResetAllGateTimeStamps();
}
}
void Circuit::ResetAllGateTimeStamps() const
{
const auto &gateList = this->GetAllGates();
const auto &gateList = GetAllGates();
for (auto &gate : gateList) {
const_cast<Gate *>(this->LoadGatePtrConst(gate))->SetMark(MarkCode::EMPTY, 0);
const_cast<Gate *>(LoadGatePtrConst(gate))->SetMark(MarkCode::EMPTY, 0);
}
}
TimeStamp Circuit::GetTime() const
{
return this->time;
return time_;
}
MarkCode Circuit::GetMark(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->GetMark(this->GetTime());
return LoadGatePtrConst(gate)->GetMark(GetTime());
}
void Circuit::SetMark(GateRef gate, MarkCode mark) const
{
const_cast<Gate *>(this->LoadGatePtrConst(gate))->SetMark(mark, this->GetTime());
const_cast<Gate *>(LoadGatePtrConst(gate))->SetMark(mark, GetTime());
}
bool Circuit::Verify(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->Verify();
return LoadGatePtrConst(gate)->Verify();
}
GateRef Circuit::NullGate()
@ -203,7 +246,7 @@ GateRef Circuit::NullGate()
bool Circuit::IsLoopHead(GateRef gate) const
{
if (gate != NullGate()) {
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
return curGate->GetOpCode().IsLoopHead();
}
return false;
@ -212,7 +255,7 @@ bool Circuit::IsLoopHead(GateRef gate) const
bool Circuit::IsControlCase(GateRef gate) const
{
if (gate != NullGate()) {
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
return curGate->GetOpCode().IsControlCase();
}
return false;
@ -221,9 +264,8 @@ bool Circuit::IsControlCase(GateRef gate) const
bool Circuit::IsSelector(GateRef gate) const
{
if (gate != NullGate()) {
const Gate *curGate = this->LoadGatePtrConst(gate);
return curGate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS &&
curGate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64;
const Gate *curGate = LoadGatePtrConst(gate);
return curGate->GetOpCode() == OpCode::VALUE_SELECTOR;
}
return false;
}
@ -231,41 +273,42 @@ bool Circuit::IsSelector(GateRef gate) const
std::vector<GateRef> Circuit::GetInVector(GateRef gate) const
{
std::vector<GateRef> result;
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
result.push_back(this->SaveGatePtr(curGate->GetInGateConst(idx)));
result.push_back(SaveGatePtr(curGate->GetInGateConst(idx)));
}
return result;
}
GateRef Circuit::GetIn(GateRef gate, size_t idx) const
{
const Gate *curGate = this->LoadGatePtrConst(gate);
return this->SaveGatePtr(curGate->GetInGateConst(idx));
ASSERT(idx < LoadGatePtrConst(gate)->GetNumIns());
const Gate *curGate = LoadGatePtrConst(gate);
return SaveGatePtr(curGate->GetInGateConst(idx));
}
bool Circuit::IsInGateNull(GateRef gate, size_t idx) const
{
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
return curGate->GetInConst(idx)->IsGateNull();
}
bool Circuit::IsFirstOutNull(GateRef gate) const
{
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
return curGate->IsFirstOutNull();
}
std::vector<GateRef> Circuit::GetOutVector(GateRef gate) const
{
std::vector<GateRef> result;
const Gate *curGate = this->LoadGatePtrConst(gate);
const Gate *curGate = LoadGatePtrConst(gate);
if (!curGate->IsFirstOutNull()) {
const Out *curOut = curGate->GetFirstOutConst();
result.push_back(this->SaveGatePtr(curOut->GetGateConst()));
result.push_back(SaveGatePtr(curOut->GetGateConst()));
while (!curOut->IsNextOutNull()) {
curOut = curOut->GetNextOutConst();
result.push_back(this->SaveGatePtr(curOut->GetGateConst()));
result.push_back(SaveGatePtr(curOut->GetGateConst()));
}
}
return result;
@ -273,115 +316,130 @@ std::vector<GateRef> Circuit::GetOutVector(GateRef gate) const
void Circuit::NewIn(GateRef gate, size_t idx, GateRef in)
{
this->LoadGatePtr(gate)->NewIn(idx, this->LoadGatePtr(in));
#ifndef NDEBUG
ASSERT(idx < LoadGatePtrConst(gate)->GetNumIns());
ASSERT(Circuit::IsInGateNull(gate, idx));
#endif
LoadGatePtr(gate)->NewIn(idx, LoadGatePtr(in));
}
void Circuit::ModifyIn(GateRef gate, size_t idx, GateRef in)
{
this->LoadGatePtr(gate)->ModifyIn(idx, this->LoadGatePtr(in));
#ifndef NDEBUG
ASSERT(idx < LoadGatePtrConst(gate)->GetNumIns());
ASSERT(!Circuit::IsInGateNull(gate, idx));
#endif
LoadGatePtr(gate)->ModifyIn(idx, LoadGatePtr(in));
}
void Circuit::DeleteIn(GateRef gate, size_t idx)
{
this->LoadGatePtr(gate)->DeleteIn(idx);
ASSERT(idx < LoadGatePtrConst(gate)->GetNumIns());
ASSERT(!Circuit::IsInGateNull(gate, idx));
LoadGatePtr(gate)->DeleteIn(idx);
}
void Circuit::DeleteGate(GateRef gate)
{
this->LoadGatePtr(gate)->DeleteGate();
LoadGatePtr(gate)->DeleteGate();
}
void Circuit::SetOpCode(GateRef gate, OpCode opcode)
{
this->LoadGatePtr(gate)->SetOpCode(opcode);
LoadGatePtr(gate)->SetOpCode(opcode);
}
void Circuit::SetTypeCode(GateRef gate, TypeCode type)
{
this->LoadGatePtr(gate)->SetTypeCode(type);
LoadGatePtr(gate)->SetTypeCode(type);
}
void Circuit::SetValueCode(GateRef gate, ValueCode valCode)
{
LoadGatePtr(gate)->SetValueCode(valCode);
}
TypeCode Circuit::GetTypeCode(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->GetTypeCode();
return LoadGatePtrConst(gate)->GetTypeCode();
}
OpCode Circuit::GetOpCode(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->GetOpCode();
return LoadGatePtrConst(gate)->GetOpCode();
}
GateId Circuit::GetId(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->GetId();
return LoadGatePtrConst(gate)->GetId();
}
BitField Circuit::GetBitField(GateRef gate) const
{
return this->LoadGatePtrConst(gate)->GetBitField();
return LoadGatePtrConst(gate)->GetBitField();
}
void Circuit::Print(GateRef gate) const
{
this->LoadGatePtrConst(gate)->Print();
LoadGatePtrConst(gate)->Print();
}
std::vector<uint8_t> Circuit::GetDataSection() const
{
return this->dataSection;
return dataSection_;
}
void Circuit::SetDataSection(const std::vector<uint8_t> &data)
{
this->dataSection = data;
dataSection_ = data;
}
size_t Circuit::GetCircuitDataSize() const
{
return this->circuitSize;
return circuitSize_;
}
const void *Circuit::GetSpaceDataStartPtrConst() const
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return this->GetDataPtrConst(0);
return GetDataPtrConst(0);
}
const void *Circuit::GetSpaceDataEndPtrConst() const
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return this->GetDataPtrConst(this->circuitSize);
return GetDataPtrConst(circuitSize_);
}
const uint8_t *Circuit::GetDataPtrConst(size_t offset) const
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return this->space.data() + offset;
return space_.data() + offset;
}
uint8_t *Circuit::GetDataPtr(size_t offset)
{
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return this->space.data() + offset;
return space_.data() + offset;
}
size_t Circuit::GetSpaceDataSize() const
{
return this->space.size();
return space_.size();
}
void Circuit::SetSpaceDataSize(size_t sz)
{
return this->space.resize(sz);
return space_.resize(sz);
}
panda::ecmascript::FrameType Circuit::GetFrameType() const
{
return this->frameType;
return frameType_;
}
void Circuit::SetFrameType(panda::ecmascript::FrameType type)
{
this->frameType = type;
frameType_ = type;
}
} // namespace panda::ecmascript::kungfu

View File

@ -28,6 +28,8 @@
#include "securec.h"
namespace panda::ecmascript::kungfu {
class ByteCodeCircuitBuilder;
const size_t INITIAL_SPACE = 1U << 0U; // this should be tuned
const size_t MAX_SPACE = 1U << 24U; // this should be tuned
const size_t SCALE_RATE = 1U << 1U; // this should be tuned
@ -42,11 +44,16 @@ public:
Circuit(Circuit &&circuit) = default;
Circuit &operator=(Circuit &&circuit) = default;
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
GateRef NewGate(OpCode op, ValueCode bitValue, BitField bitfield, size_t numIns, const GateRef inList[],
TypeCode type, MarkCode mark = MarkCode::EMPTY);
GateRef NewGate(OpCode op, ValueCode bitValue, BitField bitfield, const std::vector<GateRef> &inList, TypeCode type,
MarkCode mark = MarkCode::EMPTY);
GateRef NewGate(OpCode op, BitField bitfield, size_t numIns, const GateRef inList[], TypeCode type,
MarkCode mark = MarkCode::EMPTY);
MarkCode mark = MarkCode::EMPTY);
GateRef NewGate(OpCode op, BitField bitfield, const std::vector<GateRef> &inList, TypeCode type,
MarkCode mark = MarkCode::EMPTY);
MarkCode mark = MarkCode::EMPTY);
void PrintAllGates() const;
void PrintAllGates(BytecodeCircuitBuilder &builder) const;
[[nodiscard]] std::vector<GateRef> GetAllGates() const;
[[nodiscard]] static GateRef GetCircuitRoot(OpCode opcode);
void AdvanceTime() const;
@ -69,10 +76,12 @@ public:
void Print(GateRef gate) const;
void SetOpCode(GateRef gate, OpCode opcode);
void SetTypeCode(GateRef gate, TypeCode type);
void SetValueCode(GateRef gate, ValueCode valCode);
[[nodiscard]] OpCode GetOpCode(GateRef gate) const;
[[nodiscard]] TimeStamp GetTime() const;
[[nodiscard]] MarkCode GetMark(GateRef gate) const;
[[nodiscard]] TypeCode GetTypeCode(GateRef gate) const;
[[nodiscard]] ValueCode GetValueCode(GateRef gate) const;
void SetMark(GateRef gate, MarkCode mark) const;
[[nodiscard]] bool Verify(GateRef gate) const;
[[nodiscard]] Gate *LoadGatePtr(GateRef shift);
@ -95,12 +104,12 @@ private:
Gate *AllocateGateSpace(size_t numIns);
private:
std::vector<uint8_t> space;
size_t circuitSize;
size_t gateCounter;
TimeStamp time;
std::vector<uint8_t> dataSection;
panda::ecmascript::FrameType frameType {panda::ecmascript::FrameType::OPTIMIZED_FRAME};
std::vector<uint8_t> space_ {};
size_t circuitSize_;
size_t gateCount_;
TimeStamp time_;
std::vector<uint8_t> dataSection_ {};
panda::ecmascript::FrameType frameType_ {panda::ecmascript::FrameType::OPTIMIZED_FRAME};
};
} // namespace panda::ecmascript::kungfu

View File

@ -22,7 +22,7 @@ using TaggedValue = panda::coretypes::TaggedValue;
GateRef CircuitBuilder::NewArguments(size_t index)
{
auto argListOfCircuit = Circuit::GetCircuitRoot(OpCode(OpCode::ARG_LIST));
return circuit_->NewGate(OpCode(OpCode::JS_ARG), index, {argListOfCircuit}, TypeCode::NOTYPE);
return circuit_->NewGate(OpCode(OpCode::ARG), ValueCode::INT64, index, {argListOfCircuit}, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewMerge(GateRef *inList, size_t controlCount)
@ -53,42 +53,67 @@ GateRef CircuitBuilder::NewSelectorGate(OpCode opCode, GateRef control, std::vec
return circuit_->NewGate(opCode, valueCounts, inList, MachineType2TypeCode(type));
}
GateRef CircuitBuilder::NewSelectorGate(OpCode opcode, ValueCode valCode, GateRef control, int valueCounts,
MachineType type)
{
std::vector<GateRef> inList;
inList.push_back(control);
for (int i = 0; i < valueCounts; i++) {
inList.push_back(Circuit::NullGate());
}
return circuit_->NewGate(opcode, valCode, valueCounts, inList, MachineType2TypeCode(type));
}
GateRef CircuitBuilder::NewSelectorGate(OpCode opcode, ValueCode valCode, GateRef control, std::vector<GateRef> &values,
int valueCounts, MachineType type)
{
std::vector<GateRef> inList;
inList.push_back(control);
for (int i = 0; i < valueCounts; i++) {
inList.push_back(values[i]);
}
return circuit_->NewGate(opcode, valCode, valueCounts, inList, MachineType2TypeCode(type));
}
GateRef CircuitBuilder::NewIntegerConstant(int32_t val)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
return circuit_->NewGate(OpCode(OpCode::INT32_CONSTANT), val, {constantList}, TypeCode::NOTYPE);
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT32, val, {constantList}, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewInteger64Constant(int64_t val)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
return circuit_->NewGate(OpCode(OpCode::INT64_CONSTANT), val, {constantList}, TypeCode::NOTYPE);
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT64, val, {constantList}, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewBooleanConstant(bool val)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
return circuit_->NewGate(OpCode(OpCode::INT32_CONSTANT), val ? 1 : 0, {constantList}, TypeCode::NOTYPE);
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT32, val ? 1 : 0, {constantList}, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewDoubleConstant(double val)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
return circuit_->NewGate(OpCode(OpCode::FLOAT64_CONSTANT), bit_cast<int64_t>(val), {constantList},
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::FLOAT64, bit_cast<int64_t>(val), {constantList},
TypeCode::NOTYPE);
}
GateRef CircuitBuilder::UndefineConstant(TypeCode type)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
return circuit_->NewGate(OpCode(OpCode::INT64_CONSTANT), TaggedValue::VALUE_UNDEFINED, { constantList }, type);
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT64, TaggedValue::VALUE_UNDEFINED, { constantList },
type);
}
GateRef CircuitBuilder::HoleConstant(TypeCode type)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
// NOTE: add bitfield value here
return circuit_->NewGate(OpCode(OpCode::JS_CONSTANT), TaggedValue::VALUE_HOLE, { constantList },
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT64, TaggedValue::VALUE_HOLE, { constantList },
type);
}
@ -96,7 +121,7 @@ GateRef CircuitBuilder::NullConstant(TypeCode type)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
// NOTE: add bitfield value here
return circuit_->NewGate(OpCode(OpCode::JS_CONSTANT), TaggedValue::VALUE_NULL, { constantList },
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT64, TaggedValue::VALUE_NULL, { constantList },
type);
}
@ -104,7 +129,8 @@ GateRef CircuitBuilder::ExceptionConstant(TypeCode type)
{
auto constantList = Circuit::GetCircuitRoot(OpCode(OpCode::CONSTANT_LIST));
// NOTE: add bitfield value here
return circuit_->NewGate(OpCode(OpCode::JS_CONSTANT), TaggedValue::VALUE_EXCEPTION, { constantList }, type);
return circuit_->NewGate(OpCode(OpCode::CONSTANT), ValueCode::INT64, TaggedValue::VALUE_EXCEPTION, { constantList },
type);
}
GateRef CircuitBuilder::Branch(GateRef state, GateRef condition)
@ -165,101 +191,101 @@ GateRef CircuitBuilder::NewDefaultCase(GateRef switchBranch)
return circuit_->NewGate(OpCode(OpCode::DEFAULT_CASE), 0, { switchBranch }, TypeCode::NOTYPE);
}
OpCode CircuitBuilder::GetStoreOpCodeFromMachineType(MachineType type)
ValueCode CircuitBuilder::GetStoreValueCodeFromMachineType(MachineType type)
{
switch (type) {
case MachineType::INT8:
return OpCode(OpCode::INT8_STORE);
return ValueCode::INT8;
case MachineType::INT16:
return OpCode(OpCode::INT16_STORE);
return ValueCode::INT16;
case MachineType::INT32:
return OpCode(OpCode::INT32_STORE);
return ValueCode::INT32;
case MachineType::INT64:
return OpCode(OpCode::INT64_STORE);
return ValueCode::INT64;
case MachineType::BOOL:
return OpCode(OpCode::INT32_STORE);
return ValueCode::INT32;
case MachineType::UINT8:
return OpCode(OpCode::INT8_STORE);
return ValueCode::INT8;
case MachineType::UINT16:
return OpCode(OpCode::INT16_STORE);
return ValueCode::INT16;
case MachineType::UINT32:
return OpCode(OpCode::INT32_STORE);
return ValueCode::INT32;
case MachineType::UINT64:
case MachineType::TAGGED:
case MachineType::TAGGED_POINTER:
return OpCode(OpCode::INT64_STORE);
return ValueCode::INT64;
case MachineType::FLOAT32:
return OpCode(OpCode::FLOAT32_STORE);
return ValueCode::FLOAT32;
case MachineType::FLOAT64:
return OpCode(OpCode::FLOAT64_STORE);
return ValueCode::FLOAT64;
default:
UNREACHABLE();
}
}
OpCode CircuitBuilder::GetLoadOpCodeFromMachineType(MachineType type)
ValueCode CircuitBuilder::GetLoadValueCodeFromMachineType(MachineType type)
{
switch (type) {
case MachineType::INT8:
return OpCode(OpCode::INT8_LOAD);
return ValueCode::INT8;
case MachineType::INT16:
return OpCode(OpCode::INT16_LOAD);
return ValueCode::INT16;
case MachineType::INT32:
return OpCode(OpCode::INT32_LOAD);
return ValueCode::INT32;
case MachineType::INT64:
return OpCode(OpCode::INT64_LOAD);
return ValueCode::INT64;
case MachineType::BOOL:
return OpCode(OpCode::INT32_LOAD);
return ValueCode::INT32;
case MachineType::UINT8:
return OpCode(OpCode::INT8_LOAD);
return ValueCode::INT8;
case MachineType::UINT16:
return OpCode(OpCode::INT16_LOAD);
return ValueCode::INT16;
case MachineType::UINT32:
return OpCode(OpCode::INT32_LOAD);
return ValueCode::INT32;
case MachineType::UINT64:
case MachineType::TAGGED:
case MachineType::TAGGED_POINTER:
return OpCode(OpCode::INT64_LOAD);
return ValueCode::INT64;
case MachineType::FLOAT32:
return OpCode(OpCode::FLOAT32_LOAD);
return ValueCode::FLOAT32;
case MachineType::FLOAT64:
return OpCode(OpCode::FLOAT64_LOAD);
return ValueCode::FLOAT64;
default:
UNREACHABLE();
}
}
OpCode CircuitBuilder::GetSelectOpCodeFromMachineType(MachineType type)
ValueCode CircuitBuilder::GetValueCodeFromMachineType(MachineType type)
{
switch (type) {
case MachineType::NONE:
return OpCode(OpCode::DEPEND_SELECTOR);
return ValueCode::NOVALUE;
case MachineType::INT8:
return OpCode(OpCode::VALUE_SELECTOR_INT8);
return ValueCode::INT8;
case MachineType::INT16:
return OpCode(OpCode::VALUE_SELECTOR_INT16);
return ValueCode::INT16;
case MachineType::INT32:
return OpCode(OpCode::VALUE_SELECTOR_INT32);
return ValueCode::INT32;
case MachineType::INT64:
return OpCode(OpCode::VALUE_SELECTOR_INT64);
return ValueCode::INT64;
case MachineType::BOOL:
return OpCode(OpCode::VALUE_SELECTOR_INT1);
return ValueCode::INT1;
case MachineType::UINT8:
return OpCode(OpCode::VALUE_SELECTOR_INT8);
return ValueCode::INT8;
case MachineType::UINT16:
return OpCode(OpCode::VALUE_SELECTOR_INT16);
return ValueCode::INT16;
case MachineType::UINT32:
return OpCode(OpCode::VALUE_SELECTOR_INT32);
return ValueCode::INT32;
case MachineType::NATIVE_POINTER:
return OpCode(OpCode::VALUE_SELECTOR_ANYVALUE);
return ValueCode::ANYVALUE;
case MachineType::UINT64:
case MachineType::TAGGED:
case MachineType::TAGGED_POINTER:
return OpCode(OpCode::VALUE_SELECTOR_INT64);
return ValueCode::INT64;
case MachineType::FLOAT32:
return OpCode(OpCode::VALUE_SELECTOR_FLOAT32);
return ValueCode::FLOAT32;
case MachineType::FLOAT64:
return OpCode(OpCode::VALUE_SELECTOR_FLOAT64);
return ValueCode::FLOAT64;
default:
UNREACHABLE();
}
@ -281,68 +307,80 @@ GateRef CircuitBuilder::NewDependAnd(std::initializer_list<GateRef> args)
GateRef CircuitBuilder::NewLoadGate(MachineType type, GateRef val, GateRef depend)
{
OpCode op = GetLoadOpCodeFromMachineType(type);
return circuit_->NewGate(op, static_cast<BitField>(type), { depend, val }, MachineType2TypeCode(type));
ValueCode valCode = GetLoadValueCodeFromMachineType(type);
return circuit_->NewGate(OpCode(OpCode::LOAD), valCode, static_cast<BitField>(type), { depend, val },
MachineType2TypeCode(type));
}
GateRef CircuitBuilder::NewStoreGate(MachineType type, GateRef ptr, GateRef val, GateRef depend)
{
OpCode op = GetStoreOpCodeFromMachineType(type);
return circuit_->NewGate(op, static_cast<BitField>(type), { depend, val, ptr }, MachineType2TypeCode(type));
return circuit_->NewGate(OpCode(OpCode::STORE), static_cast<BitField>(type), { depend, val, ptr },
MachineType2TypeCode(type));
}
GateRef CircuitBuilder::NewArithMeticGate(OpCode opcode, GateRef left, GateRef right)
GateRef CircuitBuilder::NewArithmeticGate(OpCode opcode, ValueCode valCode, GateRef left, GateRef right)
{
TypeCode type = circuit_->LoadGatePtr(left)->GetTypeCode();
return circuit_->NewGate(opcode, 0, { left, right }, type);
return circuit_->NewGate(opcode, valCode, 0, { left, right }, type);
}
GateRef CircuitBuilder::NewArithMeticGate(OpCode opcode, GateRef value)
GateRef CircuitBuilder::NewArithmeticGate(OpCode opcode, ValueCode valCode, GateRef value)
{
return circuit_->NewGate(opcode, valCode, 0, { value }, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewArithmeticGate(OpCode opcode, GateRef value)
{
return circuit_->NewGate(opcode, 0, { value }, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewLogicGate(OpCode opcode, ValueCode valCode, GateRef left, GateRef right)
{
return circuit_->NewGate(opcode, valCode, static_cast<BitField>(MachineType::BOOL), { left, right },
TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewLogicGate(OpCode opcode, GateRef left, GateRef right)
{
return circuit_->NewGate(opcode, static_cast<BitField>(MachineType::BOOL), { left, right }, TypeCode::NOTYPE);
}
GateRef CircuitBuilder::NewLogicGate(OpCode opcode, GateRef value)
GateRef CircuitBuilder::NewLogicGate(OpCode opcode, ValueCode valCode, GateRef value)
{
return circuit_->NewGate(opcode, static_cast<BitField>(MachineType::BOOL), { value }, TypeCode::NOTYPE);
return circuit_->NewGate(opcode, valCode, static_cast<BitField>(MachineType::BOOL), { value }, TypeCode::NOTYPE);
}
OpCode CircuitBuilder::GetCallOpCodeFromMachineType(MachineType type)
ValueCode CircuitBuilder::GetCallValueCodeFromMachineType(MachineType type)
{
switch (type) {
case MachineType::NONE:
return OpCode(OpCode::CALL);
return ValueCode::NOVALUE;
case MachineType::INT8:
return OpCode(OpCode::INT8_CALL);
return ValueCode::INT8;
case MachineType::INT16:
return OpCode(OpCode::INT16_CALL);
return ValueCode::INT64;
case MachineType::INT32:
return OpCode(OpCode::INT32_CALL);
return ValueCode::INT32;
case MachineType::INT64:
return OpCode(OpCode::INT64_CALL);
return ValueCode::INT64;
case MachineType::BOOL:
return OpCode(OpCode::INT1_CALL);
return ValueCode::INT1;
case MachineType::UINT8:
return OpCode(OpCode::INT8_CALL);
return ValueCode::INT8;
case MachineType::UINT16:
return OpCode(OpCode::INT16_CALL);
return ValueCode::INT16;
case MachineType::UINT32:
return OpCode(OpCode::INT32_CALL);
return ValueCode::INT32;
case MachineType::NATIVE_POINTER:
return OpCode(OpCode::ANYVALUE_CALL);
return ValueCode::ANYVALUE;
case MachineType::UINT64:
case MachineType::TAGGED:
case MachineType::TAGGED_POINTER:
return OpCode(OpCode::INT64_CALL);
return ValueCode::INT64;
case MachineType::FLOAT32:
return OpCode(OpCode::FLOAT32_CALL);
return ValueCode::FLOAT32;
case MachineType::FLOAT64:
return OpCode(OpCode::FLOAT64_CALL);
return ValueCode::FLOAT64;
default:
UNREACHABLE();
}
@ -361,9 +399,9 @@ GateRef CircuitBuilder::NewCallGate(StubDescriptor *descriptor, GateRef glue, Ga
for (auto arg : args) {
inputs.push_back(arg);
}
OpCode opcode = GetCallOpCodeFromMachineType(descriptor->GetReturnType());
ValueCode valCode = GetCallValueCodeFromMachineType(descriptor->GetReturnType());
TypeCode type = MachineType2TypeCode(descriptor->GetReturnType());
return circuit_->NewGate(opcode, args.size() + extraparamCnt, inputs, type);
return circuit_->NewGate(OpCode(OpCode::CALL), valCode, args.size() + extraparamCnt, inputs, type);
}
GateRef CircuitBuilder::NewCallGate(StubDescriptor *descriptor, GateRef glue, GateRef target,
@ -376,15 +414,15 @@ GateRef CircuitBuilder::NewCallGate(StubDescriptor *descriptor, GateRef glue, Ga
for (auto arg : args) {
inputs.push_back(arg);
}
OpCode opcode = GetCallOpCodeFromMachineType(descriptor->GetReturnType());
ValueCode valCode = GetCallValueCodeFromMachineType(descriptor->GetReturnType());
TypeCode type = MachineType2TypeCode(descriptor->GetReturnType());
// 2 : 2 means extra two input gates (target glue)
return circuit_->NewGate(opcode, args.size() + 2, inputs, type);
return circuit_->NewGate(OpCode(OpCode::CALL), valCode, args.size() + 2, inputs, type);
}
GateRef CircuitBuilder::Alloca(int size, TypeCode type)
GateRef CircuitBuilder::Alloca(int size)
{
auto allocaList = Circuit::GetCircuitRoot(OpCode(OpCode::ALLOCA_LIST));
return circuit_->NewGate(OpCode(OpCode::ALLOCA), size, { allocaList }, type);
return circuit_->NewGate(OpCode(OpCode::ALLOCA), size, { allocaList }, TypeCode::NOTYPE);
}
} // namespace panda::ecmascript::kungfu

View File

@ -31,9 +31,13 @@ public:
GateRef NewArguments(size_t index);
GateRef NewMerge(GateRef *in, size_t controlCount);
GateRef NewSelectorGate(OpCode opcode, GateRef control, int valueCounts,
MachineType type = MachineType::NONE);
MachineType type = MachineType::NONE);
GateRef NewSelectorGate(OpCode opcode, GateRef control, std::vector<GateRef> &values, int valueCounts,
MachineType type = MachineType::NONE);
MachineType type = MachineType::NONE);
GateRef NewSelectorGate(OpCode opcode, ValueCode valCode, GateRef control, int valueCounts,
MachineType type = MachineType::NONE);
GateRef NewSelectorGate(OpCode opcode, ValueCode valCode, GateRef control, std::vector<GateRef> &values,
int valueCounts, MachineType type = MachineType::NONE);
GateRef NewIntegerConstant(int32_t value);
GateRef NewInteger64Constant(int64_t value);
GateRef NewWord64Constant(uint64_t val);
@ -43,7 +47,7 @@ public:
GateRef HoleConstant(TypeCode type);
GateRef NullConstant(TypeCode type);
GateRef ExceptionConstant(TypeCode type);
GateRef Alloca(int size, TypeCode type);
GateRef Alloca(int size);
GateRef Branch(GateRef state, GateRef condition);
GateRef SwitchBranch(GateRef state, GateRef index, int caseCounts);
GateRef Return(GateRef state, GateRef depend, GateRef value);
@ -59,18 +63,20 @@ public:
GateRef NewStoreGate(MachineType type, GateRef ptr, GateRef val, GateRef depend);
GateRef NewDependRelay(GateRef state, GateRef depend);
GateRef NewDependAnd(std::initializer_list<GateRef> args);
GateRef NewArithMeticGate(OpCode opcode, GateRef left, GateRef right);
GateRef NewArithMeticGate(OpCode opcode, GateRef value);
GateRef NewArithmeticGate(OpCode opcode, ValueCode valCode, GateRef left, GateRef right);
GateRef NewArithmeticGate(OpCode opcode, ValueCode valCode, GateRef value);
GateRef NewArithmeticGate(OpCode opcode, GateRef value);
GateRef NewLogicGate(OpCode opcode, ValueCode valCode, GateRef left, GateRef right);
GateRef NewLogicGate(OpCode opcode, GateRef left, GateRef right);
GateRef NewLogicGate(OpCode opcode, GateRef value);
GateRef NewLogicGate(OpCode opcode, ValueCode valCode, GateRef value);
GateRef NewCallGate(StubDescriptor *descriptor, GateRef glue, GateRef target,
std::initializer_list<GateRef> args);
GateRef NewCallGate(StubDescriptor *descriptor, GateRef glue, GateRef target,
GateRef depend, std::initializer_list<GateRef> args);
static OpCode GetLoadOpCodeFromMachineType(MachineType type);
static OpCode GetStoreOpCodeFromMachineType(MachineType type);
static OpCode GetSelectOpCodeFromMachineType(MachineType type);
static OpCode GetCallOpCodeFromMachineType(MachineType type);
static ValueCode GetLoadValueCodeFromMachineType(MachineType type);
static ValueCode GetStoreValueCodeFromMachineType(MachineType type);
static ValueCode GetValueCodeFromMachineType(MachineType type);
static ValueCode GetCallValueCodeFromMachineType(MachineType type);
static TypeCode MachineType2TypeCode(MachineType type)
{

View File

@ -76,18 +76,29 @@ GateRef LabelImpl::ReadVariable(Variable *var)
GateRef LabelImpl::ReadVariableRecursive(Variable *var)
{
GateRef val;
OpCode opcode = CircuitBuilder::GetSelectOpCodeFromMachineType(var->Type());
ValueCode valueCode = CircuitBuilder::GetValueCodeFromMachineType(var->Type());
if (!IsSealed()) {
// only loopheader gate will be not sealed
int valueCounts = static_cast<int>(this->predecessors_.size()) + 1;
val = lm_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, valueCounts, var->Type());
if (valueCode == ValueCode::NOVALUE) {
val = lm_->GetCircuitBuilder().NewSelectorGate(OpCode(OpCode::DEPEND_SELECTOR), valueCode, predeControl_,
valueCounts, var->Type());
} else {
val = lm_->GetCircuitBuilder().NewSelectorGate(OpCode(OpCode::VALUE_SELECTOR), valueCode, predeControl_,
valueCounts, var->Type());
}
lm_->AddSelectorToLabel(val, Label(this));
incompletePhis_[var] = val;
} else if (predecessors_.size() == 1) {
val = predecessors_[0]->ReadVariable(var);
} else {
val = lm_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, this->predecessors_.size(), var->Type());
if (valueCode == ValueCode::NOVALUE) {
val = lm_->GetCircuitBuilder().NewSelectorGate(OpCode(OpCode::DEPEND_SELECTOR), valueCode, predeControl_,
this->predecessors_.size(), var->Type());
} else {
val = lm_->GetCircuitBuilder().NewSelectorGate(OpCode(OpCode::VALUE_SELECTOR), valueCode, predeControl_,
this->predecessors_.size(), var->Type());
}
lm_->AddSelectorToLabel(val, Label(this));
WriteVariable(var, val);
val = var->AddPhiOperand(val);

View File

@ -225,8 +225,7 @@ public:
}
bool IsSelector(const Gate *gate) const
{
return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS
&& gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64;
return gate->GetOpCode() == OpCode::VALUE_SELECTOR;
}
uint32_t GetId() const
{

View File

@ -14,6 +14,7 @@
*/
#include "ecmascript/compiler/gate.h"
#include "ecmascript/compiler/bytecode_circuit_builder.h"
namespace panda::ecmascript::kungfu {
constexpr size_t ONE_DEPEND = 1;
@ -57,8 +58,6 @@ Properties OpCode::GetProperties() const
return {NOVALUE, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CIRCUIT_ROOT)};
case RETURN:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, VALUE(ANYVALUE), OpCode(RETURN_LIST)};
case RETURN_VOID:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, NO_VALUE, OpCode(RETURN_LIST)};
case THROW:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, VALUE(JSValueCode()), OpCode(THROW_LIST)};
case ORDINARY_BLOCK:
@ -66,10 +65,13 @@ Properties OpCode::GetProperties() const
case IF_BRANCH:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, VALUE(INT1), NO_ROOT};
case SWITCH_BRANCH:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, VALUE(INT64), NO_ROOT};
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case IF_TRUE:
case IF_FALSE:
return {NOVALUE, STATE(OpCode(IF_BRANCH)), NO_DEPEND, NO_VALUE, NO_ROOT};
case IF_SUCCESS:
case IF_EXCEPTION:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
case SWITCH_CASE:
case DEFAULT_CASE:
return {NOVALUE, STATE(OpCode(SWITCH_BRANCH)), NO_DEPEND, NO_VALUE, NO_ROOT};
@ -79,24 +81,8 @@ Properties OpCode::GetProperties() const
return {NOVALUE, STATE(OpCode(GENERAL_STATE), OpCode(LOOP_BACK)), NO_DEPEND, NO_VALUE, NO_ROOT};
case LOOP_BACK:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, NO_VALUE, NO_ROOT};
case VALUE_SELECTOR_JS:
return {JSValueCode(), STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(JSValueCode()), NO_ROOT};
case VALUE_SELECTOR_INT1:
return {INT1, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(INT1), NO_ROOT};
case VALUE_SELECTOR_INT8:
return {INT8, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(INT8), NO_ROOT};
case VALUE_SELECTOR_INT16:
return {INT16, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(INT16), NO_ROOT};
case VALUE_SELECTOR_INT32:
return {INT32, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(INT32), NO_ROOT};
case VALUE_SELECTOR_INT64:
return {INT64, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(INT64), NO_ROOT};
case VALUE_SELECTOR_FLOAT32:
return {FLOAT32, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(FLOAT32), NO_ROOT};
case VALUE_SELECTOR_FLOAT64:
return {FLOAT64, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(FLOAT64), NO_ROOT};
case VALUE_SELECTOR_ANYVALUE:
return {ANYVALUE, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(ANYVALUE), NO_ROOT};
case VALUE_SELECTOR:
return {FLEX, STATE(OpCode(GENERAL_STATE)), NO_DEPEND, MANY_VALUE(FLEX), NO_ROOT};
case DEPEND_SELECTOR:
return {NOVALUE, STATE(OpCode(GENERAL_STATE)), MANY_DEPEND, NO_VALUE, NO_ROOT};
case DEPEND_RELAY:
@ -104,214 +90,80 @@ Properties OpCode::GetProperties() const
case DEPEND_AND:
return {NOVALUE, NO_STATE, MANY_DEPEND, NO_VALUE, NO_ROOT};
// High Level IR
case JS_CALL:
return {JSValueCode(), NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE), NO_ROOT};
case JS_CONSTANT:
return {JSValueCode(), NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case JS_ARG:
return {JSValueCode(), NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case JS_ADD:
case JS_SUB:
case JS_MUL:
case JS_EXP:
case JS_DIV:
case JS_MOD:
case JS_AND:
case JS_XOR:
case JS_OR:
case JS_LSL:
case JS_LSR:
case JS_ASR:
case JS_LOGIC_AND:
case JS_LOGIC_OR:
case JS_LT:
case JS_LE:
case JS_GT:
case JS_GE:
case JS_EQ:
case JS_NE:
case JS_STRICT_EQ:
case JS_STRICT_NE:
return {JSValueCode(), NO_STATE, NO_DEPEND, VALUE(JSValueCode(), JSValueCode()), NO_ROOT};
case JS_LOGIC_NOT:
return {JSValueCode(), NO_STATE, NO_DEPEND, VALUE(JSValueCode()), NO_ROOT};
case JS_BYTECODE:
return {INT64, STATE(OpCode(GENERAL_STATE)), ONE_DEPEND, MANY_VALUE(ANYVALUE), NO_ROOT};
// Middle Level IR
case CALL:
return {NOVALUE, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case INT1_CALL:
return {INT1, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case INT8_CALL:
return {INT8, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case INT16_CALL:
return {INT16, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case INT32_CALL:
return {INT32, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case INT64_CALL:
return {INT64, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case FLOAT32_CALL:
return {FLOAT32, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case FLOAT64_CALL:
return {FLOAT64, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case ANYVALUE_CALL:
return {ANYVALUE, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
return {FLEX, NO_STATE, ONE_DEPEND, MANY_VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case ALLOCA:
return {ANYVALUE, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ALLOCA_LIST)};
case INT1_ARG:
return {INT1, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case INT8_ARG:
return {INT8, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case INT16_ARG:
return {INT16, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case INT32_ARG:
return {INT32, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case INT64_ARG:
return {INT64, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case FLOAT32_ARG:
return {FLOAT32, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case FLOAT64_ARG:
return {FLOAT64, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
return {ARCH, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ALLOCA_LIST)};
case ARG:
return {FLEX, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(ARG_LIST)};
case MUTABLE_DATA:
case CONST_DATA:
return {ANYVALUE, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case INT1_CONSTANT:
return {INT1, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case INT8_CONSTANT:
return {INT8, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case INT16_CONSTANT:
return {INT16, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case INT32_CONSTANT:
return {INT32, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case INT64_CONSTANT:
return {INT64, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case FLOAT32_CONSTANT:
return {FLOAT32, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case FLOAT64_CONSTANT:
return {FLOAT64, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case ZEXT_INT32_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
case ZEXT_INT1_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
case ZEXT_INT8_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
case ZEXT_INT16_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT16), NO_ROOT};
case ZEXT_INT1_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
case SEXT_INT32_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
case SEXT_INT1_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
case SEXT_INT8_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
case SEXT_INT16_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT8), NO_ROOT};
case SEXT_INT1_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT1), NO_ROOT};
case TRUNC_INT64_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
case TRUNC_INT64_TO_INT1:
return {INT1, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
case TRUNC_INT32_TO_INT1:
return {INT1, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
case INT32_REV:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
case INT32_ADD:
case INT32_SUB:
case INT32_MUL:
case INT32_EXP:
case INT32_SDIV:
case INT32_SMOD:
case INT32_UDIV:
case INT32_UMOD:
case INT32_AND:
case INT32_XOR:
case INT32_OR:
case INT32_LSL:
case INT32_LSR:
case INT32_ASR:
return {INT32, NO_STATE, NO_DEPEND, VALUE(INT32, INT32), NO_ROOT};
case INT32_SLT:
case INT32_SLE:
case INT32_SGT:
case INT32_SGE:
case INT32_ULT:
case INT32_ULE:
case INT32_UGT:
case INT32_UGE:
case INT32_EQ:
case INT32_NE:
return {INT1, NO_STATE, NO_DEPEND, VALUE(INT32, INT32), NO_ROOT};
case INT64_REV:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
case INT64_ADD:
case INT64_SUB:
case INT64_MUL:
case INT64_EXP:
case INT64_SDIV:
case INT64_SMOD:
case INT64_UDIV:
case INT64_UMOD:
case INT64_AND:
case INT64_XOR:
case INT64_OR:
case INT64_LSL:
case INT64_LSR:
case INT64_ASR:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT64, INT64), NO_ROOT};
case INT64_SLT:
case INT64_SLE:
case INT64_SGT:
case INT64_SGE:
case INT64_ULT:
case INT64_ULE:
case INT64_UGT:
case INT64_UGE:
case INT64_EQ:
case INT64_NE:
return {INT1, NO_STATE, NO_DEPEND, VALUE(INT64, INT64), NO_ROOT};
case FLOAT64_ADD:
case FLOAT64_SUB:
case FLOAT64_MUL:
case FLOAT64_DIV:
case FLOAT64_EXP:
case FLOAT64_SMOD:
return {FLOAT64, NO_STATE, NO_DEPEND, VALUE(FLOAT64, FLOAT64), NO_ROOT};
case FLOAT64_EQ:
return {INT1, NO_STATE, NO_DEPEND, VALUE(FLOAT64, FLOAT64), NO_ROOT};
case INT8_LOAD:
return {INT8, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case INT16_LOAD:
return {INT16, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case INT32_LOAD:
return {INT32, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case INT64_LOAD:
return {INT64, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case FLOAT32_LOAD:
return {FLOAT32, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case FLOAT64_LOAD:
return {FLOAT64, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case INT8_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(INT8, ANYVALUE), NO_ROOT};
case INT16_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(INT16, ANYVALUE), NO_ROOT};
case INT32_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(INT32, ANYVALUE), NO_ROOT};
case INT64_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(INT64, ANYVALUE), NO_ROOT};
case FLOAT32_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(FLOAT32, ANYVALUE), NO_ROOT};
case FLOAT64_STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(FLOAT64, ANYVALUE), NO_ROOT};
case INT32_TO_FLOAT64:
return {FLOAT64, NO_STATE, NO_DEPEND, VALUE(INT32), NO_ROOT};
case FLOAT64_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(FLOAT64), NO_ROOT};
case TAGGED_POINTER_TO_INT64:
return {ARCH, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case CONSTANT:
return {FLEX, NO_STATE, NO_DEPEND, NO_VALUE, OpCode(CONSTANT_LIST)};
case ZEXT_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case BITCAST_INT64_TO_FLOAT64:
return {FLOAT64, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
case BITCAST_FLOAT64_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(FLOAT64), NO_ROOT};
case ZEXT_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case SEXT_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case SEXT_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case TRUNC_TO_INT32:
return {INT32, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case TRUNC_TO_INT1:
return {INT1, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case REV:
return {FLEX, NO_STATE, NO_DEPEND, VALUE(FLEX), NO_ROOT};
case ADD:
case SUB:
case MUL:
case EXP:
case SDIV:
case SMOD:
case UDIV:
case UMOD:
case FDIV:
case FMOD:
case AND:
case XOR:
case OR:
case LSL:
case LSR:
case ASR:
return {FLEX, NO_STATE, NO_DEPEND, VALUE(FLEX, FLEX), NO_ROOT};
case SLT:
case SLE:
case SGT:
case SGE:
case ULT:
case ULE:
case UGT:
case UGE:
case FLT:
case FLE:
case FGT:
case FGE:
case EQ:
case NE:
return {INT1, NO_STATE, NO_DEPEND, VALUE(ANYVALUE, ANYVALUE), NO_ROOT};
case LOAD:
return {FLEX, NO_STATE, ONE_DEPEND, VALUE(ARCH), NO_ROOT};
case STORE:
return {NOVALUE, NO_STATE, ONE_DEPEND, VALUE(ANYVALUE, ARCH), NO_ROOT};
case TAGGED_TO_INT64:
return {INT64, NO_STATE, NO_DEPEND, VALUE(INT64), NO_ROOT};
case SIGNED_INT_TO_FLOAT:
case UNSIGNED_INT_TO_FLOAT:
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case FLOAT_TO_SIGNED_INT:
case UNSIGNED_FLOAT_TO_INT:
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
case BITCAST:
return {FLEX, NO_STATE, NO_DEPEND, VALUE(ANYVALUE), NO_ROOT};
default:
std::cerr << "Please complete OpCode properties (OpCode=" << op_ << ")" << std::endl;
UNREACHABLE();
@ -329,7 +181,6 @@ Properties OpCode::GetProperties() const
std::string OpCode::Str() const
{
const std::map<GateOp, const char *> strMap = {
// SHARED
{NOP, "NOP"},
{CIRCUIT_ROOT, "CIRCUIT_ROOT"},
{STATE_ENTRY, "STATE_ENTRY"},
@ -348,164 +199,69 @@ std::string OpCode::Str() const
{SWITCH_BRANCH, "SWITCH_BRANCH"},
{IF_TRUE, "IF_TRUE"},
{IF_FALSE, "IF_FALSE"},
{IF_SUCCESS, "IF_SUCCESS"},
{IF_EXCEPTION, "IF_EXCEPTION"},
{SWITCH_CASE, "SWITCH_CASE"},
{DEFAULT_CASE, "DEFAULT_CASE"},
{MERGE, "MERGE"},
{LOOP_BEGIN, "LOOP_BEGIN"},
{LOOP_BACK, "LOOP_BACK"},
{VALUE_SELECTOR_JS, "VALUE_SELECTOR_JS"},
{VALUE_SELECTOR_INT1, "VALUE_SELECTOR_INT1"},
{VALUE_SELECTOR_INT8, "VALUE_SELECTOR_INT8"},
{VALUE_SELECTOR_INT16, "VALUE_SELECTOR_INT16"},
{VALUE_SELECTOR_INT32, "VALUE_SELECTOR_INT32"},
{VALUE_SELECTOR_INT64, "VALUE_SELECTOR_INT64"},
{VALUE_SELECTOR_FLOAT32, "VALUE_SELECTOR_FLOAT32"},
{VALUE_SELECTOR_FLOAT64, "VALUE_SELECTOR_FLOAT64"},
{VALUE_SELECTOR, "VALUE_SELECTOR"},
{DEPEND_SELECTOR, "DEPEND_SELECTOR"},
{DEPEND_RELAY, "DEPEND_RELAY"},
{DEPEND_AND, "DEPEND_AND"},
// High Level IR
{JS_CALL, "JS_CALL"},
{JS_CONSTANT, "JS_CONSTANT"},
{JS_ARG, "JS_ARG"},
{JS_ADD, "JS_ADD"},
{JS_SUB, "JS_SUB"},
{JS_MUL, "JS_MUL"},
{JS_EXP, "JS_EXP"},
{JS_DIV, "JS_DIV"},
{JS_MOD, "JS_MOD"},
{JS_AND, "JS_AND"},
{JS_XOR, "JS_XOR"},
{JS_OR, "JS_OR"},
{JS_LSL, "JS_LSL"},
{JS_LSR, "JS_LSR"},
{JS_ASR, "JS_ASR"},
{JS_LOGIC_AND, "JS_LOGIC_AND"},
{JS_LOGIC_OR, "JS_LOGIC_OR"},
{JS_LT, "JS_LT"},
{JS_LE, "JS_LE"},
{JS_GT, "JS_GT"},
{JS_GE, "JS_GE"},
{JS_EQ, "JS_EQ"},
{JS_NE, "JS_NE"},
{JS_STRICT_EQ, "JS_STRICT_EQ"},
{JS_STRICT_NE, "JS_STRICT_NE"},
{JS_LOGIC_NOT, "JS_LOGIC_NOT"},
// Middle Level IR
{JS_BYTECODE, "JS_BYTECODE"},
{CALL, "CALL"},
{INT1_CALL, "INT1_CALL"},
{INT8_CALL, "INT8_CALL"},
{INT16_CALL, "INT16_CALL"},
{INT32_CALL, "INT32_CALL"},
{INT64_CALL, "INT64_CALL"},
{FLOAT32_CALL, "FLOAT32_CALL"},
{FLOAT64_CALL, "FLOAT64_CALL"},
{ANYVALUE_CALL, "ANYVALUE_CALL"},
{TAGGED_POINTER_CALL, "TAGGED_POINTER_CALL"},
{ALLOCA, "ALLOCA"},
{INT1_ARG, "INT1_ARG"},
{INT8_ARG, "INT8_ARG"},
{INT16_ARG, "INT16_ARG"},
{INT32_ARG, "INT32_ARG"},
{INT64_ARG, "INT64_ARG"},
{FLOAT32_ARG, "FLOAT32_ARG"},
{FLOAT64_ARG, "FLOAT64_ARG"},
{ARG, "ARG"},
{MUTABLE_DATA, "MUTABLE_DATA"},
{CONST_DATA, "CONST_DATA"},
{INT1_CONSTANT, "INT1_CONSTANT"},
{INT8_CONSTANT, "INT8_CONSTANT"},
{INT16_CONSTANT, "INT16_CONSTANT"},
{INT32_CONSTANT, "INT32_CONSTANT"},
{INT64_CONSTANT, "INT64_CONSTANT"},
{FLOAT32_CONSTANT, "FLOAT32_CONSTANT"},
{FLOAT64_CONSTANT, "FLOAT64_CONSTANT"},
{ZEXT_INT32_TO_INT64, "ZEXT_INT32_TO_INT64"},
{ZEXT_INT1_TO_INT32, "ZEXT_INT1_TO_INT32"},
{ZEXT_INT8_TO_INT32, "ZEXT_INT8_TO_INT32"},
{ZEXT_INT16_TO_INT32, "ZEXT_INT16_TO_INT32"},
{ZEXT_INT1_TO_INT64, "ZEXT_INT1_TO_INT64"},
{SEXT_INT32_TO_INT64, "SEXT_INT32_TO_INT64"},
{SEXT_INT1_TO_INT32, "SEXT_INT1_TO_INT32"},
{SEXT_INT8_TO_INT32, "SEXT_INT8_TO_INT32"},
{SEXT_INT16_TO_INT32, "SEXT_INT16_TO_INT32"},
{SEXT_INT1_TO_INT64, "SEXT_INT1_TO_INT64"},
{TRUNC_INT64_TO_INT32, "TRUNC_INT64_TO_INT32"},
{TRUNC_INT64_TO_INT1, "TRUNC_INT64_TO_INT1"},
{TRUNC_INT32_TO_INT1, "TRUNC_INT32_TO_INT1"},
{INT32_REV, "INT32_REV"},
{INT32_ADD, "INT32_ADD"},
{INT32_SUB, "INT32_SUB"},
{INT32_MUL, "INT32_MUL"},
{INT32_EXP, "INT32_EXP"},
{INT32_SDIV, "INT32_SDIV"},
{INT32_SMOD, "INT32_SMOD"},
{INT32_UDIV, "INT32_UDIV"},
{INT32_UMOD, "INT32_UMOD"},
{INT32_AND, "INT32_AND"},
{INT32_XOR, "INT32_XOR"},
{INT32_OR, "INT32_OR"},
{INT32_LSL, "INT32_LSL"},
{INT32_LSR, "INT32_LSR"},
{INT32_ASR, "INT32_ASR"},
{INT32_SLT, "INT32_SLT"},
{INT32_SLE, "INT32_SLE"},
{INT32_SGT, "INT32_SGT"},
{INT32_SGE, "INT32_SGE"},
{INT32_ULT, "INT32_ULT"},
{INT32_ULE, "INT32_ULE"},
{INT32_UGT, "INT32_UGT"},
{INT32_UGE, "INT32_UGE"},
{INT32_EQ, "INT32_EQ"},
{INT32_NE, "INT32_NE"},
{INT64_ADD, "INT64_ADD"},
{INT64_SUB, "INT64_SUB"},
{INT64_MUL, "INT64_MUL"},
{INT64_EXP, "INT64_EXP"},
{INT64_SDIV, "INT64_SDIV"},
{INT64_SMOD, "INT64_SMOD"},
{INT64_UDIV, "INT64_UDIV"},
{INT64_UMOD, "INT64_UMOD"},
{INT64_AND, "INT64_AND"},
{INT64_XOR, "INT64_XOR"},
{INT64_OR, "INT64_OR"},
{INT64_LSL, "INT64_LSL"},
{INT64_LSR, "INT64_LSR"},
{INT64_ASR, "INT64_ASR"},
{INT64_SLT, "INT64_SLT"},
{INT64_SLE, "INT64_SLE"},
{INT64_SGT, "INT64_SGT"},
{INT64_SGE, "INT64_SGE"},
{INT64_ULT, "INT64_ULT"},
{INT64_ULE, "INT64_ULE"},
{INT64_UGT, "INT64_UGT"},
{INT64_UGE, "INT64_UGE"},
{INT64_EQ, "INT64_EQ"},
{INT64_NE, "INT64_NE"},
{INT64_REV, "INT64_REV"},
{FLOAT64_ADD, "FLOAT64_ADD"},
{FLOAT64_SUB, "FLOAT64_SUB"},
{FLOAT64_MUL, "FLOAT64_MUL"},
{FLOAT64_DIV, "FLOAT64_DIV"},
{FLOAT64_EXP, "FLOAT64_EXP"},
{FLOAT64_EQ, "FLOAT64_EQ"},
{INT8_LOAD, "INT8_LOAD"},
{INT16_LOAD, "INT16_LOAD"},
{INT32_LOAD, "INT32_LOAD"},
{INT64_LOAD, "INT64_LOAD"},
{FLOAT32_LOAD, "FLOAT32_LOAD"},
{FLOAT64_LOAD, "FLOAT64_LOAD"},
{INT8_STORE, "INT8_STORE"},
{INT16_STORE, "INT16_STORE"},
{INT32_STORE, "INT32_STORE"},
{INT64_STORE, "INT64_STORE"},
{FLOAT32_STORE, "FLOAT32_STORE"},
{FLOAT64_STORE, "FLOAT64_STORE"},
{INT32_TO_FLOAT64, "INT32_TO_FLOAT64"},
{FLOAT64_TO_INT32, "FLOAT64_TO_INT32"},
{TAGGED_POINTER_TO_INT64, "TAGGED_POINTER_TO_INT64"},
{BITCAST_INT64_TO_FLOAT64, "BITCAST_INT64_TO_FLOAT64"},
{BITCAST_FLOAT64_TO_INT64, "BITCAST_FLOAT64_TO_INT64"},
{VALUE_SELECTOR_ANYVALUE, "VALUE_SELECTOR_ANYVALUE"},
{CONSTANT, "CONSTANT"},
{ZEXT_TO_INT64, "ZEXT_TO_INT64"},
{ZEXT_TO_INT32, "ZEXT_TO_INT32"},
{SEXT_TO_INT64, "SEXT_TO_INT64"},
{SEXT_TO_INT32, "SEXT_TO_INT32"},
{TRUNC_TO_INT32, "TRUNC_TO_INT32"},
{TRUNC_TO_INT1, "TRUNC_TO_INT1"},
{REV, "REV"},
{ADD, "ADD"},
{SUB, "SUB"},
{MUL, "MUL"},
{EXP, "EXP"},
{SDIV, "SDIV"},
{SMOD, "SMOD"},
{UDIV, "UDIV"},
{UMOD, "UMOD"},
{FDIV, "FDIV"},
{FMOD, "FMOD"},
{AND, "AND"},
{XOR, "XOR"},
{OR, "OR"},
{LSL, "LSL"},
{LSR, "LSR"},
{ASR, "ASR"},
{SLT, "SLT"},
{SLE, "SLE"},
{SGT, "SGT"},
{SGE, "SGE"},
{ULT, "ULT"},
{ULE, "ULE"},
{UGT, "UGT"},
{UGE, "UGE"},
{FLT, "FLT"},
{FLE, "FLE"},
{FGT, "FGT"},
{FGE, "FGE"},
{EQ, "EQ"},
{NE, "NE"},
{LOAD, "LOAD"},
{STORE, "STORE"},
{TAGGED_TO_INT64, "TAGGED_TO_INT64"},
{SIGNED_INT_TO_FLOAT, "SIGNED_INT_TO_FLOAT"},
{UNSIGNED_INT_TO_FLOAT, "UNSIGNED_INT_TO_FLOAT"},
{FLOAT_TO_SIGNED_INT, "FLOAT_TO_SIGNED_INT"},
{UNSIGNED_FLOAT_TO_INT, "UNSIGNED_FLOAT_TO_INT"},
{BITCAST, "BITCAST"},
};
if (strMap.count(op_) > 0) {
return strMap.at(op_);
@ -635,6 +391,13 @@ std::optional<std::pair<std::string, size_t>> Gate::CheckValueInput() const
for (size_t idx = valueStart; idx < valueEnd; idx++) {
auto expectedIn = GetOpCode().GetInValueCode(GetBitField(), idx);
auto actualIn = GetInGateConst(idx)->GetOpCode().GetValueCode();
if (expectedIn == ValueCode::FLEX) {
expectedIn = GetValueCode();
}
if (actualIn == ValueCode::FLEX) {
actualIn = GetInGateConst(idx)->GetValueCode();
}
if ((expectedIn != actualIn) && (expectedIn != ANYVALUE)) {
return std::make_pair("Value input does not match (expected: " + ValueCodeToStr(expectedIn) +
" actual: " + ValueCodeToStr(actualIn) + ")",
@ -734,9 +497,7 @@ std::optional<std::pair<std::string, size_t>> Gate::CheckNOP() const
std::optional<std::pair<std::string, size_t>> Gate::CheckSelector() const
{
if (GetOpCode() == OpCode::VALUE_SELECTOR_JS ||
(OpCode::VALUE_SELECTOR_INT1 <= GetOpCode() && GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64) ||
GetOpCode() == OpCode::DEPEND_SELECTOR) {
if (GetOpCode() == OpCode::VALUE_SELECTOR || GetOpCode() == OpCode::DEPEND_SELECTOR) {
auto stateOp = GetInGateConst(0)->GetOpCode();
if (stateOp == OpCode::MERGE || stateOp == OpCode::LOOP_BEGIN) {
if (GetInGateConst(0)->GetNumIns() != GetNumIns() - 1) {
@ -765,11 +526,10 @@ std::optional<std::pair<std::string, size_t>> Gate::CheckRelay() const
if (GetOpCode() == OpCode::DEPEND_RELAY) {
auto stateOp = GetInGateConst(0)->GetOpCode();
if (!(stateOp == OpCode::IF_TRUE || stateOp == OpCode::IF_FALSE || stateOp == OpCode::SWITCH_CASE ||
stateOp == OpCode::DEFAULT_CASE)) {
return std::make_pair(
"State input does not match (expected:[IF_TRUE|IF_FALSE|SWITCH_CASE|DEFAULT_CASE] actual:" +
stateOp.Str() + ")",
0);
stateOp == OpCode::DEFAULT_CASE || stateOp == OpCode::IF_SUCCESS || stateOp == OpCode::IF_EXCEPTION)) {
return std::make_pair("State input does not match ("
"expected:[IF_TRUE|IF_FALSE|SWITCH_CASE|DEFAULT_CASE|IF_SUCCESS|IF_EXCEPTION] actual:" +
stateOp.Str() + ")", 0);
}
}
return std::nullopt;
@ -854,7 +614,7 @@ bool Gate::Verify() const
}
if (failed) {
std::cerr << "[Verifier][Error] Gate level input list schema verify failed" << std::endl;
Print(true, highlightIdx);
Print("", true, highlightIdx);
std::cerr << "Note: " << errorString << std::endl;
}
return !failed;
@ -1020,6 +780,25 @@ bool In::IsGateNull() const
}
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
Gate::Gate(GateId id, OpCode opcode, ValueCode bitValue, BitField bitfield, Gate *inList[], TypeCode type,
MarkCode mark)
: id_(id), opcode_(opcode), bitValue_(bitValue), type_(type), stamp_(1), mark_(mark), bitfield_(bitfield),
firstOut_(0)
{
auto numIns = GetNumIns();
for (size_t idx = 0; idx < numIns; idx++) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
auto in = inList[idx];
if (in == nullptr) {
GetIn(idx)->SetGateNull();
} else {
NewIn(idx, in);
}
auto curOut = GetOut(idx);
curOut->SetIndex(idx);
}
}
Gate::Gate(GateId id, OpCode opcode, BitField bitfield, Gate *inList[], TypeCode type, MarkCode mark)
: id_(id), opcode_(opcode), type_(type), stamp_(1), mark_(mark), bitfield_(bitfield), firstOut_(0)
{
@ -1198,6 +977,16 @@ OpCode Gate::GetOpCode() const
return opcode_;
}
ValueCode Gate::GetValueCode() const
{
return bitValue_;
}
void Gate::SetValueCode(ValueCode valueCode)
{
bitValue_ = valueCode;
}
void Gate::SetOpCode(OpCode opcode)
{
opcode_ = opcode;
@ -1233,27 +1022,54 @@ void Gate::SetBitField(BitField bitfield)
bitfield_ = bitfield;
}
void Gate::Print(bool inListPreview, size_t highlightIdx) const
std::string Gate::ValueCodeStr(ValueCode valCode) const
{
const std::map<ValueCode, const char *> strMap = {
{NOVALUE, "NOVALUE"},
{ANYVALUE, "ANYVALUE"},
{ARCH, "ARCH"},
{FLEX, "FLEX"},
{INT1, "INT1"},
{INT8, "INT8"},
{INT16, "INT16"},
{INT32, "INT32"},
{INT64, "INT64"},
{FLOAT32, "FLOAT32"},
{FLOAT64, "FLOAT64"},
};
if (strMap.count(valCode) > 0) {
return strMap.at(valCode);
}
return "ValueCode-" + std::to_string(valCode);
}
void Gate::Print(std::string bytecode, bool inListPreview, size_t highlightIdx) const
{
if (GetOpCode() != OpCode::NOP) {
std::cerr << std::dec << "("
<< "id=" << id_ << ", "
<< "op=" << GetOpCode().Str() << ", "
<< ((bytecode.compare("") == 0) ? "" : "bytecode=") << bytecode
<< ((bytecode.compare("") == 0) ? "" : ", ")
<< "valCode=" << ValueCodeStr(GetValueCode()) << ", "
<< "bitfield=" << std::to_string(bitfield_) << ", "
<< "type=" << static_cast<uint32_t>(type_) << ", "
<< "stamp=" << static_cast<uint32_t>(stamp_) << ", "
<< "mark=" << static_cast<uint32_t>(mark_) << ", ";
std::cerr << "in="
<< "[";
for (size_t idx = 0; idx < GetNumIns(); idx++) {
std::cerr << std::dec << ((idx == 0) ? "" : " ") << ((idx == highlightIdx) ? "\033[4;31m" : "")
<< ((IsInGateNull(idx)
? "N"
: (std::to_string(GetInGateConst(idx)->GetId()) +
(inListPreview ? std::string(":" + GetInGateConst(idx)->GetOpCode().Str())
: std::string("")))))
<< ((idx == highlightIdx) ? "\033[0m" : "");
}
auto numInsArray = GetOpCode().GetOpCodeNumInsArray(GetBitField());
size_t idx = 0;
auto stateSize = numInsArray[0];
auto dependSize = numInsArray[1];
auto valueSize = numInsArray[2]; // 2 : 2 means the third element.
auto rootSize = numInsArray[3]; // 3 : 3 means the four element.
idx = PrintInGate(stateSize, idx, 0, inListPreview, highlightIdx);
idx = PrintInGate(stateSize + dependSize, idx, stateSize, inListPreview, highlightIdx);
idx = PrintInGate(stateSize + dependSize + valueSize, idx, stateSize + dependSize, inListPreview, highlightIdx);
PrintInGate(stateSize + dependSize + valueSize + rootSize, idx, stateSize + dependSize + valueSize,
inListPreview, highlightIdx, true);
std::cerr << "]"
<< ", ";
std::cerr << "out="
@ -1276,6 +1092,29 @@ void Gate::Print(bool inListPreview, size_t highlightIdx) const
}
}
size_t Gate::PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx,
bool isEnd) const
{
std::cerr << "[";
for (; idx < numIns; idx++) {
std::cerr << std::dec << ((idx == size) ? "" : " ") << ((idx == highlightIdx) ? "\033[4;31m" : "")
<< ((IsInGateNull(idx)
? "N"
: (std::to_string(GetInGateConst(idx)->GetId()) +
(inListPreview ? std::string(":" + GetInGateConst(idx)->GetOpCode().Str())
: std::string("")))))
<< ((idx == highlightIdx) ? "\033[0m" : "");
}
std::cerr << "]"
<< ((isEnd) ? "" : ", ");
return idx;
}
void Gate::PrintByteCode(std::string bytecode) const
{
Print(bytecode);
}
MarkCode Gate::GetMark(TimeStamp stamp) const
{
return (stamp_ == stamp) ? mark_ : MarkCode::EMPTY;
@ -1319,9 +1158,10 @@ bool OpCode::IsState() const
bool OpCode::IsGeneralState() const
{
return ((op_ == OpCode::IF_TRUE) || (op_ == OpCode::IF_FALSE) || (op_ == OpCode::SWITCH_CASE) ||
(op_ == OpCode::DEFAULT_CASE) || (op_ == OpCode::MERGE) || (op_ == OpCode::LOOP_BEGIN) ||
(op_ == OpCode::ORDINARY_BLOCK) || (op_ == OpCode::STATE_ENTRY));
return ((op_ == OpCode::IF_TRUE) || (op_ == OpCode::IF_FALSE) || (op_ == OpCode::IF_SUCCESS) ||
(op_ == OpCode::IF_EXCEPTION) || (op_ == OpCode::SWITCH_CASE) ||
(op_ == OpCode::DEFAULT_CASE) || (op_ == OpCode::MERGE) || (op_ == OpCode::LOOP_BEGIN) ||
(op_ == OpCode::ORDINARY_BLOCK) || (op_ == OpCode::STATE_ENTRY));
}
bool OpCode::IsTerminalState() const
@ -1337,7 +1177,8 @@ bool OpCode::IsCFGMerge() const
bool OpCode::IsControlCase() const
{
return (op_ == OpCode::IF_BRANCH) || (op_ == OpCode::SWITCH_BRANCH) || (op_ == OpCode::IF_TRUE) ||
(op_ == OpCode::IF_FALSE) || (op_ == OpCode::SWITCH_CASE) || (op_ == OpCode::DEFAULT_CASE);
(op_ == OpCode::IF_FALSE) || (op_ == OpCode::IF_SUCCESS) || (op_ == OpCode::IF_EXCEPTION) ||
(op_ == OpCode::SWITCH_CASE) || (op_ == OpCode::DEFAULT_CASE);
}
bool OpCode::IsLoopHead() const

View File

@ -26,8 +26,8 @@
#include <type_traits>
#include <vector>
#include "libpandabase/macros.h"
#include "ecmascript/compiler/type.h"
#include "libpandabase/macros.h"
namespace panda::ecmascript::kungfu {
using GateRef = int32_t; // for external users
@ -35,15 +35,18 @@ using GateId = uint32_t;
using GateOp = uint8_t;
using GateMark = uint8_t;
using TimeStamp = uint8_t;
using GateRef = int32_t;
using SecondaryOp = uint8_t;
using BitField = uint64_t;
using OutIdx = uint32_t;
class Gate;
struct Properties;
class BytecodeCircuitBuilder;
enum ValueCode {
NOVALUE,
ANYVALUE,
ARCH,
FLEX,
INT1,
INT8,
INT16,
@ -77,166 +80,71 @@ public:
SWITCH_BRANCH,
IF_TRUE,
IF_FALSE,
IF_SUCCESS,
IF_EXCEPTION,
SWITCH_CASE,
DEFAULT_CASE,
MERGE,
LOOP_BEGIN,
LOOP_BACK,
VALUE_SELECTOR_JS,
VALUE_SELECTOR_INT1,
VALUE_SELECTOR_INT8,
VALUE_SELECTOR_INT16,
VALUE_SELECTOR_INT32,
VALUE_SELECTOR_INT64,
VALUE_SELECTOR_FLOAT32,
VALUE_SELECTOR_FLOAT64,
VALUE_SELECTOR_ANYVALUE,
VALUE_SELECTOR,
DEPEND_SELECTOR,
DEPEND_RELAY,
DEPEND_AND,
// High Level IR
JS_CALL,
JS_CONSTANT,
JS_ARG,
JS_ADD,
JS_SUB,
JS_MUL,
JS_EXP,
JS_DIV,
JS_MOD,
JS_AND,
JS_XOR,
JS_OR,
JS_LSL,
JS_LSR,
JS_ASR,
JS_LOGIC_AND,
JS_LOGIC_OR,
JS_LT,
JS_LE,
JS_GT,
JS_GE,
JS_EQ,
JS_NE,
JS_STRICT_EQ,
JS_STRICT_NE,
JS_LOGIC_NOT,
JS_BYTECODE,
// Middle Level IR
CALL,
INT1_CALL,
INT8_CALL,
INT16_CALL,
INT32_CALL,
INT64_CALL,
FLOAT32_CALL,
FLOAT64_CALL,
TAGGED_POINTER_CALL,
ANYVALUE_CALL,
ALLOCA,
INT1_ARG,
INT8_ARG,
INT16_ARG,
INT32_ARG,
INT64_ARG,
FLOAT32_ARG,
FLOAT64_ARG,
ARG,
MUTABLE_DATA,
CONST_DATA,
INT1_CONSTANT,
INT8_CONSTANT,
INT16_CONSTANT,
INT32_CONSTANT,
INT64_CONSTANT,
FLOAT32_CONSTANT,
FLOAT64_CONSTANT,
ZEXT_INT32_TO_INT64,
ZEXT_INT1_TO_INT32,
ZEXT_INT8_TO_INT32,
ZEXT_INT16_TO_INT32,
ZEXT_INT1_TO_INT64,
SEXT_INT32_TO_INT64,
SEXT_INT1_TO_INT32,
SEXT_INT8_TO_INT32,
SEXT_INT16_TO_INT32,
SEXT_INT1_TO_INT64,
TRUNC_INT64_TO_INT32,
TRUNC_INT64_TO_INT1,
TRUNC_INT32_TO_INT1,
INT32_REV,
INT32_ADD,
INT32_SUB,
INT32_MUL,
INT32_EXP,
INT32_SDIV,
INT32_SMOD,
INT32_UDIV,
INT32_UMOD,
INT32_AND,
INT32_XOR,
INT32_OR,
INT32_LSL,
INT32_LSR,
INT32_ASR,
INT32_SLT,
INT32_SLE,
INT32_SGT,
INT32_SGE,
INT32_ULT,
INT32_ULE,
INT32_UGT,
INT32_UGE,
INT32_EQ,
INT32_NE,
INT64_REV,
INT64_ADD,
INT64_SUB,
INT64_MUL,
INT64_EXP,
INT64_SDIV,
INT64_SMOD,
INT64_UDIV,
INT64_UMOD,
INT64_AND,
INT64_XOR,
INT64_OR,
INT64_LSL,
INT64_LSR,
INT64_ASR,
INT64_SLT,
INT64_SLE,
INT64_SGT,
INT64_SGE,
INT64_ULT,
INT64_ULE,
INT64_UGT,
INT64_UGE,
INT64_EQ,
INT64_NE,
FLOAT64_ADD,
FLOAT64_SUB,
FLOAT64_MUL,
FLOAT64_DIV,
FLOAT64_EXP,
FLOAT64_EQ,
FLOAT64_SMOD,
INT8_LOAD,
INT16_LOAD,
INT32_LOAD,
INT64_LOAD,
FLOAT32_LOAD,
FLOAT64_LOAD,
INT8_STORE,
INT16_STORE,
INT32_STORE,
INT64_STORE,
FLOAT32_STORE,
FLOAT64_STORE,
INT32_TO_FLOAT64,
FLOAT64_TO_INT32,
TAGGED_POINTER_TO_INT64,
BITCAST_INT64_TO_FLOAT64,
BITCAST_FLOAT64_TO_INT64,
TAG64_TO_INT1,
CONSTANT,
ZEXT_TO_INT64,
ZEXT_TO_INT32,
SEXT_TO_INT64,
SEXT_TO_INT32,
TRUNC_TO_INT32,
TRUNC_TO_INT1,
REV,
ADD,
SUB,
MUL,
EXP,
SDIV,
SMOD,
UDIV,
UMOD,
FDIV,
FMOD,
AND,
XOR,
OR,
LSL,
LSR,
ASR,
SLT,
SLE,
SGT,
SGE,
ULT,
ULE,
UGT,
UGE,
FLT,
FLE,
FGT,
FGE,
EQ,
NE,
LOAD,
STORE,
TAGGED_TO_INT64,
SIGNED_INT_TO_FLOAT,
UNSIGNED_INT_TO_FLOAT,
FLOAT_TO_SIGNED_INT,
UNSIGNED_FLOAT_TO_INT,
BITCAST,
};
OpCode() = default;
@ -330,6 +238,7 @@ private:
class Gate {
public:
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
Gate(GateId id, OpCode opcode, ValueCode bitValue, BitField bitfield, Gate *inList[], TypeCode type, MarkCode mark);
Gate(GateId id, OpCode opcode, BitField bitfield, Gate *inList[], TypeCode type, MarkCode mark);
[[nodiscard]] static size_t GetGateSize(size_t numIns);
[[nodiscard]] size_t GetGateSize() const;
@ -367,7 +276,10 @@ public:
[[nodiscard]] BitField GetBitField() const;
void SetBitField(BitField bitfield);
void AppendIn(const Gate *in); // considered very slow
void Print(bool inListPreview = false, size_t highlightIdx = -1) const;
void Print(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,
bool isEnd = false) const;
void PrintByteCode(std::string bytecode) const;
std::optional<std::pair<std::string, size_t>> CheckNullInput() const;
std::optional<std::pair<std::string, size_t>> CheckStateInput() const;
std::optional<std::pair<std::string, size_t>> CheckValueInput() const;
@ -381,6 +293,9 @@ public:
[[nodiscard]] bool Verify() const;
[[nodiscard]] MarkCode GetMark(TimeStamp stamp) const;
void SetMark(MarkCode mark, TimeStamp stamp);
[[nodiscard]] ValueCode GetValueCode() const;
void SetValueCode(ValueCode valueCode);
std::string ValueCodeStr(ValueCode valCode) const;
~Gate() = default;
private:
@ -388,8 +303,9 @@ private:
// out(2)
// out(1)
// out(0)
GateId id_;
GateId id_ {0};
OpCode opcode_;
ValueCode bitValue_ = ValueCode::NOVALUE;
TypeCode type_;
TimeStamp stamp_;
MarkCode mark_;
@ -400,6 +316,6 @@ private:
// in(2)
// ...
};
} // namespace panda::ecmascript::kungfu
} // namespace panda::ecmascript::kungfu
#endif // ECMASCRIPT_COMPILER_GATE_H

View File

@ -54,7 +54,7 @@
using namespace panda::ecmascript;
namespace panda::ecmascript::kungfu {
void LLVMCodeGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index,
void LLVMIRGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index,
const CompilationConfig *cfg)
{
auto function = module_->GetStubFunction(index);
@ -203,7 +203,7 @@ void LLVMAssembler::BuildAndRunPasses()
{
COMPILER_LOG(DEBUG) << "BuildAndRunPasses - ";
LLVMPassManagerBuilderRef pmBuilder = LLVMPassManagerBuilderCreate();
LLVMPassManagerBuilderSetOptLevel(pmBuilder, 3); // using O3 optimization level
LLVMPassManagerBuilderSetOptLevel(pmBuilder, options_.OptLevel); // using O3 optimization level
LLVMPassManagerBuilderSetSizeLevel(pmBuilder, 0);
// pass manager creation:rs4gc pass is the only pass in modPass, other opt module-based pass are in modPass1
@ -306,7 +306,7 @@ void LLVMAssembler::Initialize()
}
llvm::linkAllBuiltinGCs();
LLVMInitializeMCJITCompilerOptions(&options_, sizeof(options_));
options_.OptLevel = 2; // opt level 2
options_.OptLevel = 3; // opt level 2
// Just ensure that this field still exists.
options_.NoFramePointerElim = true;
}

View File

@ -196,10 +196,10 @@ private:
struct CodeInfo codeInfo_ {};
};
class LLVMCodeGeneratorImpl : public CodeGeneratorImpl {
class LLVMIRGeneratorImpl : public CodeGeneratorImpl {
public:
explicit LLVMCodeGeneratorImpl(LLVMStubModule *module) : module_(module) {}
~LLVMCodeGeneratorImpl() = default;
explicit LLVMIRGeneratorImpl(LLVMStubModule *module) : module_(module) {}
~LLVMIRGeneratorImpl() = default;
void GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index,
const CompilationConfig *cfg) override;

View File

@ -18,7 +18,6 @@
#include <iostream>
#include <set>
#include <string>
#include <tuple>
#include "ecmascript/compiler/circuit.h"
#include "ecmascript/compiler/compiler_macros.h"
@ -26,7 +25,6 @@
#include "ecmascript/compiler/gate.h"
#include "ecmascript/compiler/stub_descriptor.h"
#include "ecmascript/frames.h"
#include "ecmascript/js_array.h"
#include "ecmascript/js_thread.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/Host.h"
@ -106,81 +104,42 @@ void LLVMIRBuilder::AssignHandleMap()
{OpCode::IF_FALSE, &LLVMIRBuilder::HandleGoto}, {OpCode::SWITCH_CASE, &LLVMIRBuilder::HandleGoto},
{OpCode::MERGE, &LLVMIRBuilder::HandleGoto}, {OpCode::DEFAULT_CASE, &LLVMIRBuilder::HandleGoto},
{OpCode::LOOP_BEGIN, &LLVMIRBuilder::HandleGoto}, {OpCode::LOOP_BACK, &LLVMIRBuilder::HandleGoto},
{OpCode::VALUE_SELECTOR_INT1, &LLVMIRBuilder::HandlePhi},
{OpCode::VALUE_SELECTOR_INT32, &LLVMIRBuilder::HandlePhi},
{OpCode::VALUE_SELECTOR_INT64, &LLVMIRBuilder::HandlePhi},
{OpCode::VALUE_SELECTOR_FLOAT64, &LLVMIRBuilder::HandlePhi},
{OpCode::CALL, &LLVMIRBuilder::HandleCall}, {OpCode::INT1_CALL, &LLVMIRBuilder::HandleCall},
{OpCode::INT32_CALL, &LLVMIRBuilder::HandleCall}, {OpCode::FLOAT64_CALL, &LLVMIRBuilder::HandleCall},
{OpCode::INT64_CALL, &LLVMIRBuilder::HandleCall}, {OpCode::ALLOCA, &LLVMIRBuilder::HandleAlloca},
{OpCode::ANYVALUE_CALL, &LLVMIRBuilder::HandleCall},
{OpCode::INT1_ARG, &LLVMIRBuilder::HandleParameter}, {OpCode::INT32_ARG, &LLVMIRBuilder::HandleParameter},
{OpCode::INT64_ARG, &LLVMIRBuilder::HandleParameter},
{OpCode::INT32_CONSTANT, &LLVMIRBuilder::HandleInt32Constant},
{OpCode::JS_CONSTANT, &LLVMIRBuilder::HandleInt64Constant},
{OpCode::INT64_CONSTANT, &LLVMIRBuilder::HandleInt64Constant},
{OpCode::FLOAT64_CONSTANT, &LLVMIRBuilder::HandleFloat64Constant},
{OpCode::ZEXT_INT1_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
{OpCode::ZEXT_INT8_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
{OpCode::ZEXT_INT16_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
{OpCode::ZEXT_INT32_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
{OpCode::ZEXT_INT1_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
{OpCode::SEXT_INT1_TO_INT32, &LLVMIRBuilder::HandleSExtInt},
{OpCode::SEXT_INT1_TO_INT64, &LLVMIRBuilder::HandleSExtInt},
{OpCode::SEXT_INT32_TO_INT64, &LLVMIRBuilder::HandleSExtInt},
{OpCode::TRUNC_INT64_TO_INT1, &LLVMIRBuilder::HandleCastIntXToIntY},
{OpCode::TRUNC_INT32_TO_INT1, &LLVMIRBuilder::HandleCastIntXToIntY},
{OpCode::TRUNC_INT64_TO_INT32, &LLVMIRBuilder::HandleCastIntXToIntY},
{OpCode::INT32_REV, &LLVMIRBuilder::HandleIntRev},
{OpCode::INT64_REV, &LLVMIRBuilder::HandleIntRev},
{OpCode::INT32_ADD, &LLVMIRBuilder::HandleIntAdd},
{OpCode::INT64_ADD, &LLVMIRBuilder::HandleIntAdd},
{OpCode::FLOAT64_ADD, &LLVMIRBuilder::HandleFloatAdd},
{OpCode::FLOAT64_SUB, &LLVMIRBuilder::HandleFloatSub},
{OpCode::FLOAT64_MUL, &LLVMIRBuilder::HandleFloatMul},
{OpCode::FLOAT64_DIV, &LLVMIRBuilder::HandleFloatDiv},
{OpCode::INT32_SUB, &LLVMIRBuilder::HandleIntSub},
{OpCode::INT64_SUB, &LLVMIRBuilder::HandleIntSub},
{OpCode::INT32_MUL, &LLVMIRBuilder::HandleIntMul},
{OpCode::INT64_MUL, &LLVMIRBuilder::HandleIntMul},
{OpCode::INT32_AND, &LLVMIRBuilder::HandleIntAnd},
{OpCode::INT64_AND, &LLVMIRBuilder::HandleIntAnd},
{OpCode::INT32_OR, &LLVMIRBuilder::HandleIntOr},
{OpCode::INT64_OR, &LLVMIRBuilder::HandleIntOr},
{OpCode::INT64_XOR, &LLVMIRBuilder::HandleIntXor},
{OpCode::INT32_LSR, &LLVMIRBuilder::HandleIntLsr},
{OpCode::INT64_LSR, &LLVMIRBuilder::HandleIntLsr},
{OpCode::INT32_SLT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_SLT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT32_ULT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_ULT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT32_SLE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_SLE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT32_SGT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_SGT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT32_SGE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_SGE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT32_EQ, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_EQ, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::FLOAT64_EQ, &LLVMIRBuilder::HandleFloatOrDoubleCmp},
{OpCode::INT32_NE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT64_NE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::INT8_LOAD, &LLVMIRBuilder::HandleLoad},
{OpCode::INT16_LOAD, &LLVMIRBuilder::HandleLoad},
{OpCode::INT32_LOAD, &LLVMIRBuilder::HandleLoad},
{OpCode::INT64_LOAD, &LLVMIRBuilder::HandleLoad},
{OpCode::INT32_STORE, &LLVMIRBuilder::HandleStore},
{OpCode::INT64_STORE, &LLVMIRBuilder::HandleStore},
{OpCode::INT32_TO_FLOAT64, &LLVMIRBuilder::HandleChangeInt32ToDouble},
{OpCode::FLOAT64_TO_INT32, &LLVMIRBuilder::HandleChangeDoubleToInt32},
{OpCode::TAGGED_POINTER_TO_INT64, &LLVMIRBuilder::HandleChangeTaggedPointerToInt64},
{OpCode::BITCAST_INT64_TO_FLOAT64, &LLVMIRBuilder::HandleCastInt64ToDouble},
{OpCode::BITCAST_FLOAT64_TO_INT64, &LLVMIRBuilder::HandleCastDoubleToInt},
{OpCode::INT32_LSL, &LLVMIRBuilder::HandleIntLsl},
{OpCode::INT64_LSL, &LLVMIRBuilder::HandleIntLsl},
{OpCode::FLOAT64_SMOD, &LLVMIRBuilder::HandleFloatMod},
{OpCode::INT32_SMOD, &LLVMIRBuilder::HandleIntMod},
{OpCode::TAGGED_POINTER_CALL, &LLVMIRBuilder::HandleCall},
{OpCode::VALUE_SELECTOR, &LLVMIRBuilder::HandlePhi},
{OpCode::CALL, &LLVMIRBuilder::HandleCall},
{OpCode::ALLOCA, &LLVMIRBuilder::HandleAlloca},
{OpCode::ARG, &LLVMIRBuilder::HandleParameter},
{OpCode::CONSTANT, &LLVMIRBuilder::HandleConstant},
{OpCode::ZEXT_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
{OpCode::ZEXT_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
{OpCode::SEXT_TO_INT32, &LLVMIRBuilder::HandleSExtInt},
{OpCode::SEXT_TO_INT64, &LLVMIRBuilder::HandleSExtInt},
{OpCode::TRUNC_TO_INT1, &LLVMIRBuilder::HandleCastIntXToIntY},
{OpCode::TRUNC_TO_INT32, &LLVMIRBuilder::HandleCastIntXToIntY},
{OpCode::REV, &LLVMIRBuilder::HandleIntRev},
{OpCode::ADD, &LLVMIRBuilder::HandleAdd},
{OpCode::SUB, &LLVMIRBuilder::HandleSub},
{OpCode::MUL, &LLVMIRBuilder::HandleMul},
{OpCode::FDIV, &LLVMIRBuilder::HandleFloatDiv},
{OpCode::AND, &LLVMIRBuilder::HandleIntAnd},
{OpCode::OR, &LLVMIRBuilder::HandleIntOr},
{OpCode::XOR, &LLVMIRBuilder::HandleIntXor},
{OpCode::LSR, &LLVMIRBuilder::HandleIntLsr},
{OpCode::SLT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::ULT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::SLE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::SGT, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::SGE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::NE, &LLVMIRBuilder::HandleIntOrUintCmp},
{OpCode::EQ, &LLVMIRBuilder::HandleEqCmp},
{OpCode::LOAD, &LLVMIRBuilder::HandleLoad},
{OpCode::STORE, &LLVMIRBuilder::HandleStore},
{OpCode::SIGNED_INT_TO_FLOAT, &LLVMIRBuilder::HandleChangeInt32ToDouble},
{OpCode::FLOAT_TO_SIGNED_INT, &LLVMIRBuilder::HandleChangeDoubleToInt32},
{OpCode::TAGGED_TO_INT64, &LLVMIRBuilder::HandleChangeTaggedPointerToInt64},
{OpCode::BITCAST, &LLVMIRBuilder::HandleBitCast},
{OpCode::LSL, &LLVMIRBuilder::HandleIntLsl},
{OpCode::SMOD, &LLVMIRBuilder::HandleMod},
{OpCode::FMOD, &LLVMIRBuilder::HandleMod},
};
opCodeHandleIgnore = {
OpCode::NOP, OpCode::CIRCUIT_ROOT, OpCode::DEPEND_ENTRY,
@ -478,20 +437,7 @@ LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const
void LLVMIRBuilder::HandleCall(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
switch (circuit_->GetOpCode(gate)) {
case OpCode::CALL:
case OpCode::ANYVALUE_CALL:
case OpCode::INT1_CALL:
case OpCode::INT32_CALL:
case OpCode::FLOAT64_CALL:
case OpCode::INT64_CALL: {
VisitCall(gate, ins);
break;
}
default: {
break;
}
}
VisitCall(gate, ins);
}
LLVMValueRef LLVMIRBuilder::GetCurrentSP()
@ -515,7 +461,7 @@ void LLVMIRBuilder::SaveCurrentSP()
LLVMValueRef frameSpSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_,
3 * slotSize_, false), ""); // 3: type + threadsp + current sp
LLVMValueRef addr = LLVMBuildIntToPtr(builder_, frameSpSlotAddr,
LLVMPointerType(slotType_, 0), "frameCallSiteSP.Addr");
LLVMPointerType(slotType_, 0), "frameCallSiteSP.Addr");
LLVMMetadataRef meta;
if (compCfg_->IsAmd64()) {
meta = LLVMMDStringInContext2(context_, "rsp", 4); // 4 : 4 means len of "rsp"
@ -685,11 +631,12 @@ void LLVMIRBuilder::HandleAlloca(GateRef gate)
void LLVMIRBuilder::VisitAlloca(GateRef gate)
{
uint64_t sizeEnum = circuit_->GetBitField(gate);
LLVMTypeRef sizeType = GetMachineRepType(static_cast<MachineRep>(sizeEnum));
COMPILER_LOG(DEBUG) << LLVMGetTypeKind(sizeType);
gateToLLVMMaps_[gate] = LLVMBuildPtrToInt(builder_, LLVMBuildAlloca(builder_, sizeType, ""),
ConvertLLVMTypeFromGate(gate), ""); // NOTE: pointer val is currently viewed as 64bits
uint64_t machineRep = circuit_->GetBitField(gate);
LLVMTypeRef dataType = GetMachineRepType(static_cast<MachineRep>(machineRep));
COMPILER_LOG(DEBUG) << LLVMPrintTypeToString(dataType);
COMPILER_LOG(DEBUG) << LLVMPrintTypeToString(ConvertLLVMTypeFromGate(gate));
gateToLLVMMaps_[gate] = LLVMBuildPtrToInt(builder_, LLVMBuildAlloca(builder_, dataType, ""),
ConvertLLVMTypeFromGate(gate), "");
return;
}
@ -845,23 +792,47 @@ void LLVMIRBuilder::VisitGoto(int block, int bbOut)
EndCurrentBlock();
}
void LLVMIRBuilder::HandleInt32Constant(GateRef gate)
void LLVMIRBuilder::HandleConstant(GateRef gate)
{
int32_t value = circuit_->GetBitField(gate);
VisitInt32Constant(gate, value);
std::bitset<64> value = circuit_->GetBitField(gate); // 64: bit width
VisitConstant(gate, value);
}
void LLVMIRBuilder::HandleInt64Constant(GateRef gate)
void LLVMIRBuilder::VisitConstant(GateRef gate, std::bitset<64> value) // 64: bit width
{
int64_t value = circuit_->GetBitField(gate);
VisitInt64Constant(gate, value);
}
void LLVMIRBuilder::HandleFloat64Constant(GateRef gate)
{
int64_t value = circuit_->GetBitField(gate);
double doubleValue = bit_cast<double>(value); // actual double value
VisitFloat64Constant(gate, doubleValue);
LLVMValueRef llvmValue = nullptr;
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
if (valCode == ValueCode::INT32) {
llvmValue = LLVMConstInt(LLVMInt32Type(), value.to_ulong(), 0);
} else if (valCode == ValueCode::INT64) {
llvmValue = LLVMConstInt(LLVMInt64Type(), value.to_ullong(), 0);
LLVMTypeRef type = ConvertLLVMTypeFromGate(gate);
if (LLVMGetTypeKind(type) == LLVMPointerTypeKind) {
llvmValue = LLVMBuildIntToPtr(builder_, llvmValue, type, "");
} else if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
LLVMValueRef tmp1Value =
LLVMBuildLShr(builder_, llvmValue, LLVMConstInt(LLVMInt32Type(), 32, 0), ""); // 32: offset
LLVMValueRef tmp2Value = LLVMBuildIntCast(builder_, llvmValue, LLVMInt32Type(), ""); // low
LLVMValueRef emptyValue = LLVMGetUndef(type);
tmp1Value = LLVMBuildIntToPtr(builder_, tmp1Value, LLVMPointerType(LLVMInt8Type(), 1), "");
tmp2Value = LLVMBuildIntToPtr(builder_, tmp2Value, LLVMPointerType(LLVMInt8Type(), 1), "");
llvmValue = LLVMBuildInsertElement(
builder_, emptyValue, tmp2Value, LLVMConstInt(LLVMInt32Type(), 0, 0), "");
llvmValue = LLVMBuildInsertElement(builder_, llvmValue, tmp1Value, LLVMConstInt(LLVMInt32Type(), 1, 0), "");
} else if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind) {
// do nothing
} else {
abort();
}
} else if (valCode == ValueCode::FLOAT64) {
auto doubleValue = bit_cast<double>(value.to_ullong()); // actual double value
llvmValue = LLVMConstReal(LLVMDoubleType(), doubleValue);
} else {
abort();
}
gateToLLVMMaps_[gate] = llvmValue;
COMPILER_LOG(DEBUG) << "VisitConstant set gate:" << gate << " value:" << value;
COMPILER_LOG(DEBUG) << "VisitConstant " << LLVMValueToString(llvmValue);
}
void LLVMIRBuilder::HandleZExtInt(GateRef gate)
@ -876,47 +847,6 @@ void LLVMIRBuilder::HandleSExtInt(GateRef gate)
VisitSExtInt(gate, ins[0]);
}
void LLVMIRBuilder::VisitInt32Constant(GateRef gate, int32_t value)
{
LLVMValueRef llvmValue = LLVMConstInt(LLVMInt32Type(), value, 0);
gateToLLVMMaps_[gate] = llvmValue;
COMPILER_LOG(DEBUG) << "VisitInt32Constant set gate:" << gate << " value:" << value;
COMPILER_LOG(DEBUG) << "VisitInt32Constant " << LLVMValueToString(llvmValue);
}
void LLVMIRBuilder::VisitInt64Constant(GateRef gate, int64_t value)
{
LLVMValueRef llvmValue = LLVMConstInt(LLVMInt64Type(), value, 0);
LLVMTypeRef type = ConvertLLVMTypeFromGate(gate);
if (LLVMGetTypeKind(type) == LLVMPointerTypeKind) {
llvmValue = LLVMBuildIntToPtr(builder_, llvmValue, type, "");
} else if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
LLVMValueRef tmp1Value =
LLVMBuildLShr(builder_, llvmValue, LLVMConstInt(LLVMInt32Type(), 32, 0), ""); // 32: offset
LLVMValueRef tmp2Value = LLVMBuildIntCast(builder_, llvmValue, LLVMInt32Type(), ""); // low
LLVMValueRef emptyValue = LLVMGetUndef(type);
tmp1Value = LLVMBuildIntToPtr(builder_, tmp1Value, LLVMPointerType(LLVMInt8Type(), 1), "");
tmp2Value = LLVMBuildIntToPtr(builder_, tmp2Value, LLVMPointerType(LLVMInt8Type(), 1), "");
llvmValue = LLVMBuildInsertElement(builder_, emptyValue, tmp2Value, LLVMConstInt(LLVMInt32Type(), 0, 0), "");
llvmValue = LLVMBuildInsertElement(builder_, llvmValue, tmp1Value, LLVMConstInt(LLVMInt32Type(), 1, 0), "");
} else if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind) {
// do nothing
} else {
abort();
}
gateToLLVMMaps_[gate] = llvmValue;
COMPILER_LOG(DEBUG) << "VisitInt64Constant set gate:" << gate << " value:" << value;
COMPILER_LOG(DEBUG) << "VisitInt64Constant " << LLVMValueToString(llvmValue);
}
void LLVMIRBuilder::VisitFloat64Constant(GateRef gate, double value)
{
LLVMValueRef llvmValue = LLVMConstReal(LLVMDoubleType(), value);
gateToLLVMMaps_[gate] = llvmValue;
COMPILER_LOG(DEBUG) << "VisitFloat64Constant set gate:" << gate << " value:" << value;
COMPILER_LOG(DEBUG) << "VisitFloat64Constant " << LLVMValueToString(llvmValue);
}
void LLVMIRBuilder::HandleParameter(GateRef gate)
{
return VisitParameter(gate);
@ -927,7 +857,7 @@ void LLVMIRBuilder::VisitParameter(GateRef gate)
int argth = circuit_->LoadGatePtrConst(gate)->GetBitField();
COMPILER_LOG(DEBUG) << " Parameter value" << argth;
LLVMValueRef value = LLVMGetParam(function_, argth);
ASSERT(LLVMTypeOf(value) == ConvertLLVMTypeFromGate(gate));
gateToLLVMMaps_[gate] = value;
COMPILER_LOG(DEBUG) << "VisitParameter set gate:" << gate << " value:" << value;
// NOTE: caller put args, otherwise crash
@ -949,38 +879,30 @@ void LLVMIRBuilder::HandleBranch(GateRef gate)
VisitBranch(gate, ins[1], bbTrue, bbFalse);
}
void LLVMIRBuilder::HandleIntMod(GateRef gate)
void LLVMIRBuilder::HandleMod(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
VisitIntMod(gate, ins[0], ins[1]);
VisitMod(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::VisitIntMod(GateRef gate, GateRef e1, GateRef e2)
void LLVMIRBuilder::VisitMod(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "int mod gate:" << gate;
COMPILER_LOG(DEBUG) << "mod gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildSRem(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleFloatMod(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
VisitFloatMod(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::VisitFloatMod(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "float mod gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFRem(builder_, e1Value, e2Value, "");
LLVMValueRef result = nullptr;
ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e1));
ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e2));
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
if (valCode == ValueCode::INT32) {
result = LLVMBuildSRem(builder_, e1Value, e2Value, "");
} else if (valCode == ValueCode::FLOAT64) {
result = LLVMBuildFRem(builder_, e1Value, e2Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
@ -1123,18 +1045,6 @@ LLVMValueRef LLVMIRBuilder::CanonicalizeToPtr(LLVMValueRef value)
}
}
void LLVMIRBuilder::VisitFloatOrDoubleCmp(GateRef gate, GateRef e1, GateRef e2, LLVMRealPredicate opcode)
{
COMPILER_LOG(DEBUG) << "cmp gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFCmp(builder_, opcode, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleIntRev(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
@ -1146,18 +1056,18 @@ void LLVMIRBuilder::VisitIntRev(GateRef gate, GateRef e1)
COMPILER_LOG(DEBUG) << "int sign invert gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef result = LLVMBuildNot(builder_, e1Value, "");
ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e1));
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
LLVMValueRef result = nullptr;
if (valCode == ValueCode::INT32 || valCode == ValueCode::INT64) {
result = LLVMBuildNot(builder_, e1Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleIntAdd(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitIntAdd(gate, ins[0], ins[1]);
}
LLVMValueRef LLVMIRBuilder::PointerAdd(LLVMValueRef baseAddr, LLVMValueRef offset, LLVMTypeRef rep)
{
LLVMValueRef ptr = CanonicalizeToPtr(baseAddr);
@ -1174,36 +1084,6 @@ LLVMValueRef LLVMIRBuilder::VectorAdd(LLVMValueRef baseAddr, LLVMValueRef offset
return result;
}
void LLVMIRBuilder::VisitIntAdd(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "int add gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMTypeRef e1Type = ConvertLLVMTypeFromGate(e1);
LLVMValueRef result;
LLVMValueRef offset = e2Value;
/* pointer int
vector{i8 * x 2} int
*/
LLVMTypeRef returnType = ConvertLLVMTypeFromGate(gate);
if (LLVMGetTypeKind(e1Type) == LLVMPointerTypeKind) { // for scenario: pointer + offset
result = PointerAdd(e1Value, offset, returnType);
} else if (LLVMGetTypeKind(e1Type) == LLVMVectorTypeKind) {
result = VectorAdd(e1Value, offset, returnType);
} else {
LLVMValueRef tmp1Value = LLVMBuildIntCast2(builder_, e1Value, returnType, 0, "");
LLVMValueRef tmp2Value = LLVMBuildIntCast2(builder_, e2Value, returnType, 0, "");
result = LLVMBuildAdd(builder_, tmp1Value, tmp2Value, "");
if (LLVMTypeOf(tmp1Value) != LLVMTypeOf(tmp2Value)) {
ASSERT(LLVMTypeOf(tmp1Value) == LLVMTypeOf(tmp2Value));
}
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
LLVMTypeRef LLVMIRBuilder::ConvertLLVMTypeFromGate(GateRef gate) const
{
if (circuit_->GetTypeCode(gate) >= TypeCode::JS_TYPE_OBJECT_START) {
@ -1213,17 +1093,9 @@ LLVMTypeRef LLVMIRBuilder::ConvertLLVMTypeFromGate(GateRef gate) const
return LLVMPointerType(LLVMInt64Type(), 1);
}
}
switch (circuit_->GetOpCode(gate).GetValueCode()) {
switch (circuit_->LoadGatePtrConst(gate)->GetValueCode()) {
case ValueCode::NOVALUE:
return LLVMVoidType();
case ValueCode::ANYVALUE:
{
if (compCfg_->IsArm32()) {
return LLVMInt32Type();
} else {
return LLVMInt64Type();
}
}
case ValueCode::INT1:
return LLVMInt1Type();
case ValueCode::INT8:
@ -1238,42 +1110,146 @@ LLVMTypeRef LLVMIRBuilder::ConvertLLVMTypeFromGate(GateRef gate) const
return LLVMFloatType();
case ValueCode::FLOAT64:
return LLVMDoubleType();
case ValueCode::ARCH: {
if (compCfg_->IsArm32()) {
return LLVMInt32Type();
} else {
return LLVMInt64Type();
}
}
default:
abort();
}
}
void LLVMIRBuilder::HandleFloatAdd(GateRef gate)
int64_t LLVMIRBuilder::GetBitWidthFromValueCode(ValueCode valCode) const
{
switch (valCode) {
case NOVALUE:
return 0;
case ANYVALUE:
if (compCfg_->IsArm32()) {
return 32; // 32: 32bit platform
} else {
return 64; // 64: bit64 platform
}
case ARCH:
return 48; // 48: Pointer representation in different architectures
case INT1:
return 1;
case INT8:
return 8; // 8: bit width
case INT16:
return 16; // 16: bit width
case INT32:
return 32; // 32: bit width
case INT64:
return 64; // 64: bit width
case FLOAT32:
return 32; // 32: bit width
case FLOAT64:
return 64; // 64: bit width
case FLEX:
abort();
break;
}
}
void LLVMIRBuilder::HandleAdd(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitFloatAdd(gate, ins[0], ins[1]);
VisitAdd(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::VisitFloatAdd(GateRef gate, GateRef e1, GateRef e2)
void LLVMIRBuilder::VisitAdd(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "float add gate:" << gate;
COMPILER_LOG(DEBUG) << "add gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFAdd(builder_, e1Value, e2Value, "");
LLVMValueRef result = nullptr;
/* pointer int
vector{i8 * x 2} int
*/
LLVMTypeRef returnType = ConvertLLVMTypeFromGate(gate);
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
if (valCode == ValueCode::INT32 || valCode == ValueCode::INT64) {
auto e1Type = LLVMGetTypeKind(ConvertLLVMTypeFromGate(e1));
if (e1Type == LLVMVectorTypeKind) {
result = VectorAdd(e1Value, e2Value, returnType);
} else if (e1Type == LLVMPointerTypeKind) {
result = PointerAdd(e1Value, e2Value, returnType);
} else {
LLVMValueRef tmp1Value = LLVMBuildIntCast2(builder_, e1Value, returnType, 0, "");
LLVMValueRef tmp2Value = LLVMBuildIntCast2(builder_, e2Value, returnType, 0, "");
result = LLVMBuildAdd(builder_, tmp1Value, tmp2Value, "");
if (LLVMTypeOf(tmp1Value) != LLVMTypeOf(tmp2Value)) {
ASSERT(LLVMTypeOf(tmp1Value) == LLVMTypeOf(tmp2Value));
}
}
} else if (valCode == ValueCode::FLOAT64) {
result = LLVMBuildFAdd(builder_, e1Value, e2Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleFloatSub(GateRef gate)
void LLVMIRBuilder::HandleSub(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitFloatSub(gate, ins[0], ins[1]);
VisitSub(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::HandleFloatMul(GateRef gate)
void LLVMIRBuilder::VisitSub(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "sub gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = nullptr;
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
if (valCode == ValueCode::INT32 || valCode == ValueCode::INT64) {
result = LLVMBuildSub(builder_, e1Value, e2Value, "");
} else if (valCode == ValueCode::FLOAT64) {
result = LLVMBuildFSub(builder_, e1Value, e2Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleMul(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitFloatMul(gate, ins[0], ins[1]);
VisitMul(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::VisitMul(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "mul gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = nullptr;
auto valCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
if (valCode == ValueCode::INT32 || valCode == ValueCode::INT64) {
result = LLVMBuildMul(builder_, e1Value, e2Value, "");
} else if (valCode == ValueCode::FLOAT64) {
result = LLVMBuildFMul(builder_, e1Value, e2Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleFloatDiv(GateRef gate)
@ -1283,20 +1259,6 @@ void LLVMIRBuilder::HandleFloatDiv(GateRef gate)
VisitFloatDiv(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::HandleIntSub(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitIntSub(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::HandleIntMul(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitIntMul(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::HandleIntOr(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
@ -1318,43 +1280,33 @@ void LLVMIRBuilder::HandleIntLsr(GateRef gate)
VisitIntLsr(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::HandleIntOrUintCmp(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
switch (circuit_->GetOpCode(gate)) {
case OpCode::INT32_SLT: // no break, fall through
case OpCode::INT64_SLT: {
case OpCode::SLT: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntSLT);
break;
}
case OpCode::INT32_ULT: // no break, fall through
case OpCode::INT64_ULT: {
case OpCode::ULT: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntULT);
break;
}
case OpCode::INT32_SLE: // no break, fall through
case OpCode::INT64_SLE: {
case OpCode::SLE: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntSLE);
break;
}
case OpCode::INT32_SGT: // no break, fall through
case OpCode::INT64_SGT: {
case OpCode::SGT: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntSGT);
break;
}
case OpCode::INT32_SGE: // no break, fall through
case OpCode::INT64_SGE: {
case OpCode::SGE: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntSGE);
break;
}
case OpCode::INT32_EQ: // no break, fall through
case OpCode::INT64_EQ: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntEQ);
break;
}
case OpCode::INT32_NE: // no break, fall through
case OpCode::INT64_NE: {
case OpCode::NE: {
VisitIntOrUintCmp(gate, ins[0], ins[1], LLVMIntNE);
break;
}
@ -1364,11 +1316,35 @@ void LLVMIRBuilder::HandleIntOrUintCmp(GateRef gate)
}
}
void LLVMIRBuilder::HandleFloatOrDoubleCmp(GateRef gate)
void LLVMIRBuilder::HandleEqCmp(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
std::vector<GateRef> outs = circuit_->GetOutVector(gate);
VisitFloatOrDoubleCmp(gate, ins[0], ins[1], LLVMRealOEQ);
VisitEqCmp(gate, ins[0], ins[1]);
}
void LLVMIRBuilder::VisitEqCmp(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "cmp gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = nullptr;
auto e1ValCode = circuit_->LoadGatePtrConst(e1)->GetValueCode();
[[maybe_unused]]auto e2ValCode = circuit_->LoadGatePtrConst(e2)->GetValueCode();
ASSERT(e1ValCode == e2ValCode);
if (e1ValCode == ValueCode::INT32 || e1ValCode == ValueCode::INT64) {
e1Value = CanonicalizeToInt(e1Value);
e2Value = CanonicalizeToInt(e2Value);
result = LLVMBuildICmp(builder_, LLVMIntEQ, e1Value, e2Value, "");
} else if (e1ValCode == ValueCode::FLOAT64) {
result = LLVMBuildFCmp(builder_, LLVMRealOEQ, e1Value, e2Value, "");
} else {
abort();
}
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleLoad(GateRef gate)
@ -1404,30 +1380,6 @@ void LLVMIRBuilder::HandleChangeTaggedPointerToInt64(GateRef gate)
VisitChangeTaggedPointerToInt64(gate, ins[0]);
}
void LLVMIRBuilder::VisitFloatSub(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "float sub gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFSub(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::VisitFloatMul(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "float mul gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFMul(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::VisitFloatDiv(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "float div gate:" << gate;
@ -1435,35 +1387,12 @@ void LLVMIRBuilder::VisitFloatDiv(GateRef gate, GateRef e1, GateRef e2)
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildFDiv(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::VisitIntSub(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "int sub gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildSub(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::VisitIntMul(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "int mul gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef e2Value = gateToLLVMMaps_[e2];
COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
LLVMValueRef result = LLVMBuildMul(builder_, e1Value, e2Value, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::VisitIntOr(GateRef gate, GateRef e1, GateRef e2)
{
COMPILER_LOG(DEBUG) << "int or gate:" << gate;
@ -1552,6 +1481,8 @@ void LLVMIRBuilder::VisitZExtInt(GateRef gate, GateRef e1)
COMPILER_LOG(DEBUG) << "int zero extension gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
ASSERT(GetBitWidthFromValueCode(circuit_->LoadGatePtrConst(e1)->GetValueCode()) <=
GetBitWidthFromValueCode(circuit_->LoadGatePtrConst(gate)->GetValueCode()));
LLVMValueRef result = LLVMBuildZExt(builder_, e1Value, ConvertLLVMTypeFromGate(gate), "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
@ -1613,50 +1544,26 @@ void LLVMIRBuilder::VisitChangeTaggedPointerToInt64(GateRef gate, GateRef e1)
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleCastInt64ToDouble(GateRef gate)
void LLVMIRBuilder::HandleBitCast(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
VisitCastInt64ToDouble(gate, ins[0]);
VisitBitCast(gate, ins[0]);
}
void LLVMIRBuilder::VisitCastInt64ToDouble(GateRef gate, GateRef e1)
void LLVMIRBuilder::VisitBitCast(GateRef gate, GateRef e1)
{
COMPILER_LOG(DEBUG) << "int cast2 double gate:" << gate;
COMPILER_LOG(DEBUG) << "bitcast gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, LLVMDoubleType(), "");
[[maybe_unused]] auto gateValCode = circuit_->LoadGatePtrConst(gate)->GetValueCode();
[[maybe_unused]] auto e1ValCode = circuit_->LoadGatePtrConst(e1)->GetValueCode();
ASSERT(GetBitWidthFromValueCode(gateValCode) == GetBitWidthFromValueCode(e1ValCode));
auto returnType = ConvertLLVMTypeFromGate(gate);
LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, returnType, "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
void LLVMIRBuilder::HandleCastDoubleToInt(GateRef gate)
{
std::vector<GateRef> ins = circuit_->GetInVector(gate);
VisitCastDoubleToInt(gate, ins[0]);
}
void LLVMIRBuilder::VisitCastDoubleToInt(GateRef gate, GateRef e1)
{
COMPILER_LOG(DEBUG) << "double cast2 int gate:" << gate;
LLVMValueRef e1Value = gateToLLVMMaps_[e1];
COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, LLVMInt64Type(), "");
gateToLLVMMaps_[gate] = result;
COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
}
LLVMTypeRef LLVMIRBuilder::ConvertLLVMTypeFromTypeCode(TypeCode type) const
{
if (UNLIKELY(type == TypeCode::NOTYPE)) {
UNREACHABLE();
}
if (type <= TypeCode::JS_TYPE_SPECIAL_STOP) {
return LLVMInt64Type();
}
// type >= TypeCode::JS_TYPE_OBJECT_START
return LLVMPointerType(LLVMInt64Type(), 1);
}
LLVMStubModule::LLVMStubModule(const std::string &name, const std::string &triple)
: compCfg_(triple)
{

View File

@ -168,43 +168,35 @@ private:
V(Block, (int id, const OperandsVector &predecessors)) \
V(Goto, (int block, int bbout)) \
V(Parameter, (GateRef gate)) \
V(Int32Constant, (GateRef gate, int32_t value)) \
V(Int64Constant, (GateRef gate, int64_t value)) \
V(Float64Constant, (GateRef gate, double value)) \
V(Constant, (GateRef gate, std::bitset<64> value)) \
V(ZExtInt, (GateRef gate, GateRef e1)) \
V(SExtInt, (GateRef gate, GateRef e1)) \
V(Load, (GateRef gate, GateRef base)) \
V(Store, (GateRef gate, GateRef base, GateRef value)) \
V(IntRev, (GateRef gate, GateRef e1)) \
V(IntAdd, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatAdd, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatSub, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatMul, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatDiv, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntSub, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntMul, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntRev, (GateRef gate, GateRef e1)) \
V(Add, (GateRef gate, GateRef e1, GateRef e2)) \
V(Sub, (GateRef gate, GateRef e1, GateRef e2)) \
V(Mul, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatDiv, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntOr, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntAnd, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntXor, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntLsr, (GateRef gate, GateRef e1, GateRef e2)) \
V(Int32LessThanOrEqual, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntOrUintCmp, (GateRef gate, GateRef e1, GateRef e2, LLVMIntPredicate opcode)) \
V(FloatOrDoubleCmp, (GateRef gate, GateRef e1, GateRef e2, LLVMRealPredicate opcode)) \
V(EqCmp, (GateRef gate, GateRef e1, GateRef e2)) \
V(Branch, (GateRef gate, GateRef cmp, GateRef btrue, GateRef bfalse)) \
V(Switch, (GateRef gate, GateRef input, const std::vector<GateRef> &outList)) \
V(SwitchCase, (GateRef gate, GateRef switchBranch, GateRef out)) \
V(Phi, (GateRef gate, const std::vector<GateRef> &srcGates)) \
V(Return, (GateRef gate, GateRef popCount, const std::vector<GateRef> &operands)) \
V(ReturnVoid, (GateRef gate)) \
V(ReturnVoid, (GateRef gate)) \
V(CastIntXToIntY, (GateRef gate, GateRef e1)) \
V(ChangeInt32ToDouble, (GateRef gate, GateRef e1)) \
V(ChangeDoubleToInt32, (GateRef gate, GateRef e1)) \
V(CastInt64ToDouble, (GateRef gate, GateRef e1)) \
V(CastDoubleToInt, (GateRef gate, GateRef e1)) \
V(CastInt64ToPointer, (GateRef gate, GateRef e1)) \
V(BitCast, (GateRef gate, GateRef e1)) \
V(IntLsl, (GateRef gate, GateRef e1, GateRef e2)) \
V(IntMod, (GateRef gate, GateRef e1, GateRef e2)) \
V(FloatMod, (GateRef gate, GateRef e1, GateRef e2)) \
V(Mod, (GateRef gate, GateRef e1, GateRef e2)) \
V(ChangeTaggedPointerToInt64, (GateRef gate, GateRef e1))
class LLVMIRBuilder {
@ -241,7 +233,6 @@ private:
void ProcessPhiWorkList();
void AssignHandleMap();
std::string LLVMValueToString(LLVMValueRef val) const;
LLVMTypeRef ConvertLLVMTypeFromTypeCode(TypeCode type) const;
LLVMTypeRef GetArchRelate() const
{
@ -251,6 +242,7 @@ private:
return LLVMInt64Type();
}
LLVMTypeRef ConvertLLVMTypeFromGate(GateRef gate) const;
int64_t GetBitWidthFromValueCode(ValueCode valCode) const;
LLVMValueRef PointerAdd(LLVMValueRef baseAddr, LLVMValueRef offset, LLVMTypeRef rep);
LLVMValueRef VectorAdd(LLVMValueRef e1Value, LLVMValueRef e2Value, LLVMTypeRef rep);
LLVMValueRef CanonicalizeToInt(LLVMValueRef value);

View File

@ -190,7 +190,6 @@ GateRef Stub::GetHoleConstant(MachineType type)
return env_.GetCircuitBuilder().HoleConstant(CircuitBuilder::MachineType2TypeCode(type));
}
GateRef Stub::GetNullConstant(MachineType type)
{
return env_.GetCircuitBuilder().NullConstant(CircuitBuilder::MachineType2TypeCode(type));
@ -219,37 +218,42 @@ GateRef Stub::Argument(size_t index)
GateRef Stub::Int1Argument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT1_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT1);
return argument;
}
GateRef Stub::Int32Argument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT32_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT32);
return argument;
}
GateRef Stub::Int64Argument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT64);
return argument;
}
GateRef Stub::TaggedArgument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetTypeCode(argument, TypeCode::JS_ANY);
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT64);
return argument;
}
GateRef Stub::TaggedPointerArgument(size_t index, TypeCode type)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetTypeCode(argument, type);
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT64);
return argument;
}
@ -258,9 +262,11 @@ GateRef Stub::PtrArgument(size_t index, TypeCode type)
GateRef argument = Argument(index);
env_.GetCircuit()->SetTypeCode(argument, type);
if (env_.IsArch64Bit()) {
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT64);
} else if (env_.IsArch32Bit()) {
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT32_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::INT32);
} else {
UNREACHABLE();
}
@ -270,20 +276,22 @@ GateRef Stub::PtrArgument(size_t index, TypeCode type)
GateRef Stub::Float32Argument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::FLOAT32_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::FLOAT32);
return argument;
}
GateRef Stub::Float64Argument(size_t index)
{
GateRef argument = Argument(index);
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::FLOAT64_ARG));
env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::ARG));
env_.GetCircuit()->SetValueCode(argument, ValueCode::FLOAT64);
return argument;
}
GateRef Stub::Alloca(int size, TypeCode type)
GateRef Stub::Alloca(int size)
{
return env_.GetCircuitBuilder().Alloca(size, type);
return env_.GetCircuitBuilder().Alloca(size);
}
GateRef Stub::Return(GateRef value)
@ -388,17 +396,17 @@ GateRef Stub::Load(MachineType type, GateRef base)
// arithmetic
GateRef Stub::Int32Add(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_ADD), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ADD), ValueCode::INT32, x, y);
}
GateRef Stub::Int64Add(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_ADD), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ADD), ValueCode::INT64, x, y);
}
GateRef Stub::DoubleAdd(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_ADD), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ADD), ValueCode::FLOAT64, x, y);
}
GateRef Stub::ArchRelateAdd(GateRef x, GateRef y)
@ -429,112 +437,112 @@ GateRef Stub::PtrSub(GateRef x, GateRef y)
GateRef Stub::Int32Sub(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SUB), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SUB), ValueCode::INT32, x, y);
}
GateRef Stub::Int64Sub(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_SUB), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SUB), ValueCode::INT64, x, y);
}
GateRef Stub::DoubleSub(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_SUB), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SUB), ValueCode::FLOAT64, x, y);
}
GateRef Stub::Int32Mul(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_MUL), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::MUL), ValueCode::INT32, x, y);
}
GateRef Stub::Int64Mul(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_MUL), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::MUL), ValueCode::INT64, x, y);
}
GateRef Stub::DoubleMul(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_MUL), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::MUL), ValueCode::FLOAT64, x, y);
}
GateRef Stub::DoubleDiv(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_DIV), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::FDIV), ValueCode::FLOAT64, x, y);
}
GateRef Stub::Int32Div(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SDIV), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SDIV), ValueCode::INT32, x, y);
}
GateRef Stub::Word32Div(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_UDIV), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::UDIV), ValueCode::INT32, x, y);
}
GateRef Stub::Int32Mod(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SMOD), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SMOD), ValueCode::INT32, x, y);
}
GateRef Stub::DoubleMod(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_SMOD), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SMOD), ValueCode::FLOAT64, x, y);
}
// bit operation
GateRef Stub::Word32Or(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_OR), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::OR), ValueCode::INT32, x, y);
}
GateRef Stub::Word32And(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_AND), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::AND), ValueCode::INT32, x, y);
}
GateRef Stub::Word32Not(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_REV), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::REV), ValueCode::INT32, x);
}
GateRef Stub::Word64Or(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_OR), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::OR), ValueCode::INT64, x, y);
}
GateRef Stub::Word64And(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_AND), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::AND), ValueCode::INT64, x, y);
}
GateRef Stub::Word64Xor(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_XOR), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::XOR), ValueCode::INT64, x, y);
}
GateRef Stub::Word64Not(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_REV), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::REV), ValueCode::INT64, x);
}
GateRef Stub::Word32LSL(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSL), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::LSL), ValueCode::INT32, x, y);
}
GateRef Stub::Word64LSL(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSL), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::LSL), ValueCode::INT64, x, y);
}
GateRef Stub::Word32LSR(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSR), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::LSR), ValueCode::INT32, x, y);
}
GateRef Stub::Word64LSR(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSR), x, y);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::LSR), ValueCode::INT64, x, y);
}
GateRef Stub::TaggedIsInt(GateRef x)
@ -688,7 +696,7 @@ GateRef Stub::DoubleBuildTaggedWithNoGC(GateRef x)
GateRef Stub::CastDoubleToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::BITCAST_FLOAT64_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::BITCAST), ValueCode::INT64, x);
}
GateRef Stub::TaggedTrue()
@ -704,119 +712,119 @@ GateRef Stub::TaggedFalse()
// compare operation
GateRef Stub::Word32Equal(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_EQ), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::EQ), x, y);
}
GateRef Stub::Word32NotEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_NE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::NE), x, y);
}
GateRef Stub::Word64Equal(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_EQ), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::EQ), x, y);
}
GateRef Stub::DoubleEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::FLOAT64_EQ), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::EQ), x, y);
}
GateRef Stub::Word64NotEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_NE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::NE), x, y);
}
GateRef Stub::Int32GreaterThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SGT), x, y);
}
GateRef Stub::Int32LessThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SLT), x, y);
}
GateRef Stub::Int32GreaterThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SGE), x, y);
}
GateRef Stub::Int32LessThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SLE), x, y);
}
GateRef Stub::Word32GreaterThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::UGT), x, y);
}
GateRef Stub::Word32LessThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::ULT), x, y);
}
GateRef Stub::Word32LessThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::ULE), x, y);
}
GateRef Stub::Word32GreaterThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::UGE), x, y);
}
GateRef Stub::Int64GreaterThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SGT), x, y);
}
GateRef Stub::Int64LessThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SLT), x, y);
}
GateRef Stub::Int64LessThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SLE), x, y);
}
GateRef Stub::Int64GreaterThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::SGE), x, y);
}
GateRef Stub::Word64GreaterThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::UGT), x, y);
}
GateRef Stub::Word64LessThan(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULT), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::ULT), x, y);
}
GateRef Stub::Word64LessThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::ULE), x, y);
}
GateRef Stub::Word64GreaterThanOrEqual(GateRef x, GateRef y)
{
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGE), x, y);
return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::UGE), x, y);
}
// cast operation
GateRef Stub::ChangeInt64ToInt32(GateRef val)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TRUNC_TO_INT32), val);
}
GateRef Stub::ChangeInt64ToUintPtr(GateRef val)
{
if (env_.IsArch32Bit()) {
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TRUNC_TO_INT32), val);
}
return val;
}
@ -1504,77 +1512,77 @@ GateRef Stub::TaggedCastToWeakReferentUnChecked(GateRef x)
GateRef Stub::ChangeInt32ToFloat64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_TO_FLOAT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SIGNED_INT_TO_FLOAT), ValueCode::FLOAT64, x);
}
GateRef Stub::ChangeFloat64ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::FLOAT_TO_SIGNED_INT), ValueCode::INT32, x);
}
GateRef Stub::ChangeTaggedPointerToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TAGGED_POINTER_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TAGGED_TO_INT64), x);
}
GateRef Stub::CastInt64ToFloat64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::BITCAST_INT64_TO_FLOAT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::BITCAST), ValueCode::FLOAT64, x);
}
GateRef Stub::SExtInt32ToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT32_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SEXT_TO_INT64), x);
}
GateRef Stub::SExtInt1ToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SEXT_TO_INT64), x);
}
GateRef Stub::SExtInt1ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::SEXT_TO_INT32), x);
}
GateRef Stub::ZExtInt32ToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT32_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ZEXT_TO_INT64), x);
}
GateRef Stub::ZExtInt1ToInt64(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT64), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ZEXT_TO_INT64), x);
}
GateRef Stub::ZExtInt1ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ZEXT_TO_INT32), x);
}
GateRef Stub::ZExtInt8ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT8_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ZEXT_TO_INT32), x);
}
GateRef Stub::ZExtInt16ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT16_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::ZEXT_TO_INT32), x);
}
GateRef Stub::TruncInt64ToInt32(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TRUNC_TO_INT32), x);
}
GateRef Stub::TruncInt64ToInt1(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT1), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TRUNC_TO_INT1), x);
}
GateRef Stub::TruncInt32ToInt1(GateRef x)
{
return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT32_TO_INT1), x);
return env_.GetCircuitBuilder().NewArithmeticGate(OpCode(OpCode::TRUNC_TO_INT1), x);
}
GateRef Stub::GetGlobalConstantAddr(GateRef index)

View File

@ -139,18 +139,29 @@ GateRef LabelImpl::ReadVariable(Variable *var)
GateRef LabelImpl::ReadVariableRecursive(Variable *var)
{
GateRef val;
OpCode opcode = CircuitBuilder::GetSelectOpCodeFromMachineType(var->Type());
ValueCode valueCode = CircuitBuilder::GetValueCodeFromMachineType(var->Type());
if (!IsSealed()) {
// only loopheader gate will be not sealed
int valueCounts = static_cast<int>(this->predecessors_.size()) + 1;
val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, valueCounts, var->Type());
int valueCounts = static_cast<int>(predecessors_.size()) + 1;
if (valueCode == ValueCode::NOVALUE) {
val = env_->GetCircuitBuilder().NewSelectorGate(
OpCode(OpCode::DEPEND_SELECTOR), predeControl_, valueCounts, var->Type());
} else {
val = env_->GetCircuitBuilder().NewSelectorGate(
OpCode(OpCode::VALUE_SELECTOR), valueCode, predeControl_, valueCounts, var->Type());
}
env_->AddSelectorToLabel(val, Label(this));
incompletePhis_[var] = val;
} else if (predecessors_.size() == 1) {
val = predecessors_[0]->ReadVariable(var);
} else {
val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, this->predecessors_.size(), var->Type());
if (valueCode == ValueCode::NOVALUE) {
val = env_->GetCircuitBuilder().NewSelectorGate(
OpCode(OpCode::DEPEND_SELECTOR), predeControl_, predecessors_.size(), var->Type());
} else {
val = env_->GetCircuitBuilder().NewSelectorGate(
OpCode(OpCode::VALUE_SELECTOR), valueCode, predeControl_, predecessors_.size(), var->Type());
}
env_->AddSelectorToLabel(val, Label(this));
WriteVariable(var, val);
val = var->AddPhiOperand(val);
@ -229,7 +240,7 @@ void LabelImpl::MergeAllDepend()
// Merge all depends to depend_seclector
std::vector<GateRef> dependsList;
for (auto prede : this->GetPredecessors()) {
for (auto prede : GetPredecessors()) {
dependsList.push_back(prede->GetDepend());
}
depend_ = env_->GetCircuitBuilder().NewSelectorGate(OpCode(OpCode::DEPEND_SELECTOR), predeControl_, dependsList,
@ -445,6 +456,7 @@ GateRef Stub::FindElementFromNumberDictionary(GateRef glue, GateRef elements, Ga
DEFVARIABLE(count, MachineType::INT32, GetInt32Constant(1));
GateRef pKey = Alloca(static_cast<int>(MachineRep::K_WORD32));
GateRef keyStore = Store(MachineType::INT32, glue, pKey, GetArchRelateConstant(0), TaggedCastToInt32(key));
StubDescriptor *getHash32Descriptor = GET_STUBDESCRIPTOR(GetHash32);
GateRef len = GetInt32Constant(sizeof(int) / sizeof(uint8_t));
@ -2255,7 +2267,7 @@ GateRef Stub::FindTransitions(GateRef glue, GateRef receiver, GateRef hclass, Ga
Branch(Word64Equal(cachedKey, key), &keyMatch, &notMatch);
Bind(&keyMatch);
{
Branch(Word64Equal(metaData, cachedMetaData), &isMatch, &notMatch);
Branch(Word32Equal(metaData, cachedMetaData), &isMatch, &notMatch);
Bind(&isMatch);
{
#if ECMASCRIPT_ENABLE_IC
@ -2419,8 +2431,8 @@ GateRef Stub::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef index,
GateRef Stub::SetPropertyByName(GateRef glue, GateRef receiver, GateRef key, GateRef value)
{
auto env = GetEnvironment();
Label entry(env);
env->PushCurrentLabel(&entry);
Label entryPass(env);
env->PushCurrentLabel(&entryPass);
DEFVARIABLE(result, MachineType::UINT64, GetHoleConstant(MachineType::UINT64));
DEFVARIABLE(holder, MachineType::TAGGED_POINTER, receiver);
Label exit(env);

View File

@ -372,8 +372,7 @@ public:
}
bool IsSelector(const Gate *gate) const
{
return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS
&& gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64;
return gate->GetOpCode() == OpCode::VALUE_SELECTOR;
}
uint32_t GetId() const
{
@ -446,7 +445,8 @@ public:
inline GateRef PtrArgument(size_t index, TypeCode type = TypeCode::NOTYPE);
inline GateRef Float32Argument(size_t index);
inline GateRef Float64Argument(size_t index);
inline GateRef Alloca(int size, TypeCode type = TypeCode::NOTYPE);
inline GateRef Alloca(int size);
inline GateRef NativePointerAlloca(int size);
// control flow
inline GateRef Return(GateRef value);
inline GateRef Return();

View File

@ -114,11 +114,11 @@ public:
}
};
class LLVMCodegenPass {
class LLVMIRGenPass {
public:
void CreateCodeGen(LLVMStubModule *module)
{
llvmImpl_ = std::make_unique<LLVMCodeGeneratorImpl>(module);
llvmImpl_ = std::make_unique<LLVMIRGeneratorImpl>(module);
}
bool Run(PassPayLoad *data, int index)
{
@ -146,7 +146,7 @@ void StubAotCompiler::BuildStubModuleAndSave(const std::string &triple, panda::e
pipeline.RunPass<BuildCircuitPass>();
pipeline.RunPass<VerifierPass>();
pipeline.RunPass<SchedulerPass>();
pipeline.RunPass<LLVMCodegenPass>(i);
pipeline.RunPass<LLVMIRGenPass>(i);
}
}

View File

@ -0,0 +1,158 @@
/*
* 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.
*/
#include <chrono>
#include <iostream>
#include <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers)
#include <vector>
#include "ecmascript/compiler/bytecode_circuit_builder.h"
#include "ecmascript/ecma_language_context.h"
#include "ecmascript/ecma_string.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/js_runtime_options.h"
#include "ecmascript/napi/include/jsnapi.h"
#include "include/runtime.h"
#include "libpandabase/os/native_stack.h"
#include "libpandabase/utils/pandargs.h"
#include "libpandabase/utils/span.h"
#include "libpandafile/file.h"
namespace panda::ecmascript::kungfu {
void BlockSignals()
{
#if defined(PANDA_TARGET_UNIX)
sigset_t set;
if (sigemptyset(&set) == -1) {
LOG(ERROR, RUNTIME) << "sigemptyset failed";
return;
}
int rc = 0;
if (rc < 0) {
LOG(ERROR, RUNTIME) << "sigaddset failed";
return;
}
if (panda::os::native_stack::g_PandaThreadSigmask(SIG_BLOCK, &set, nullptr) != 0) {
LOG(ERROR, RUNTIME) << "g_PandaThreadSigmask failed";
}
#endif // PANDA_TARGET_UNIX
}
int Main(const int argc, const char **argv)
{
auto startTime =
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch())
.count();
BlockSignals();
Span<const char *> sp(argv, argc);
JSRuntimeOptions runtimeOptions(sp[0]);
panda::PandArg<bool> help("help", false, "Print this message and exit");
panda::PandArg<bool> options("options", false, "Print compiler and runtime options");
// tail arguments
panda::PandArg<arg_list_t> files("files", {""}, "path to pandafiles", ":");
panda::PandArg<std::string> entrypoint("entrypoint", "_GLOBAL::func_main_0",
"full name of entrypoint function or method");
panda::PandArgParser paParser;
runtimeOptions.AddOptions(&paParser);
paParser.Add(&help);
paParser.Add(&options);
paParser.PushBackTail(&files);
paParser.PushBackTail(&entrypoint);
paParser.EnableTail();
paParser.EnableRemainder();
if (!paParser.Parse(argc, argv) || files.GetValue().empty() || entrypoint.GetValue().empty() || help.GetValue()) {
std::cerr << paParser.GetErrorString() << std::endl;
std::cerr << "Usage: "
<< "panda"
<< " [OPTIONS] [file1:file2:file3] [entrypoint] -- [arguments]" << std::endl;
std::cerr << std::endl;
std::cerr << "optional arguments:" << std::endl;
std::cerr << paParser.GetHelpString() << std::endl;
return 1;
}
arg_list_t arguments = paParser.GetRemainder();
if (runtimeOptions.IsStartupTime()) {
std::cout << "\n"
<< "Startup start time: " << startTime << std::endl;
}
auto runtimeOptionsErr = runtimeOptions.Validate();
if (runtimeOptionsErr) {
std::cerr << "Error: " << runtimeOptionsErr.value().GetMessage() << std::endl;
return 1;
}
runtimeOptions.SetShouldLoadBootPandaFiles(false);
runtimeOptions.SetShouldInitializeIntrinsics(false);
runtimeOptions.SetBootClassSpaces({"ecmascript"});
runtimeOptions.SetRuntimeType("ecmascript");
JSNApi::SetOptions(runtimeOptions);
static EcmaLanguageContext lcEcma;
bool ret = Runtime::Create(runtimeOptions, {&lcEcma});
if (!ret) {
std::cerr << "Error: cannot Create Runtime" << std::endl;
return -1;
}
auto runtime = Runtime::GetCurrent();
if (options.GetValue()) {
std::cout << paParser.GetRegularArgs() << std::endl;
}
EcmaVM *vm = EcmaVM::Cast(runtime->GetPandaVM());
LocalScope scope(vm);
std::string entry = entrypoint.GetValue();
arg_list_t fileNames = files.GetValue();
BytecodeCircuitBuilder builder;
for (const auto &fileName : fileNames) {
LOG_ECMA(DEBUG) << "start to execute ark file" << fileName;
std::vector<BytecodeTranslationInfo> infoList;
const panda_file::File *file = nullptr;
auto res = vm->CollectInfoOfPandaFile(fileName, entry, infoList, file);
if (!res) {
std::cerr << "Cannot execute panda file '" << fileName << "' with entry '" << entry << "'" << std::endl;
ret = false;
break;
}
for (auto &info : infoList) {
builder.BytecodeToCircuit(info.pcArray, *info.file, info.method);
}
}
if (!Runtime::Destroy()) {
std::cerr << "Error: cannot destroy Runtime" << std::endl;
return -1;
}
paParser.DisableTail();
return ret ? 0 : -1;
}
} // namespace panda::ecmascript::kungfu
int main(const int argc, const char **argv)
{
auto result = panda::ecmascript::kungfu::Main(argc, argv);
std::cout << (result == 0 ? "ts aot execute success" : "ts aot execute failed") << std::endl;
return result;
}

View File

@ -173,7 +173,6 @@ bool EcmaVM::Initialize()
#endif
SetupRegExpResultCache();
microJobQueue_ = factory_->NewMicroJobQueue().GetTaggedValue();
{
Builtins builtins;
builtins.Initialize(globalEnvHandle, thread_);
@ -343,6 +342,30 @@ bool EcmaVM::ExecuteFromPf(std::string_view filename, std::string_view entryPoin
return Execute(*pf_ptr, entryPoint, args);
}
bool EcmaVM::CollectInfoOfPandaFile(std::string_view filename, std::string_view entryPoint,
std::vector<BytecodeTranslationInfo> &infoList, const panda_file::File *&pf)
{
const panda_file::File *pf_ptr = nullptr;
std::unique_ptr<const panda_file::File> file;
if (frameworkPandaFile_ == nullptr || !IsFrameworkPandaFile(filename)) {
file = panda_file::OpenPandaFileOrZip(filename, panda_file::File::READ_WRITE);
if (file == nullptr) {
return false;
}
pf_ptr = file.get();
}
// Get ClassName and MethodName
size_t pos = entryPoint.find_last_of("::");
if (pos == std::string_view::npos) {
LOG_ECMA(ERROR) << "EntryPoint:" << entryPoint << " is illegal";
return false;
}
CString methodName(entryPoint.substr(pos + 1));
PandaFileTranslator::TranslateAndCollectPandaFile(this, *pf_ptr, methodName, infoList);
pf = file.release();
return true;
}
bool EcmaVM::ExecuteFromBuffer(const void *buffer, size_t size, std::string_view entryPoint,
const std::vector<std::string> &args)
{
@ -379,7 +402,6 @@ bool EcmaVM::Execute(const panda_file::File &pf, std::string_view entryPoint, co
return false;
}
CString methodName(entryPoint.substr(pos + 1));
// For Ark application startup
InvokeEcmaEntrypoint(pf, methodName, args);
return true;

View File

@ -68,6 +68,7 @@ class JSFunction;
class Program;
class ModuleManager;
class EcmaModule;
struct BytecodeTranslationInfo;
using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm,
const JSHandle<JSPromise> promise,
const JSHandle<JSTaggedValue> reason,
@ -102,6 +103,9 @@ public:
bool ExecuteFromBuffer(const void *buffer, size_t size, std::string_view entryPoint,
const std::vector<std::string> &args);
bool PUBLIC_API CollectInfoOfPandaFile(std::string_view filename, std::string_view entryPoint,
std::vector<BytecodeTranslationInfo> &infoList, const panda_file::File *&pf);
PtJSExtractor *GetDebugInfoExtractor(const panda_file::File *file);
bool IsInitialized() const
@ -492,7 +496,6 @@ private:
ChunkVector<JSMethod *> nativeMethods_;
ModuleManager *moduleManager_ {nullptr};
bool optionalLogEnabled_ {false};
// weak reference need Redirect address
CVector<std::tuple<Program *, const panda_file::File *, bool>> pandaFileWithProgram_;
// Debugger

View File

@ -86,7 +86,7 @@
// |- - - - - - - - - | |
// | frameType | |
// |- - - - - - - - - | |
// | sp | v
// | callsiteSp | v
// +--------------------------+
// Optimized Entry Frame(alias OptimizedEntryFrame) layout

View File

@ -3712,6 +3712,167 @@ bool EcmaInterpreter::UpdateHotnessCounter(JSThread* thread, JSTaggedType *sp, J
method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
return false;
}
std::string GetEcmaOpcodeStr(EcmaOpcode opcode)
{
const std::map<EcmaOpcode, const char *> strMap = {
{LDNAN_PREF, "LDNAN"},
{LDINFINITY_PREF, "LDINFINITY"},
{LDGLOBALTHIS_PREF, "LDGLOBALTHIS"},
{LDUNDEFINED_PREF, "LDUNDEFINED"},
{LDNULL_PREF, "LDNULL"},
{LDSYMBOL_PREF, "LDSYMBOL"},
{LDGLOBAL_PREF, "LDGLOBAL"},
{LDTRUE_PREF, "LDTRUE"},
{LDFALSE_PREF, "LDFALSE"},
{THROWDYN_PREF, "THROWDYN"},
{TYPEOFDYN_PREF, "TYPEOFDYN"},
{LDLEXENVDYN_PREF, "LDLEXENVDYN"},
{POPLEXENVDYN_PREF, "POPLEXENVDYN"},
{GETUNMAPPEDARGS_PREF, "GETUNMAPPEDARGS"},
{GETPROPITERATOR_PREF, "GETPROPITERATOR"},
{ASYNCFUNCTIONENTER_PREF, "ASYNCFUNCTIONENTER"},
{LDHOLE_PREF, "LDHOLE"},
{RETURNUNDEFINED_PREF, "RETURNUNDEFINED"},
{CREATEEMPTYOBJECT_PREF, "CREATEEMPTYOBJECT"},
{CREATEEMPTYARRAY_PREF, "CREATEEMPTYARRAY"},
{GETITERATOR_PREF, "GETITERATOR"},
{THROWTHROWNOTEXISTS_PREF, "THROWTHROWNOTEXISTS"},
{THROWPATTERNNONCOERCIBLE_PREF, "THROWPATTERNNONCOERCIBLE"},
{LDHOMEOBJECT_PREF, "LDHOMEOBJECT"},
{THROWDELETESUPERPROPERTY_PREF, "THROWDELETESUPERPROPERTY"},
{DEBUGGER_PREF, "DEBUGGER"},
{ADD2DYN_PREF_V8, "ADD2DYN"},
{SUB2DYN_PREF_V8, "SUB2DYN"},
{MUL2DYN_PREF_V8, "MUL2DYN"},
{DIV2DYN_PREF_V8, "DIV2DYN"},
{MOD2DYN_PREF_V8, "MOD2DYN"},
{EQDYN_PREF_V8, "EQDYN"},
{NOTEQDYN_PREF_V8, "NOTEQDYN"},
{LESSDYN_PREF_V8, "LESSDYN"},
{LESSEQDYN_PREF_V8, "LESSEQDYN"},
{GREATERDYN_PREF_V8, "GREATERDYN"},
{GREATEREQDYN_PREF_V8, "GREATEREQDYN"},
{SHL2DYN_PREF_V8, "SHL2DYN"},
{SHR2DYN_PREF_V8, "SHR2DYN"},
{ASHR2DYN_PREF_V8, "ASHR2DYN"},
{AND2DYN_PREF_V8, "AND2DYN"},
{OR2DYN_PREF_V8, "OR2DYN"},
{XOR2DYN_PREF_V8, "XOR2DYN"},
{TONUMBER_PREF_V8, "TONUMBER"},
{NEGDYN_PREF_V8, "NEGDYN"},
{NOTDYN_PREF_V8, "NOTDYN"},
{INCDYN_PREF_V8, "INCDYN"},
{DECDYN_PREF_V8, "DECDYN"},
{EXPDYN_PREF_V8, "EXPDYN"},
{ISINDYN_PREF_V8, "ISINDYN"},
{INSTANCEOFDYN_PREF_V8, "INSTANCEOFDYN"},
{STRICTNOTEQDYN_PREF_V8, "STRICTNOTEQDYN"},
{STRICTEQDYN_PREF_V8, "STRICTEQDYN"},
{RESUMEGENERATOR_PREF_V8, "RESUMEGENERATOR"},
{GETRESUMEMODE_PREF_V8, "GETRESUMEMODE"},
{CREATEGENERATOROBJ_PREF_V8, "CREATEGENERATOROBJ"},
{THROWCONSTASSIGNMENT_PREF_V8, "THROWCONSTASSIGNMENT"},
{GETTEMPLATEOBJECT_PREF_V8, "GETTEMPLATEOBJECT"},
{GETNEXTPROPNAME_PREF_V8, "GETNEXTPROPNAME"},
{CALLARG0DYN_PREF_V8, "CALLARG0DYN"},
{THROWIFNOTOBJECT_PREF_V8, "THROWIFNOTOBJECT"},
{ITERNEXT_PREF_V8, "ITERNEXT"},
{CLOSEITERATOR_PREF_V8, "CLOSEITERATOR"},
{COPYMODULE_PREF_V8, "COPYMODULE"},
{SUPERCALLSPREAD_PREF_V8, "SUPERCALLSPREAD"},
{DELOBJPROP_PREF_V8_V8, "DELOBJPROP"},
{NEWOBJSPREADDYN_PREF_V8_V8, "NEWOBJSPREADDYN"},
{CREATEITERRESULTOBJ_PREF_V8_V8, "CREATEITERRESULTOBJ"},
{SUSPENDGENERATOR_PREF_V8_V8, "SUSPENDGENERATOR"},
{ASYNCFUNCTIONAWAITUNCAUGHT_PREF_V8_V8, "ASYNCFUNCTIONAWAITUNCAUGHT"},
{THROWUNDEFINEDIFHOLE_PREF_V8_V8, "THROWUNDEFINEDIFHOLE"},
{CALLARG1DYN_PREF_V8_V8, "CALLARG1DYN"},
{COPYDATAPROPERTIES_PREF_V8_V8, "COPYDATAPROPERTIES"},
{STARRAYSPREAD_PREF_V8_V8, "STARRAYSPREAD"},
{GETITERATORNEXT_PREF_V8_V8, "GETITERATORNEXT"},
{SETOBJECTWITHPROTO_PREF_V8_V8, "SETOBJECTWITHPROTO"},
{LDOBJBYVALUE_PREF_V8_V8, "LDOBJBYVALUE"},
{STOBJBYVALUE_PREF_V8_V8, "STOBJBYVALUE"},
{STOWNBYVALUE_PREF_V8_V8, "STOWNBYVALUE"},
{LDSUPERBYVALUE_PREF_V8_V8, "LDSUPERBYVALUE"},
{STSUPERBYVALUE_PREF_V8_V8, "STSUPERBYVALUE"},
{LDOBJBYINDEX_PREF_V8_IMM32, "LDOBJBYINDEX"},
{STOBJBYINDEX_PREF_V8_IMM32, "STOBJBYINDEX"},
{STOWNBYINDEX_PREF_V8_IMM32, "STOWNBYINDEX"},
{CALLSPREADDYN_PREF_V8_V8_V8, "CALLSPREADDYN"},
{ASYNCFUNCTIONRESOLVE_PREF_V8_V8_V8, "ASYNCFUNCTIONRESOLVE"},
{ASYNCFUNCTIONREJECT_PREF_V8_V8_V8, "ASYNCFUNCTIONREJECT"},
{CALLARGS2DYN_PREF_V8_V8_V8, "CALLARGS2DYN"},
{CALLARGS3DYN_PREF_V8_V8_V8_V8, "CALLARGS3DYN"},
{DEFINEGETTERSETTERBYVALUE_PREF_V8_V8_V8_V8, "DEFINEGETTERSETTERBYVALUE"},
{NEWOBJDYNRANGE_PREF_IMM16_V8, "NEWOBJDYNRANGE"},
{CALLIRANGEDYN_PREF_IMM16_V8, "CALLIRANGEDYN"},
{CALLITHISRANGEDYN_PREF_IMM16_V8, "CALLITHISRANGEDYN"},
{SUPERCALL_PREF_IMM16_V8, "SUPERCALL"},
{CREATEOBJECTWITHEXCLUDEDKEYS_PREF_IMM16_V8_V8, "CREATEOBJECTWITHEXCLUDEDKEYS"},
{DEFINEFUNCDYN_PREF_ID16_IMM16_V8, "DEFINEFUNCDYN"},
{DEFINENCFUNCDYN_PREF_ID16_IMM16_V8, "DEFINENCFUNCDYN"},
{DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8, "DEFINEGENERATORFUNC"},
{DEFINEASYNCFUNC_PREF_ID16_IMM16_V8, "DEFINEASYNCFUNC"},
{DEFINEMETHOD_PREF_ID16_IMM16_V8, "DEFINEMETHOD"},
{NEWLEXENVDYN_PREF_IMM16, "NEWLEXENVDYN"},
{COPYRESTARGS_PREF_IMM16, "COPYRESTARGS"},
{CREATEARRAYWITHBUFFER_PREF_IMM16, "CREATEARRAYWITHBUFFER"},
{CREATEOBJECTHAVINGMETHOD_PREF_IMM16, "CREATEOBJECTHAVINGMETHOD"},
{THROWIFSUPERNOTCORRECTCALL_PREF_IMM16, "THROWIFSUPERNOTCORRECTCALL"},
{CREATEOBJECTWITHBUFFER_PREF_IMM16, "CREATEOBJECTWITHBUFFER"},
{LDLEXVARDYN_PREF_IMM4_IMM4, "LDLEXVARDYN"},
{LDLEXVARDYN_PREF_IMM8_IMM8, "LDLEXVARDYN"},
{LDLEXVARDYN_PREF_IMM16_IMM16, "LDLEXVARDYN"},
{STLEXVARDYN_PREF_IMM4_IMM4_V8, "STLEXVARDYN"},
{STLEXVARDYN_PREF_IMM8_IMM8_V8, "STLEXVARDYN"},
{STLEXVARDYN_PREF_IMM16_IMM16_V8, "STLEXVARDYN"},
{DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8, "DEFINECLASSWITHBUFFER"},
{IMPORTMODULE_PREF_ID32, "IMPORTMODULE"},
{STMODULEVAR_PREF_ID32, "STMODULEVAR"},
{TRYLDGLOBALBYNAME_PREF_ID32, "TRYLDGLOBALBYNAME"},
{TRYSTGLOBALBYNAME_PREF_ID32, "TRYSTGLOBALBYNAME"},
{LDGLOBALVAR_PREF_ID32, "LDGLOBALVAR"},
{STGLOBALVAR_PREF_ID32, "STGLOBALVAR"},
{LDOBJBYNAME_PREF_ID32_V8, "LDOBJBYNAME"},
{STOBJBYNAME_PREF_ID32_V8, "STOBJBYNAME"},
{STOWNBYNAME_PREF_ID32_V8, "STOWNBYNAME"},
{LDSUPERBYNAME_PREF_ID32_V8, "LDSUPERBYNAME"},
{STSUPERBYNAME_PREF_ID32_V8, "STSUPERBYNAME"},
{LDMODVARBYNAME_PREF_ID32_V8, "LDMODVARBYNAME"},
{CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, "CREATEREGEXPWITHLITERAL"},
{ISTRUE_PREF, "ISTRUE"},
{ISFALSE_PREF, "ISFALSE"},
{STCONSTTOGLOBALRECORD_PREF_ID32, "STCONSTTOGLOBALRECORD"},
{STLETTOGLOBALRECORD_PREF_ID32, "STLETTOGLOBALRECORD"},
{STCLASSTOGLOBALRECORD_PREF_ID32, "STCLASSTOGLOBALRECORD"},
{STOWNBYVALUEWITHNAMESET_PREF_V8_V8, "STOWNBYVALUEWITHNAMESET"},
{STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, "STOWNBYNAMEWITHNAMESET"},
{LDFUNCTION_PREF, "LDFUNCTION"},
{MOV_DYN_V8_V8, "MOV_DYN"},
{MOV_DYN_V16_V16, "MOV_DYN"},
{LDA_STR_ID32, "LDA_STR"},
{LDAI_DYN_IMM32, "LDAI_DYN"},
{FLDAI_DYN_IMM64, "FLDAI_DYN"},
{JMP_IMM8, "JMP"},
{JMP_IMM16, "JMP"},
{JMP_IMM32, "JMP"},
{JEQZ_IMM8, "JEQZ"},
{JEQZ_IMM16, "JEQZ"},
{LDA_DYN_V8, "LDA_DYN"},
{STA_DYN_V8, "STA_DYN"},
{RETURN_DYN, "RETURN_DYN"},
{MOV_V4_V4, "MOV"},
{JNEZ_IMM8, "JNEZ"},
{JNEZ_IMM16, "JNEZ"},
{LAST_OPCODE, "LAST_OPCODE"},
};
if (strMap.count(opcode) > 0) {
return strMap.at(opcode);
}
return "bytecode-" + std::to_string(opcode);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)

View File

@ -223,5 +223,8 @@ enum EcmaOpcode {
JNEZ_IMM16,
LAST_OPCODE,
};
// if modify EcmaOpcode, please update GetEcmaOpcodeStr()
inline std::string GetEcmaOpcodeStr(EcmaOpcode opcode);
} // namespace panda::ecmascript
#endif // ECMASCRIPT_INTERPRETER_INTERPRETER_H

View File

@ -46,6 +46,7 @@ public:
parser->Add(&stub_module_file_);
parser->Add(&enable_cpuprofiler_);
parser->Add(&ark_properties_);
parser->Add(&enable_ts_aot_);
}
bool IsEnableArkTools() const
@ -123,6 +124,21 @@ public:
enable_cpuprofiler_.SetValue(value);
}
bool IsEnableTsAot() const
{
return enable_ts_aot_.GetValue();
}
void SetEnableTsAot(bool value)
{
enable_ts_aot_.SetValue(value);
}
bool WasSetEnableTsAot() const
{
return enable_ts_aot_.WasSet();
}
void SetArkProperties(int prop)
{
if (prop != ArkProperties::DEFAULT) {
@ -183,6 +199,7 @@ private:
true,
R"(if true trigger compress gc, else trigger semi and old gc)"};
PandArg<int> ark_properties_ {"ark-properties", GetDefaultProperties(), R"(set ark properties)"};
PandArg<int> enable_ts_aot_ {"enable-ts-aot", false, R"(enable aot of fast stub. Default: false)"};
};
} // namespace panda::ecmascript

View File

@ -14,7 +14,6 @@
*/
#include <chrono>
#include <ctime>
#include <iostream>
#include <limits>
#include <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers)