mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
commit
6e5d6b8739
1
BUILD.gn
1
BUILD.gn
@ -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})",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
}
|
||||
|
2293
ecmascript/compiler/bytecode_circuit_builder.cpp
Normal file
2293
ecmascript/compiler/bytecode_circuit_builder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
183
ecmascript/compiler/bytecode_circuit_builder.h
Normal file
183
ecmascript/compiler/bytecode_circuit_builder.h
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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, ¬Match);
|
||||
Bind(&keyMatch);
|
||||
{
|
||||
Branch(Word64Equal(metaData, cachedMetaData), &isMatch, ¬Match);
|
||||
Branch(Word32Equal(metaData, cachedMetaData), &isMatch, ¬Match);
|
||||
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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
158
ecmascript/compiler/ts_aot_compiler.cpp
Normal file
158
ecmascript/compiler/ts_aot_compiler.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -86,7 +86,7 @@
|
||||
// |- - - - - - - - - | |
|
||||
// | frameType | |
|
||||
// |- - - - - - - - - | |
|
||||
// | sp | v
|
||||
// | callsiteSp | v
|
||||
// +--------------------------+
|
||||
|
||||
// Optimized Entry Frame(alias OptimizedEntryFrame) layout
|
||||
|
@ -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__)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers)
|
||||
|
Loading…
Reference in New Issue
Block a user