From 09e8ef3e0dae29be7aa21a6e22a118a3f545945f Mon Sep 17 00:00:00 2001 From: Richard-Qin-X Date: Wed, 12 Aug 2026 19:45:09 +0800 Subject: [Tooling] Complete the LLVM MIR command-line contract --- backend/tools/MIRTool/MIRToolMain.cpp | 221 ++++++++++++++++++++-------------- 1 file changed, 128 insertions(+), 93 deletions(-) (limited to 'backend/tools/MIRTool/MIRToolMain.cpp') diff --git a/backend/tools/MIRTool/MIRToolMain.cpp b/backend/tools/MIRTool/MIRToolMain.cpp index ea180d6..2c0fe8d 100644 --- a/backend/tools/MIRTool/MIRToolMain.cpp +++ b/backend/tools/MIRTool/MIRToolMain.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later +#include "rcc/CodeGen/CommandFlags.h" #include "rcc/CodeGen/MachineFunction.h" #include "rcc/Support/Error.h" #include "rcc/Target/RISCV/RISCVPipeline.h" @@ -68,6 +69,7 @@ struct CommandLine final { rcc::tooling::PipelineControls Controls; rcc::tooling::MIRFuzzOptions FuzzOptions; bool OutputWasSpecified = false; + bool DiscardOutput = false; bool PrintActions = false; bool ShowHelp = false; }; @@ -83,14 +85,16 @@ void printUsage(std::ostream &Output) { "pipeline/output:\n" " -run-pass Run one named pass\n" " -passes Run an explicit pass sequence\n" - " -stop-before Stop before a pass occurrence\n" - " -stop-after Stop after a pass occurrence\n" - " -print-before Print snapshots before passes\n" - " -print-after Print snapshots after passes\n" + " -start-before Start before a pass instance\n" + " -start-after Start after a pass instance\n" + " -stop-before Stop before a pass instance\n" + " -stop-after Stop after a pass instance\n" + " -print-before Print snapshots before passes\n" + " -print-after Print snapshots after passes\n" " -simplify-mir Omit default-valued MIR fields\n" " -verify-machineinstrs Verify each machine pass result\n" " --stage-snapshots Print every stage boundary\n" - " --emit Select the output artifact\n" + " -filetype Select the output artifact\n" " -o Select the output path\n" "reproduction/cache/fuzz:\n" " --crash-reproducer Save input and manifest before execution\n" @@ -118,7 +122,9 @@ void printUsage(std::ostream &Output) { std::string_view Name, int &Index, int ArgumentCount, char *Arguments[]) { - if (Argument == Name) { + const std::string LongName = + Name.starts_with('-') && !Name.starts_with("--") ? "-" + std::string(Name) : std::string(); + if (Argument == Name || (!LongName.empty() && Argument == LongName)) { if (Index + 1 >= ArgumentCount) { return rcc::makeUnexpected(ErrorCode::InvalidInvocation, "missing value for command-line option '" + std::string(Name) + @@ -130,6 +136,12 @@ void printUsage(std::ostream &Output) { Prefix.push_back('='); if (Argument.starts_with(Prefix)) return Argument.substr(Prefix.size()); + if (!LongName.empty()) { + std::string LongPrefix(LongName); + LongPrefix.push_back('='); + if (Argument.starts_with(LongPrefix)) + return Argument.substr(LongPrefix.size()); + } return std::nullopt; } @@ -237,6 +249,13 @@ void applyFeatureOverrides(std::vector Overrides, std::vector parseCommandLine(int ArgumentCount, char *Arguments[]) { CommandLine Command; bool ExplicitPipeline = false; + bool UsedRunPass = false; + bool UsedPasses = false; + rcc::CodeGenCommandFlags CodeGenFlags; + std::vector ArgumentViews; + ArgumentViews.reserve(static_cast(ArgumentCount)); + for (int Index = 0; Index < ArgumentCount; ++Index) + ArgumentViews.emplace_back(Arguments[Index]); for (int Index = 1; Index < ArgumentCount; ++Index) { const std::string_view Argument(Arguments[Index]); if (Argument == "--help" || Argument == "-h") { @@ -259,11 +278,11 @@ void applyFeatureOverrides(std::vector Overrides, std::vector Overrides, std::vector(Index); + auto CodeGenFlag = rcc::parseCodeGenCommandFlag(ArgumentViews, CodeGenIndex, CodeGenFlags); + if (!CodeGenFlag) + return std::unexpected(CodeGenFlag.error()); + if (*CodeGenFlag) { + Index = static_cast(CodeGenIndex); continue; } - auto Input = takeOption(Argument, "--input", Index, ArgumentCount, Arguments); - if (!Input) - return std::unexpected(Input.error()); - if (*Input) { - if (!Command.InputPath.empty()) - return rcc::makeUnexpected(ErrorCode::InvalidInvocation, "input path is specified twice"); - Command.InputPath = std::string(**Input); - continue; - } auto Output = takeOption(Argument, "-o", Index, ArgumentCount, Arguments); if (!Output) return std::unexpected(Output.error()); @@ -305,25 +315,22 @@ void applyFeatureOverrides(std::vector Overrides, std::vectorbegin()), + std::make_move_iterator(Names->end())); + UsedRunPass = true; ExplicitPipeline = true; continue; } @@ -331,13 +338,14 @@ void applyFeatureOverrides(std::vector Overrides, std::vector Overrides, std::vector &Destination) -> Expected { @@ -515,28 +543,6 @@ void applyFeatureOverrides(std::vector Overrides, std::vector Overrides, std::vector Overrides, std::vector Overrides, std::vector outputFromArtifact(ArtifactKind Artifact) { - const auto Value = static_cast(static_cast(Artifact)); - if (rcc::tooling::spelling(Value) == "invalid") - return rcc::makeUnexpected(ErrorCode::ReproducerError, "invalid reproducer artifact kind"); - return Value; + switch (Artifact) { + case ArtifactKind::PreLegalizerMIR: + return BackendOutputKind::PreLegalizerMIR; + case ArtifactKind::LegalizedMIR: + return BackendOutputKind::LegalizedMIR; + case ArtifactKind::RegisterBankMIR: + return BackendOutputKind::RegisterBankMIR; + case ArtifactKind::SelectedMIR: + return BackendOutputKind::SelectedMIR; + case ArtifactKind::PostSSAMIR: + return BackendOutputKind::PostSSAMIR; + case ArtifactKind::PostRegisterAllocationMIR: + return BackendOutputKind::PostRegisterAllocationMIR; + case ArtifactKind::FinalMIR: + return BackendOutputKind::FinalMIR; + case ArtifactKind::Assembly: + return BackendOutputKind::Assembly; + case ArtifactKind::RelocatableObject: + return BackendOutputKind::RelocatableObject; + } + return rcc::makeUnexpected(ErrorCode::ReproducerError, "invalid reproducer artifact kind"); } void printSnapshots(const BackendRunResult &Result) { @@ -996,6 +1029,8 @@ runWithCache(const CommandLine &Command, CanonicalMIR Input, const rcc::TargetDe printSnapshots(*Run); if (Command.PrintActions) printActions(*Run); + if (Command.DiscardOutput) + return {}; return writeOutput(Command.OutputPath, Run->Output); } -- cgit v1.2.3