1/* 2 * Copyright (c) 2021-2024 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 "generateBin.h" 17#include "bytecode_optimizer/bytecodeopt_options.h" 18#include "bytecode_optimizer/optimize_bytecode.h" 19#include "compiler/compiler_logger.h" 20#include "compiler/compiler_options.h" 21 22namespace ark::es2panda::util { 23 24[[maybe_unused]] static void InitializeLogging(const util::Options *options) 25{ 26 ark::Logger::ComponentMask componentMask; 27 componentMask.set(ark::Logger::Component::ASSEMBLER); 28 componentMask.set(ark::Logger::Component::COMPILER); 29 componentMask.set(ark::Logger::Component::BYTECODE_OPTIMIZER); 30 31 if (!ark::Logger::IsInitialized()) { 32 ark::Logger::InitializeStdLogging(Logger::LevelFromString(options->LogLevel()), componentMask); 33 } else { 34 ark::Logger::EnableComponent(componentMask); 35 } 36} 37 38#ifdef PANDA_WITH_BYTECODE_OPTIMIZER 39static int OptimizeBytecode(ark::pandasm::Program *prog, const util::Options *options, const ReporterFun &reporter, 40 std::map<std::string, size_t> *statp, 41 ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp) 42{ 43 if (options->OptLevel() != 0) { 44 InitializeLogging(options); 45 if (!ark::pandasm::AsmEmitter::Emit(options->CompilerOutput(), *prog, statp, mapsp, true)) { 46 reporter("Failed to emit binary data: " + ark::pandasm::AsmEmitter::GetLastError()); 47 return 1; 48 } 49 50 ark::bytecodeopt::g_options.SetOptLevel(options->OptLevel()); 51 // Set default value instead of maximum set in ark::bytecodeopt::SetCompilerOptions() 52 ark::compiler::CompilerLogger::Init({"all"}); 53 ark::compiler::g_options.SetCompilerMaxBytecodeSize(ark::compiler::g_options.GetCompilerMaxBytecodeSize()); 54 ark::bytecodeopt::OptimizeBytecode(prog, mapsp, options->CompilerOutput(), options->IsDynamic(), true); 55 } 56 57 return 0; 58} 59#endif 60 61static int GenerateProgramImpl(ark::pandasm::Program *prog, const util::Options *options, const ReporterFun &reporter, 62 std::map<std::string, size_t> *statp, 63 ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp) 64{ 65 if (options->CompilerOptions().dumpAsm) { 66 es2panda::Compiler::DumpAsm(prog); 67 } 68 69 if (!ark::pandasm::AsmEmitter::AssignProfileInfo(prog)) { 70 reporter("AssignProfileInfo failed"); 71 return 1; 72 } 73 74 if (!ark::pandasm::AsmEmitter::Emit(options->CompilerOutput(), *prog, statp, mapsp, true)) { 75 reporter("Failed to emit binary data: " + ark::pandasm::AsmEmitter::GetLastError()); 76 return 1; 77 } 78 79 if (options->SizeStat()) { 80 size_t totalSize = 0; 81 std::cout << "Panda file size statistic:" << std::endl; 82 constexpr std::array<std::string_view, 2> INFO_STATS = {"instructions_number", "codesize"}; 83 84 auto &stat = *statp; 85 for (const auto &[name, size] : stat) { 86 if (find(INFO_STATS.begin(), INFO_STATS.end(), name) != INFO_STATS.end()) { 87 continue; 88 } 89 std::cout << name << " section: " << size << std::endl; 90 totalSize += size; 91 } 92 93 for (const auto &name : INFO_STATS) { 94 std::cout << name << ": " << stat.at(std::string(name)) << std::endl; 95 } 96 97 std::cout << "total: " << totalSize << std::endl; 98 } 99 100 return 0; 101} 102 103int GenerateProgram(ark::pandasm::Program *prog, const util::Options *options, const ReporterFun &reporter) 104{ 105 std::map<std::string, size_t> stat; 106 std::map<std::string, size_t> *statp = options->OptLevel() != 0 ? &stat : nullptr; 107 ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps maps {}; 108 ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps *mapsp = options->OptLevel() != 0 ? &maps : nullptr; 109 110#ifdef PANDA_WITH_BYTECODE_OPTIMIZER 111 if (OptimizeBytecode(prog, options, reporter, statp, mapsp) != 0) { 112 return 1; 113 } 114#endif 115 if (GenerateProgramImpl(prog, options, reporter, statp, mapsp) != 0) { 116 return 1; 117 } 118 119 return 0; 120} 121 122} // namespace ark::es2panda::util 123