mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
fa5b47c71a
Signed-off-by: g00416891 <guobingbing3@huawei.com> Change-Id: Ia9bfc1e905962127d2afea6adb21704d4f0cd6d0
314 lines
9.4 KiB
C++
314 lines
9.4 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ECMASCRIPT_COMPILER_PASS_H
|
|
#define ECMASCRIPT_COMPILER_PASS_H
|
|
|
|
#include "ecmascript/compiler/async_function_lowering.h"
|
|
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
|
#include "ecmascript/compiler/common_stubs.h"
|
|
#include "ecmascript/compiler/guard_eliminating.h"
|
|
#include "ecmascript/compiler/guard_lowering.h"
|
|
#include "ecmascript/compiler/llvm_codegen.h"
|
|
#include "ecmascript/compiler/scheduler.h"
|
|
#include "ecmascript/compiler/slowpath_lowering.h"
|
|
#include "ecmascript/compiler/ts_inline_lowering.h"
|
|
#include "ecmascript/compiler/ts_type_lowering.h"
|
|
#include "ecmascript/compiler/type_inference/type_infer.h"
|
|
#include "ecmascript/compiler/type_lowering.h"
|
|
#include "ecmascript/compiler/verifier.h"
|
|
#include "ecmascript/compiler/compiler_log.h"
|
|
|
|
namespace panda::ecmascript::kungfu {
|
|
class PassInfo;
|
|
|
|
class PassData {
|
|
public:
|
|
PassData(BytecodeCircuitBuilder *builder, Circuit *circuit, PassInfo *info, CompilerLog *log,
|
|
std::string methodName, size_t methodInfoIndex = 0,
|
|
bool hasTypes = false, const CString &recordName = "",
|
|
MethodLiteral *methodLiteral = nullptr, uint32_t methodOffset = 0)
|
|
: builder_(builder), circuit_(circuit), info_(info), log_(log), methodName_(methodName),
|
|
methodInfoIndex_(methodInfoIndex), hasTypes_(hasTypes), recordName_(recordName),
|
|
methodLiteral_(methodLiteral), methodOffset_(methodOffset)
|
|
{
|
|
}
|
|
|
|
virtual ~PassData() = default;
|
|
|
|
const ControlFlowGraph &GetConstScheduleResult() const
|
|
{
|
|
return cfg_;
|
|
}
|
|
|
|
ControlFlowGraph &GetCfg()
|
|
{
|
|
return cfg_;
|
|
}
|
|
|
|
virtual Circuit* GetCircuit() const
|
|
{
|
|
return circuit_;
|
|
}
|
|
|
|
BytecodeCircuitBuilder* GetBuilder() const
|
|
{
|
|
return builder_;
|
|
}
|
|
|
|
PassInfo* GetInfo() const
|
|
{
|
|
return info_;
|
|
}
|
|
|
|
CompilationConfig* GetCompilerConfig() const
|
|
{
|
|
return info_->GetCompilerConfig();
|
|
}
|
|
|
|
TSManager* GetTSManager() const
|
|
{
|
|
return info_->GetTSManager();
|
|
}
|
|
|
|
const JSPandaFile* GetJSPandaFile() const
|
|
{
|
|
return info_->GetJSPandaFile();
|
|
}
|
|
|
|
LLVMModule* GetAotModule() const
|
|
{
|
|
return info_->GetAOTModule();
|
|
}
|
|
|
|
CompilerLog* GetLog() const
|
|
{
|
|
return log_;
|
|
}
|
|
|
|
const std::string& GetMethodName() const
|
|
{
|
|
return methodName_;
|
|
}
|
|
|
|
const MethodLiteral* GetMethodLiteral() const
|
|
{
|
|
return methodLiteral_;
|
|
}
|
|
|
|
uint32_t GetMethodOffset() const
|
|
{
|
|
return methodOffset_;
|
|
}
|
|
|
|
size_t GetMethodInfoIndex() const
|
|
{
|
|
return methodInfoIndex_;
|
|
}
|
|
|
|
bool HasTypes() const
|
|
{
|
|
return hasTypes_;
|
|
}
|
|
|
|
const CString &GetRecordName() const
|
|
{
|
|
return recordName_;
|
|
}
|
|
|
|
private:
|
|
BytecodeCircuitBuilder *builder_ {nullptr};
|
|
Circuit *circuit_ {nullptr};
|
|
ControlFlowGraph cfg_;
|
|
PassInfo *info_ {nullptr};
|
|
CompilerLog *log_ {nullptr};
|
|
std::string methodName_;
|
|
size_t methodInfoIndex_;
|
|
bool hasTypes_;
|
|
const CString &recordName_;
|
|
MethodLiteral *methodLiteral_ {nullptr};
|
|
uint32_t methodOffset_;
|
|
};
|
|
|
|
template<typename T1>
|
|
class PassRunner {
|
|
public:
|
|
explicit PassRunner(T1* data) : data_(data) {}
|
|
virtual ~PassRunner() = default;
|
|
template<typename T2, typename... Args>
|
|
bool RunPass(Args... args)
|
|
{
|
|
T2 pass;
|
|
return pass.Run(data_, std::forward<Args>(args)...);
|
|
}
|
|
|
|
private:
|
|
T1* data_;
|
|
};
|
|
|
|
class TypeInferPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("TypeInferPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
if (data->HasTypes()) {
|
|
bool enableLog = data->GetLog()->GetEnableMethodLog() && data->GetLog()->OutputType();
|
|
TypeInfer typeInfer(data->GetBuilder(), data->GetCircuit(), data->GetInfo(), data->GetMethodInfoIndex(),
|
|
enableLog, data->GetMethodName(), data->GetRecordName());
|
|
typeInfer.TraverseCircuit();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class TSTypeLoweringPass {
|
|
public:
|
|
bool Run(PassData *data)
|
|
{
|
|
TimeScope timescope("TSTypeLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
TSTypeLowering lowering(data->GetCircuit(), data->GetInfo(), enableLog,
|
|
data->GetMethodName());
|
|
lowering.RunTSTypeLowering();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class TypeLoweringPass {
|
|
public:
|
|
bool Run(PassData *data)
|
|
{
|
|
TimeScope timescope("TypeLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
TypeLowering lowering(data->GetCircuit(), data->GetCompilerConfig(), data->GetTSManager(),
|
|
enableLog, data->GetMethodName());
|
|
lowering.RunTypeLowering();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class TSInlineLoweringPass {
|
|
public:
|
|
bool Run(PassData *data, PassInfo *info)
|
|
{
|
|
TimeScope timescope("TSInlineLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
TSInlineLowering inlining(data->GetCircuit(), info, enableLog, data->GetMethodName());
|
|
inlining.RunTSInlineLowering();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class SlowPathLoweringPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("SlowPathLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
SlowPathLowering lowering(data->GetCircuit(), data->GetCompilerConfig(), data->GetTSManager(),
|
|
data->GetMethodLiteral(), enableLog, data->GetMethodName());
|
|
lowering.CallRuntimeLowering();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class VerifierPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("VerifierPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
bool isQualified = Verifier::Run(data->GetCircuit(), data->GetMethodName(), enableLog);
|
|
if (!isQualified) {
|
|
LOG_FULL(FATAL) << "VerifierPass fail";
|
|
UNREACHABLE();
|
|
}
|
|
return isQualified;
|
|
}
|
|
};
|
|
|
|
class GuardEliminatingPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("GuardEliminatingPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
GuardEliminating(data->GetCircuit(), data->GetCompilerConfig(), enableLog, data->GetMethodName()).Run();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class SchedulingPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("SchedulingPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
Scheduler::Run(data->GetCircuit(), data->GetCfg(), data->GetMethodName(), enableLog);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLVMIRGenPass {
|
|
public:
|
|
void CreateCodeGen(LLVMModule *module, bool enableLog)
|
|
{
|
|
llvmImpl_ = std::make_unique<LLVMIRGeneratorImpl>(module, enableLog);
|
|
}
|
|
|
|
bool Run(PassData *data)
|
|
{
|
|
auto module = data->GetAotModule();
|
|
TimeScope timescope("LLVMIRGenPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
CreateCodeGen(module, enableLog);
|
|
CodeGenerator codegen(llvmImpl_, data->GetMethodName());
|
|
codegen.Run(data->GetCircuit(), data->GetConstScheduleResult(), module->GetCompilationConfig(),
|
|
data->GetMethodLiteral(), data->GetJSPandaFile());
|
|
return true;
|
|
}
|
|
private:
|
|
std::unique_ptr<CodeGeneratorImpl> llvmImpl_ {nullptr};
|
|
};
|
|
|
|
class AsyncFunctionLoweringPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("AsyncFunctionLoweringPass", data->GetMethodName(),
|
|
data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
AsyncFunctionLowering lowering(data->GetBuilder(), data->GetCircuit(), data->GetCompilerConfig(),
|
|
enableLog, data->GetMethodName());
|
|
if (lowering.IsAsyncRelated()) {
|
|
lowering.ProcessAll();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class GuardLoweringPass {
|
|
public:
|
|
bool Run(PassData* data)
|
|
{
|
|
TimeScope timescope("GuardLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
|
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
|
GuardLowering(data->GetCompilerConfig(), data->GetCircuit(), data->GetMethodName(), enableLog).Run();
|
|
return true;
|
|
}
|
|
};
|
|
} // namespace panda::ecmascript::kungfu
|
|
#endif
|