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 { AbcFileInfopanda::ecmascript::kungfu::AbcFileInfo32 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 isEnableOptString_ {true}; 81 bool isEnableOptPGOType_ {true}; 82 bool isEnableOptTrackField_ {true}; 83 bool isEnableOptLoopPeeling_ {true}; 84 bool isEnableOptLoopInvariantCodeMotion_ {false}; 85 bool isEnableOptConstantFolding_ {true}; 86 bool isEnableLexenvSpecialization_ {false}; 87 bool isEnableNativeInline_ {true}; 88 bool isEnablePGOHCRLowering_ {false}; 89 bool isEnableLoweringBuiltin_ {true}; 90 bool isEnableOptBranchProfiling_ {true}; 91 bool isEnableEscapeAnalysis_ {false}; 92 bool isEnableInductionVariableAnalysis_ {false}; 93 bool isEnableVerifierPass_ {true}; 94 bool isEnableBaselinePgo_ {false}; 95 std::map<std::string, std::vector<std::string>> optionSelectMethods_; 96 std::map<std::string, std::vector<std::string>> optionSkipMethods_; 97 }; 98 99 class AotCompilerPreprocessor { 100 public: AotCompilerPreprocessor(EcmaVM *vm, JSRuntimeOptions &runtimeOptions, std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs, PGOProfilerDecoder &profilerDecoder, arg_list_t &pandaFileNames)101 AotCompilerPreprocessor(EcmaVM *vm, JSRuntimeOptions &runtimeOptions, 102 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs, 103 PGOProfilerDecoder &profilerDecoder, arg_list_t &pandaFileNames) 104 : vm_(vm), 105 runtimeOptions_(runtimeOptions), 106 pkgsArgs_(pkgsArgs), 107 profilerDecoder_(profilerDecoder), 108 pandaFileNames_(pandaFileNames), 109 aotCompilationEnv_(vm) {}; 110 111 ~AotCompilerPreprocessor() = default; 112 113 bool HandleTargetCompilerMode(CompilationOptions &cOptions); 114 115 bool HandlePandaFileNames(const int argc, const char **argv); 116 117 void AOTInitialize(); 118 119 void DoPreAnalysis(CompilationOptions &cOptions); 120 121 void AnalyzeGraphs(JSPandaFile *jsPandaFile, BytecodeInfoCollector &collector, CompilationOptions &cOptions); 122 123 void AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions, BytecodeInfoCollector &collector, 124 MethodLiteral *methodLiteral, MethodPcInfo &methodPCInfo); 125 126 void Process(CompilationOptions &cOptions); 127 128 uint32_t GenerateAbcFileInfos(); 129 130 void GenerateBytecodeInfoCollectors(const CompilationOptions &cOptions); 131 132 bool HandleMergedPgoFile(uint32_t checksum); 133 134 void GeneratePGOTypes(); 135 136 void SnapshotInitialize(); 137 138 bool FilterOption(const std::map<std::string, std::vector<std::string>> &optionMap, 139 const std::string &recordName, const std::string &methodName) const; 140 141 bool IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo, 142 const CString &recordName, const MethodLiteral *methodLiteral, 143 const MethodPcInfo &methodPCInfo, const std::string &methodName, 144 CompilationOptions &cOptions) const; 145 146 void GenerateMethodMap(CompilationOptions &cOptions); 147 148 bool MethodHasTryCatch(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral) const; 149 150 bool HasSkipMethod(const CVector<std::string> &methodList, const std::string &methodName) const; 151 152 bool ForbidenRebuildAOT(std::string &fileName) const; 153 154 bool HasPreloadAotFile() const; 155 156 bool HasExistsAOTFiles(CompilationOptions &cOptions) const; 157 SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall)158 void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall) 159 { 160 callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall); 161 } 162 IsFastCall(CString fileDesc, uint32_t methodOffset)163 bool IsFastCall(CString fileDesc, uint32_t methodOffset) 164 { 165 return callMethodFlagMap_.IsFastCall(fileDesc, methodOffset); 166 } 167 SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile)168 void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile) 169 { 170 callMethodFlagMap_.SetIsAotCompile(fileDesc, methodOffset, isAotCompile); 171 } 172 GetIsAotCompile(CString fileDesc, uint32_t methodOffset)173 bool GetIsAotCompile(CString fileDesc, uint32_t methodOffset) 174 { 175 return callMethodFlagMap_.IsAotCompile(fileDesc, methodOffset); 176 } 177 178 std::string GetMainPkgArgsAppSignature() const; 179 GetCompilerResult()180 bool GetCompilerResult() 181 { 182 // The size of fileInfos is not equal to pandaFiles size, set compiler result to false 183 return fileInfos_.size() == pandaFileNames_.size(); 184 } 185 GetAbcFileInfo() const186 const CVector<AbcFileInfo>& GetAbcFileInfo() const 187 { 188 return fileInfos_; 189 } 190 GetBcInfoCollectors() const191 const CVector<std::unique_ptr<BytecodeInfoCollector>>& GetBcInfoCollectors() const 192 { 193 return bcInfoCollectors_; 194 } 195 GetMainPkgArgs() const196 std::shared_ptr<OhosPkgArgs> GetMainPkgArgs() const 197 { 198 if (pkgsArgs_.empty()) { 199 return nullptr; 200 } 201 return pkgsArgs_.at(mainPkgName_); 202 } 203 GetPkgsArgs() const204 const std::map<std::string, std::shared_ptr<OhosPkgArgs>> &GetPkgsArgs() const 205 { 206 return pkgsArgs_; 207 } GetCallMethodFlagMap()208 CallMethodFlagMap *GetCallMethodFlagMap() 209 { 210 return &callMethodFlagMap_; 211 } 212 GetHelper()213 static std::string GetHelper() 214 { 215 std::string str; 216 str.append(COMPILER_HELP_HEAD_MSG); 217 str.append(HELP_OPTION_MSG); 218 return str; 219 } 220 221 private: 222 NO_COPY_SEMANTIC(AotCompilerPreprocessor); 223 NO_MOVE_SEMANTIC(AotCompilerPreprocessor); 224 void HandleTargetModeInfo(CompilationOptions &cOptions); 225 226 std::shared_ptr<JSPandaFile> CreateAndVerifyJSPandaFile(const std::string &fileName); 227 228 void ResolveModule(const JSPandaFile *jsPandaFile, const std::string &fileName); 229 OutCompiledMethodsRange() const230 bool OutCompiledMethodsRange() const 231 { 232 static uint32_t compiledMethodsCount = 0; 233 ++compiledMethodsCount; 234 return compiledMethodsCount < runtimeOptions_.GetCompilerMethodsRange().first || 235 runtimeOptions_.GetCompilerMethodsRange().second <= compiledMethodsCount; 236 } 237 238 EcmaVM *vm_; 239 JSRuntimeOptions &runtimeOptions_; 240 std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs_; 241 std::string mainPkgName_; 242 PGOProfilerDecoder &profilerDecoder_; 243 arg_list_t &pandaFileNames_; 244 CVector<AbcFileInfo> fileInfos_; 245 CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_; 246 CallMethodFlagMap callMethodFlagMap_; 247 AOTCompilationEnv aotCompilationEnv_; 248 CVector<std::string> irreducibleMethods_; 249 friend class OhosPkgArgs; 250 }; 251 } // namespace panda::ecmascript::kungfu 252 #endif // ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H 253