• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "option.h"
17 #include <iostream>
18 #include <cstring>
19 #include <cctype>
20 #include "driver_options.h"
21 #include "file_utils.h"
22 #include "mpl_logging.h"
23 #include "mpl2mpl_options.h"
24 #include "triple.h"
25 
26 namespace maple {
27 
28 bool Options::dumpBefore = false;
29 bool Options::dumpAfter = false;
30 std::string Options::dumpPhase = "";
31 std::string Options::dumpFunc = "*";
32 std::string Options::skipPhase;
33 std::string Options::skipFrom;
34 std::string Options::skipAfter;
35 bool Options::quiet = false;
36 bool Options::regNativeFunc = false;
37 bool Options::nativeWrapper = true;  // Enabled by default
38 bool Options::inlineWithProfile = false;
39 bool Options::useInline = true;  // Enabled by default
40 bool Options::enableIPAClone = true;
41 bool Options::useCrossModuleInline = true;  // Enabled by default
42 std::string Options::noInlineFuncList = "";
43 std::string Options::importFileList = "";
44 uint32 Options::inlineSmallFunctionThreshold = 80;  // Only for srcLangC, value will be reset later for other srcLang
45 uint32 Options::inlineHotFunctionThreshold = 100;   // Only for srcLangC, value will be reset later for other srcLang
46 uint32 Options::inlineRecursiveFunctionThreshold = 15;
47 uint32 Options::inlineDepth = 8;
48 uint32 Options::inlineModuleGrowth = 10;
49 uint32 Options::inlineColdFunctionThreshold = 3;
50 uint32 Options::profileHotCount = 1000;
51 uint32 Options::profileColdCount = 10;
52 uint32 Options::numOfCloneVersions = 2;
53 uint32 Options::numOfImpExprLowBound = 2;
54 uint32 Options::numOfImpExprHighBound = 5;
55 uint32 Options::numOfCallSiteLowBound = 2;
56 uint32 Options::numOfCallSiteUpBound = 10;
57 uint32 Options::numOfConstpropValue = 2;
58 bool Options::profileHotCountSeted = false;
59 bool Options::profileColdCountSeted = false;
60 uint32 Options::profileHotRate = 500000;
61 uint32 Options::profileColdRate = 900000;
62 bool Options::regNativeDynamicOnly = false;
63 std::string Options::staticBindingList;
64 bool Options::usePreg = false;
65 bool Options::mapleLinker = false;
66 bool Options::dumpMuidFile = false;
67 bool Options::emitVtableImpl = false;
68 #if MIR_JAVA
69 bool Options::skipVirtualMethod = false;
70 #endif
71 bool Options::profileGen = false;
72 bool Options::profileUse = false;
73 bool Options::genLMBC = false;
74 
75 // Ready to be deleted.
76 bool Options::noRC = false;
77 bool Options::analyzeCtor = true;
78 bool Options::strictNaiveRC = false;
79 bool Options::gcOnly = false;
80 bool Options::bigEndian = false;
81 bool Options::rcOpt1 = true;
82 bool Options::nativeOpt = true;
83 bool Options::optForSize = false;
84 bool Options::O2 = false;
85 bool Options::noDot = false;
86 bool Options::genIRProfile = false;
87 bool Options::profileTest = false;
88 std::string Options::criticalNativeFile = "maple/mrt/codetricks/profile.pv/criticalNative.list";
89 std::string Options::fastNativeFile = "maple/mrt/codetricks/profile.pv/fastNative.list";
90 bool Options::barrier = false;
91 std::string Options::nativeFuncPropertyFile = "maple/mrt/codetricks/native_binding/native_func_property.list";
92 bool Options::mapleLinkerTransformLocal = true;
93 bool Options::partialAot = false;
94 uint32 Options::decoupleInit = 0;
95 uint32 Options::buildApp = kNoDecouple;
96 std::string Options::sourceMuid = "";
97 bool Options::decoupleSuper = false;
98 bool Options::deferredVisit = false;
99 bool Options::deferredVisit2 = false;
100 bool Options::genVtabAndItabForDecouple = false;
101 bool Options::profileFunc = false;
102 uint32 Options::parserOpt = 0;
103 std::string Options::dumpDevirtualList = "";
104 std::string Options::readDevirtualList = "";
105 bool Options::usePreloadedClass = false;
106 std::string Options::profile = "";
107 std::string Options::appPackageName = "";
108 bool Options::profileStaticFields = false;
109 std::string Options::proFileData = "";
110 std::string Options::proFileFuncData = "";
111 std::string Options::proFileClassData = "";
112 std::string Options::classLoaderInvocationList = "";  // maple/mrt/codetricks/profile.pv/classloaderInvocation.list
113 bool Options::dumpClassLoaderInvocation = false;
114 unsigned int Options::warningLevel = 0;
115 bool Options::lazyBinding = false;
116 bool Options::hotFix = false;
117 bool Options::compactMeta = false;
118 bool Options::genPGOReport = false;
119 bool Options::verify = false;
120 uint32 Options::inlineCache = 0;
121 bool Options::checkArrayStore = false;
122 bool Options::noComment = false;
123 bool Options::rmNoUseFunc = true;  // default remove no-used static function
124 bool Options::sideEffect = true;
125 bool Options::dumpIPA = false;
126 bool Options::wpaa = false;  // whole program alias analysis
127 
GetInstance()128 Options &Options::GetInstance()
129 {
130     static Options instance;
131     return instance;
132 }
133 
DecideMpl2MplRealLevel() const134 void Options::DecideMpl2MplRealLevel() const
135 {
136     if (opts::mpl2mpl::o2 || opts::mpl2mpl::os) {
137         if (opts::mpl2mpl::os) {
138             optForSize = true;
139         }
140         O2 = true;
141         usePreg = true;
142     }
143 }
144 
SolveOptions(bool isDebug) const145 bool Options::SolveOptions(bool isDebug) const
146 {
147     DecideMpl2MplRealLevel();
148 
149     for (const auto &opt : mpl2mplCategory.GetEnabledOptions()) {
150         std::string printOpt;
151         if (isDebug) {
152             for (const auto &val : opt->GetRawValues()) {
153                 printOpt += opt->GetName() + " " + val + " ";
154             }
155             LogInfo::MapleLogger() << "mpl2mpl options: " << printOpt << '\n';
156         }
157     }
158 
159     maplecl::CopyIfEnabled(dumpBefore, opts::mpl2mpl::dumpBefore);
160     maplecl::CopyIfEnabled(dumpAfter, opts::mpl2mpl::dumpAfter);
161     maplecl::CopyIfEnabled(dumpFunc, opts::mpl2mpl::dumpFunc);
162 
163     // quiet can be set by verbose option in driver
164     maplecl::CopyIfEnabled(quiet, !opts::verbose, opts::verbose);
165     maplecl::CopyIfEnabled(quiet, opts::mpl2mpl::quiet);
166 
167     maplecl::CopyIfEnabled(dumpPhase, opts::mpl2mpl::dumpPhase);
168     maplecl::CopyIfEnabled(skipPhase, opts::mpl2mpl::skipPhase);
169     maplecl::CopyIfEnabled(skipFrom, opts::mpl2mpl::skipFrom);
170     maplecl::CopyIfEnabled(skipAfter, opts::mpl2mpl::skipAfter);
171     maplecl::CopyIfEnabled(regNativeDynamicOnly, opts::mpl2mpl::regnativeDynamicOnly);
172     maplecl::CopyIfEnabled(staticBindingList, opts::mpl2mpl::staticBindingList);
173     maplecl::CopyIfEnabled(regNativeFunc, opts::mpl2mpl::regnativefunc);
174     maplecl::CopyIfEnabled(nativeWrapper, opts::mpl2mpl::nativewrapper);
175     maplecl::CopyIfEnabled(inlineWithProfile, opts::mpl2mpl::inlineWithProfile);
176     maplecl::CopyIfEnabled(useInline, opts::mpl2mpl::inlineOpt);
177     maplecl::CopyIfEnabled(enableIPAClone, opts::mpl2mpl::ipaClone);
178     maplecl::CopyIfEnabled(noInlineFuncList, opts::mpl2mpl::noInlineFunc);
179     maplecl::CopyIfEnabled(importFileList, opts::mpl2mpl::importFileList);
180     maplecl::CopyIfEnabled(numOfCloneVersions, opts::mpl2mpl::numOfCloneVersions);
181     maplecl::CopyIfEnabled(numOfImpExprLowBound, opts::mpl2mpl::numOfImpExprLowBound);
182     maplecl::CopyIfEnabled(numOfImpExprHighBound, opts::mpl2mpl::numOfImpExprHighBound);
183     maplecl::CopyIfEnabled(numOfCallSiteLowBound, opts::mpl2mpl::numOfCallSiteLowBound);
184     maplecl::CopyIfEnabled(numOfCallSiteUpBound, opts::mpl2mpl::numOfCallSiteUpBound);
185     maplecl::CopyIfEnabled(numOfConstpropValue, opts::mpl2mpl::numOfConstpropValue);
186     maplecl::CopyIfEnabled(useCrossModuleInline, opts::mpl2mpl::crossModuleInline);
187     maplecl::CopyIfEnabled(inlineSmallFunctionThreshold, opts::mpl2mpl::inlineSmallFunctionThreshold);
188     maplecl::CopyIfEnabled(inlineHotFunctionThreshold, opts::mpl2mpl::inlineHotFunctionThreshold);
189     maplecl::CopyIfEnabled(inlineRecursiveFunctionThreshold, opts::mpl2mpl::inlineRecursiveFunctionThreshold);
190     maplecl::CopyIfEnabled(inlineDepth, opts::mpl2mpl::inlineDepth);
191     maplecl::CopyIfEnabled(inlineModuleGrowth, opts::mpl2mpl::inlineModuleGrow);
192     maplecl::CopyIfEnabled(inlineColdFunctionThreshold, opts::mpl2mpl::inlineColdFuncThresh);
193     maplecl::CopyIfEnabled(profileHotCount, opts::mpl2mpl::profileHotCount);
194     maplecl::CopyIfEnabled(profileColdCount, opts::mpl2mpl::profileColdCount);
195     maplecl::CopyIfEnabled(profileHotRate, opts::mpl2mpl::profileHotRate);
196     maplecl::CopyIfEnabled(profileColdRate, opts::mpl2mpl::profileColdRate);
197 
198     if (opts::mpl2mpl::maplelinker) {
199         mapleLinker = opts::mpl2mpl::maplelinker;
200         dumpMuidFile = mapleLinker;  // quiet is overwrited by maplelinker option
201         if (isDebug) {
202             LogInfo::MapleLogger() << "--sub options: dumpMuidFile " << dumpMuidFile << '\n';
203         }
204     }
205 
206     maplecl::CopyIfEnabled(dumpMuidFile, opts::mpl2mpl::dumpMuid);
207     maplecl::CopyIfEnabled(emitVtableImpl, opts::mpl2mpl::emitVtableImpl);
208 
209 #if MIR_JAVA
210     maplecl::CopyIfEnabled(skipVirtualMethod, opts::mpl2mpl::skipvirtual);
211 #endif
212 
213     maplecl::CopyIfEnabled(noRC, !opts::mpl2mpl::userc, opts::mpl2mpl::userc);
214     maplecl::CopyIfEnabled(strictNaiveRC, opts::mpl2mpl::strictNaiveRc);
215 
216     /* big endian can be set with several options: --target, -Be.
217      * Triple takes to account all these options and allows to detect big endian with IsBigEndian() interface */
218     if (Triple::GetTriple().IsBigEndian()) {
219         bigEndian = true;
220     }
221 
222     maplecl::CopyIfEnabled(rcOpt1, opts::mpl2mpl::rcOpt1);
223     maplecl::CopyIfEnabled(nativeOpt, opts::mpl2mpl::nativeopt);
224     maplecl::CopyIfEnabled(criticalNativeFile, opts::mpl2mpl::criticalNative);
225     maplecl::CopyIfEnabled(fastNativeFile, opts::mpl2mpl::fastNative);
226     maplecl::CopyIfEnabled(noDot, opts::mpl2mpl::nodot);
227     maplecl::CopyIfEnabled(genIRProfile, opts::mpl2mpl::genIrProfile);
228     maplecl::CopyIfEnabled(profileTest, opts::mpl2mpl::profileTest);
229     maplecl::CopyIfEnabled(barrier, opts::mpl2mpl::barrier);
230     maplecl::CopyIfEnabled(nativeFuncPropertyFile, opts::mpl2mpl::nativeFuncPropertyFile);
231 
232     maplecl::CopyIfEnabled(mapleLinkerTransformLocal, !opts::mpl2mpl::maplelinkerNolocal,
233                            opts::mpl2mpl::maplelinkerNolocal);
234     maplecl::CopyIfEnabled(deferredVisit, opts::mpl2mpl::deferredVisit);
235 
236     if (opts::mpl2mpl::deferredVisit.IsEnabledByUser()) {
237         deferredVisit = true;
238         deferredVisit2 = true;
239         if (isDebug) {
240             LogInfo::MapleLogger() << "--sub options: deferredVisit " << deferredVisit << '\n';
241             LogInfo::MapleLogger() << "--sub options: deferredVisit2 " << deferredVisit2 << '\n';
242         }
243     }
244 
245     maplecl::CopyIfEnabled(decoupleSuper, opts::mpl2mpl::decoupleSuper);
246 
247     if (opts::mpl2mpl::buildApp.IsEnabledByUser()) {
248         if (opts::mpl2mpl::buildApp != kMpl2MplLevelZero && opts::mpl2mpl::buildApp != kMpl2MplLevelOne &&
249             opts::mpl2mpl::buildApp != kMpl2MplLevelTwo) {
250             LogInfo::MapleLogger(kLlErr) << "expecting 0,1,2 or empty for --build-app\n";
251             return false;
252         }
253         /* Default buildApp value is 1, so if an User does not select buildApp (with --buildApp=2), it will be 1 */
254         buildApp = opts::mpl2mpl::buildApp;
255     }
256 
257     maplecl::CopyIfEnabled(sourceMuid, opts::mpl2mpl::sourceMuid);
258 
259     maplecl::CopyIfEnabled(partialAot, opts::mpl2mpl::partialAot);
260 
261     if (opts::mpl2mpl::decoupleInit.IsEnabledByUser()) {
262         if (opts::mpl2mpl::decoupleInit != kNoDecouple && opts::mpl2mpl::decoupleInit != kConservativeDecouple &&
263             opts::mpl2mpl::decoupleInit != kAggressiveDecouple) {
264             std::cerr << "expecting 0,1,2 or empty for --decouple-init\n";
265             return false;
266         }
267 
268         /* Default opts::mpl2mpl::decoupleInit value is Options::kConservativeDecouple==1
269          * so if an User does not select buildApp (with --decouple-init=2), it will be 1.
270          */
271         decoupleInit = opts::mpl2mpl::decoupleInit;
272         buildApp = Options::kConservativeDecouple;
273     }
274 
275     maplecl::CopyIfEnabled(genVtabAndItabForDecouple, opts::mpl2mpl::genDecoupleVtab);
276     maplecl::CopyIfEnabled(profileFunc, opts::mpl2mpl::profileFunc);
277     maplecl::CopyIfEnabled(dumpDevirtualList, opts::mpl2mpl::dumpDevirtual);
278     maplecl::CopyIfEnabled(readDevirtualList, opts::mpl2mpl::readDevirtual);
279     maplecl::CopyIfEnabled(usePreloadedClass, opts::mpl2mpl::usewhiteclass);
280 
281     if (opts::profileGen.IsEnabledByUser()) {
282         if (O2) {
283             LogInfo::MapleLogger(kLlErr) << "profileGen requires no optimization\n";
284             return false;
285         } else {
286             profileGen = true;
287         }
288     }
289 
290     maplecl::CopyIfEnabled(profileUse, opts::profileUse);
291     maplecl::CopyIfEnabled(genLMBC, opts::genLMBC);
292     maplecl::CopyIfEnabled(appPackageName, opts::mpl2mpl::appPackageName);
293     maplecl::CopyIfEnabled(classLoaderInvocationList, opts::mpl2mpl::checkClInvocation);
294     maplecl::CopyIfEnabled(dumpClassLoaderInvocation, opts::mpl2mpl::dumpClInvocation);
295     maplecl::CopyIfEnabled(warningLevel, opts::mpl2mpl::warning);
296     maplecl::CopyIfEnabled(lazyBinding, opts::mpl2mpl::lazyBinding);
297     maplecl::CopyIfEnabled(hotFix, opts::mpl2mpl::hotFix);
298     maplecl::CopyIfEnabled(compactMeta, opts::mpl2mpl::compactMeta);
299     maplecl::CopyIfEnabled(genPGOReport, opts::mpl2mpl::genPGOReport);
300 
301     if (opts::mpl2mpl::inlineCache.IsEnabledByUser()) {
302         if (opts::mpl2mpl::inlineCache != 0 && opts::mpl2mpl::inlineCache != 1 &&
303             opts::mpl2mpl::inlineCache != 2 && opts::mpl2mpl::inlineCache != 3) { // expecting 0, 1, 2, 3
304             LogInfo::MapleLogger(kLlErr) << "expecting 0,1,2,3 or empty for --inlineCache\n";
305             return false;
306         }
307 
308         inlineCache = opts::mpl2mpl::inlineCache;
309     }
310 
311     maplecl::CopyIfEnabled(noComment, opts::mpl2mpl::noComment);
312     maplecl::CopyIfEnabled(rmNoUseFunc, opts::mpl2mpl::rmnousefunc);
313     maplecl::CopyIfEnabled(sideEffect, opts::mpl2mpl::sideeffect);
314     maplecl::CopyIfEnabled(dumpIPA, opts::mpl2mpl::dumpIPA);
315     maplecl::CopyIfEnabled(wpaa, opts::mpl2mpl::wpaa);
316 
317     return true;
318 }
319 
ParseOptions(int argc,char ** argv,std::string & fileName) const320 bool Options::ParseOptions(int argc, char **argv, std::string &fileName) const
321 {
322     (void)maplecl::CommandLine::GetCommandLine().Parse(argc, static_cast<char **>(argv), mpl2mplCategory);
323     bool result = SolveOptions(false);
324     if (!result) {
325         return result;
326     }
327 
328     auto &badArgs = maplecl::CommandLine::GetCommandLine().badCLArgs;
329     int inputFileCount = 0;
330     for (auto &arg : badArgs) {
331         if (FileUtils::IsFileExists(arg.first)) {
332             inputFileCount++;
333             fileName = arg.first;
334         } else {
335             LogInfo::MapleLogger(kLlErr) << "Unknown Option: " << arg.first;
336             return false;
337         }
338     }
339 
340     if (inputFileCount != 1) {
341         LogInfo::MapleLogger(kLlErr) << "expecting one .mpl file as last argument, found: ";
342         for (const auto &optionArg : badArgs) {
343             LogInfo::MapleLogger(kLlErr) << optionArg.first << " ";
344         }
345         LogInfo::MapleLogger(kLlErr) << "\n";
346         return false;
347     }
348 
349 #ifdef DEBUG_OPTION
350     LogInfo::MapleLogger() << "mpl file : " << fileName << "\t";
351     DumpOptions();
352 #endif
353 
354     return true;
355 }
356 
DumpOptions() const357 void Options::DumpOptions() const
358 {
359     LogInfo::MapleLogger() << "phase sequence : \t";
360     if (phaseSeq.empty()) {
361         LogInfo::MapleLogger() << "default phase sequence\n";
362     } else {
363         for (size_t i = 0; i < phaseSeq.size(); ++i) {
364             LogInfo::MapleLogger() << " " << phaseSeq[i];
365         }
366     }
367     LogInfo::MapleLogger() << "\n";
368 }
369 };  // namespace maple
370