• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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