mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Add AOT Pass Manager
Modify aot compiler main process to pass manager, as to compile file by file. Add PassData to manage data interact between passes, PassRunner to execute every pass that is registered on specific order. Issue: I4SW05 Change-Id: I5b83b84880c7375e26e1c47e02c9943bfefc647a Signed-off-by: Hailiang Hu <allenpas@huawei.com>
This commit is contained in:
parent
f037ce6928
commit
e97de69528
@ -217,7 +217,10 @@ ohos_executable("ark_stub_opt") {
|
||||
}
|
||||
|
||||
ohos_executable("ark_ts_aot") {
|
||||
sources = [ "ts_aot_compiler.cpp" ]
|
||||
sources = [
|
||||
"aot_compiler.cpp",
|
||||
"pass_manager.cpp",
|
||||
]
|
||||
|
||||
configs = [
|
||||
":include_llvm",
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "libpandabase/utils/pandargs.h"
|
||||
#include "libpandabase/utils/span.h"
|
||||
#include "libpandafile/file.h"
|
||||
#include "pass_manager.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
void BlockSignals()
|
||||
@ -104,7 +105,7 @@ int Main(const int argc, const char **argv)
|
||||
|
||||
runtimeOptions.SetShouldLoadBootPandaFiles(false);
|
||||
runtimeOptions.SetShouldInitializeIntrinsics(false);
|
||||
runtimeOptions.SetBootClassSpaces( {"ecmascript"} );
|
||||
runtimeOptions.SetBootClassSpaces({"ecmascript"});
|
||||
runtimeOptions.SetRuntimeType("ecmascript");
|
||||
JSNApi::SetOptions(runtimeOptions);
|
||||
static EcmaLanguageContext lcEcma;
|
||||
@ -125,20 +126,13 @@ int Main(const int argc, const char **argv)
|
||||
std::string entry = entrypoint.GetValue();
|
||||
|
||||
arg_list_t fileNames = files.GetValue();
|
||||
PassManager passManager(vm, entry);
|
||||
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;
|
||||
LOG_ECMA(DEBUG) << "start to execute ark file: " << fileName;
|
||||
if (passManager.Compile(fileName) == false) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
for (auto &info : infoList) {
|
||||
BytecodeCircuitBuilder builder;
|
||||
builder.BytecodeToCircuit(info.pcArray, *info.file, info.method);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Runtime::Destroy()) {
|
@ -120,14 +120,9 @@ public:
|
||||
void PUBLIC_API BytecodeToCircuit(const std::vector<uint8_t *> &pcArray, const panda_file::File &pf,
|
||||
const JSMethod *method);
|
||||
|
||||
[[nodiscard]] kungfu::Circuit& GetCircuit()
|
||||
[[nodiscard]] kungfu::Circuit* GetCircuit()
|
||||
{
|
||||
return circuit_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const kungfu::Circuit& GetCircuit() const
|
||||
{
|
||||
return circuit_;
|
||||
return &circuit_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::map<kungfu::GateRef, std::pair<size_t, uint8_t *>>& GetGateToBytecode() const
|
||||
|
102
ecmascript/compiler/pass.h
Normal file
102
ecmascript/compiler/pass.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 "verifier.h"
|
||||
#include "scheduler.h"
|
||||
#include "fast_stub.h"
|
||||
#include "llvm_codegen.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class PassData {
|
||||
public:
|
||||
explicit PassData(Circuit* circuit) : circuit_(circuit) {}
|
||||
~PassData() = default;
|
||||
const ControlFlowGraph &GetScheduleResult() const
|
||||
{
|
||||
return cfg_;
|
||||
}
|
||||
|
||||
void SetScheduleResult(const ControlFlowGraph &result)
|
||||
{
|
||||
cfg_ = result;
|
||||
}
|
||||
|
||||
virtual Circuit* GetCircuit() const
|
||||
{
|
||||
return circuit_;
|
||||
}
|
||||
|
||||
private:
|
||||
Circuit* circuit_;
|
||||
ControlFlowGraph cfg_;
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
class PassRunner {
|
||||
public:
|
||||
explicit PassRunner(T1* data) : data_(data) {}
|
||||
~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 GenericLoweringPass {
|
||||
public:
|
||||
bool Run(PassData* data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class VerifierPass {
|
||||
public:
|
||||
bool Run(PassData* data)
|
||||
{
|
||||
Verifier::Run(data->GetCircuit());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SchedulingPass {
|
||||
public:
|
||||
bool Run(PassData* data)
|
||||
{
|
||||
data->SetScheduleResult(Scheduler::Run(data->GetCircuit()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLVMIRGenPass {
|
||||
public:
|
||||
bool Run(PassData* data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<CodeGeneratorImpl> llvmImpl_ {nullptr};
|
||||
};
|
||||
}
|
||||
#endif
|
42
ecmascript/compiler/pass_manager.cpp
Normal file
42
ecmascript/compiler/pass_manager.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 "pass_manager.h"
|
||||
#include "pass.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
bool PassManager::Compile(std::string 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;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto &info : infoList) {
|
||||
BytecodeCircuitBuilder builder;
|
||||
builder.BytecodeToCircuit(info.pcArray, *info.file, info.method);
|
||||
PassData data(builder.GetCircuit());
|
||||
PassRunner<PassData> pipeline(&data);
|
||||
pipeline.RunPass<GenericLoweringPass>();
|
||||
pipeline.RunPass<VerifierPass>();
|
||||
pipeline.RunPass<SchedulingPass>();
|
||||
pipeline.RunPass<LLVMIRGenPass>();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
34
ecmascript/compiler/pass_manager.h
Normal file
34
ecmascript/compiler/pass_manager.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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_MANAGER_H
|
||||
#define ECMASCRIPT_COMPILER_PASS_MANAGER_H
|
||||
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "bytecode_circuit_builder.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class PassManager {
|
||||
public:
|
||||
PassManager(EcmaVM* vm, std::string entry) : vm_(vm), entry_(entry) {}
|
||||
PassManager() = default;
|
||||
bool Compile(std::string fileName);
|
||||
|
||||
private:
|
||||
EcmaVM* vm_;
|
||||
std::string entry_;
|
||||
};
|
||||
}
|
||||
#endif
|
@ -28,21 +28,13 @@
|
||||
#include "scheduler.h"
|
||||
#include "stub-inl.h"
|
||||
#include "verifier.h"
|
||||
#include "pass.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class PassPayLoad {
|
||||
class StubPassData : public PassData {
|
||||
public:
|
||||
explicit PassPayLoad(Stub *stub, LLVMStubModule *module) : module_(module), stub_(stub) {}
|
||||
~PassPayLoad() = default;
|
||||
const ControlFlowGraph &GetScheduleResult() const
|
||||
{
|
||||
return cfg_;
|
||||
}
|
||||
|
||||
void SetScheduleResult(const ControlFlowGraph &result)
|
||||
{
|
||||
cfg_ = result;
|
||||
}
|
||||
explicit StubPassData(Stub *stub, LLVMStubModule *module) : PassData(nullptr), module_(module), stub_(stub) {}
|
||||
~StubPassData() = default;
|
||||
|
||||
const CompilationConfig *GetCompilationConfig() const
|
||||
{
|
||||
@ -67,27 +59,11 @@ public:
|
||||
private:
|
||||
LLVMStubModule *module_;
|
||||
Stub *stub_;
|
||||
ControlFlowGraph cfg_;
|
||||
};
|
||||
|
||||
class PassRunner {
|
||||
class StubBuildCircuitPass {
|
||||
public:
|
||||
explicit PassRunner(PassPayLoad *data) : data_(data) {}
|
||||
~PassRunner() = default;
|
||||
template<typename T, typename... Args>
|
||||
bool RunPass(Args... args)
|
||||
{
|
||||
T pass;
|
||||
return pass.Run(data_, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
PassPayLoad *data_;
|
||||
};
|
||||
|
||||
class BuildCircuitPass {
|
||||
public:
|
||||
bool Run(PassPayLoad *data)
|
||||
bool Run(StubPassData *data)
|
||||
{
|
||||
auto stub = data->GetStub();
|
||||
std::cout << "Stub Name: " << stub->GetMethodName() << std::endl;
|
||||
@ -96,31 +72,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class VerifierPass {
|
||||
public:
|
||||
bool Run(PassPayLoad *data)
|
||||
{
|
||||
Verifier::Run(data->GetCircuit());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SchedulerPass {
|
||||
public:
|
||||
bool Run(PassPayLoad *data)
|
||||
{
|
||||
data->SetScheduleResult(Scheduler::Run(data->GetCircuit()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLVMIRGenPass {
|
||||
class StubLLVMIRGenPass {
|
||||
public:
|
||||
void CreateCodeGen(LLVMStubModule *module)
|
||||
{
|
||||
llvmImpl_ = std::make_unique<LLVMIRGeneratorImpl>(module);
|
||||
}
|
||||
bool Run(PassPayLoad *data, int index)
|
||||
bool Run(StubPassData *data, int index)
|
||||
{
|
||||
auto stubModule = data->GetStubModule();
|
||||
CreateCodeGen(stubModule);
|
||||
@ -141,12 +99,12 @@ void StubAotCompiler::BuildStubModuleAndSave(const std::string &triple, panda::e
|
||||
for (int i = 0; i < FAST_STUB_MAXCOUNT; i++) {
|
||||
auto stub = stubs_[i];
|
||||
if (stub != nullptr) {
|
||||
PassPayLoad data(stub, &stubModule);
|
||||
PassRunner pipeline(&data);
|
||||
pipeline.RunPass<BuildCircuitPass>();
|
||||
StubPassData data(stub, &stubModule);
|
||||
PassRunner<StubPassData> pipeline(&data);
|
||||
pipeline.RunPass<StubBuildCircuitPass>();
|
||||
pipeline.RunPass<VerifierPass>();
|
||||
pipeline.RunPass<SchedulerPass>();
|
||||
pipeline.RunPass<LLVMIRGenPass>(i);
|
||||
pipeline.RunPass<SchedulingPass>();
|
||||
pipeline.RunPass<StubLLVMIRGenPass>(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user