1# Copyright (c) 2023-2024 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6# http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14import("//arkcompiler/runtime_core/static_core/ark_config.gni")
15import("//build/ohos.gni")
16
17if (is_llvmbackend) {
18  assert(target_cpu == "amd64" || target_cpu == "arm64" ||
19         target_cpu == "x64" || target_cpu == "x86_64")
20
21  ### LLVM
22  import("llvm.gni")
23  if (current_toolchain == host_toolchain && target_cpu == "arm64") {
24    llvm_dir = llvm_host_dir
25  } else {
26    llvm_dir = llvm_target_dir
27  }
28
29  llvm_include_dir = "$llvm_dir/include"
30  llvm_lib_file = "$llvm_dir/$llvm_lib_file_suffix"
31
32  copy("llvm_lib") {
33    sources = [ "$llvm_lib_file" ]
34    basename = get_path_info("$llvm_lib_file", "file")
35    if (ark_static_standalone_build) {
36      outputs = [ "$root_out_dir/lib/$basename" ]
37    } else {
38      outputs = [ "$root_out_dir/$ark_subsystem_name/$ark_part_name/$basename" ]
39    }
40  }
41
42  ### LLVM Backend
43  config("libllvmbackend_public_config") {
44    include_dirs = [
45      "$ark_root/libllvmbackend",
46      "$target_gen_dir",
47      llvm_include_dir,
48    ]
49
50    libs = get_target_outputs(":llvm_lib")
51  }
52
53  libllvmbackend_sources = [
54    "llvm_ark_interface.cpp",
55    "llvm_compiler.cpp",
56    "llvm_irtoc_compiler.cpp",
57    "llvm_logger.cpp",
58    "llvm_options.cpp",
59    "lowering/debug_data_builder.cpp",
60    "lowering/gc_barriers.cpp",
61    "lowering/irtoc_function_utils.cpp",
62    "lowering/llvm_ir_constructor.cpp",
63    "lowering/wrapped_module.cpp",
64    "mir_compiler.cpp",
65    "object_code/ark_aot_linker.cpp",
66    "object_code/code_info_producer.cpp",
67    "object_code/created_object_file.cpp",
68    "object_code/dump.cpp",
69    "target_machine_builder.cpp",
70    "transforms/builtins.cpp",
71    "transforms/gc_utils.cpp",
72    "transforms/llvm_optimizer.cpp",
73    "transforms/passes/aarch64_fixup_sdiv.cpp",
74    "transforms/passes/ark_frame_lowering/frame_builder.cpp",
75    "transforms/passes/ark_frame_lowering/frame_lowering.cpp",
76    "transforms/passes/ark_gvn.cpp",
77    "transforms/passes/ark_inlining.cpp",
78    "transforms/passes/check_external.cpp",
79    "transforms/passes/check_tail_calls.cpp",
80    "transforms/passes/devirt.cpp",
81    "transforms/passes/expand_atomics.cpp",
82    "transforms/passes/fixup_poisons.cpp",
83    "transforms/passes/gc_intrusion.cpp",
84    "transforms/passes/gc_intrusion_check.cpp",
85    "transforms/passes/gep_propagation.cpp",
86    "transforms/passes/infer_flags.cpp",
87    "transforms/passes/inline_devirt.cpp",
88    "transforms/passes/inline_ir/cleanup_inline_module.cpp",
89    "transforms/passes/inline_ir/discard_inline_module.cpp",
90    "transforms/passes/inline_ir/inline_ir_utils.cpp",
91    "transforms/passes/inline_ir/mark_always_inline.cpp",
92    "transforms/passes/inline_ir/mark_inline_module.cpp",
93    "transforms/passes/inline_ir/patch_return_handler_stack_adjustment.cpp",
94    "transforms/passes/inline_ir/remove_unused_functions.cpp",
95    "transforms/passes/insert_safepoints.cpp",
96    "transforms/passes/intrinsics_lowering.cpp",
97    "transforms/passes/loop_peeling.cpp",
98    "transforms/passes/mem_barriers.cpp",
99    "transforms/passes/panda_runtime_lowering.cpp",
100    "transforms/passes/propagate_lenarray.cpp",
101    "transforms/passes/prune_deopt.cpp",
102    "transforms/runtime_calls.cpp",
103    "utils.cpp",
104  ]
105
106  ohos_shared_library("libllvmbackend") {
107    defines = [ "REQUIRED_LLVM_VERSION=$llvm_version" ]
108
109    sources = libllvmbackend_sources
110
111    configs = [
112      ":libllvmbackend_public_config",
113      "$ark_root:ark_config",
114      "$ark_root/compiler/aot/aot_builder:aotbuilder_public_config",
115      "$ark_root/libpandabase:arkbase_public_config",
116      "$ark_root/libpandafile:arkfile_public_config",
117      "$ark_root/runtime:arkruntime_public_config",
118    ]
119
120    deps = [
121      ":libllvmbackend_can_compile_intrinsics_gen_inl",
122      ":libllvmbackend_emit_intrinsic_llvm_ir_constructor_gen_inl",
123      ":libllvmbackend_entrypoints_gen_inl",
124      ":libllvmbackend_entrypoints_llvm_ark_interface_gen_inl",
125      ":libllvmbackend_get_intrinsic_id_llvm_ark_interface_gen_h_inl",
126      ":libllvmbackend_get_intrinsic_id_llvm_ark_interface_gen_inl",
127      ":libllvmbackend_intrinsic_names_gen_inl",
128      ":libllvmbackend_intrinsics_gen_inl",
129      ":libllvmbackend_intrinsics_llvm_codegen_inl",
130      ":libllvmbackend_llvm_ir_constructor_gen_h_inl",
131      ":libllvmbackend_llvm_ir_constructor_gen_inl",
132      ":libllvmbackend_llvm_logger_components_inc",
133      ":libllvmbackend_llvm_options_gen_h",
134      ":libllvmbackend_llvm_passes_inl",
135      ":libllvmbackend_pipeline_gen_inc",
136      ":libllvmbackend_pipeline_irtoc_gen_inc",
137      ":llvm_lib",
138      "$ark_root/compiler:libarktscompiler",
139      "$ark_root/libpandabase:libarktsbase",
140      "$ark_root/libpandafile:libarktsfile",
141    ]
142
143    external_deps = [ sdk_libc_secshared_dep ]
144
145    if (is_llvm_aot) {
146      libllvmbackend_aot_sources = [ "llvm_aot_compiler.cpp" ]
147      sources += libllvmbackend_aot_sources
148    }
149
150    deps += [ "$ark_root/compiler/aot/aot_builder:aotbuilder" ]
151
152    part_name = ark_part_name
153    subsystem_name = ark_subsystem_name
154  }
155
156  ##### Generate
157  llvmbackend_dir = "$ark_root/libllvmbackend"
158  llvmbackend_templates_dir = "$llvmbackend_dir/templates"
159
160  intrinsics_yaml = "$target_gen_dir/../runtime/intrinsics.yaml"
161  ark_gen_file("libllvmbackend_intrinsics_gen_inl") {
162    template_file = "$llvmbackend_templates_dir/intrinsics_gen.inl.erb"
163    data = [ intrinsics_yaml ]
164    api = [ "$llvmbackend_templates_dir/intrinsics.rb" ]
165    requires = [ "$ark_root/libpandabase/utils.rb" ]
166    output_file = "$target_gen_dir/intrinsics_gen.inl"
167    extra_dependencies = [ "$ark_root/runtime:arkruntime_gen_intrinsics_yaml" ]
168  }
169
170  ark_gen_file("libllvmbackend_can_compile_intrinsics_gen_inl") {
171    template_file =
172        "$llvmbackend_templates_dir/can_compile_intrinsics_gen.inl.erb"
173    data = [ intrinsics_yaml ]
174    api = [ "$llvmbackend_templates_dir/intrinsics.rb" ]
175    requires = [ "$ark_root/libpandabase/utils.rb" ]
176    output_file = "$target_gen_dir/can_compile_intrinsics_gen.inl"
177    extra_dependencies = [ "$ark_root/runtime:arkruntime_gen_intrinsics_yaml" ]
178  }
179
180  ark_gen_file("libllvmbackend_intrinsic_names_gen_inl") {
181    template_file = "$llvmbackend_templates_dir/intrinsic_names_gen.inl.erb"
182    data = [ intrinsics_yaml ]
183    api = [ "$llvmbackend_templates_dir/intrinsics.rb" ]
184    requires = [ "$ark_root/libpandabase/utils.rb" ]
185    output_file = "$target_gen_dir/intrinsic_names_gen.inl"
186    extra_dependencies = [ "$ark_root/runtime:arkruntime_gen_intrinsics_yaml" ]
187  }
188
189  ark_gen_file("libllvmbackend_intrinsics_llvm_codegen_inl") {
190    template_file = "$llvmbackend_templates_dir/intrinsics_llvm_codegen.inl.erb"
191    data = [ intrinsics_yaml ]
192    api = [ "$llvmbackend_templates_dir/intrinsics.rb" ]
193    requires = [ "$ark_root/libpandabase/utils.rb" ]
194    output_file = "$target_gen_dir/intrinsics_llvm_codegen.inl"
195    extra_dependencies = [ "$ark_root/runtime:arkruntime_gen_intrinsics_yaml" ]
196  }
197
198  entrypoints_yaml = "$ark_root/runtime/entrypoints/entrypoints.yaml"
199  ark_gen_file("libllvmbackend_entrypoints_gen_inl") {
200    template_file = "$llvmbackend_templates_dir/entrypoints_gen.inl.erb"
201    data = [ entrypoints_yaml ]
202    api = [ "$llvmbackend_templates_dir/entrypoints.rb" ]
203    output_file = "$target_gen_dir/entrypoints_gen.inl"
204  }
205
206  ark_gen_file("libllvmbackend_entrypoints_llvm_ark_interface_gen_inl") {
207    template_file =
208        "$llvmbackend_templates_dir/entrypoints_llvm_ark_interface_gen.inl.erb"
209    data = [ entrypoints_yaml ]
210    api = [ "$llvmbackend_templates_dir/entrypoints.rb" ]
211    output_file = "$target_gen_dir/entrypoints_llvm_ark_interface_gen.inl"
212  }
213
214  ark_gen_file("libllvmbackend_llvm_passes_inl") {
215    template_file = "$llvmbackend_templates_dir/llvm_passes.inl.erb"
216    data = [ "$llvmbackend_dir/transforms/passes/passes.yaml" ]
217    api = [ "$llvmbackend_templates_dir/llvm_pass.rb" ]
218    output_file = "$target_gen_dir/llvm_passes.inl"
219  }
220
221  ark_gen_file("libllvmbackend_llvm_options_gen_h") {
222    template_file = "$ark_root/templates/options/options.h.erb"
223    data = [ "llvmbackend.yaml" ]
224    api = [ "$ark_root/templates/common.rb" ]
225    output_file = "$target_gen_dir/llvm_options_gen.h"
226  }
227
228  ark_gen_file("libllvmbackend_llvm_logger_components_inc") {
229    template_file =
230        "$ark_root/templates/logger_components/logger_components.inc.erb"
231    data = [ "llvmbackend.yaml" ]
232    api = [ "$ark_root/templates/common.rb" ]
233    output_file = "$target_gen_dir/llvm_logger_components.inc"
234  }
235
236  ark_gen_file("libllvmbackend_emit_intrinsic_llvm_ir_constructor_gen_inl") {
237    extra_dependencies = [ "$ark_root:concat_plugins_yamls" ]
238    template_file = "templates/emit_intrinsic_llvm_ir_constructor_gen.inl.erb"
239    data = [ ark_plugin_options_yaml ]
240    api = [ "$ark_root/templates/plugin_options.rb" ]
241    output_file = "$target_gen_dir/emit_intrinsic_llvm_ir_constructor_gen.inl"
242  }
243
244  ark_gen_file("libllvmbackend_llvm_ir_constructor_gen_inl") {
245    extra_dependencies = [ "$ark_root:concat_plugins_yamls" ]
246    template_file = "templates/llvm_ir_constructor_gen.inl.erb"
247    data = [ ark_plugin_options_yaml ]
248    api = [ "$ark_root/templates/plugin_options.rb" ]
249    output_file = "$target_gen_dir/llvm_ir_constructor_gen.inl"
250  }
251
252  ark_gen_file("libllvmbackend_llvm_ir_constructor_gen_h_inl") {
253    extra_dependencies = [ "$ark_root:concat_plugins_yamls" ]
254    template_file = "templates/llvm_ir_constructor_gen.h.inl.erb"
255    data = [ ark_plugin_options_yaml ]
256    api = [ "$ark_root/templates/plugin_options.rb" ]
257    output_file = "$target_gen_dir/llvm_ir_constructor_gen.h.inl"
258  }
259
260  ark_gen_file("libllvmbackend_get_intrinsic_id_llvm_ark_interface_gen_h_inl") {
261    extra_dependencies = [ "$ark_root:concat_plugins_yamls" ]
262    template_file =
263        "templates/get_intrinsic_id_llvm_ark_interface_gen.h.inl.erb"
264    data = [ ark_plugin_options_yaml ]
265    api = [ "$ark_root/templates/plugin_options.rb" ]
266    output_file =
267        "$target_gen_dir/get_intrinsic_id_llvm_ark_interface_gen.h.inl"
268  }
269
270  ark_gen_file("libllvmbackend_get_intrinsic_id_llvm_ark_interface_gen_inl") {
271    extra_dependencies = [ "$ark_root:concat_plugins_yamls" ]
272    template_file = "templates/get_intrinsic_id_llvm_ark_interface_gen.inl.erb"
273    data = [ ark_plugin_options_yaml ]
274    api = [ "$ark_root/templates/plugin_options.rb" ]
275    output_file = "$target_gen_dir/get_intrinsic_id_llvm_ark_interface_gen.inl"
276  }
277
278  action("libllvmbackend_pipeline_gen_inc") {
279    script = "$llvmbackend_templates_dir/pipeline.rb"
280    outputs = [ "$target_gen_dir/pipeline_gen.inc" ]
281    args = [
282      "-d",
283      rebase_path("$llvmbackend_dir/transforms/pipeline.cfg"),
284      "-o",
285      rebase_path("$target_gen_dir/pipeline_gen.inc"),
286    ]
287  }
288
289  ##### IRTOC
290  ohos_source_set("bitcode") {
291    cflags_cc = [
292      "-Wno-invalid-offsetof",
293      "-emit-llvm",
294      "-O1",
295      "-mllvm",
296      "-disable-llvm-optzns",
297    ]
298
299    sources = [
300      "$ark_root/runtime/class_linker.cpp",
301      "$ark_root/runtime/entrypoints/entrypoints.cpp",
302      "$ark_root/runtime/interpreter/runtime_interface.cpp",
303      "$ark_root/runtime/mem/heap_manager.cpp",
304      "$ark_root/runtime/mem/tlab.cpp",
305      "$ark_root/runtime/object_header.cpp",
306      "$ark_root/runtime/runtime.cpp",
307    ]
308
309    public_configs = [
310      "$ark_root:ark_config",
311      "$ark_root/libpandabase:arkbase_public_config",
312      "$ark_root/runtime:arkruntime_public_config",
313      "$ark_root/runtime:arkruntime_config",
314      "$ark_root/libpandafile:arkfile_public_config",
315    ]
316
317    deps = [
318      "$ark_root/compiler:libarkcompiler_intrinsics_gen_inl_intrinsics_enum_inl",
319      "$ark_root/cross_values:cross_values_getters_generate(${default_toolchain})",
320      "$ark_root/runtime:plugins_entrypoints_gen_h",
321    ]
322
323    external_deps = [ sdk_libc_secshared_dep ]
324
325    part_name = ark_part_name
326    subsystem_name = "$ark_subsystem_name"
327  }
328
329  action("irtoc_int_llvm_inl_module") {
330    if (target_cpu == "arm64") {
331      script = "$llvm_host_dir/bin/llvm-link"
332    } else {
333      script = "$llvm_dir/bin/llvm-link"
334    }
335
336    outputs = [ "$target_gen_dir/interpreter_inline.bc" ]
337    deps = [ ":bitcode" ]
338    args = [
339      rebase_path("$target_out_dir/../runtime/bitcode/runtime.o"),
340      rebase_path(
341          "$target_out_dir/../runtime/entrypoints/bitcode/entrypoints.o"),
342      rebase_path(
343          "$target_out_dir/../runtime/interpreter/bitcode/runtime_interface.o"),
344      rebase_path("$target_out_dir/../runtime/bitcode/object_header.o"),
345      rebase_path("$target_out_dir/../runtime/mem/bitcode/heap_manager.o"),
346      rebase_path("$target_out_dir/../runtime/mem/bitcode/tlab.o"),
347      rebase_path("$target_out_dir/../runtime/bitcode/class_linker.o"),
348      "-o",
349      rebase_path("$target_gen_dir/interpreter_inline.bc"),
350    ]
351  }
352
353  action("libllvmbackend_pipeline_irtoc_gen_inc") {
354    script = "$llvmbackend_templates_dir/pipeline.rb"
355    outputs = [ "$target_gen_dir/pipeline_iroc_gen.inc" ]
356    args = [
357      "-d",
358      rebase_path("$llvmbackend_dir/transforms/pipeline_irtoc.cfg"),
359      "-o",
360      rebase_path("$target_gen_dir/pipeline_irtoc_gen.inc"),
361      "-s",
362      "_IRTOC",
363    ]
364  }
365}
366