mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
Add irreducible loop check
1.skip empty catch bb for aot and jit 2.add irreducible loop check Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IANMXK Signed-off-by: zoumujia <zoumujia0920@163.com>
This commit is contained in:
parent
2dc30245ec
commit
5398c8555d
@ -14,17 +14,18 @@
|
|||||||
*/
|
*/
|
||||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||||
|
|
||||||
|
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
||||||
#include "ecmascript/compiler/pgo_type/pgo_type_parser.h"
|
#include "ecmascript/compiler/pgo_type/pgo_type_parser.h"
|
||||||
|
#include "ecmascript/compiler/pass_manager.h"
|
||||||
#include "ecmascript/jspandafile/program_object.h"
|
#include "ecmascript/jspandafile/program_object.h"
|
||||||
|
#include "ecmascript/js_runtime_options.h"
|
||||||
#include "ecmascript/module/js_shared_module_manager.h"
|
#include "ecmascript/module/js_shared_module_manager.h"
|
||||||
#include "ecmascript/module/js_module_manager.h"
|
#include "ecmascript/module/js_module_manager.h"
|
||||||
#include "ecmascript/ohos/ohos_pgo_processor.h"
|
#include "ecmascript/ohos/ohos_pgo_processor.h"
|
||||||
#include "ecmascript/ohos/ohos_pkg_args.h"
|
#include "ecmascript/ohos/ohos_pkg_args.h"
|
||||||
|
|
||||||
namespace panda::ecmascript::kungfu {
|
namespace panda::ecmascript::kungfu {
|
||||||
namespace {
|
|
||||||
constexpr int32_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
|
|
||||||
} // namespace
|
|
||||||
using PGOProfilerManager = pgo::PGOProfilerManager;
|
using PGOProfilerManager = pgo::PGOProfilerManager;
|
||||||
|
|
||||||
CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
|
CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
|
||||||
@ -49,6 +50,7 @@ CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
|
|||||||
isEnableArrayBoundsCheckElimination_ = runtimeOptions.IsEnableArrayBoundsCheckElimination();
|
isEnableArrayBoundsCheckElimination_ = runtimeOptions.IsEnableArrayBoundsCheckElimination();
|
||||||
isEnableTypeLowering_ = runtimeOptions.IsEnableTypeLowering();
|
isEnableTypeLowering_ = runtimeOptions.IsEnableTypeLowering();
|
||||||
isEnableEarlyElimination_ = runtimeOptions.IsEnableEarlyElimination();
|
isEnableEarlyElimination_ = runtimeOptions.IsEnableEarlyElimination();
|
||||||
|
isEnableEmptyCatchFunction_ = runtimeOptions.IsEnableEmptyCatchFunction();
|
||||||
isEnableLaterElimination_ = runtimeOptions.IsEnableLaterElimination();
|
isEnableLaterElimination_ = runtimeOptions.IsEnableLaterElimination();
|
||||||
isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
|
isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
|
||||||
isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
|
isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
|
||||||
@ -67,7 +69,6 @@ CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
|
|||||||
isEnableInductionVariableAnalysis_ = runtimeOptions.IsEnableInductionVariableAnalysis();
|
isEnableInductionVariableAnalysis_ = runtimeOptions.IsEnableInductionVariableAnalysis();
|
||||||
isEnableVerifierPass_ = !runtimeOptions.IsTargetCompilerMode();
|
isEnableVerifierPass_ = !runtimeOptions.IsTargetCompilerMode();
|
||||||
isEnableBaselinePgo_ = runtimeOptions.IsEnableBaselinePgo();
|
isEnableBaselinePgo_ = runtimeOptions.IsEnableBaselinePgo();
|
||||||
|
|
||||||
std::string optionSelectMethods = runtimeOptions.GetCompilerSelectMethods();
|
std::string optionSelectMethods = runtimeOptions.GetCompilerSelectMethods();
|
||||||
std::string optionSkipMethods = runtimeOptions.GetCompilerSkipMethods();
|
std::string optionSkipMethods = runtimeOptions.GetCompilerSkipMethods();
|
||||||
if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) {
|
if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) {
|
||||||
@ -145,6 +146,18 @@ void AotCompilerPreprocessor::HandleTargetModeInfo(CompilationOptions &cOptions)
|
|||||||
cOptions.optLevel_ = DEFAULT_OPT_LEVEL;
|
cOptions.optLevel_ = DEFAULT_OPT_LEVEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AotCompilerPreprocessor::MethodHasTryCatch(const JSPandaFile *jsPandaFile,
|
||||||
|
const MethodLiteral *methodLiteral) const
|
||||||
|
{
|
||||||
|
if (jsPandaFile == nullptr || methodLiteral == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto pf = jsPandaFile->GetPandaFile();
|
||||||
|
panda_file::MethodDataAccessor mda(*pf, methodLiteral->GetMethodId());
|
||||||
|
panda_file::CodeDataAccessor cda(*pf, mda.GetCodeId().value());
|
||||||
|
return cda.GetTriesSize() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool AotCompilerPreprocessor::HandlePandaFileNames(const int argc, const char **argv)
|
bool AotCompilerPreprocessor::HandlePandaFileNames(const int argc, const char **argv)
|
||||||
{
|
{
|
||||||
if (runtimeOptions_.GetCompilerPkgJsonInfo().empty() || pkgsArgs_.empty()) {
|
if (runtimeOptions_.GetCompilerPkgJsonInfo().empty() || pkgsArgs_.empty()) {
|
||||||
@ -174,9 +187,78 @@ void AotCompilerPreprocessor::Process(CompilationOptions &cOptions)
|
|||||||
GenerateBytecodeInfoCollectors(cOptions);
|
GenerateBytecodeInfoCollectors(cOptions);
|
||||||
GeneratePGOTypes();
|
GeneratePGOTypes();
|
||||||
SnapshotInitialize();
|
SnapshotInitialize();
|
||||||
|
DoPreAnalysis(cOptions);
|
||||||
GenerateMethodMap(cOptions);
|
GenerateMethodMap(cOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AotCompilerPreprocessor::DoPreAnalysis(CompilationOptions &cOptions)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0 ; i < fileInfos_.size(); ++i) {
|
||||||
|
JSPandaFile *jsPandaFile = fileInfos_[i].jsPandaFile_.get();
|
||||||
|
auto &collector = *bcInfoCollectors_[i];
|
||||||
|
AnalyzeGraphs(jsPandaFile, collector, cOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AotCompilerPreprocessor::AnalyzeGraphs(JSPandaFile *jsPandaFile,
|
||||||
|
BytecodeInfoCollector &collector, CompilationOptions &cOptions)
|
||||||
|
{
|
||||||
|
if (jsPandaFile == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto &bytecodeInfo = collector.GetBytecodeInfo();
|
||||||
|
auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos();
|
||||||
|
for (auto &[methodId, methodInfo] : bytecodeInfo.GetMethodList()) {
|
||||||
|
auto methodLiteral = jsPandaFile->FindMethodLiteral(methodId);
|
||||||
|
auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()];
|
||||||
|
if (MethodHasTryCatch(jsPandaFile, methodLiteral)) {
|
||||||
|
AnalyzeGraph(bytecodeInfo, cOptions, collector, methodLiteral, methodPcInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AotCompilerPreprocessor::AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions,
|
||||||
|
BytecodeInfoCollector &collector, MethodLiteral *methodLiteral,
|
||||||
|
MethodPcInfo &methodPCInfo)
|
||||||
|
{
|
||||||
|
if (methodLiteral == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AotMethodLogList logList(cOptions.logMethodsList_);
|
||||||
|
AOTCompilationEnv aotCompilationEnv(vm_);
|
||||||
|
CompilerLog log(cOptions.logOption_);
|
||||||
|
AOTFileGenerator generator(&log, &logList, &aotCompilationEnv, cOptions.triple_, false);
|
||||||
|
PGOProfilerDecoder profilerDecoder;
|
||||||
|
LOptions lOptions = LOptions(DEFAULT_OPT_LEVEL, FPFlag::RESERVE_FP, DEFAULT_REL_MODE);
|
||||||
|
Module *m = generator.AddModule("", cOptions.triple_, lOptions, false);
|
||||||
|
PassContext ctx(cOptions.triple_, &log, &collector, m->GetModule(), &profilerDecoder);
|
||||||
|
auto jsPandaFile = ctx.GetJSPandaFile();
|
||||||
|
auto cmpCfg = ctx.GetCompilerConfig();
|
||||||
|
auto module = m->GetModule();
|
||||||
|
std::string fullName = module->GetFuncName(methodLiteral, jsPandaFile);
|
||||||
|
|
||||||
|
Circuit circuit(vm_->GetNativeAreaAllocator(), ctx.GetAOTModule()->GetDebugInfo(),
|
||||||
|
fullName.c_str(), cmpCfg->Is64Bit(), FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
|
||||||
|
|
||||||
|
PGOProfilerDecoder *decoder = cOptions.isEnableOptPGOType_ ? &profilerDecoder : nullptr;
|
||||||
|
|
||||||
|
BytecodeCircuitBuilder builder(jsPandaFile, methodLiteral, methodPCInfo, &circuit,
|
||||||
|
ctx.GetByteCodes(), false,
|
||||||
|
cOptions.isEnableTypeLowering_,
|
||||||
|
fullName, bytecodeInfo.GetRecordNameWithIndex(0), decoder, false);
|
||||||
|
{
|
||||||
|
builder.SetPreAnalysis();
|
||||||
|
builder.BytecodeToCircuit();
|
||||||
|
if (builder.HasEmptyCatchBB()) {
|
||||||
|
emptyCatchBBMethods_.push_back(fullName);
|
||||||
|
}
|
||||||
|
if (builder.HasIrreducibleLoop()) {
|
||||||
|
irreducibleMethods_.push_back(fullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m->DestroyModule();
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t AotCompilerPreprocessor::GenerateAbcFileInfos()
|
uint32_t AotCompilerPreprocessor::GenerateAbcFileInfos()
|
||||||
{
|
{
|
||||||
size_t size = pandaFileNames_.size();
|
size_t size = pandaFileNames_.size();
|
||||||
@ -357,6 +439,15 @@ bool AotCompilerPreprocessor::IsSkipMethod(const JSPandaFile *jsPandaFile, const
|
|||||||
return FilterOption(cOptions.optionSkipMethods_, ConvertToStdString(recordName), methodName);
|
return FilterOption(cOptions.optionSkipMethods_, ConvertToStdString(recordName), methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string fullName = IRModule::GetFuncName(methodLiteral, jsPandaFile);
|
||||||
|
if (HasSkipMethod(irreducibleMethods_, fullName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasSkipMethod(emptyCatchBBMethods_, fullName) && !cOptions.isEnableEmptyCatchFunction_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,6 +481,12 @@ void AotCompilerPreprocessor::GenerateMethodMap(CompilationOptions &cOptions)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AotCompilerPreprocessor::HasSkipMethod(const CVector<std::string> &methodList,
|
||||||
|
const std::string &methodName) const
|
||||||
|
{
|
||||||
|
return std::find(methodList.begin(), methodList.end(), methodName) != methodList.end();
|
||||||
|
}
|
||||||
|
|
||||||
std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const
|
std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const
|
||||||
{
|
{
|
||||||
return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature();
|
return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature();
|
||||||
|
@ -75,6 +75,7 @@ struct CompilationOptions {
|
|||||||
bool isEnableLaterElimination_ {true};
|
bool isEnableLaterElimination_ {true};
|
||||||
bool isEnableValueNumbering_ {true};
|
bool isEnableValueNumbering_ {true};
|
||||||
bool isEnableOptInlining_ {true};
|
bool isEnableOptInlining_ {true};
|
||||||
|
bool isEnableEmptyCatchFunction_ {false};
|
||||||
bool isEnableOptString_ {true};
|
bool isEnableOptString_ {true};
|
||||||
bool isEnableOptPGOType_ {true};
|
bool isEnableOptPGOType_ {true};
|
||||||
bool isEnableOptTrackField_ {true};
|
bool isEnableOptTrackField_ {true};
|
||||||
@ -114,6 +115,13 @@ public:
|
|||||||
|
|
||||||
void AOTInitialize();
|
void AOTInitialize();
|
||||||
|
|
||||||
|
void DoPreAnalysis(CompilationOptions &cOptions);
|
||||||
|
|
||||||
|
void AnalyzeGraphs(JSPandaFile *jsPandaFile, BytecodeInfoCollector &collector, CompilationOptions &cOptions);
|
||||||
|
|
||||||
|
void AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions, BytecodeInfoCollector &collector,
|
||||||
|
MethodLiteral *methodLiteral, MethodPcInfo &methodPCInfo);
|
||||||
|
|
||||||
void Process(CompilationOptions &cOptions);
|
void Process(CompilationOptions &cOptions);
|
||||||
|
|
||||||
uint32_t GenerateAbcFileInfos();
|
uint32_t GenerateAbcFileInfos();
|
||||||
@ -136,6 +144,10 @@ public:
|
|||||||
|
|
||||||
void GenerateMethodMap(CompilationOptions &cOptions);
|
void GenerateMethodMap(CompilationOptions &cOptions);
|
||||||
|
|
||||||
|
bool MethodHasTryCatch(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral) const;
|
||||||
|
|
||||||
|
bool HasSkipMethod(const CVector<std::string> &methodList, const std::string &methodName) const;
|
||||||
|
|
||||||
void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall)
|
void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall)
|
||||||
{
|
{
|
||||||
callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall);
|
callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall);
|
||||||
@ -226,6 +238,8 @@ private:
|
|||||||
CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_;
|
CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_;
|
||||||
CallMethodFlagMap callMethodFlagMap_;
|
CallMethodFlagMap callMethodFlagMap_;
|
||||||
AOTCompilationEnv aotCompilationEnv_;
|
AOTCompilationEnv aotCompilationEnv_;
|
||||||
|
CVector<std::string> emptyCatchBBMethods_;
|
||||||
|
CVector<std::string> irreducibleMethods_;
|
||||||
friend class OhosPkgArgs;
|
friend class OhosPkgArgs;
|
||||||
};
|
};
|
||||||
} // namespace panda::ecmascript::kungfu
|
} // namespace panda::ecmascript::kungfu
|
||||||
|
@ -15,12 +15,16 @@
|
|||||||
|
|
||||||
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
#include "ecmascript/compiler/bytecode_circuit_builder.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
#include "ecmascript/base/number_helper.h"
|
#include "ecmascript/base/number_helper.h"
|
||||||
#include "ecmascript/compiler/gate_accessor.h"
|
#include "ecmascript/compiler/gate_accessor.h"
|
||||||
#include "ecmascript/deoptimizer/deoptimizer.h"
|
#include "ecmascript/deoptimizer/deoptimizer.h"
|
||||||
#include "ecmascript/interpreter/interpreter-inl.h"
|
#include "ecmascript/interpreter/interpreter-inl.h"
|
||||||
#include "libpandafile/bytecode_instruction-inl.h"
|
#include "libpandafile/bytecode_instruction-inl.h"
|
||||||
|
|
||||||
|
|
||||||
namespace panda::ecmascript::kungfu {
|
namespace panda::ecmascript::kungfu {
|
||||||
void BytecodeCircuitBuilder::BytecodeToCircuit()
|
void BytecodeCircuitBuilder::BytecodeToCircuit()
|
||||||
{
|
{
|
||||||
@ -147,6 +151,161 @@ void BytecodeCircuitBuilder::CollectTryCatchBlockInfo(ExceptionInfo &byteCodeExc
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BytecodeCircuitBuilder::IsAncestor(size_t nodeA, size_t nodeB)
|
||||||
|
{
|
||||||
|
return timeIn_[bbIdToDfsTimestamp_[nodeA]] <= timeIn_[bbIdToDfsTimestamp_[nodeB]] &&
|
||||||
|
timeOut_[bbIdToDfsTimestamp_[nodeA]] >= timeOut_[bbIdToDfsTimestamp_[nodeB]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeCircuitBuilder::PerformDFS(const std::vector<size_t> &immDom, size_t listSize)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<size_t>> sonList(listSize);
|
||||||
|
for (size_t idx = 1; idx < immDom.size(); idx++) {
|
||||||
|
sonList[immDom[idx]].push_back(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
size_t timestamp = 0;
|
||||||
|
struct DFSState {
|
||||||
|
size_t cur;
|
||||||
|
std::vector<size_t> &succList;
|
||||||
|
size_t idx;
|
||||||
|
};
|
||||||
|
std::stack<DFSState> dfsStack;
|
||||||
|
size_t root = 0;
|
||||||
|
dfsStack.push({root, sonList[root], 0});
|
||||||
|
timeIn_[root] = timestamp++;
|
||||||
|
while (!dfsStack.empty()) {
|
||||||
|
auto &curState = dfsStack.top();
|
||||||
|
auto &cur = curState.cur;
|
||||||
|
auto &succList = curState.succList;
|
||||||
|
auto &idx = curState.idx;
|
||||||
|
if (idx == succList.size()) {
|
||||||
|
timeOut_[cur] = timestamp++;
|
||||||
|
dfsStack.pop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto &succ = succList[idx];
|
||||||
|
dfsStack.push({succ, sonList[succ], 0});
|
||||||
|
timeIn_[succ] = timestamp++;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BytecodeCircuitBuilder::ReducibilityCheck()
|
||||||
|
{
|
||||||
|
std::vector<size_t> basicBlockList;
|
||||||
|
std::vector<size_t> immDom;
|
||||||
|
std::unordered_map<size_t, size_t> bbDfsTimestampToIdx;
|
||||||
|
ComputeDominatorTree(basicBlockList, immDom, bbDfsTimestampToIdx);
|
||||||
|
timeIn_.resize(basicBlockList.size());
|
||||||
|
timeOut_.resize(basicBlockList.size());
|
||||||
|
PerformDFS(immDom, basicBlockList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeCircuitBuilder::ComputeImmediateDominators(const std::vector<size_t> &basicBlockList,
|
||||||
|
std::unordered_map<size_t, size_t> &dfsFatherIdx,
|
||||||
|
std::vector<size_t> &immDom,
|
||||||
|
std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx)
|
||||||
|
{
|
||||||
|
std::vector<size_t> semiDom(basicBlockList.size());
|
||||||
|
std::vector<std::vector<size_t> > semiDomTree(basicBlockList.size());
|
||||||
|
{
|
||||||
|
std::vector<size_t> parent(basicBlockList.size());
|
||||||
|
std::iota(parent.begin(), parent.end(), 0);
|
||||||
|
std::vector<size_t> minIdx(basicBlockList.size());
|
||||||
|
std::function<size_t(size_t)> unionFind = [&] (size_t idx) -> size_t {
|
||||||
|
if (parent[idx] == idx) return idx;
|
||||||
|
size_t unionFindSetRoot = unionFind(parent[idx]);
|
||||||
|
if (semiDom[minIdx[idx]] > semiDom[minIdx[parent[idx]]]) {
|
||||||
|
minIdx[idx] = minIdx[parent[idx]];
|
||||||
|
}
|
||||||
|
return parent[idx] = unionFindSetRoot;
|
||||||
|
};
|
||||||
|
auto merge = [&] (size_t fatherIdx, size_t sonIdx) -> void {
|
||||||
|
size_t parentFatherIdx = unionFind(fatherIdx);
|
||||||
|
size_t parentSonIdx = unionFind(sonIdx);
|
||||||
|
parent[parentSonIdx] = parentFatherIdx;
|
||||||
|
};
|
||||||
|
auto calculateSemiDom = [&](size_t idx, const ChunkVector<BytecodeRegion *> &blocks) {
|
||||||
|
for (const auto &preBlock : blocks) {
|
||||||
|
if (bbDfsTimestampToIdx[preBlock->id] < idx) {
|
||||||
|
semiDom[idx] = std::min(semiDom[idx], bbDfsTimestampToIdx[preBlock->id]);
|
||||||
|
} else {
|
||||||
|
unionFind(bbDfsTimestampToIdx[preBlock->id]);
|
||||||
|
semiDom[idx] = std::min(semiDom[idx], semiDom[minIdx[bbDfsTimestampToIdx[preBlock->id]]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::iota(semiDom.begin(), semiDom.end(), 0);
|
||||||
|
semiDom[0] = semiDom.size();
|
||||||
|
for (size_t idx = basicBlockList.size() - 1; idx >= 1; idx--) {
|
||||||
|
calculateSemiDom(idx, graph_[basicBlockList[idx]]->preds);
|
||||||
|
if (!graph_[basicBlockList[idx]]->trys.empty()) {
|
||||||
|
calculateSemiDom(idx, graph_[basicBlockList[idx]]->trys);
|
||||||
|
}
|
||||||
|
for (const auto &succDomIdx : semiDomTree[idx]) {
|
||||||
|
unionFind(succDomIdx);
|
||||||
|
if (idx == semiDom[minIdx[succDomIdx]]) {
|
||||||
|
immDom[succDomIdx] = idx;
|
||||||
|
} else {
|
||||||
|
immDom[succDomIdx] = minIdx[succDomIdx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
minIdx[idx] = idx;
|
||||||
|
merge(dfsFatherIdx[basicBlockList[idx]], idx);
|
||||||
|
semiDomTree[semiDom[idx]].emplace_back(idx);
|
||||||
|
}
|
||||||
|
for (size_t idx = 1; idx < basicBlockList.size(); idx++) {
|
||||||
|
if (immDom[idx] != semiDom[idx]) {
|
||||||
|
immDom[idx] = immDom[immDom[idx]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
semiDom[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeCircuitBuilder::ComputeDominatorTree(std::vector<size_t> &basicBlockList, std::vector<size_t> &immDom,
|
||||||
|
std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx)
|
||||||
|
{
|
||||||
|
std::unordered_map<size_t, size_t> dfsFatherIdx;
|
||||||
|
size_t timestamp = 0;
|
||||||
|
std::deque<size_t> pendingList;
|
||||||
|
std::vector<size_t> visited(graph_.size(), 0);
|
||||||
|
auto basicBlockId = graph_[0]->id;
|
||||||
|
visited[graph_[0]->id] = 1;
|
||||||
|
pendingList.emplace_back(basicBlockId);
|
||||||
|
|
||||||
|
auto visitConnectedBlocks = [&](const ChunkVector<BytecodeRegion *> &succs, size_t curBlockId) {
|
||||||
|
for (const auto &succBlock : succs) {
|
||||||
|
if (visited[succBlock->id] == 0) {
|
||||||
|
visited[succBlock->id] = 1;
|
||||||
|
pendingList.emplace_back(succBlock->id);
|
||||||
|
dfsFatherIdx[succBlock->id] = bbIdToDfsTimestamp_[curBlockId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!pendingList.empty()) {
|
||||||
|
size_t curBlockId = pendingList.back();
|
||||||
|
pendingList.pop_back();
|
||||||
|
basicBlockList.emplace_back(curBlockId);
|
||||||
|
bbIdToDfsTimestamp_[curBlockId] = timestamp++;
|
||||||
|
visitConnectedBlocks(graph_[curBlockId]->succs, curBlockId);
|
||||||
|
if (!graph_[curBlockId]->catches.empty()) {
|
||||||
|
visitConnectedBlocks(graph_[curBlockId]->catches, curBlockId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t idx = 0; idx < basicBlockList.size(); idx++) {
|
||||||
|
bbDfsTimestampToIdx[basicBlockList[idx]] = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
immDom.resize(basicBlockList.size());
|
||||||
|
ComputeImmediateDominators(basicBlockList, dfsFatherIdx, immDom, bbDfsTimestampToIdx);
|
||||||
|
}
|
||||||
|
|
||||||
void BytecodeCircuitBuilder::BuildEntryBlock()
|
void BytecodeCircuitBuilder::BuildEntryBlock()
|
||||||
{
|
{
|
||||||
BytecodeRegion &entryBlock = RegionAt(0);
|
BytecodeRegion &entryBlock = RegionAt(0);
|
||||||
@ -156,23 +315,9 @@ void BytecodeCircuitBuilder::BuildEntryBlock()
|
|||||||
entryBlock.bytecodeIterator_.Reset(this, 0, BytecodeIterator::INVALID_INDEX);
|
entryBlock.bytecodeIterator_.Reset(this, 0, BytecodeIterator::INVALID_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytecodeCircuitBuilder::BuildRegions(const ExceptionInfo &byteCodeException)
|
void BytecodeCircuitBuilder::BuildBasicBlock()
|
||||||
{
|
{
|
||||||
auto &items = regionsInfo_.GetBlockItems();
|
auto &items = regionsInfo_.GetBlockItems();
|
||||||
auto blockSize = items.size();
|
|
||||||
|
|
||||||
// 1 : entry block. if the loop head is in the first bb block, the variables used in the head cannot correctly
|
|
||||||
// generate Phi nodes through the dominator-tree algorithm, resulting in an infinite loop. Therefore, an empty
|
|
||||||
// BB block is generated as an entry block
|
|
||||||
graph_.resize(blockSize + 1, nullptr);
|
|
||||||
for (size_t i = 0; i < graph_.size(); i++) {
|
|
||||||
graph_[i] = circuit_->chunk()->New<BytecodeRegion>(circuit_->chunk());
|
|
||||||
}
|
|
||||||
|
|
||||||
// build entry block
|
|
||||||
BuildEntryBlock();
|
|
||||||
|
|
||||||
// build basic block
|
|
||||||
size_t blockId = 1;
|
size_t blockId = 1;
|
||||||
for (const auto &item : items) {
|
for (const auto &item : items) {
|
||||||
auto &curBlock = GetBasicBlockById(blockId);
|
auto &curBlock = GetBasicBlockById(blockId);
|
||||||
@ -194,6 +339,25 @@ void BytecodeCircuitBuilder::BuildRegions(const ExceptionInfo &byteCodeException
|
|||||||
auto &lastBlock = RegionAt(blockId - 1); // 1: last block
|
auto &lastBlock = RegionAt(blockId - 1); // 1: last block
|
||||||
lastBlock.end = GetLastBcIndex();
|
lastBlock.end = GetLastBcIndex();
|
||||||
lastBlock.bytecodeIterator_.Reset(this, lastBlock.start, lastBlock.end);
|
lastBlock.bytecodeIterator_.Reset(this, lastBlock.start, lastBlock.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BytecodeCircuitBuilder::BuildRegions(const ExceptionInfo &byteCodeException)
|
||||||
|
{
|
||||||
|
auto blockSize = regionsInfo_.GetBlockItems().size();
|
||||||
|
|
||||||
|
// 1 : entry block. if the loop head is in the first bb block, the variables used in the head cannot correctly
|
||||||
|
// generate Phi nodes through the dominator-tree algorithm, resulting in an infinite loop. Therefore, an empty
|
||||||
|
// BB block is generated as an entry block
|
||||||
|
graph_.resize(blockSize + 1, nullptr);
|
||||||
|
for (size_t i = 0; i < graph_.size(); i++) {
|
||||||
|
graph_[i] = circuit_->chunk()->New<BytecodeRegion>(circuit_->chunk());
|
||||||
|
}
|
||||||
|
|
||||||
|
// build entry block
|
||||||
|
BuildEntryBlock();
|
||||||
|
|
||||||
|
// build basic block
|
||||||
|
BuildBasicBlock();
|
||||||
|
|
||||||
auto &splitItems = regionsInfo_.GetSplitItems();
|
auto &splitItems = regionsInfo_.GetSplitItems();
|
||||||
for (const auto &item : splitItems) {
|
for (const auto &item : splitItems) {
|
||||||
@ -213,7 +377,10 @@ void BytecodeCircuitBuilder::BuildRegions(const ExceptionInfo &byteCodeException
|
|||||||
CollectTryPredsInfo();
|
CollectTryPredsInfo();
|
||||||
}
|
}
|
||||||
RemoveUnreachableRegion();
|
RemoveUnreachableRegion();
|
||||||
if (IsLogEnabled()) {
|
if (NeedIrreducibleLoopCheck()) {
|
||||||
|
ReducibilityCheck();
|
||||||
|
}
|
||||||
|
if (IsLogEnabled() && !IsPreAnalysis()) {
|
||||||
PrintGraph(std::string("Update CFG [" + methodName_ + "]").c_str());
|
PrintGraph(std::string("Update CFG [" + methodName_ + "]").c_str());
|
||||||
}
|
}
|
||||||
BuildCircuit();
|
BuildCircuit();
|
||||||
@ -227,6 +394,7 @@ void BytecodeCircuitBuilder::UpdateEmptyCatchBB()
|
|||||||
if (it != candidateEmptyCatch_.end()) {
|
if (it != candidateEmptyCatch_.end()) {
|
||||||
if (it->second) {
|
if (it->second) {
|
||||||
bb.IsEmptyCatchBB = true;
|
bb.IsEmptyCatchBB = true;
|
||||||
|
hasEmptyCatchBB_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1039,12 +1207,18 @@ void BytecodeCircuitBuilder::BuildCircuit()
|
|||||||
// create osr arg gates array
|
// create osr arg gates array
|
||||||
BuildOSRArgs();
|
BuildOSRArgs();
|
||||||
frameStateBuilder_.DoBytecodeAnalysis();
|
frameStateBuilder_.DoBytecodeAnalysis();
|
||||||
|
if (TerminateAnalysis()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// build states sub-circuit of osr block
|
// build states sub-circuit of osr block
|
||||||
BuildOsrCircuit();
|
BuildOsrCircuit();
|
||||||
} else {
|
} else {
|
||||||
// create arg gates array
|
// create arg gates array
|
||||||
BuildCircuitArgs();
|
BuildCircuitArgs();
|
||||||
frameStateBuilder_.DoBytecodeAnalysis();
|
frameStateBuilder_.DoBytecodeAnalysis();
|
||||||
|
if (TerminateAnalysis()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// build states sub-circuit of each block
|
// build states sub-circuit of each block
|
||||||
BuildSubCircuit();
|
BuildSubCircuit();
|
||||||
}
|
}
|
||||||
|
@ -572,6 +572,51 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetIrreducibleLoop()
|
||||||
|
{
|
||||||
|
isIrreducible_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasIrreducibleLoop() const
|
||||||
|
{
|
||||||
|
return isIrreducible_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetJitCompile()
|
||||||
|
{
|
||||||
|
isJitCompile_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsJitCompile() const
|
||||||
|
{
|
||||||
|
return isJitCompile_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPreAnalysis()
|
||||||
|
{
|
||||||
|
preAnalysis_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsPreAnalysis() const
|
||||||
|
{
|
||||||
|
return preAnalysis_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasEmptyCatchBB() const
|
||||||
|
{
|
||||||
|
return hasEmptyCatchBB_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NeedIrreducibleLoopCheck() const
|
||||||
|
{
|
||||||
|
return IsPreAnalysis() || IsJitCompile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TerminateAnalysis() const
|
||||||
|
{
|
||||||
|
return IsPreAnalysis() || HasIrreducibleLoop();
|
||||||
|
}
|
||||||
|
|
||||||
bool IsOSR() const
|
bool IsOSR() const
|
||||||
{
|
{
|
||||||
return osrOffset_ != MachineCode::INVALID_OSR_OFFSET;
|
return osrOffset_ != MachineCode::INVALID_OSR_OFFSET;
|
||||||
@ -584,10 +629,26 @@ public:
|
|||||||
|
|
||||||
void ComputeNumOfLoopBack();
|
void ComputeNumOfLoopBack();
|
||||||
|
|
||||||
|
enum class MarkState : uint8_t {
|
||||||
|
UNVISITED = 0,
|
||||||
|
ON_STACK,
|
||||||
|
PENDING,
|
||||||
|
VISITED,
|
||||||
|
VISITED1,
|
||||||
|
UNVISITED1 = VISITED
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VisitedInfo {
|
||||||
|
size_t needVisitIndex;
|
||||||
|
bool isVisitedCatchBlock = false;
|
||||||
|
};
|
||||||
|
bool IsAncestor(size_t nodeA, size_t nodeB);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CollectTryCatchBlockInfo(ExceptionInfo &Exception);
|
void CollectTryCatchBlockInfo(ExceptionInfo &Exception);
|
||||||
void BuildCatchBlocks(const ExceptionInfo &Exception);
|
void BuildCatchBlocks(const ExceptionInfo &Exception);
|
||||||
void BuildEntryBlock();
|
void BuildEntryBlock();
|
||||||
|
void BuildBasicBlock();
|
||||||
void BuildRegions(const ExceptionInfo &Exception);
|
void BuildRegions(const ExceptionInfo &Exception);
|
||||||
// build circuit
|
// build circuit
|
||||||
void BuildCircuitArgs();
|
void BuildCircuitArgs();
|
||||||
@ -621,6 +682,13 @@ private:
|
|||||||
void BuildRegionInfo();
|
void BuildRegionInfo();
|
||||||
void BuildFrameArgs();
|
void BuildFrameArgs();
|
||||||
void RemoveIfInRpoList(BytecodeRegion *bb);
|
void RemoveIfInRpoList(BytecodeRegion *bb);
|
||||||
|
void PerformDFS(const std::vector<size_t> &immDom, size_t listSize);
|
||||||
|
void ReducibilityCheck();
|
||||||
|
void ComputeImmediateDominators(const std::vector<size_t> &basicBlockList,
|
||||||
|
std::unordered_map<size_t, size_t> &dfsFatherIdx, std::vector<size_t> &immDom,
|
||||||
|
std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx);
|
||||||
|
void ComputeDominatorTree(std::vector<size_t> &basicBlockList, std::vector<size_t> &immDom,
|
||||||
|
std::unordered_map<size_t, size_t> &bbDfsTimestampToIdx);
|
||||||
|
|
||||||
BytecodeRegion &RegionAt(size_t i)
|
BytecodeRegion &RegionAt(size_t i)
|
||||||
{
|
{
|
||||||
@ -654,8 +722,15 @@ private:
|
|||||||
size_t numOfLiveBB_ {0};
|
size_t numOfLiveBB_ {0};
|
||||||
bool isInline_ {false};
|
bool isInline_ {false};
|
||||||
uint32_t methodId_ {0};
|
uint32_t methodId_ {0};
|
||||||
|
bool preAnalysis_ {false};
|
||||||
std::set<const BytecodeRegion *> catchBBOfOSRLoop_{};
|
std::set<const BytecodeRegion *> catchBBOfOSRLoop_{};
|
||||||
std::map<uint32_t, bool> candidateEmptyCatch_ {};
|
std::map<uint32_t, bool> candidateEmptyCatch_ {};
|
||||||
|
bool hasEmptyCatchBB_ {false};
|
||||||
|
bool isIrreducible_ {false};
|
||||||
|
bool isJitCompile_ {false};
|
||||||
|
CVector<size_t> timeIn_ {};
|
||||||
|
CVector<size_t> timeOut_ {};
|
||||||
|
std::unordered_map<size_t, size_t> bbIdToDfsTimestamp_ {};
|
||||||
};
|
};
|
||||||
} // namespace panda::ecmascript::kungfu
|
} // namespace panda::ecmascript::kungfu
|
||||||
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
|
#endif // ECMASCRIPT_CLASS_LINKER_BYTECODE_CIRCUIT_IR_BUILDER_H
|
||||||
|
@ -149,13 +149,13 @@ public:
|
|||||||
Module *GetModule();
|
Module *GetModule();
|
||||||
|
|
||||||
template <class Callback>
|
template <class Callback>
|
||||||
void CompileMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral,
|
bool CompileMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral,
|
||||||
JSHandle<ProfileTypeInfo> &profileTypeInfo, const uint8_t *pcStart,
|
JSHandle<ProfileTypeInfo> &profileTypeInfo, const uint8_t *pcStart,
|
||||||
const panda_file::File::Header *header, ApEntityId abcId, const Callback &cb)
|
const panda_file::File::Header *header, ApEntityId abcId, const Callback &cb)
|
||||||
{
|
{
|
||||||
SetCurrentCompilationFile();
|
SetCurrentCompilationFile();
|
||||||
if (methodLiteral == nullptr) {
|
if (methodLiteral == nullptr) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId()));
|
const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId()));
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ public:
|
|||||||
bytecodeInfo_.EraseSkippedMethod(methodOffset);
|
bytecodeInfo_.EraseSkippedMethod(methodOffset);
|
||||||
|
|
||||||
Module *module = GetModule();
|
Module *module = GetModule();
|
||||||
cb(bytecodeInfo_.GetRecordNameWithIndex(0), methodName, methodLiteral, profileTypeInfo,
|
return cb(bytecodeInfo_.GetRecordNameWithIndex(0), methodName, methodLiteral, profileTypeInfo,
|
||||||
methodOffset, methodPcInfo, methodInfo, module, pcStart, header, abcId);
|
methodOffset, methodPcInfo, methodInfo, module, pcStart, header, abcId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -943,6 +943,9 @@ public:
|
|||||||
void Run()
|
void Run()
|
||||||
{
|
{
|
||||||
ComputeLoopBack();
|
ComputeLoopBack();
|
||||||
|
if (bcBuilder_->TerminateAnalysis()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
TryClearDeadBlock();
|
TryClearDeadBlock();
|
||||||
bcBuilder_->ComputeNumOfLoopBack();
|
bcBuilder_->ComputeNumOfLoopBack();
|
||||||
frameBuilder_->numLoops_ = numLoops_;
|
frameBuilder_->numLoops_ = numLoops_;
|
||||||
@ -967,6 +970,19 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckDominance()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < loopbacks_.size(); i++) {
|
||||||
|
auto loopBackinfo = loopbacks_[i];
|
||||||
|
bool isDom = bcBuilder_->IsAncestor(loopBackinfo.toId, loopBackinfo.fromId);
|
||||||
|
if (!isDom) {
|
||||||
|
bcBuilder_->SetIrreducibleLoop();
|
||||||
|
LOG_COMPILER(INFO) << "CFG is not reducible. Compilation aborted.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ComputeLoopBack()
|
void ComputeLoopBack()
|
||||||
{
|
{
|
||||||
auto size = bcBuilder_->GetBasicBlockCount();
|
auto size = bcBuilder_->GetBasicBlockCount();
|
||||||
@ -1015,6 +1031,10 @@ public:
|
|||||||
frameBuilder_->rpoList_.push_front(bbId);
|
frameBuilder_->rpoList_.push_front(bbId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bcBuilder_->NeedIrreducibleLoopCheck()) {
|
||||||
|
CheckDominance();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryClearDeadBlock()
|
void TryClearDeadBlock()
|
||||||
@ -1340,7 +1360,7 @@ void FrameStateBuilder::ComputeLoopInfo()
|
|||||||
{
|
{
|
||||||
BlockLoopAnalysis loopAnalysis(this, circuit_->chunk());
|
BlockLoopAnalysis loopAnalysis(this, circuit_->chunk());
|
||||||
loopAnalysis.Run();
|
loopAnalysis.Run();
|
||||||
if (numLoops_ != 0) {
|
if (numLoops_ != 0 && !bcBuilder_->HasIrreducibleLoop()) {
|
||||||
ChunkVector<GateRef>& headerGates = bcBuilder_->GetLoopHeaderGates();
|
ChunkVector<GateRef>& headerGates = bcBuilder_->GetLoopHeaderGates();
|
||||||
headerGates.resize(numLoops_, Circuit::NullGate());
|
headerGates.resize(numLoops_, Circuit::NullGate());
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public:
|
|||||||
|
|
||||||
virtual ModuleKind GetModuleKind() const = 0;
|
virtual ModuleKind GetModuleKind() const = 0;
|
||||||
|
|
||||||
std::string GetFuncName(const MethodLiteral *methodLiteral, const JSPandaFile *jsPandaFile);
|
static std::string GetFuncName(const MethodLiteral *methodLiteral, const JSPandaFile *jsPandaFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebugInfo *debugInfo_ {nullptr};
|
DebugInfo *debugInfo_ {nullptr};
|
||||||
|
@ -71,7 +71,7 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
|
|||||||
log_,
|
log_,
|
||||||
log_->OutputASM(),
|
log_->OutputASM(),
|
||||||
maxMethodsInModule_);
|
maxMethodsInModule_);
|
||||||
cmpDriver_->CompileMethod(jsPandaFile, methodLiteral, profileTypeInfo, pcStart, header, abcId,
|
return cmpDriver_->CompileMethod(jsPandaFile, methodLiteral, profileTypeInfo, pcStart, header, abcId,
|
||||||
[this, &fileName, &osrOffset] (
|
[this, &fileName, &osrOffset] (
|
||||||
const CString &recordName,
|
const CString &recordName,
|
||||||
const std::string &methodName,
|
const std::string &methodName,
|
||||||
@ -83,7 +83,7 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
|
|||||||
Module *m,
|
Module *m,
|
||||||
const uint8_t *pcStart,
|
const uint8_t *pcStart,
|
||||||
const panda_file::File::Header *header,
|
const panda_file::File::Header *header,
|
||||||
ApEntityId abcId) {
|
ApEntityId abcId) -> bool {
|
||||||
if (compilationEnv_->GetJSOptions().GetTraceJIT()) {
|
if (compilationEnv_->GetJSOptions().GetTraceJIT()) {
|
||||||
LOG_COMPILER(INFO) << "JIT Compile Method Start: " << methodName << ", " << methodOffset << "\n";
|
LOG_COMPILER(INFO) << "JIT Compile Method Start: " << methodName << ", " << methodOffset << "\n";
|
||||||
}
|
}
|
||||||
@ -130,7 +130,16 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
|
|||||||
builder_->SetOsrOffset(osrOffset);
|
builder_->SetOsrOffset(osrOffset);
|
||||||
{
|
{
|
||||||
TimeScope timeScope("BytecodeToCircuit", methodName, methodOffset, log_);
|
TimeScope timeScope("BytecodeToCircuit", methodName, methodOffset, log_);
|
||||||
|
builder_->SetJitCompile();
|
||||||
builder_->BytecodeToCircuit();
|
builder_->BytecodeToCircuit();
|
||||||
|
if (builder_->HasIrreducibleLoop()) {
|
||||||
|
LOG_JIT(DEBUG) << "compile fail as has irreducible loop:" << methodName;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (builder_->HasEmptyCatchBB() && compilationEnv_->GetJSOptions().IsEnableAPPJIT()) {
|
||||||
|
LOG_JIT(DEBUG) << "compile fail as has empty catch bb:" << methodName;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CallMethodFlagMap methodFlagMap;
|
CallMethodFlagMap methodFlagMap;
|
||||||
@ -192,8 +201,8 @@ bool JitPassManager::Compile(JSHandle<ProfileTypeInfo> &profileTypeInfo,
|
|||||||
pipeline.RunPass<VerifierPass>();
|
pipeline.RunPass<VerifierPass>();
|
||||||
}
|
}
|
||||||
pipeline.RunPass<GraphLinearizerPass>();
|
pipeline.RunPass<GraphLinearizerPass>();
|
||||||
});
|
|
||||||
return true;
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JitPassManager::RunCg()
|
bool JitPassManager::RunCg()
|
||||||
@ -261,7 +270,6 @@ bool PassManager::Compile(JSPandaFile *jsPandaFile, const std::string &fileName,
|
|||||||
LOG_COMPILER(ERROR) << "The input panda file [" << fileName
|
LOG_COMPILER(ERROR) << "The input panda file [" << fileName
|
||||||
<< "] of AOT Compiler is debuggable version, do not use for performance test!";
|
<< "] of AOT Compiler is debuggable version, do not use for performance test!";
|
||||||
}
|
}
|
||||||
|
|
||||||
LOptions lOptions(optLevel_, FPFlag::RESERVE_FP, relocMode_);
|
LOptions lOptions(optLevel_, FPFlag::RESERVE_FP, relocMode_);
|
||||||
CompilationDriver cmpDriver(profilerDecoder_,
|
CompilationDriver cmpDriver(profilerDecoder_,
|
||||||
&collector,
|
&collector,
|
||||||
|
@ -466,7 +466,6 @@ bool JitTask::AsyncTask::AllocFromFortAndCopy()
|
|||||||
|
|
||||||
bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
||||||
{
|
{
|
||||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "AsyncTask::Run");
|
|
||||||
if (IsTerminate() || !jitTask_->GetHostThread()->GetEcmaVM()->IsInitialized()) {
|
if (IsTerminate() || !jitTask_->GetHostThread()->GetEcmaVM()->IsInitialized()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -474,15 +473,8 @@ bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
|||||||
|
|
||||||
CString info = "compile method:" + jitTask_->GetMethodName();
|
CString info = "compile method:" + jitTask_->GetMethodName();
|
||||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("JIT::Compile:" + info));
|
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, ConvertToStdString("JIT::Compile:" + info));
|
||||||
// JitCompileMode ASYNC
|
|
||||||
// check init ok
|
|
||||||
jitTask_->SetRunState(RunState::RUNNING);
|
|
||||||
|
|
||||||
JSThread *compilerThread = jitTask_->GetCompilerThread();
|
AsyncTaskRunScope asyncTaskRunScope(jitTask_.get());
|
||||||
ASSERT(compilerThread->IsJitThread());
|
|
||||||
JitThread *jitThread = static_cast<JitThread*>(compilerThread);
|
|
||||||
JitVM *jitvm = jitThread->GetJitVM();
|
|
||||||
jitvm->SetHostVM(jitTask_->GetHostThread());
|
|
||||||
|
|
||||||
if (jitTask_->GetJsFunction().GetAddress() == 0) {
|
if (jitTask_->GetJsFunction().GetAddress() == 0) {
|
||||||
// for unit test
|
// for unit test
|
||||||
@ -510,8 +502,23 @@ bool JitTask::AsyncTask::Run([[maybe_unused]] uint32_t threadIndex)
|
|||||||
JitDfx::GetInstance()->RecordSpentTimeAndPrintStatsLogInJitThread(compilerTime, jitTask_->methodName_,
|
JitDfx::GetInstance()->RecordSpentTimeAndPrintStatsLogInJitThread(compilerTime, jitTask_->methodName_,
|
||||||
jitTask_->compilerTier_ == CompilerTier::BASELINE, jitTask_->mainThreadCompileTime_);
|
jitTask_->compilerTier_ == CompilerTier::BASELINE, jitTask_->mainThreadCompileTime_);
|
||||||
}
|
}
|
||||||
jitvm->ReSetHostVM();
|
|
||||||
jitTask_->SetRunStateFinish();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JitTask::AsyncTask::AsyncTaskRunScope::AsyncTaskRunScope(JitTask *jitTask)
|
||||||
|
{
|
||||||
|
jitTask_ = jitTask;
|
||||||
|
jitTask_->SetRunState(RunState::RUNNING);
|
||||||
|
JSThread *compilerThread = jitTask_->GetCompilerThread();
|
||||||
|
ASSERT(compilerThread->IsJitThread());
|
||||||
|
JitThread *jitThread = static_cast<JitThread*>(compilerThread);
|
||||||
|
jitvm_ = jitThread->GetJitVM();
|
||||||
|
jitvm_->SetHostVM(jitTask_->GetHostThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
JitTask::AsyncTask::AsyncTaskRunScope::~AsyncTaskRunScope()
|
||||||
|
{
|
||||||
|
jitvm_->ReSetHostVM();
|
||||||
|
jitTask_->SetRunStateFinish();
|
||||||
|
}
|
||||||
} // namespace panda::ecmascript
|
} // namespace panda::ecmascript
|
||||||
|
@ -270,6 +270,15 @@ public:
|
|||||||
private:
|
private:
|
||||||
ARK_INLINE bool CopyCodeToFort();
|
ARK_INLINE bool CopyCodeToFort();
|
||||||
std::shared_ptr<JitTask> jitTask_ { nullptr };
|
std::shared_ptr<JitTask> jitTask_ { nullptr };
|
||||||
|
|
||||||
|
class AsyncTaskRunScope {
|
||||||
|
public:
|
||||||
|
AsyncTaskRunScope(JitTask *jitTask);
|
||||||
|
~AsyncTaskRunScope();
|
||||||
|
private:
|
||||||
|
JitTask *jitTask_ { nullptr };
|
||||||
|
JitVM *jitvm_ { nullptr };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
void SustainingJSHandles();
|
void SustainingJSHandles();
|
||||||
|
@ -89,6 +89,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
|
|||||||
"--compiler-opt-later-elimination: Enable LaterElimination for aot compiler. Default: 'true'\n"
|
"--compiler-opt-later-elimination: Enable LaterElimination for aot compiler. Default: 'true'\n"
|
||||||
"--compiler-opt-string: Enable string optimization pass for aot compiler. Default: 'true'\n"
|
"--compiler-opt-string: Enable string optimization pass for aot compiler. Default: 'true'\n"
|
||||||
"--compiler-opt-value-numbering: Enable ValueNumbering for aot compiler. Default: 'true'\n"
|
"--compiler-opt-value-numbering: Enable ValueNumbering for aot compiler. Default: 'true'\n"
|
||||||
|
"--compiler-empty-catch-function: Enable function with empty-catch for aot compiler: Default: 'false'\n"
|
||||||
"--compiler-opt-inlining: Enable inlining function for aot compiler: Default: 'true'\n"
|
"--compiler-opt-inlining: Enable inlining function for aot compiler: Default: 'true'\n"
|
||||||
"--compiler-opt-pgotype: Enable pgo type for aot compiler: Default: 'true'\n"
|
"--compiler-opt-pgotype: Enable pgo type for aot compiler: Default: 'true'\n"
|
||||||
"--compiler-opt-track-field: Enable track field for aot compiler: Default: 'false'\n"
|
"--compiler-opt-track-field: Enable track field for aot compiler: Default: 'false'\n"
|
||||||
@ -242,6 +243,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
|||||||
{"compiler-opt-value-numbering", required_argument, nullptr, OPTION_COMPILER_OPT_VALUE_NUMBERING},
|
{"compiler-opt-value-numbering", required_argument, nullptr, OPTION_COMPILER_OPT_VALUE_NUMBERING},
|
||||||
{"compiler-opt-new-value-numbering", required_argument, nullptr, OPTION_COMPILER_OPT_NEW_VALUE_NUMBERING},
|
{"compiler-opt-new-value-numbering", required_argument, nullptr, OPTION_COMPILER_OPT_NEW_VALUE_NUMBERING},
|
||||||
{"compiler-opt-inlining", required_argument, nullptr, OPTION_COMPILER_OPT_INLINING},
|
{"compiler-opt-inlining", required_argument, nullptr, OPTION_COMPILER_OPT_INLINING},
|
||||||
|
{"compiler-empty-catch-function", required_argument, nullptr, OPTION_COMPILER_EMPTY_CATCH_FUNCTION},
|
||||||
{"compiler-opt-pgotype", required_argument, nullptr, OPTION_COMPILER_OPT_PGOTYPE},
|
{"compiler-opt-pgotype", required_argument, nullptr, OPTION_COMPILER_OPT_PGOTYPE},
|
||||||
{"compiler-opt-track-field", required_argument, nullptr, OPTION_COMPILER_OPT_TRACK_FIELD},
|
{"compiler-opt-track-field", required_argument, nullptr, OPTION_COMPILER_OPT_TRACK_FIELD},
|
||||||
{"entry-point", required_argument, nullptr, OPTION_ENTRY_POINT},
|
{"entry-point", required_argument, nullptr, OPTION_ENTRY_POINT},
|
||||||
@ -850,6 +852,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPTION_COMPILER_EMPTY_CATCH_FUNCTION:
|
||||||
|
ret = ParseBoolParam(&argBool);
|
||||||
|
if (ret) {
|
||||||
|
SetEnableEmptyCatchFunction(argBool);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case OPTION_COMPILER_OPT_INSTRUCTIONE_COMBINE:
|
case OPTION_COMPILER_OPT_INSTRUCTIONE_COMBINE:
|
||||||
ret = ParseBoolParam(&argBool);
|
ret = ParseBoolParam(&argBool);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -26,6 +26,11 @@
|
|||||||
#include "ecmascript/mem/mem_common.h"
|
#include "ecmascript/mem/mem_common.h"
|
||||||
#include "libpandabase/os/file.h"
|
#include "libpandabase/os/file.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr size_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
|
||||||
|
constexpr size_t DEFAULT_REL_MODE = 2;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// namespace panda {
|
// namespace panda {
|
||||||
namespace panda::ecmascript {
|
namespace panda::ecmascript {
|
||||||
using arg_list_t = std::vector<std::string>;
|
using arg_list_t = std::vector<std::string>;
|
||||||
@ -210,6 +215,7 @@ enum CommandValues {
|
|||||||
OPTION_COMPILER_OPT_STRING,
|
OPTION_COMPILER_OPT_STRING,
|
||||||
OPTION_OPEN_ARK_TOOLS,
|
OPTION_OPEN_ARK_TOOLS,
|
||||||
OPTION_COMPILER_OPT_FRAME_STATE_ELIMINATION,
|
OPTION_COMPILER_OPT_FRAME_STATE_ELIMINATION,
|
||||||
|
OPTION_COMPILER_EMPTY_CATCH_FUNCTION
|
||||||
};
|
};
|
||||||
static_assert(OPTION_SPLIT_ONE == 64); // add new option at the bottom, DO NOT modify this value
|
static_assert(OPTION_SPLIT_ONE == 64); // add new option at the bottom, DO NOT modify this value
|
||||||
static_assert(OPTION_SPLIT_TWO == 128); // add new option at the bottom, DO NOT modify this value
|
static_assert(OPTION_SPLIT_TWO == 128); // add new option at the bottom, DO NOT modify this value
|
||||||
@ -1344,6 +1350,16 @@ public:
|
|||||||
enableOptInlining_ = value;
|
enableOptInlining_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetEnableEmptyCatchFunction(bool value)
|
||||||
|
{
|
||||||
|
enableEmptyCatchFunction_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEnableEmptyCatchFunction() const
|
||||||
|
{
|
||||||
|
return enableEmptyCatchFunction_;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsEnableOptInlining() const
|
bool IsEnableOptInlining() const
|
||||||
{
|
{
|
||||||
return enableOptInlining_;
|
return enableOptInlining_;
|
||||||
@ -1937,7 +1953,6 @@ public:
|
|||||||
static constexpr int32_t MAX_APP_COMPILE_METHOD_SIZE = 4_KB;
|
static constexpr int32_t MAX_APP_COMPILE_METHOD_SIZE = 4_KB;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int32_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
|
|
||||||
|
|
||||||
static bool StartsWith(const std::string& haystack, const std::string& needle)
|
static bool StartsWith(const std::string& haystack, const std::string& needle)
|
||||||
{
|
{
|
||||||
@ -2033,6 +2048,7 @@ private:
|
|||||||
bool enableInstrcutionCombine {true};
|
bool enableInstrcutionCombine {true};
|
||||||
bool enableNewValueNumbering_ {true};
|
bool enableNewValueNumbering_ {true};
|
||||||
bool enableOptInlining_ {true};
|
bool enableOptInlining_ {true};
|
||||||
|
bool enableEmptyCatchFunction_ {false};
|
||||||
bool enableOptPGOType_ {true};
|
bool enableOptPGOType_ {true};
|
||||||
bool enableFastJIT_ {false};
|
bool enableFastJIT_ {false};
|
||||||
bool enableAPPJIT_ {false};
|
bool enableAPPJIT_ {false};
|
||||||
|
@ -13,3 +13,4 @@
|
|||||||
|
|
||||||
Test Success
|
Test Success
|
||||||
true
|
true
|
||||||
|
false
|
@ -13,3 +13,4 @@
|
|||||||
|
|
||||||
Test Success
|
Test Success
|
||||||
false
|
false
|
||||||
|
false
|
@ -29,3 +29,19 @@ function f3() {
|
|||||||
|
|
||||||
f3()
|
f3()
|
||||||
print(ArkTools.isAOTCompiled(f3));
|
print(ArkTools.isAOTCompiled(f3));
|
||||||
|
|
||||||
|
function f4() {
|
||||||
|
let v3 = 3;
|
||||||
|
for (let i44 = 0; i44 < 5; i44++) {
|
||||||
|
let v53 = 0;
|
||||||
|
do {
|
||||||
|
i44 = v3;
|
||||||
|
try {
|
||||||
|
i44.o(375);
|
||||||
|
} catch (e) {}
|
||||||
|
v53++;
|
||||||
|
} while (v53 < 2)
|
||||||
|
v3++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(ArkTools.isAOTCompiled(f4));
|
@ -15,6 +15,7 @@ group("ark_jit_ts_test") {
|
|||||||
testonly = true
|
testonly = true
|
||||||
test_list = [
|
test_list = [
|
||||||
"create_arguments",
|
"create_arguments",
|
||||||
|
"try_catch_empty",
|
||||||
"ldobjbyname",
|
"ldobjbyname",
|
||||||
"for_loop",
|
"for_loop",
|
||||||
"typed_array",
|
"typed_array",
|
||||||
|
18
test/jittest/try_catch_empty/BUILD.gn
Normal file
18
test/jittest/try_catch_empty/BUILD.gn
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright (c) 2024 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_jit_test_action("try_catch_empty") {
|
||||||
|
deps = []
|
||||||
|
}
|
15
test/jittest/try_catch_empty/expect_output.txt
Normal file
15
test/jittest/try_catch_empty/expect_output.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2024 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.
|
||||||
|
|
||||||
|
true
|
||||||
|
130
|
50
test/jittest/try_catch_empty/try_catch_empty.ts
Normal file
50
test/jittest/try_catch_empty/try_catch_empty.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 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.
|
||||||
|
*/
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
function SmallFunc() {
|
||||||
|
try {
|
||||||
|
i += 10;
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function EmptyCatch() {
|
||||||
|
try {
|
||||||
|
i += 10;
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function CallSmallFunc() {
|
||||||
|
SmallFunc();
|
||||||
|
try {
|
||||||
|
i += 10;
|
||||||
|
} catch (e) {
|
||||||
|
i += 10;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyCatch();
|
||||||
|
CallSmallFunc();
|
||||||
|
ArkTools.jitCompileAsync(EmptyCatch);
|
||||||
|
ArkTools.jitCompileAsync(CallSmallFunc);
|
||||||
|
var ret = ArkTools.waitJitCompileFinish(CallSmallFunc);
|
||||||
|
for (let j = 0; j < 10; j++) {
|
||||||
|
EmptyCatch()
|
||||||
|
}
|
||||||
|
print(ret);
|
||||||
|
print(i);
|
@ -1220,7 +1220,7 @@ template("host_aot_js_test_action") {
|
|||||||
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
||||||
|
|
||||||
_aot_compile_options_ = " --aot-file=" + rebase_path(_test_aot_arg_) +
|
_aot_compile_options_ = " --aot-file=" + rebase_path(_test_aot_arg_) +
|
||||||
" --log-level=" + _test_aot_log_level + " --log-components=compiler --compiler-opt-type-lowering=false --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --log-level=" + _test_aot_log_level + " --log-components=compiler --compiler-opt-type-lowering=false --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false" + " --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -1493,7 +1493,8 @@ template("host_aot_js_test_action") {
|
|||||||
" --compiler-opt-type-lowering=false" +
|
" --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true"
|
" --compiler-enable-litecg=true" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -1749,7 +1750,8 @@ template("host_aot_js_test_action") {
|
|||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true" +
|
" --compiler-enable-litecg=true" +
|
||||||
" --compiler-target-triple=aarch64-unknown-linux-gnu"
|
" --compiler-target-triple=aarch64-unknown-linux-gnu" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -2104,7 +2106,7 @@ template("host_aot_js_assert_test_action") {
|
|||||||
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
||||||
|
|
||||||
_aot_compile_options_ = " --aot-file=" + rebase_path(_test_aot_arg_) +
|
_aot_compile_options_ = " --aot-file=" + rebase_path(_test_aot_arg_) +
|
||||||
" --log-level=" + _test_aot_log_level + " --log-components=compiler --compiler-opt-type-lowering=false --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --log-level=" + _test_aot_log_level + " --log-components=compiler --compiler-opt-type-lowering=false --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false" + " --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -2530,7 +2532,9 @@ template("host_aot_test_action") {
|
|||||||
_aot_compile_options_ =
|
_aot_compile_options_ =
|
||||||
" --aot-file=" + rebase_path(_test_aot_arg_) + " --log-level=" +
|
" --aot-file=" + rebase_path(_test_aot_arg_) + " --log-level=" +
|
||||||
_test_aot_log_level + " --log-components=compiler" +
|
_test_aot_log_level + " --log-components=compiler" +
|
||||||
" --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --compiler-opt-inlining=false" +
|
||||||
|
" --compiler-opt-loop-peeling=false" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ +=
|
_aot_compile_options_ +=
|
||||||
@ -2627,7 +2631,10 @@ template("host_aot_test_action") {
|
|||||||
" --aot-file=" + rebase_path(_test_aot_arg_slowpath_) +
|
" --aot-file=" + rebase_path(_test_aot_arg_slowpath_) +
|
||||||
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
||||||
" --compiler-opt-type-lowering=false" +
|
" --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --compiler-opt-inlining=false" +
|
||||||
|
" --compiler-opt-loop-peeling=false" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_trace_deopt) &&
|
if (defined(invoker.is_enable_trace_deopt) &&
|
||||||
invoker.is_enable_trace_deopt) {
|
invoker.is_enable_trace_deopt) {
|
||||||
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
||||||
@ -2946,7 +2953,8 @@ template("host_aot_test_action") {
|
|||||||
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true"
|
" --compiler-enable-litecg=true" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ +=
|
_aot_compile_options_ +=
|
||||||
@ -3047,7 +3055,8 @@ template("host_aot_test_action") {
|
|||||||
" --compiler-opt-type-lowering=false" +
|
" --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true"
|
" --compiler-enable-litecg=true" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
if (defined(invoker.is_enable_trace_deopt) &&
|
if (defined(invoker.is_enable_trace_deopt) &&
|
||||||
invoker.is_enable_trace_deopt) {
|
invoker.is_enable_trace_deopt) {
|
||||||
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
||||||
@ -3356,7 +3365,8 @@ template("host_aot_test_action") {
|
|||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true" +
|
" --compiler-enable-litecg=true" +
|
||||||
" --compiler-target-triple=aarch64-unknown-linux-gnu"
|
" --compiler-target-triple=aarch64-unknown-linux-gnu" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ +=
|
_aot_compile_options_ +=
|
||||||
@ -3458,7 +3468,8 @@ template("host_aot_test_action") {
|
|||||||
" --compiler-opt-inlining=false" +
|
" --compiler-opt-inlining=false" +
|
||||||
" --compiler-opt-loop-peeling=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-enable-litecg=true" +
|
" --compiler-enable-litecg=true" +
|
||||||
" --compiler-target-triple=aarch64-unknown-linux-gnu"
|
" --compiler-target-triple=aarch64-unknown-linux-gnu" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
if (defined(invoker.is_enable_trace_deopt) &&
|
if (defined(invoker.is_enable_trace_deopt) &&
|
||||||
invoker.is_enable_trace_deopt) {
|
invoker.is_enable_trace_deopt) {
|
||||||
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
_aot_compile_options_ += " --compiler-trace-deopt=true"
|
||||||
@ -3872,7 +3883,9 @@ template("host_aot_assert_test_action") {
|
|||||||
_aot_compile_options_ =
|
_aot_compile_options_ =
|
||||||
" --aot-file=" + rebase_path(_test_aot_arg_) + " --log-level=" +
|
" --aot-file=" + rebase_path(_test_aot_arg_) + " --log-level=" +
|
||||||
_test_aot_log_level + " --log-components=compiler" +
|
_test_aot_log_level + " --log-components=compiler" +
|
||||||
" --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --compiler-opt-inlining=false" +
|
||||||
|
" --compiler-opt-loop-peeling=false" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
if (defined(invoker.is_enable_pgo) && invoker.is_enable_pgo) {
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -3971,7 +3984,9 @@ template("host_aot_assert_test_action") {
|
|||||||
" --aot-file=" + rebase_path(_test_aot_arg_slowpath_) +
|
" --aot-file=" + rebase_path(_test_aot_arg_slowpath_) +
|
||||||
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
" --log-level=" + _test_aot_log_level + " --log-components=compiler" +
|
||||||
" --compiler-opt-type-lowering=false" +
|
" --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-inlining=false" + " --compiler-opt-loop-peeling=false"
|
" --compiler-opt-inlining=false" +
|
||||||
|
" --compiler-opt-loop-peeling=false" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
if (defined(invoker.aot_log_option)) {
|
if (defined(invoker.aot_log_option)) {
|
||||||
_aot_compile_options_ += invoker.aot_log_option
|
_aot_compile_options_ += invoker.aot_log_option
|
||||||
@ -4367,7 +4382,8 @@ template("host_pgotypeinfer_test_action") {
|
|||||||
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
||||||
|
|
||||||
_aot_compile_options_ = " --compiler-opt-type-lowering=false" +
|
_aot_compile_options_ = " --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-loop-peeling=false"
|
" --compiler-opt-loop-peeling=false" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
# Pgo Option
|
# Pgo Option
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
@ -4414,9 +4430,10 @@ template("host_pgotypeinfer_test_action") {
|
|||||||
|
|
||||||
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
script = "//arkcompiler/ets_runtime/script/run_ark_executable.py"
|
||||||
|
|
||||||
_aot_compile_options_ =
|
_aot_compile_options_ = " --compiler-opt-type-lowering=false" +
|
||||||
" --compiler-opt-type-lowering=false" +
|
" --compiler-opt-loop-peeling=false" +
|
||||||
" --compiler-opt-loop-peeling=false" + " --compiler-enable-litecg=true"
|
" --compiler-enable-litecg=true" +
|
||||||
|
" --compiler-empty-catch-function=true"
|
||||||
|
|
||||||
# Pgo Option
|
# Pgo Option
|
||||||
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
_aot_compile_options_ += " --compiler-pgo-profiler-path=" +
|
||||||
|
Loading…
Reference in New Issue
Block a user