• 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 "ecmascript/compiler/stub_compiler.h"
17 
18 #include "ecmascript/compiler/pass.h"
19 #include "ecmascript/compiler/stub.h"
20 
21 namespace panda::ecmascript::kungfu {
22 class StubPassData : public PassData {
23 public:
StubPassData(Stub * stub,LLVMModule * module,CompilerLog * log)24     StubPassData(Stub *stub, LLVMModule *module, CompilerLog *log)
25         : PassData(nullptr, nullptr, nullptr, log, "stubs"),
26           cfg_(module->GetTripleStr()),
27           module_(module),
28           stub_(stub) {}
29     ~StubPassData() = default;
30 
GetCompilationConfig() const31     const CompilationConfig *GetCompilationConfig() const
32     {
33         return &cfg_;
34     }
35 
GetCircuit() const36     Circuit *GetCircuit() const
37     {
38         return stub_->GetCircuit();
39     }
40 
GetStubModule() const41     LLVMModule *GetStubModule() const
42     {
43         return module_;
44     }
45 
GetStub() const46     Stub *GetStub() const
47     {
48         return stub_;
49     }
50 
51 private:
52     CompilationConfig cfg_;
53     LLVMModule *module_;
54     Stub *stub_;
55 };
56 
57 class StubBuildCircuitPass {
58 public:
Run(StubPassData * data)59     bool Run(StubPassData *data)
60     {
61         auto stub = data->GetStub();
62         LOG_COMPILER(INFO) << "Stub Name: " << stub->GetMethodName();
63         stub->GenerateCircuit(data->GetCompilationConfig());
64         return true;
65     }
66 };
67 
68 class StubLLVMIRGenPass {
69 public:
CreateCodeGen(LLVMModule * module,bool enableLog)70     void CreateCodeGen(LLVMModule *module, bool enableLog)
71     {
72         llvmImpl_ = std::make_unique<LLVMIRGeneratorImpl>(module, enableLog);
73     }
74 
Run(StubPassData * data,size_t index)75     bool Run(StubPassData *data, size_t index)
76     {
77         bool enableLog = data->GetLog()->EnableMethodCIRLog() || data->GetLog()->OutputASM();
78         auto stubModule = data->GetStubModule();
79         CreateCodeGen(stubModule, enableLog);
80         CodeGenerator codegen(llvmImpl_, "stubs");
81         codegen.RunForStub(data->GetCircuit(), data->GetConstScheduleResult(), index, data->GetCompilationConfig());
82         return true;
83     }
84 private:
85     std::unique_ptr<CodeGeneratorImpl> llvmImpl_ {nullptr};
86 };
87 
RunPipeline(LLVMModule * module,NativeAreaAllocator * allocator) const88 void StubCompiler::RunPipeline(LLVMModule *module, NativeAreaAllocator *allocator) const
89 {
90     auto callSigns = module->GetCSigns();
91     CompilerLog *log = GetLog();
92     for (size_t i = 0; i < callSigns.size(); i++) {
93         auto &cs = callSigns[i];
94         Circuit circuit(allocator, module->GetDebugInfo(), cs->GetName().c_str(), module->Is64Bit());
95         Stub stub(cs, &circuit);
96         log->SetStubLog(stub.GetMethodName(), GetLogList());
97 
98         StubPassData data(&stub, module, log);
99         PassRunner<StubPassData> pipeline(&data);
100         pipeline.RunPass<StubBuildCircuitPass>();
101         pipeline.RunPass<VerifierPass>();
102         pipeline.RunPass<SchedulingPass>();
103         pipeline.RunPass<StubLLVMIRGenPass>(i);
104     }
105 }
106 
InitializeCS() const107 void StubCompiler::InitializeCS() const
108 {
109     BytecodeStubCSigns::Initialize();
110     CommonStubCSigns::Initialize();
111     BaselineStubCSigns::Initialize();
112     BuiltinsStubCSigns::Initialize();
113     RuntimeStubCSigns::Initialize();
114 }
115 
BuildStubModuleAndSave() const116 bool StubCompiler::BuildStubModuleAndSave() const
117 {
118     if (filePath_.empty()) {
119         return false;
120     }
121 
122     InitializeCS();
123     CompilerLog *log = GetLog();
124     MethodLogList *logList = GetLogList();
125 
126     NativeAreaAllocator allocator;
127     StubFileGenerator generator(log, logList, triple_, concurrentCompile_);
128 
129     LOG_COMPILER(INFO) << "=============== compiling bytecode handler stubs ===============";
130     LOptions stubOp(optLevel_, FPFlag::ELIM_FP, relocMode_);
131     Module* stubM = generator.AddModule(&allocator, "bc_stub", triple_, stubOp, log->OutputASM(), StubFileKind::BC);
132     if (!stubM->IsLLVM()) {
133         LOG_COMPILER(FATAL) << " Stub compiler is not supported for litecg ===============";
134         return false;
135     }
136     RunPipeline(static_cast<LLVMModule*>(stubM->GetModule()), &allocator);
137 
138     LOG_COMPILER(INFO) << "=============== compiling common stubs ===============";
139     LOptions comOp(optLevel_, FPFlag::RESERVE_FP, relocMode_);
140     Module* comM = generator.AddModule(&allocator, "com_stub", triple_, comOp, log->OutputASM(), StubFileKind::COM);
141     if (!comM->IsLLVM()) {
142         LOG_COMPILER(FATAL) << " Stub compiler is not supported for litecg ===============";
143         return false;
144     }
145     RunPipeline(static_cast<LLVMModule*>(comM->GetModule()), &allocator);
146 
147     LOG_COMPILER(INFO) << "=============== compiling builtins stubs ===============";
148     LOptions builtinOp(optLevel_, FPFlag::RESERVE_FP, relocMode_);
149     Module* builtinM = generator.AddModule(&allocator, "builtin_stub", triple_, builtinOp, log->OutputASM(),
150                                            StubFileKind::BUILTIN);
151     if (!builtinM->IsLLVM()) {
152         LOG_COMPILER(FATAL) << " Stub compiler is not supported for litecg ===============";
153         return false;
154     }
155     RunPipeline(static_cast<LLVMModule*>(builtinM->GetModule()), &allocator);
156 
157     LOG_COMPILER(INFO) << "=============== compiling baseline stubs ===============";
158     LOptions baselineOp(optLevel_, FPFlag::RESERVE_FP, relocMode_);
159     Module* baselineM = generator.AddModule(&allocator, "baseline_stub", triple_, baselineOp, log->OutputASM(),
160                                             StubFileKind::BASELINE);
161     if (!baselineM->IsLLVM()) {
162         LOG_COMPILER(FATAL) << " Stub compiler is not supported for litecg ===============";
163         return false;
164     }
165     RunPipeline(static_cast<LLVMModule*>(baselineM->GetModule()), &allocator);
166 
167     generator.SaveStubFile(filePath_);
168     return true;
169 }
170 
GetHelper()171 std::string GetHelper()
172 {
173     std::string str;
174     str.append(STUB_HELP_HEAD_MSG);
175     str.append(HELP_OPTION_MSG);
176     return str;
177 }
178 }  // namespace panda::ecmascript::kungfu
179 
main(const int argc,const char ** argv)180 int main(const int argc, const char **argv)
181 {
182     panda::ecmascript::JSRuntimeOptions runtimeOptions;
183     bool ret = runtimeOptions.ParseCommand(argc, argv);
184     if (!ret) {
185         std::cerr << panda::ecmascript::kungfu::GetHelper();
186         return 1;
187     }
188 
189     panda::ecmascript::Log::Initialize(runtimeOptions);
190     std::string triple = runtimeOptions.GetTargetTriple();
191     std::string stubFile = runtimeOptions.GetStubFile();
192     size_t optLevel = runtimeOptions.GetOptLevel();
193     size_t relocMode = runtimeOptions.GetRelocMode();
194     std::string logOption = runtimeOptions.GetCompilerLogOption();
195     std::string methodsList = runtimeOptions.GetMethodsListForLog();
196     bool concurrentCompile = runtimeOptions.IsConcurrentCompile();
197 
198     panda::ecmascript::kungfu::CompilerLog logOpt(logOption);
199     panda::ecmascript::kungfu::MethodLogList logList(methodsList);
200     panda::ecmascript::kungfu::StubCompiler compiler(triple, stubFile, optLevel, relocMode, &logOpt, &logList,
201                                                      concurrentCompile);
202 
203     bool res = compiler.BuildStubModuleAndSave();
204     LOG_COMPILER(INFO) << "stub compiler run finish, result condition(T/F):" << std::boolalpha << res;
205     return res ? 0 : -1;
206 }
207