1 /*
2 * Copyright (c) 2023-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 "wrapped_module.h"
17 #include "transforms/gc_utils.h"
18
19 namespace ark::llvmbackend {
20
WrappedModule(std::unique_ptr<llvm::LLVMContext> llvmContext,std::unique_ptr<llvm::Module> module,std::unique_ptr<llvm::TargetMachine> targetMachine,std::unique_ptr<ark::llvmbackend::LLVMArkInterface> arkInterface,std::unique_ptr<ark::llvmbackend::DebugDataBuilder> debugData)21 WrappedModule::WrappedModule(std::unique_ptr<llvm::LLVMContext> llvmContext, std::unique_ptr<llvm::Module> module,
22 std::unique_ptr<llvm::TargetMachine> targetMachine,
23 std::unique_ptr<ark::llvmbackend::LLVMArkInterface> arkInterface,
24 std::unique_ptr<ark::llvmbackend::DebugDataBuilder> debugData)
25 : llvmContext_(std::move(llvmContext)),
26 module_(std::move(module)),
27 targetMachine_(std::move(targetMachine)),
28 arkInterface_(std::move(arkInterface)),
29 debugData_(std::move(debugData)),
30 codeInfoProducer_(std::make_unique<CodeInfoProducer>(arkInterface_->IsArm64() ? Arch::AARCH64 : Arch::X86_64,
31 arkInterface_.get()))
32 {
33 ASSERT(llvmContext_ != nullptr);
34 ASSERT(module_ != nullptr);
35 ASSERT(targetMachine_ != nullptr);
36 ASSERT(arkInterface_ != nullptr);
37 ASSERT(debugData_ != nullptr);
38 ASSERT(codeInfoProducer_ != nullptr);
39 }
40
AddMethod(ark::compiler::RuntimeInterface::MethodPtr method)41 void WrappedModule::AddMethod(ark::compiler::RuntimeInterface::MethodPtr method)
42 {
43 methods_.push_back(method);
44 }
45
SetCompiled(std::unique_ptr<ark::llvmbackend::CreatedObjectFile> objectFile)46 void WrappedModule::SetCompiled(std::unique_ptr<ark::llvmbackend::CreatedObjectFile> objectFile)
47 {
48 objectFile_ = std::move(objectFile);
49 #ifndef NDEBUG
50 arkInterface_->MarkAsCompiled();
51 #endif
52 module_ = nullptr;
53 debugData_ = nullptr;
54 llvmContext_ = nullptr;
55 }
56
IsCompiled()57 bool WrappedModule::IsCompiled()
58 {
59 return objectFile_ != nullptr;
60 }
61
HasFunctionDefinition(ark::compiler::RuntimeInterface::MethodPtr method)62 bool WrappedModule::HasFunctionDefinition(ark::compiler::RuntimeInterface::MethodPtr method)
63 {
64 llvm::Function *function = GetFunctionByMethodPtr(method);
65 return function != nullptr && !function->isDeclarationForLinker();
66 }
67
GetFunctionByMethodPtr(ark::compiler::RuntimeInterface::MethodPtr method)68 llvm::Function *WrappedModule::GetFunctionByMethodPtr(ark::compiler::RuntimeInterface::MethodPtr method)
69 {
70 return module_->getFunction(arkInterface_->GetUniqMethodName(method));
71 }
72
GetLLVMContext()73 const std::unique_ptr<llvm::LLVMContext> &WrappedModule::GetLLVMContext()
74 {
75 return llvmContext_;
76 }
77
GetModule()78 const std::unique_ptr<llvm::Module> &WrappedModule::GetModule()
79 {
80 return module_;
81 }
82
GetTargetMachine()83 const std::unique_ptr<llvm::TargetMachine> &WrappedModule::GetTargetMachine()
84 {
85 return targetMachine_;
86 }
87
GetLLVMArkInterface()88 const std::unique_ptr<ark::llvmbackend::LLVMArkInterface> &WrappedModule::GetLLVMArkInterface()
89 {
90 return arkInterface_;
91 }
92
GetDebugData()93 const std::unique_ptr<ark::llvmbackend::DebugDataBuilder> &WrappedModule::GetDebugData()
94 {
95 return debugData_;
96 }
97
GetCodeInfoProducer()98 const std::unique_ptr<ark::llvmbackend::CodeInfoProducer> &WrappedModule::GetCodeInfoProducer()
99 {
100 return codeInfoProducer_;
101 }
102
GetMethods()103 const std::vector<ark::compiler::RuntimeInterface::MethodPtr> &WrappedModule::GetMethods()
104 {
105 return methods_;
106 }
107
GetObjectFile()108 const std::unique_ptr<ark::llvmbackend::CreatedObjectFile> &WrappedModule::GetObjectFile()
109 {
110 return objectFile_;
111 }
112
GetModuleId()113 uint32_t WrappedModule::GetModuleId()
114 {
115 return moduleId_;
116 }
117
TakeObjectFile()118 std::unique_ptr<ark::llvmbackend::CreatedObjectFile> WrappedModule::TakeObjectFile()
119 {
120 return std::move(objectFile_);
121 }
122
Dump(llvm::raw_ostream * stream)123 void WrappedModule::Dump(llvm::raw_ostream *stream)
124 {
125 *stream << "Wrapped module:\n";
126
127 size_t inlineFunctions {0};
128 size_t functions {0};
129
130 for (const auto &function : *module_) {
131 if (function.getMetadata(LLVMArkInterface::FUNCTION_MD_INLINE_MODULE) == nullptr &&
132 !gc_utils::IsFunctionSupplemental(function)) {
133 *stream << "\tPrimary function '" << function.getName() << "'\n";
134 functions++;
135 }
136 }
137 for (const auto &function : *module_) {
138 if (function.getMetadata(LLVMArkInterface::FUNCTION_MD_INLINE_MODULE) != nullptr &&
139 !gc_utils::IsFunctionSupplemental(function)) {
140 *stream << "\tInline function '" << function.getName() << "'\n";
141 inlineFunctions++;
142 }
143 }
144
145 *stream << "\tTotal: functions = " << functions << ", inlineFunctions = " << inlineFunctions << "\n";
146 }
147
148 } // namespace ark::llvmbackend
149