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