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
22 namespace ark::es2panda::util {
23
InitializeLogging(const util::Options * options)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
OptimizeBytecode(ark::pandasm::Program * prog,const util::Options * options,const ReporterFun & reporter,std::map<std::string,size_t> * statp,ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps * mapsp)39 static 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
GenerateProgramImpl(ark::pandasm::Program * prog,const util::Options * options,const ReporterFun & reporter,std::map<std::string,size_t> * statp,ark::pandasm::AsmEmitter::PandaFileToPandaAsmMaps * mapsp)61 static 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
GenerateProgram(ark::pandasm::Program * prog,const util::Options * options,const ReporterFun & reporter)103 int 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