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