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 #ifndef ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 16 #define ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 17 18 #include "ecmascript/compiler/bytecode_info_collector.h" 19 #include "ecmascript/compiler/compiler_log.h" 20 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 21 #include "ecmascript/ecma_vm.h" 22 #include "macros.h" 23 #include "ecmascript/compiler/aot_compilation_env.h" 24 #include "ecmascript/compiler/aot_file/aot_file_manager.h" 25 #include "ecmascript/ohos/ohos_preload_app_info.h" 26 27 namespace panda::ecmascript::kungfu { 28 class OhosPkgArgs; 29 using PGOProfilerDecoder = pgo::PGOProfilerDecoder; 30 31 struct AbcFileInfo { AbcFileInfoAbcFileInfo32 explicit AbcFileInfo(std::string extendedFilePath, std::shared_ptr<JSPandaFile> jsPandaFile) 33 : extendedFilePath_(extendedFilePath), jsPandaFile_(jsPandaFile) {} 34 ~AbcFileInfo() = default; 35 36 std::string extendedFilePath_; 37 std::shared_ptr<JSPandaFile> jsPandaFile_; 38 }; 39 40 class CallMethodFlagMap { 41 public: CallMethodFlagMap()42 CallMethodFlagMap() {} 43 void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall); 44 bool IsFastCall(CString fileDesc, uint32_t methodOffset) const; 45 void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile); 46 bool IsAotCompile(CString fileDesc, uint32_t methodOffset) const; 47 void SetIsJitCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile); 48 bool IsJitCompile(CString fileDesc, uint32_t methodOffset) const; 49 private: 50 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsFastCall_ {}; 51 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsAotCompile_ {}; 52 std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsJitCompile_ {}; 53 }; 54 55 struct CompilationOptions { 56 explicit CompilationOptions(JSRuntimeOptions &runtimeOptions); 57 void ParseOption(const std::string &option, std::map<std::string, std::vector<std::string>> &optionMap) const; 58 std::vector<std::string> SplitString(const std::string &str, const char ch) const; 59 std::string triple_; 60 std::string outputFileName_; 61 size_t optLevel_; 62 size_t relocMode_; 63 std::string logOption_; 64 std::string logMethodsList_; 65 bool compilerLogTime_; 66 bool deviceIsScreenOff_; 67 size_t maxAotMethodSize_; 68 size_t maxMethodsInModule_; 69 uint32_t hotnessThreshold_; 70 int32_t deviceThermalLevel_ {0}; 71 std::string profilerIn_; 72 std::string optBCRange_; 73 bool needMerge_ {false}; 74 bool isEnableArrayBoundsCheckElimination_ {true}; 75 bool isEnableTypeLowering_ {true}; 76 bool isEnableEarlyElimination_ {true}; 77 bool isEnableLaterElimination_ {true}; 78 bool isEnableValueNumbering_ {true}; 79 bool isEnableOptInlining_ {true}; 80 bool isEnableEmptyCatchFunction_ {false}; 81 bool isEnableOptString_ {true}; 82 bool isEnableOptPGOType_ {true}; 83 bool isEnableOptTrackField_ {true}; 84 bool isEnableOptLoopPeeling_ {true}; 85 bool isEnableOptLoopInvariantCodeMotion_ {false}; 86 bool isEnableOptConstantFolding_ {true}; 87 bool isEnableLexenvSpecialization_ {false}; 88 bool isEnableNativeInline_ {true}; 89 bool isEnablePGOHCRLowering_ {false}; 90 bool isEnableLoweringBuiltin_ {true}; 91 bool isEnableOptBranchProfiling_ {true}; 92 bool isEnableEscapeAnalysis_ {false}; 93 bool isEnableInductionVariableAnalysis_ {false}; 94 bool isEnableVerifierPass_ {true}; 95 bool isEnableBaselinePgo_ {false}; 96 std::map<std::string, std::vector<std::string>> optionSelectMethods_; 97 std::map<std::string, std::vector<std::string>> optionSkipMethods_; 98 }; 99 100 class AotCompilerPreprocessor { 101 public: AotCompilerPreprocessor(EcmaVM * vm,JSRuntimeOptions & runtimeOptions,std::map<std::string,std::shared_ptr<OhosPkgArgs>> & pkgsArgs,PGOProfilerDecoder & profilerDecoder,arg_list_t & pandaFileNames)102 AotCompilerPreprocessor(EcmaVM *vm, JSRuntimeOptions &runtimeOptions, 103 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs, 104 PGOProfilerDecoder &profilerDecoder, arg_list_t &pandaFileNames) 105 : vm_(vm), 106 runtimeOptions_(runtimeOptions), 107 pkgsArgs_(pkgsArgs), 108 profilerDecoder_(profilerDecoder), 109 pandaFileNames_(pandaFileNames), 110 aotCompilationEnv_(vm) {}; 111 112 ~AotCompilerPreprocessor() = default; 113 114 bool HandleTargetCompilerMode(CompilationOptions &cOptions); 115 116 bool HandlePandaFileNames(const int argc, const char **argv); 117 118 void AOTInitialize(); 119 120 void DoPreAnalysis(CompilationOptions &cOptions); 121 122 void AnalyzeGraphs(JSPandaFile *jsPandaFile, BytecodeInfoCollector &collector, CompilationOptions &cOptions); 123 124 void AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions, BytecodeInfoCollector &collector, 125 MethodLiteral *methodLiteral, MethodPcInfo &methodPCInfo); 126 127 void Process(CompilationOptions &cOptions); 128 129 uint32_t GenerateAbcFileInfos(); 130 131 void GenerateBytecodeInfoCollectors(const CompilationOptions &cOptions); 132 133 bool HandleMergedPgoFile(uint32_t checksum); 134 135 void GeneratePGOTypes(); 136 137 void SnapshotInitialize(); 138 139 bool FilterOption(const std::map<std::string, std::vector<std::string>> &optionMap, 140 const std::string &recordName, const std::string &methodName) const; 141 142 bool IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo, 143 const CString &recordName, const MethodLiteral *methodLiteral, 144 const MethodPcInfo &methodPCInfo, const std::string &methodName, 145 CompilationOptions &cOptions) const; 146 147 void GenerateMethodMap(CompilationOptions &cOptions); 148 149 bool MethodHasTryCatch(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral) const; 150 151 bool HasSkipMethod(const CVector<std::string> &methodList, const std::string &methodName) const; 152 153 bool ForbidenRebuildAOT(std::string &fileName) const; 154 155 bool HasPreloadAotFile() const; 156 157 bool HasExistsAOTFiles(CompilationOptions &cOptions) const; 158 SetIsFastCall(CString fileDesc,uint32_t methodOffset,bool isFastCall)159 void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall) 160 { 161 callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall); 162 } 163 IsFastCall(CString fileDesc,uint32_t methodOffset)164 bool IsFastCall(CString fileDesc, uint32_t methodOffset) 165 { 166 return callMethodFlagMap_.IsFastCall(fileDesc, methodOffset); 167 } 168 SetIsAotCompile(CString fileDesc,uint32_t methodOffset,bool isAotCompile)169 void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile) 170 { 171 callMethodFlagMap_.SetIsAotCompile(fileDesc, methodOffset, isAotCompile); 172 } 173 GetIsAotCompile(CString fileDesc,uint32_t methodOffset)174 bool GetIsAotCompile(CString fileDesc, uint32_t methodOffset) 175 { 176 return callMethodFlagMap_.IsAotCompile(fileDesc, methodOffset); 177 } 178 179 std::string GetMainPkgArgsAppSignature() const; 180 GetCompilerResult()181 bool GetCompilerResult() 182 { 183 // The size of fileInfos is not equal to pandaFiles size, set compiler result to false 184 return fileInfos_.size() == pandaFileNames_.size(); 185 } 186 GetAbcFileInfo()187 const CVector<AbcFileInfo>& GetAbcFileInfo() const 188 { 189 return fileInfos_; 190 } 191 GetBcInfoCollectors()192 const CVector<std::unique_ptr<BytecodeInfoCollector>>& GetBcInfoCollectors() const 193 { 194 return bcInfoCollectors_; 195 } 196 GetMainPkgArgs()197 std::shared_ptr<OhosPkgArgs> GetMainPkgArgs() const 198 { 199 if (pkgsArgs_.empty()) { 200 return nullptr; 201 } 202 return pkgsArgs_.at(mainPkgName_); 203 } 204 GetMainPkgName()205 std::string GetMainPkgName() const 206 { 207 return mainPkgName_; 208 } 209 GetPkgsArgs()210 const std::map<std::string, std::shared_ptr<OhosPkgArgs>> &GetPkgsArgs() const 211 { 212 return pkgsArgs_; 213 } GetCallMethodFlagMap()214 CallMethodFlagMap *GetCallMethodFlagMap() 215 { 216 return &callMethodFlagMap_; 217 } 218 GetHelper()219 static std::string GetHelper() 220 { 221 std::string str; 222 str.append(COMPILER_HELP_HEAD_MSG); 223 str.append(HELP_OPTION_MSG); 224 return str; 225 } 226 227 private: 228 NO_COPY_SEMANTIC(AotCompilerPreprocessor); 229 NO_MOVE_SEMANTIC(AotCompilerPreprocessor); 230 void HandleTargetModeInfo(CompilationOptions &cOptions); 231 232 std::shared_ptr<JSPandaFile> CreateAndVerifyJSPandaFile(const std::string &fileName); 233 234 void ResolveModule(const JSPandaFile *jsPandaFile, const std::string &fileName); 235 OutCompiledMethodsRange()236 bool OutCompiledMethodsRange() const 237 { 238 static uint32_t compiledMethodsCount = 0; 239 ++compiledMethodsCount; 240 return compiledMethodsCount < runtimeOptions_.GetCompilerMethodsRange().first || 241 runtimeOptions_.GetCompilerMethodsRange().second <= compiledMethodsCount; 242 } 243 244 EcmaVM *vm_; 245 JSRuntimeOptions &runtimeOptions_; 246 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs_; 247 std::string mainPkgName_; 248 PGOProfilerDecoder &profilerDecoder_; 249 arg_list_t &pandaFileNames_; 250 CVector<AbcFileInfo> fileInfos_; 251 CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_; 252 CallMethodFlagMap callMethodFlagMap_; 253 AOTCompilationEnv aotCompilationEnv_; 254 CVector<std::string> emptyCatchBBMethods_; 255 CVector<std::string> irreducibleMethods_; 256 friend class OhosPkgArgs; 257 }; 258 } // namespace panda::ecmascript::kungfu 259 #endif // ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 260