/* * 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. */ #include "option.h" #include #include #include #include "driver_options.h" #include "file_utils.h" #include "mpl_logging.h" #include "mpl2mpl_options.h" #include "triple.h" namespace maple { bool Options::dumpBefore = false; bool Options::dumpAfter = false; std::string Options::dumpPhase = ""; std::string Options::dumpFunc = "*"; std::string Options::skipPhase; std::string Options::skipFrom; std::string Options::skipAfter; bool Options::quiet = false; bool Options::regNativeFunc = false; bool Options::nativeWrapper = true; // Enabled by default bool Options::inlineWithProfile = false; bool Options::useInline = true; // Enabled by default bool Options::enableIPAClone = true; bool Options::useCrossModuleInline = true; // Enabled by default std::string Options::noInlineFuncList = ""; std::string Options::importFileList = ""; uint32 Options::inlineSmallFunctionThreshold = 80; // Only for srcLangC, value will be reset later for other srcLang uint32 Options::inlineHotFunctionThreshold = 100; // Only for srcLangC, value will be reset later for other srcLang uint32 Options::inlineRecursiveFunctionThreshold = 15; uint32 Options::inlineDepth = 8; uint32 Options::inlineModuleGrowth = 10; uint32 Options::inlineColdFunctionThreshold = 3; uint32 Options::profileHotCount = 1000; uint32 Options::profileColdCount = 10; uint32 Options::numOfCloneVersions = 2; uint32 Options::numOfImpExprLowBound = 2; uint32 Options::numOfImpExprHighBound = 5; uint32 Options::numOfCallSiteLowBound = 2; uint32 Options::numOfCallSiteUpBound = 10; uint32 Options::numOfConstpropValue = 2; bool Options::profileHotCountSeted = false; bool Options::profileColdCountSeted = false; uint32 Options::profileHotRate = 500000; uint32 Options::profileColdRate = 900000; bool Options::regNativeDynamicOnly = false; std::string Options::staticBindingList; bool Options::usePreg = false; bool Options::mapleLinker = false; bool Options::dumpMuidFile = false; bool Options::emitVtableImpl = false; bool Options::profileGen = false; bool Options::profileUse = false; bool Options::genLMBC = false; // Ready to be deleted. bool Options::noRC = false; bool Options::analyzeCtor = true; bool Options::strictNaiveRC = false; bool Options::gcOnly = false; bool Options::bigEndian = false; bool Options::rcOpt1 = true; bool Options::nativeOpt = true; bool Options::optForSize = false; bool Options::O2 = false; bool Options::noDot = false; bool Options::genIRProfile = false; bool Options::profileTest = false; std::string Options::criticalNativeFile = "maple/mrt/codetricks/profile.pv/criticalNative.list"; std::string Options::fastNativeFile = "maple/mrt/codetricks/profile.pv/fastNative.list"; bool Options::barrier = false; std::string Options::nativeFuncPropertyFile = "maple/mrt/codetricks/native_binding/native_func_property.list"; bool Options::mapleLinkerTransformLocal = true; bool Options::partialAot = false; uint32 Options::decoupleInit = 0; uint32 Options::buildApp = kNoDecouple; std::string Options::sourceMuid = ""; bool Options::decoupleSuper = false; bool Options::deferredVisit = false; bool Options::deferredVisit2 = false; bool Options::genVtabAndItabForDecouple = false; bool Options::profileFunc = false; uint32 Options::parserOpt = 0; std::string Options::dumpDevirtualList = ""; std::string Options::readDevirtualList = ""; bool Options::usePreloadedClass = false; std::string Options::profile = ""; std::string Options::appPackageName = ""; bool Options::profileStaticFields = false; std::string Options::proFileData = ""; std::string Options::proFileFuncData = ""; std::string Options::proFileClassData = ""; std::string Options::classLoaderInvocationList = ""; // maple/mrt/codetricks/profile.pv/classloaderInvocation.list bool Options::dumpClassLoaderInvocation = false; unsigned int Options::warningLevel = 0; bool Options::lazyBinding = false; bool Options::hotFix = false; bool Options::compactMeta = false; bool Options::genPGOReport = false; bool Options::verify = false; uint32 Options::inlineCache = 0; bool Options::checkArrayStore = false; bool Options::noComment = false; bool Options::rmNoUseFunc = true; // default remove no-used static function bool Options::sideEffect = true; bool Options::dumpIPA = false; bool Options::wpaa = false; // whole program alias analysis Options &Options::GetInstance() { static Options instance; return instance; } void Options::DecideMpl2MplRealLevel() const { if (opts::mpl2mpl::o2 || opts::mpl2mpl::os) { if (opts::mpl2mpl::os) { optForSize = true; } O2 = true; usePreg = true; } } bool Options::SolveOptions(bool isDebug) const { DecideMpl2MplRealLevel(); for (const auto &opt : mpl2mplCategory.GetEnabledOptions()) { std::string printOpt; if (isDebug) { for (const auto &val : opt->GetRawValues()) { printOpt += opt->GetName() + " " + val + " "; } LogInfo::MapleLogger() << "mpl2mpl options: " << printOpt << '\n'; } } maplecl::CopyIfEnabled(dumpBefore, opts::mpl2mpl::dumpBefore); maplecl::CopyIfEnabled(dumpAfter, opts::mpl2mpl::dumpAfter); maplecl::CopyIfEnabled(dumpFunc, opts::mpl2mpl::dumpFunc); // quiet can be set by verbose option in driver maplecl::CopyIfEnabled(quiet, !opts::verbose, opts::verbose); maplecl::CopyIfEnabled(quiet, opts::mpl2mpl::quiet); maplecl::CopyIfEnabled(dumpPhase, opts::mpl2mpl::dumpPhase); maplecl::CopyIfEnabled(skipPhase, opts::mpl2mpl::skipPhase); maplecl::CopyIfEnabled(skipFrom, opts::mpl2mpl::skipFrom); maplecl::CopyIfEnabled(skipAfter, opts::mpl2mpl::skipAfter); maplecl::CopyIfEnabled(regNativeDynamicOnly, opts::mpl2mpl::regnativeDynamicOnly); maplecl::CopyIfEnabled(staticBindingList, opts::mpl2mpl::staticBindingList); maplecl::CopyIfEnabled(regNativeFunc, opts::mpl2mpl::regnativefunc); maplecl::CopyIfEnabled(nativeWrapper, opts::mpl2mpl::nativewrapper); maplecl::CopyIfEnabled(inlineWithProfile, opts::mpl2mpl::inlineWithProfile); maplecl::CopyIfEnabled(useInline, opts::mpl2mpl::inlineOpt); maplecl::CopyIfEnabled(enableIPAClone, opts::mpl2mpl::ipaClone); maplecl::CopyIfEnabled(noInlineFuncList, opts::mpl2mpl::noInlineFunc); maplecl::CopyIfEnabled(importFileList, opts::mpl2mpl::importFileList); maplecl::CopyIfEnabled(numOfCloneVersions, opts::mpl2mpl::numOfCloneVersions); maplecl::CopyIfEnabled(numOfImpExprLowBound, opts::mpl2mpl::numOfImpExprLowBound); maplecl::CopyIfEnabled(numOfImpExprHighBound, opts::mpl2mpl::numOfImpExprHighBound); maplecl::CopyIfEnabled(numOfCallSiteLowBound, opts::mpl2mpl::numOfCallSiteLowBound); maplecl::CopyIfEnabled(numOfCallSiteUpBound, opts::mpl2mpl::numOfCallSiteUpBound); maplecl::CopyIfEnabled(numOfConstpropValue, opts::mpl2mpl::numOfConstpropValue); maplecl::CopyIfEnabled(useCrossModuleInline, opts::mpl2mpl::crossModuleInline); maplecl::CopyIfEnabled(inlineSmallFunctionThreshold, opts::mpl2mpl::inlineSmallFunctionThreshold); maplecl::CopyIfEnabled(inlineHotFunctionThreshold, opts::mpl2mpl::inlineHotFunctionThreshold); maplecl::CopyIfEnabled(inlineRecursiveFunctionThreshold, opts::mpl2mpl::inlineRecursiveFunctionThreshold); maplecl::CopyIfEnabled(inlineDepth, opts::mpl2mpl::inlineDepth); maplecl::CopyIfEnabled(inlineModuleGrowth, opts::mpl2mpl::inlineModuleGrow); maplecl::CopyIfEnabled(inlineColdFunctionThreshold, opts::mpl2mpl::inlineColdFuncThresh); maplecl::CopyIfEnabled(profileHotCount, opts::mpl2mpl::profileHotCount); maplecl::CopyIfEnabled(profileColdCount, opts::mpl2mpl::profileColdCount); maplecl::CopyIfEnabled(profileHotRate, opts::mpl2mpl::profileHotRate); maplecl::CopyIfEnabled(profileColdRate, opts::mpl2mpl::profileColdRate); if (opts::mpl2mpl::maplelinker) { mapleLinker = opts::mpl2mpl::maplelinker; dumpMuidFile = mapleLinker; // quiet is overwrited by maplelinker option if (isDebug) { LogInfo::MapleLogger() << "--sub options: dumpMuidFile " << dumpMuidFile << '\n'; } } maplecl::CopyIfEnabled(dumpMuidFile, opts::mpl2mpl::dumpMuid); maplecl::CopyIfEnabled(emitVtableImpl, opts::mpl2mpl::emitVtableImpl); maplecl::CopyIfEnabled(noRC, !opts::mpl2mpl::userc, opts::mpl2mpl::userc); maplecl::CopyIfEnabled(strictNaiveRC, opts::mpl2mpl::strictNaiveRc); /* big endian can be set with several options: --target, -Be. * Triple takes to account all these options and allows to detect big endian with IsBigEndian() interface */ if (Triple::GetTriple().IsBigEndian()) { bigEndian = true; } maplecl::CopyIfEnabled(rcOpt1, opts::mpl2mpl::rcOpt1); maplecl::CopyIfEnabled(nativeOpt, opts::mpl2mpl::nativeopt); maplecl::CopyIfEnabled(criticalNativeFile, opts::mpl2mpl::criticalNative); maplecl::CopyIfEnabled(fastNativeFile, opts::mpl2mpl::fastNative); maplecl::CopyIfEnabled(noDot, opts::mpl2mpl::nodot); maplecl::CopyIfEnabled(genIRProfile, opts::mpl2mpl::genIrProfile); maplecl::CopyIfEnabled(profileTest, opts::mpl2mpl::profileTest); maplecl::CopyIfEnabled(barrier, opts::mpl2mpl::barrier); maplecl::CopyIfEnabled(nativeFuncPropertyFile, opts::mpl2mpl::nativeFuncPropertyFile); maplecl::CopyIfEnabled(mapleLinkerTransformLocal, !opts::mpl2mpl::maplelinkerNolocal, opts::mpl2mpl::maplelinkerNolocal); maplecl::CopyIfEnabled(deferredVisit, opts::mpl2mpl::deferredVisit); if (opts::mpl2mpl::deferredVisit.IsEnabledByUser()) { deferredVisit = true; deferredVisit2 = true; if (isDebug) { LogInfo::MapleLogger() << "--sub options: deferredVisit " << deferredVisit << '\n'; LogInfo::MapleLogger() << "--sub options: deferredVisit2 " << deferredVisit2 << '\n'; } } maplecl::CopyIfEnabled(decoupleSuper, opts::mpl2mpl::decoupleSuper); if (opts::mpl2mpl::buildApp.IsEnabledByUser()) { if (opts::mpl2mpl::buildApp != kMpl2MplLevelZero && opts::mpl2mpl::buildApp != kMpl2MplLevelOne && opts::mpl2mpl::buildApp != kMpl2MplLevelTwo) { LogInfo::MapleLogger(kLlErr) << "expecting 0,1,2 or empty for --build-app\n"; return false; } /* Default buildApp value is 1, so if an User does not select buildApp (with --buildApp=2), it will be 1 */ buildApp = opts::mpl2mpl::buildApp; } maplecl::CopyIfEnabled(sourceMuid, opts::mpl2mpl::sourceMuid); maplecl::CopyIfEnabled(partialAot, opts::mpl2mpl::partialAot); if (opts::mpl2mpl::decoupleInit.IsEnabledByUser()) { if (opts::mpl2mpl::decoupleInit != kNoDecouple && opts::mpl2mpl::decoupleInit != kConservativeDecouple && opts::mpl2mpl::decoupleInit != kAggressiveDecouple) { std::cerr << "expecting 0,1,2 or empty for --decouple-init\n"; return false; } /* Default opts::mpl2mpl::decoupleInit value is Options::kConservativeDecouple==1 * so if an User does not select buildApp (with --decouple-init=2), it will be 1. */ decoupleInit = opts::mpl2mpl::decoupleInit; buildApp = Options::kConservativeDecouple; } maplecl::CopyIfEnabled(genVtabAndItabForDecouple, opts::mpl2mpl::genDecoupleVtab); maplecl::CopyIfEnabled(profileFunc, opts::mpl2mpl::profileFunc); maplecl::CopyIfEnabled(dumpDevirtualList, opts::mpl2mpl::dumpDevirtual); maplecl::CopyIfEnabled(readDevirtualList, opts::mpl2mpl::readDevirtual); maplecl::CopyIfEnabled(usePreloadedClass, opts::mpl2mpl::usewhiteclass); if (opts::profileGen.IsEnabledByUser()) { if (O2) { LogInfo::MapleLogger(kLlErr) << "profileGen requires no optimization\n"; return false; } else { profileGen = true; } } maplecl::CopyIfEnabled(profileUse, opts::profileUse); maplecl::CopyIfEnabled(genLMBC, opts::genLMBC); maplecl::CopyIfEnabled(appPackageName, opts::mpl2mpl::appPackageName); maplecl::CopyIfEnabled(classLoaderInvocationList, opts::mpl2mpl::checkClInvocation); maplecl::CopyIfEnabled(dumpClassLoaderInvocation, opts::mpl2mpl::dumpClInvocation); maplecl::CopyIfEnabled(warningLevel, opts::mpl2mpl::warning); maplecl::CopyIfEnabled(lazyBinding, opts::mpl2mpl::lazyBinding); maplecl::CopyIfEnabled(hotFix, opts::mpl2mpl::hotFix); maplecl::CopyIfEnabled(compactMeta, opts::mpl2mpl::compactMeta); maplecl::CopyIfEnabled(genPGOReport, opts::mpl2mpl::genPGOReport); if (opts::mpl2mpl::inlineCache.IsEnabledByUser()) { if (opts::mpl2mpl::inlineCache != 0 && opts::mpl2mpl::inlineCache != 1 && opts::mpl2mpl::inlineCache != 2 && opts::mpl2mpl::inlineCache != 3) { // expecting 0, 1, 2, 3 LogInfo::MapleLogger(kLlErr) << "expecting 0,1,2,3 or empty for --inlineCache\n"; return false; } inlineCache = opts::mpl2mpl::inlineCache; } maplecl::CopyIfEnabled(noComment, opts::mpl2mpl::noComment); maplecl::CopyIfEnabled(rmNoUseFunc, opts::mpl2mpl::rmnousefunc); maplecl::CopyIfEnabled(sideEffect, opts::mpl2mpl::sideeffect); maplecl::CopyIfEnabled(dumpIPA, opts::mpl2mpl::dumpIPA); maplecl::CopyIfEnabled(wpaa, opts::mpl2mpl::wpaa); return true; } bool Options::ParseOptions(int argc, char **argv, std::string &fileName) const { (void)maplecl::CommandLine::GetCommandLine().Parse(argc, static_cast(argv), mpl2mplCategory); bool result = SolveOptions(false); if (!result) { return result; } auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs; int inputFileCount = 0; for (auto &arg : badArgs) { if (FileUtils::IsFileExists(arg.first)) { inputFileCount++; fileName = arg.first; } else { LogInfo::MapleLogger(kLlErr) << "Unknown Option: " << arg.first; return false; } } if (inputFileCount != 1) { LogInfo::MapleLogger(kLlErr) << "expecting one .mpl file as last argument, found: "; for (const auto &optionArg : badArgs) { LogInfo::MapleLogger(kLlErr) << optionArg.first << " "; } LogInfo::MapleLogger(kLlErr) << "\n"; return false; } #ifdef DEBUG_OPTION LogInfo::MapleLogger() << "mpl file : " << fileName << "\t"; DumpOptions(); #endif return true; } void Options::DumpOptions() const { LogInfo::MapleLogger() << "phase sequence : \t"; if (phaseSeq.empty()) { LogInfo::MapleLogger() << "default phase sequence\n"; } else { for (size_t i = 0; i < phaseSeq.size(); ++i) { LogInfo::MapleLogger() << " " << phaseSeq[i]; } } LogInfo::MapleLogger() << "\n"; } }; // namespace maple