diff options
| author | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-13 19:17:09 +0800 |
|---|---|---|
| committer | Richard-Qin-X <richard.qin.001@gmail.com> | 2026-08-13 19:17:09 +0800 |
| commit | 9d1485c0dd4d071e590c18fb8aa02095de3cc830 (patch) | |
| tree | 37010bf2c65857d0d6e466ad470220d2f2ad464f | |
| parent | afce8c3e93059df6f9aab1bc57f72c83674d6d92 (diff) | |
| download | rcc-project-9d1485c0dd4d071e590c18fb8aa02095de3cc830.tar.gz rcc-project-9d1485c0dd4d071e590c18fb8aa02095de3cc830.tar.xz | |
[MIRTool] Parse LLVM code generation options
| -rw-r--r-- | backend/tools/MIRTool/MIRToolMain.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/backend/tools/MIRTool/MIRToolMain.cpp b/backend/tools/MIRTool/MIRToolMain.cpp index 500eeb2..ccc0de0 100644 --- a/backend/tools/MIRTool/MIRToolMain.cpp +++ b/backend/tools/MIRTool/MIRToolMain.cpp @@ -144,6 +144,34 @@ void printUsage(std::ostream &Output) { return std::nullopt; } +[[nodiscard]] Expected<std::optional<bool>> parseBooleanOption(std::string_view Argument, + std::string_view Name) { + const std::string LongName = + Name.starts_with('-') && !Name.starts_with("--") ? "-" + std::string(Name) : std::string(); + if (Argument == Name || (!LongName.empty() && Argument == LongName)) + return true; + const auto ParseValue = [Name](std::string_view Value) -> Expected<std::optional<bool>> { + if (Value == "true" || Value == "1") + return std::optional<bool>{true}; + if (Value == "false" || Value == "0") + return std::optional<bool>{false}; + return rcc::makeUnexpected(ErrorCode::InvalidInvocation, "command-line option '" + + std::string(Name) + + "' requires true or false"); + }; + std::string Prefix(Name); + Prefix.push_back('='); + if (Argument.starts_with(Prefix)) + return ParseValue(Argument.substr(Prefix.size())); + if (!LongName.empty()) { + std::string LongPrefix(LongName); + LongPrefix.push_back('='); + if (Argument.starts_with(LongPrefix)) + return ParseValue(Argument.substr(LongPrefix.size())); + } + return std::nullopt; +} + template <typename IntegerT> [[nodiscard]] Expected<IntegerT> parseInteger(std::string_view Text, std::string_view Description) { IntegerT Value = 0; @@ -203,6 +231,15 @@ void applyFeatureOverrides(std::vector<std::string> Overrides, std::vector<std:: std::string(Text.substr(Equal + 1U))}; } +void setBackendOption(std::vector<rcc::tooling::BackendOption> &Options, std::string Name, + std::string Value) { + const auto Existing = std::ranges::find(Options, Name, &rcc::tooling::BackendOption::Name); + if (Existing == Options.end()) + Options.push_back({std::move(Name), std::move(Value)}); + else + Existing->Value = std::move(Value); +} + [[nodiscard]] Expected<void> setOperation(CommandLine &Command, Operation Action) { if (Command.Action != Operation::Run && Command.Action != Action) { return rcc::makeUnexpected(ErrorCode::InvalidInvocation, @@ -306,6 +343,54 @@ void applyFeatureOverrides(std::vector<std::string> Overrides, std::vector<std:: continue; } + bool ParsedCompatibilityOption = false; + for (const std::string_view Name : { + std::string_view{"-disable-gisel-legality-check"}, + std::string_view{"-debugify-and-strip-all-safe"}, + std::string_view{"-mcp-use-is-copy-instr"}, + std::string_view{"-riscv-enable-cfi-instr-inserter"}, + std::string_view{"-riscv-outliner-regsave"}, + std::string_view{"-outliner-leaf-descendants"}, + std::string_view{"-function-sections"}, + }) { + auto Value = parseBooleanOption(Argument, Name); + if (!Value) + return std::unexpected(Value.error()); + if (!*Value) + continue; + setBackendOption(Command.Invocation.TargetOptions, std::string(Name.substr(1)), + **Value ? "true" : "false"); + ParsedCompatibilityOption = true; + break; + } + if (ParsedCompatibilityOption) + continue; + + auto GlobalISelAbort = + takeOption(Argument, "-global-isel-abort", Index, ArgumentCount, Arguments); + if (!GlobalISelAbort) + return std::unexpected(GlobalISelAbort.error()); + if (*GlobalISelAbort) { + if (**GlobalISelAbort != "0" && **GlobalISelAbort != "1" && **GlobalISelAbort != "2") { + return rcc::makeUnexpected(ErrorCode::InvalidInvocation, + "-global-isel-abort requires 0, 1, or 2"); + } + setBackendOption(Command.Invocation.TargetOptions, "global-isel-abort", + std::string(**GlobalISelAbort)); + continue; + } + auto DebugOnly = takeOption(Argument, "-debug-only", Index, ArgumentCount, Arguments); + if (!DebugOnly) + return std::unexpected(DebugOnly.error()); + if (*DebugOnly) { + if ((**DebugOnly).empty()) { + return rcc::makeUnexpected(ErrorCode::InvalidInvocation, + "-debug-only requires a nonempty debug type"); + } + setBackendOption(Command.Invocation.TargetOptions, "debug-only", std::string(**DebugOnly)); + continue; + } + auto Output = takeOption(Argument, "-o", Index, ArgumentCount, Arguments); if (!Output) return std::unexpected(Output.error()); |
