/src/WasmEdge/lib/driver/compilerTool.cpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // SPDX-FileCopyrightText: Copyright The WasmEdge Authors |
3 | | |
4 | | #include "common/configure.h" |
5 | | #include "common/defines.h" |
6 | | #include "common/filesystem.h" |
7 | | #include "common/spdlog.h" |
8 | | #include "common/version.h" |
9 | | #include "driver/compiler.h" |
10 | | #include "driver/options.h" |
11 | | #include "loader/loader.h" |
12 | | #include "validator/validator.h" |
13 | | #include "llvm/codegen.h" |
14 | | #include "llvm/compiler.h" |
15 | | #include <algorithm> |
16 | | #include <array> |
17 | | #include <cstdint> |
18 | | #include <cstdlib> |
19 | | #include <memory> |
20 | | #include <string> |
21 | | #include <string_view> |
22 | | #include <utility> |
23 | | #include <vector> |
24 | | |
25 | | namespace WasmEdge { |
26 | | namespace Driver { |
27 | | |
28 | | #ifdef WASMEDGE_USE_LLVM |
29 | | int compileModule(const Configure &Conf, Span<const Byte> Data, |
30 | 9.37k | const std::filesystem::path &OutputPath) noexcept { |
31 | 9.37k | using namespace std::literals; |
32 | | |
33 | 9.37k | Loader::Loader Loader(Conf); |
34 | 9.37k | std::unique_ptr<AST::Module> Module; |
35 | 9.37k | if (auto Res = Loader.parseModule(Data)) { |
36 | 4.33k | Module = std::move(*Res); |
37 | 5.04k | } else { |
38 | 5.04k | const auto Err = static_cast<uint32_t>(Res.error()); |
39 | 5.04k | spdlog::error("Parse Module failed. Error code: {}"sv, Err); |
40 | 5.04k | return EXIT_FAILURE; |
41 | 5.04k | } |
42 | | |
43 | 4.33k | { |
44 | 4.33k | Validator::Validator ValidatorEngine(Conf); |
45 | 4.33k | if (auto Res = ValidatorEngine.validate(*Module); !Res) { |
46 | 1.97k | const auto Err = static_cast<uint32_t>(Res.error()); |
47 | 1.97k | spdlog::error("Validate Module failed. Error code: {}"sv, Err); |
48 | 1.97k | return EXIT_FAILURE; |
49 | 1.97k | } |
50 | 4.33k | } |
51 | | |
52 | 2.35k | LLVM::Compiler Compiler(Conf); |
53 | 2.35k | if (auto Res = Compiler.checkConfigure(); !Res) { |
54 | 0 | const auto Err = static_cast<uint32_t>(Res.error()); |
55 | 0 | spdlog::error("Compiler Configure failed. Error code: {}"sv, Err); |
56 | 0 | return EXIT_FAILURE; |
57 | 0 | } |
58 | 2.35k | LLVM::CodeGen CodeGen(Conf); |
59 | 2.35k | if (auto Res = Compiler.compile(*Module); !Res) { |
60 | 2 | const auto Err = static_cast<uint32_t>(Res.error()); |
61 | 2 | spdlog::error("Compilation failed. Error code: {}"sv, Err); |
62 | 2 | return EXIT_FAILURE; |
63 | 2.35k | } else if (auto Res2 = CodeGen.codegen(Data, std::move(*Res), OutputPath); |
64 | 2.35k | !Res2) { |
65 | 0 | const auto Err = static_cast<uint32_t>(Res2.error()); |
66 | 0 | spdlog::error("Code Generation failed. Error code: {}"sv, Err); |
67 | 0 | return EXIT_FAILURE; |
68 | 0 | } |
69 | | |
70 | 2.35k | return EXIT_SUCCESS; |
71 | 2.35k | } |
72 | | #endif |
73 | | |
74 | 0 | int Compiler([[maybe_unused]] struct DriverCompilerOptions &Opt) noexcept { |
75 | 0 | using namespace std::literals; |
76 | |
|
77 | 0 | std::ios::sync_with_stdio(false); |
78 | 0 | setLoggingLevel(Opt); |
79 | |
|
80 | 0 | #ifdef WASMEDGE_USE_LLVM |
81 | |
|
82 | 0 | Configure Conf = createProposalConfigure(Opt); |
83 | |
|
84 | 0 | using OptimizationLevel = CompilerConfigure::OptimizationLevel; |
85 | 0 | static const std::array<std::pair<std::string_view, OptimizationLevel>, 6> |
86 | 0 | OptimizationLevels{{{"0"sv, OptimizationLevel::O0}, |
87 | 0 | {"1"sv, OptimizationLevel::O1}, |
88 | 0 | {"2"sv, OptimizationLevel::O2}, |
89 | 0 | {"3"sv, OptimizationLevel::O3}, |
90 | 0 | {"s"sv, OptimizationLevel::Os}, |
91 | 0 | {"z"sv, OptimizationLevel::Oz}}}; |
92 | 0 | const auto Level = |
93 | 0 | std::find_if(OptimizationLevels.begin(), OptimizationLevels.end(), |
94 | 0 | [&Opt](const auto &L) { |
95 | 0 | return L.first == Opt.PropOptimizationLevel.value(); |
96 | 0 | }); |
97 | 0 | if (Level != OptimizationLevels.end()) { |
98 | 0 | Conf.getCompilerConfigure().setOptimizationLevel(Level->second); |
99 | 0 | } else { |
100 | 0 | spdlog::warn("Unknown --optimize value: \"{}\"; using 2. Valid values: 0, " |
101 | 0 | "1, 2, 3, s, z."sv, |
102 | 0 | Opt.PropOptimizationLevel.value()); |
103 | 0 | Conf.getCompilerConfigure().setOptimizationLevel(OptimizationLevel::O2); |
104 | 0 | } |
105 | | |
106 | | // Set interpreter run mode here so the loader reads function bodies fully |
107 | | // (the AOT compiler needs the parsed instructions, not AOT symbols). |
108 | 0 | Conf.getRuntimeConfigure().setRunMode(WasmEdge::RunMode::Interpreter); |
109 | |
|
110 | 0 | const auto InputPath = |
111 | 0 | getAbsolutePath(Opt.WasmName.value(), "input wasm file"sv); |
112 | 0 | const auto OutputPath = getAbsolutePath(Opt.SoName.value(), "output file"sv); |
113 | 0 | if (!InputPath || !OutputPath) { |
114 | 0 | return EXIT_FAILURE; |
115 | 0 | } |
116 | | |
117 | 0 | std::vector<Byte> Data; |
118 | 0 | if (auto Res = Loader::Loader(Conf).loadFile(*InputPath)) { |
119 | 0 | Data = std::move(*Res); |
120 | 0 | } else { |
121 | 0 | const auto Err = static_cast<uint32_t>(Res.error()); |
122 | 0 | spdlog::error("Load failed. Error code: {}"sv, Err); |
123 | 0 | return EXIT_FAILURE; |
124 | 0 | } |
125 | | |
126 | 0 | if (Opt.ConfDumpIR.value()) { |
127 | 0 | Conf.getCompilerConfigure().setDumpIR(true); |
128 | 0 | } |
129 | 0 | if (Opt.ConfInterruptible.value()) { |
130 | 0 | Conf.getCompilerConfigure().setInterruptible(true); |
131 | 0 | } |
132 | 0 | setStatisticsConfigure(Opt, Conf); |
133 | 0 | if (Opt.ConfGenericBinary.value()) { |
134 | 0 | Conf.getCompilerConfigure().setGenericBinary(true); |
135 | 0 | } |
136 | 0 | if (u8string(OutputPath->extension()) == WASMEDGE_LIB_EXTENSION) { |
137 | 0 | Conf.getCompilerConfigure().setOutputFormat( |
138 | 0 | CompilerConfigure::OutputFormat::Native); |
139 | 0 | } |
140 | |
|
141 | 0 | return compileModule(Conf, Data, *OutputPath); |
142 | | #else |
143 | | spdlog::error("Compilation is not supported!"sv); |
144 | | |
145 | | return EXIT_FAILURE; |
146 | | #endif |
147 | 0 | } |
148 | | |
149 | | } // namespace Driver |
150 | | } // namespace WasmEdge |