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:
xujie 2023-03-13 14:37:22 +08:00
parent 7278a4e1a0
commit 2fb2b644cc
14 changed files with 156 additions and 41 deletions

View File

@ -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;

View File

@ -559,6 +559,7 @@ private:
friend class EarlyElimination;
friend class ArgumentAccessor;
friend class BytecodeCircuitBuilder;
friend class TSInlineLowering;
};
class ConstGateAccessor {

View File

@ -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;
}

View File

@ -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>();

View File

@ -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

View File

@ -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

View File

@ -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_;

View File

@ -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;

View File

@ -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};

View File

@ -168,6 +168,7 @@ group("ark_aot_ts_test") {
"tonumeric",
"try_catch_finally",
"trystglobalbynameprefid32",
"ts_inline",
"typeof",
"xor",
]

View 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
}

View 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

View 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));

View File

@ -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",