mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Support TSAOT Inlining SR
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I6MLA9 Signed-off-by: xujie <xujie101@huawei.com> Change-Id: Ia7188f0adf59f6227d78a6de3b1a82f34c7e536e
This commit is contained in:
parent
7278a4e1a0
commit
2fb2b644cc
@ -95,6 +95,7 @@ int Main(const int argc, const char **argv)
|
||||
bool isTraceBC = runtimeOptions.IsTraceBC();
|
||||
size_t maxAotMethodSize = runtimeOptions.GetMaxAotMethodSize();
|
||||
bool isEnableTypeLowering = runtimeOptions.IsEnableTypeLowering();
|
||||
bool isEnableOptInlining = runtimeOptions.IsEnableOptInlining();
|
||||
uint32_t hotnessThreshold = runtimeOptions.GetPGOHotnessThreshold();
|
||||
BytecodeStubCSigns::Initialize();
|
||||
CommonStubCSigns::Initialize();
|
||||
@ -109,7 +110,7 @@ int Main(const int argc, const char **argv)
|
||||
entrypoint = runtimeOptions.GetEntryPoint();
|
||||
}
|
||||
PassManager passManager(vm, entrypoint, triple, optLevel, relocMode, &log, &logList, maxAotMethodSize,
|
||||
isEnableTypeLowering, profilerIn, hotnessThreshold);
|
||||
isEnableTypeLowering, profilerIn, hotnessThreshold, isEnableOptInlining);
|
||||
for (const auto &fileName : pandaFileNames) {
|
||||
auto extendedFilePath = panda::os::file::File::GetExtendedFilePath(fileName);
|
||||
LOG_COMPILER(INFO) << "AOT compile: " << extendedFilePath;
|
||||
|
@ -559,6 +559,7 @@ private:
|
||||
friend class EarlyElimination;
|
||||
friend class ArgumentAccessor;
|
||||
friend class BytecodeCircuitBuilder;
|
||||
friend class TSInlineLowering;
|
||||
};
|
||||
|
||||
class ConstGateAccessor {
|
||||
|
@ -236,11 +236,11 @@ public:
|
||||
|
||||
class TSInlineLoweringPass {
|
||||
public:
|
||||
bool Run(PassData *data, PassInfo *info)
|
||||
bool Run(PassData *data)
|
||||
{
|
||||
TimeScope timescope("TSInlineLoweringPass", data->GetMethodName(), data->GetMethodOffset(), data->GetLog());
|
||||
bool enableLog = data->GetLog()->EnableMethodCIRLog();
|
||||
TSInlineLowering inlining(data->GetCircuit(), info, enableLog, data->GetMethodName());
|
||||
TSInlineLowering inlining(data->GetCircuit(), data->GetInfo(), enableLog, data->GetMethodName());
|
||||
inlining.RunTSInlineLowering();
|
||||
return true;
|
||||
}
|
||||
|
@ -108,6 +108,9 @@ bool PassManager::Compile(const std::string &fileName, AOTFileGenerator &generat
|
||||
if (data.IsTypeAbort()) {
|
||||
return;
|
||||
}
|
||||
if (EnableOptInlining()) {
|
||||
pipeline.RunPass<TSInlineLoweringPass>();
|
||||
}
|
||||
pipeline.RunPass<AsyncFunctionLoweringPass>();
|
||||
if (EnableTypeLowering()) {
|
||||
pipeline.RunPass<TSTypeLoweringPass>();
|
||||
|
@ -102,12 +102,12 @@ class PassManager {
|
||||
public:
|
||||
PassManager(EcmaVM* vm, std::string entry, std::string &triple, size_t optLevel, size_t relocMode,
|
||||
CompilerLog *log, AotMethodLogList *logList, size_t maxAotMethodSize, bool enableTypeLowering,
|
||||
const std::string &profIn, uint32_t hotnessThreshold)
|
||||
const std::string &profIn, uint32_t hotnessThreshold, bool enableOptInlining)
|
||||
: vm_(vm), entry_(entry), triple_(triple), optLevel_(optLevel), relocMode_(relocMode), log_(log),
|
||||
logList_(logList), maxAotMethodSize_(maxAotMethodSize),
|
||||
enableTypeLowering_(enableTypeLowering),
|
||||
enableTypeInfer_(enableTypeLowering || vm_->GetTSManager()->AssertTypes()),
|
||||
profilerLoader_(profIn, hotnessThreshold) {};
|
||||
profilerLoader_(profIn, hotnessThreshold), enableOptInlining_(enableOptInlining) {};
|
||||
PassManager() = default;
|
||||
~PassManager() = default;
|
||||
|
||||
@ -128,6 +128,11 @@ private:
|
||||
return enableTypeInfer_;
|
||||
}
|
||||
|
||||
bool EnableOptInlining() const
|
||||
{
|
||||
return enableOptInlining_;
|
||||
}
|
||||
|
||||
EcmaVM *vm_ {nullptr};
|
||||
std::string entry_ {};
|
||||
std::string triple_ {};
|
||||
@ -139,6 +144,7 @@ private:
|
||||
bool enableTypeLowering_ {true};
|
||||
bool enableTypeInfer_ {true};
|
||||
PGOProfilerLoader profilerLoader_;
|
||||
bool enableOptInlining_ {true};
|
||||
};
|
||||
}
|
||||
#endif // ECMASCRIPT_COMPILER_PASS_MANAGER_H
|
||||
|
@ -172,7 +172,7 @@ void TSInlineLowering::InlineCall(MethodInfo &methodInfo, MethodPcInfo &methodPC
|
||||
bool TSInlineLowering::CheckParameter(GateRef gate, bool isCallThis, MethodLiteral* method)
|
||||
{
|
||||
size_t numIns = acc_.GetNumValueIn(gate);
|
||||
size_t fixedInputsNum = isCallThis ? 1 : 0;
|
||||
size_t fixedInputsNum = isCallThis ? 2 : 1; // 2: calltarget and this
|
||||
|
||||
uint32_t declaredNumArgs = method->GetNumArgsWithCallField();
|
||||
return declaredNumArgs == (numIns - fixedInputsNum);
|
||||
@ -208,15 +208,13 @@ void TSInlineLowering::ReplaceCallInput(GateRef gate, bool isCallThis)
|
||||
LowerToInlineCall(gate, vec);
|
||||
}
|
||||
|
||||
GateRef TSInlineLowering::MergeAllReturn(const std::vector<GateRef> &returnVector,
|
||||
GateRef &state, GateRef &depend, size_t numOfIns)
|
||||
GateRef TSInlineLowering::MergeAllReturn(const std::vector<GateRef> &returnVector, GateRef &state, GateRef &depend)
|
||||
{
|
||||
size_t numOfIns = returnVector.size();
|
||||
auto stateList = std::vector<GateRef>(numOfIns, Circuit::NullGate());
|
||||
auto dependList = std::vector<GateRef>(numOfIns + 1, Circuit::NullGate());
|
||||
auto vaueList = std::vector<GateRef>(numOfIns + 1, Circuit::NullGate());
|
||||
|
||||
dependList[0] = state;
|
||||
vaueList[0] = state;
|
||||
for (size_t i = 0; i < returnVector.size(); i++) {
|
||||
GateRef returnGate = returnVector.at(i);
|
||||
ASSERT(acc_.GetOpCode(acc_.GetState(returnGate)) != OpCode::IF_EXCEPTION);
|
||||
@ -227,8 +225,10 @@ GateRef TSInlineLowering::MergeAllReturn(const std::vector<GateRef> &returnVecto
|
||||
}
|
||||
|
||||
state = circuit_->NewGate(circuit_->Merge(numOfIns), stateList);
|
||||
dependList[0] = state;
|
||||
vaueList[0] = state;
|
||||
depend = circuit_->NewGate(circuit_->DependSelector(numOfIns), dependList);
|
||||
return circuit_->NewGate(circuit_->ValueSelector(numOfIns), MachineType::I64, numOfIns,
|
||||
return circuit_->NewGate(circuit_->ValueSelector(numOfIns), MachineType::I64, numOfIns + 1,
|
||||
vaueList.data(), GateType::AnyType());
|
||||
}
|
||||
|
||||
@ -239,39 +239,35 @@ void TSInlineLowering::ReplaceEntryGate(GateRef callGate)
|
||||
|
||||
GateRef callState = acc_.GetState(callGate);
|
||||
GateRef callDepend = acc_.GetDep(callGate);
|
||||
auto stateUse = acc_.Uses(stateEntry).begin();
|
||||
acc_.ReplaceIn(stateUse, callState);
|
||||
auto dependUse = acc_.Uses(dependEntry).begin();
|
||||
acc_.ReplaceIn(dependUse, callDepend);
|
||||
auto stateUse = acc_.Uses(stateEntry);
|
||||
for (auto stateUseIt = stateUse.begin(); stateUseIt != stateUse.end();) {
|
||||
stateUseIt = acc_.ReplaceIn(stateUseIt, callState);
|
||||
}
|
||||
|
||||
auto dependUse = acc_.Uses(dependEntry);
|
||||
for (auto dependUseIt = dependUse.begin(); dependUseIt != dependUse.end();) {
|
||||
dependUseIt = acc_.ReplaceIn(dependUseIt, callDepend);
|
||||
}
|
||||
}
|
||||
|
||||
void TSInlineLowering::ReplaceReturnGate(GateRef callGate)
|
||||
{
|
||||
std::vector<GateRef> returnVector;
|
||||
acc_.GetReturnOuts(returnVector);
|
||||
size_t successReturn = 0;
|
||||
|
||||
GateRef value = Circuit::NullGate();
|
||||
GateRef state = Circuit::NullGate();
|
||||
GateRef depend = Circuit::NullGate();
|
||||
// 2: if success and if exception
|
||||
for (size_t i = 0; i < returnVector.size(); i++) {
|
||||
GateRef returnGate = returnVector.at(i);
|
||||
|
||||
if (returnVector.size() == 1) {
|
||||
GateRef returnGate = returnVector.at(0);
|
||||
GateRef returnState = acc_.GetState(returnGate);
|
||||
if (acc_.GetOpCode(returnState) == OpCode::IF_EXCEPTION) {
|
||||
continue;
|
||||
}
|
||||
successReturn++;
|
||||
ASSERT(acc_.GetOpCode(returnState) == OpCode::IF_SUCCESS ||
|
||||
acc_.GetOpCode(returnState) == OpCode::MERGE);
|
||||
depend = acc_.GetDep(returnGate);
|
||||
state = returnState;
|
||||
value = acc_.GetValueIn(returnGate, 0);
|
||||
acc_.DeleteGate(returnGate);
|
||||
break;
|
||||
}
|
||||
if (successReturn > 1) {
|
||||
value = MergeAllReturn(returnVector, state, depend, successReturn);
|
||||
} else {
|
||||
value = MergeAllReturn(returnVector, state, depend);
|
||||
}
|
||||
ReplaceHirAndDeleteState(callGate, state, depend, value);
|
||||
}
|
||||
@ -280,16 +276,8 @@ void TSInlineLowering::ReplaceHirAndDeleteState(GateRef gate, GateRef state, Gat
|
||||
{
|
||||
auto uses = acc_.Uses(gate);
|
||||
for (auto useIt = uses.begin(); useIt != uses.end();) {
|
||||
const OpCode op = acc_.GetOpCode(*useIt);
|
||||
if (op == OpCode::IF_SUCCESS) {
|
||||
auto firstUse = acc_.Uses(*useIt).begin();
|
||||
acc_.ReplaceIn(*firstUse, firstUse.GetIndex(), state);
|
||||
useIt = acc_.DeleteGate(useIt);
|
||||
} else if (op == OpCode::IF_EXCEPTION) {
|
||||
auto exceptionUseIt = acc_.Uses(*useIt).begin();
|
||||
ASSERT(acc_.GetOpCode(*exceptionUseIt) == OpCode::RETURN);
|
||||
acc_.DeleteGate(exceptionUseIt);
|
||||
useIt = acc_.DeleteGate(useIt);
|
||||
if (acc_.IsStateIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, state);
|
||||
} else if (acc_.IsDependIn(useIt)) {
|
||||
useIt = acc_.ReplaceIn(useIt, depend);
|
||||
} else if (acc_.IsValueIn(useIt)) {
|
||||
@ -316,5 +304,18 @@ void TSInlineLowering::LowerToInlineCall(GateRef callGate, const std::vector<Gat
|
||||
ReplaceEntryGate(callGate);
|
||||
// replace use gate
|
||||
ReplaceReturnGate(callGate);
|
||||
// remove Useless root gates
|
||||
RemoveRoot();
|
||||
}
|
||||
|
||||
void TSInlineLowering::RemoveRoot()
|
||||
{
|
||||
GateRef circuitRoot = acc_.GetRoot(OpCode::CIRCUIT_ROOT);
|
||||
auto uses = acc_.Uses(circuitRoot);
|
||||
for (auto it = uses.begin(); it != uses.end();) {
|
||||
it = acc_.DeleteGate(it);
|
||||
}
|
||||
|
||||
acc_.DeleteGate(circuitRoot);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -76,11 +76,11 @@ private:
|
||||
|
||||
void ReplaceHirAndDeleteState(GateRef gate, GateRef state, GateRef depend, GateRef value);
|
||||
|
||||
GateRef MergeAllReturn(const std::vector<GateRef> &returnVector,
|
||||
GateRef &state, GateRef &depend, size_t numOfIns);
|
||||
GateRef MergeAllReturn(const std::vector<GateRef> &returnVector, GateRef &state, GateRef &depend);
|
||||
bool CheckParameter(GateRef gate, bool isCallThis, MethodLiteral* method);
|
||||
|
||||
void LowerToInlineCall(GateRef gate, const std::vector<GateRef> &args);
|
||||
void RemoveRoot();
|
||||
|
||||
Circuit *circuit_ {nullptr};
|
||||
GateAccessor acc_;
|
||||
|
@ -72,6 +72,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
|
||||
"--enable-ic: Switch of inline cache. Default: 'true'\n"
|
||||
"--enable-runtime-stat: Enable statistics of runtime state. Default: 'false'\n"
|
||||
"--enable-type-lowering: Enable TSTypeLowering and TypeLowering for aot runtime. Default: 'true'\n"
|
||||
"--enable-opt-inlining: Enable inlining function for aot compiler: Default: 'false'\n"
|
||||
"--entry-point: Full name of entrypoint function. Default: '_GLOBAL::func_main_0'\n"
|
||||
"--force-full-gc: If true trigger full gc, else trigger semi and old gc. Default: 'true'\n"
|
||||
"--framework-abc-file: Snapshot file. Default: 'strip.native.min.abc'\n"
|
||||
@ -144,6 +145,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
{"enable-ic", required_argument, nullptr, OPTION_ENABLE_IC},
|
||||
{"enable-runtime-stat", required_argument, nullptr, OPTION_ENABLE_RUNTIME_STAT},
|
||||
{"enable-type-lowering", required_argument, nullptr, OPTION_ENABLE_TYPE_LOWERING},
|
||||
{"enable-opt-inlining", required_argument, nullptr, OPTION_ENABLE_OPT_INLINING},
|
||||
{"entry-point", required_argument, nullptr, OPTION_ENTRY_POINT},
|
||||
{"force-full-gc", required_argument, nullptr, OPTION_FORCE_FULL_GC},
|
||||
{"gcThreadNum", required_argument, nullptr, OPTION_GC_THREADNUM},
|
||||
@ -522,6 +524,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case OPTION_ENABLE_OPT_INLINING:
|
||||
ret = ParseBoolParam(&argBool);
|
||||
if (ret) {
|
||||
SetEnableOptInlining(argBool);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Invalid option\n"<< std::endl;
|
||||
return false;
|
||||
|
@ -105,6 +105,7 @@ enum CommandValues {
|
||||
OPTION_ENTRY_POINT,
|
||||
OPTION_MERGE_ABC,
|
||||
OPTION_ENABLE_TYPE_LOWERING,
|
||||
OPTION_ENABLE_OPT_INLINING,
|
||||
OPTION_HELP,
|
||||
OPTION_PGO_PROFILER_PATH,
|
||||
OPTION_PGO_HOTNESS_THRESHOLD,
|
||||
@ -845,6 +846,16 @@ public:
|
||||
return enableTypeLowering_;
|
||||
}
|
||||
|
||||
void SetEnableOptInlining(bool value)
|
||||
{
|
||||
enableOptInlining_ = value;
|
||||
}
|
||||
|
||||
bool IsEnableOptInlining() const
|
||||
{
|
||||
return enableOptInlining_;
|
||||
}
|
||||
|
||||
void WasSet(int opt)
|
||||
{
|
||||
wasSet_ |= 1ULL << static_cast<uint64_t>(opt);
|
||||
@ -941,6 +952,7 @@ private:
|
||||
std::string entryPoint_ {"_GLOBAL::func_main_0"};
|
||||
bool mergeAbc_ {false};
|
||||
bool enableTypeLowering_ {true};
|
||||
bool enableOptInlining_ {false};
|
||||
uint64_t wasSet_ {0};
|
||||
bool enablePrintExecuteTime_ {false};
|
||||
bool enablePGOProfiler_ {false};
|
||||
|
@ -168,6 +168,7 @@ group("ark_aot_ts_test") {
|
||||
"tonumeric",
|
||||
"try_catch_finally",
|
||||
"trystglobalbynameprefid32",
|
||||
"ts_inline",
|
||||
"typeof",
|
||||
"xor",
|
||||
]
|
||||
|
19
test/aottest/ts_inline/BUILD.gn
Normal file
19
test/aottest/ts_inline/BUILD.gn
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2023 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.
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_test_action("ts_inline") {
|
||||
deps = []
|
||||
is_enable_opt_inlining = true
|
||||
}
|
15
test/aottest/ts_inline/expect_output.txt
Normal file
15
test/aottest/ts_inline/expect_output.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2023 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.
|
||||
|
||||
3
|
||||
0
|
28
test/aottest/ts_inline/ts_inline.ts
Normal file
28
test/aottest/ts_inline/ts_inline.ts
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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.
|
||||
*/
|
||||
|
||||
declare function print(arg:any):string;
|
||||
|
||||
function foo(arg1 : number, arg2 : number) : number {
|
||||
let res = arg1 + arg2;
|
||||
if (res > 0) {
|
||||
return res;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
print(foo(1, 2));
|
||||
print(foo(1, -2));
|
@ -371,6 +371,11 @@ template("host_aot_js_test_action") {
|
||||
_aot_compile_options_ += " --trace-deopt=true"
|
||||
}
|
||||
|
||||
if (defined(invoker.is_enable_opt_inlining) &&
|
||||
invoker.is_enable_opt_inlining) {
|
||||
_aot_compile_options_ += " --enable-type-lowering=true"
|
||||
}
|
||||
|
||||
args = [
|
||||
"--script-file",
|
||||
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime/ark_aot_compiler",
|
||||
@ -513,6 +518,10 @@ template("host_aot_test_action") {
|
||||
" --builtins-dts=" + rebase_path(root_out_dir) +
|
||||
"/obj/arkcompiler/ets_runtime/lib_ark_builtins.d.abc"
|
||||
}
|
||||
if (defined(invoker.is_enable_opt_inlining) &&
|
||||
invoker.is_enable_opt_inlining) {
|
||||
_aot_compile_options_ += " --enable-type-lowering=true"
|
||||
}
|
||||
|
||||
args = [
|
||||
"--script-file",
|
||||
@ -572,6 +581,11 @@ template("host_aot_test_action") {
|
||||
"/obj/arkcompiler/ets_runtime/lib_ark_builtins.d.abc"
|
||||
}
|
||||
|
||||
if (defined(invoker.is_enable_opt_inlining) &&
|
||||
invoker.is_enable_opt_inlining) {
|
||||
_aot_compile_options_ += " --enable-type-lowering=true"
|
||||
}
|
||||
|
||||
args = [
|
||||
"--script-file",
|
||||
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime/ark_aot_compiler",
|
||||
@ -751,6 +765,10 @@ template("host_typeinfer_test_action") {
|
||||
invoker.is_enable_trace_deopt) {
|
||||
_aot_compile_options_ += " --trace-deopt=true"
|
||||
}
|
||||
if (defined(invoker.is_enable_opt_inlining) &&
|
||||
invoker.is_enable_opt_inlining) {
|
||||
_aot_compile_options_ += " --enable-type-lowering=true"
|
||||
}
|
||||
|
||||
args = [
|
||||
"--script-file",
|
||||
|
Loading…
Reference in New Issue
Block a user