aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 13:29:50 +0800
committerRichard-Qin-X <richard.qin.001@gmail.com>2026-08-13 13:29:50 +0800
commit175fdbf4b30eae5e5344cd7fca7e953ca0b2463e (patch)
tree58a62baae7795d8d3c3da4cfbf54dbe4bef8d523
parent393e95fb39d1ddb366b1f17a51166cb3612bbbbd (diff)
downloadrcc-project-175fdbf4b30eae5e5344cd7fca7e953ca0b2463e.tar.gz
rcc-project-175fdbf4b30eae5e5344cd7fca7e953ca0b2463e.tar.xz
[Tooling] Remove the duplicate output kind
-rw-r--r--backend/include/rcc/Tooling/ArtifactStore.h3
-rw-r--r--backend/include/rcc/Tooling/BackendDriver.h20
-rw-r--r--backend/include/rcc/Tooling/PipelineDriver.h1
-rw-r--r--backend/lib/Tooling/ArtifactStore.cpp8
-rw-r--r--backend/lib/Tooling/BackendDriver.cpp113
-rw-r--r--backend/lib/Tooling/MIRFuzzer.cpp35
-rw-r--r--backend/lib/Tooling/PipelineDriver.cpp28
-rw-r--r--backend/tools/MIRTool/MIRToolMain.cpp55
-rw-r--r--backend/unittests/Tooling/MIRReducerFuzzerTest.cpp4
-rw-r--r--backend/unittests/Tooling/PipelineDriverTest.cpp43
10 files changed, 108 insertions, 202 deletions
diff --git a/backend/include/rcc/Tooling/ArtifactStore.h b/backend/include/rcc/Tooling/ArtifactStore.h
index f11cd6c..e4bca4c 100644
--- a/backend/include/rcc/Tooling/ArtifactStore.h
+++ b/backend/include/rcc/Tooling/ArtifactStore.h
@@ -37,6 +37,9 @@ struct ReproducerPackage final {
CanonicalMIR Input;
};
+[[nodiscard]] bool isMIRArtifact(ArtifactKind Artifact) noexcept;
+[[nodiscard]] bool isCacheableArtifact(ArtifactKind Artifact) noexcept;
+
[[nodiscard]] Expected<CanonicalMIR> parseAndCanonicalizeMIR(std::string SourceName,
std::string SourceText,
const TargetDescription &Target,
diff --git a/backend/include/rcc/Tooling/BackendDriver.h b/backend/include/rcc/Tooling/BackendDriver.h
index 6b04de9..8117a0c 100644
--- a/backend/include/rcc/Tooling/BackendDriver.h
+++ b/backend/include/rcc/Tooling/BackendDriver.h
@@ -19,20 +19,8 @@ class TargetDescription;
namespace tooling {
-enum class BackendOutputKind : std::uint8_t {
- PreLegalizerMIR,
- LegalizedMIR,
- RegisterBankMIR,
- SelectedMIR,
- PostSSAMIR,
- PostRegisterAllocationMIR,
- FinalMIR,
- Assembly,
- RelocatableObject,
-};
-
struct BackendRunResult final {
- BackendOutputKind Kind = BackendOutputKind::FinalMIR;
+ ArtifactKind Kind = ArtifactKind::FinalMIR;
std::vector<std::uint8_t> Output;
PipelineRunResult Pipeline;
std::vector<MachineActionEvent> Actions;
@@ -42,13 +30,9 @@ struct BackendRunResult final {
[[nodiscard]] Expected<BackendRunResult>
runBackend(CanonicalMIR Input, const TargetDescription &Target, const BackendInvocation &Invocation,
- BackendOutputKind Output, PipelineControls Controls = {},
+ ArtifactKind Output, PipelineControls Controls = {},
MachinePassInstrumentation *Instrumentation = nullptr);
-[[nodiscard]] std::string_view spelling(BackendOutputKind Output) noexcept;
-[[nodiscard]] ArtifactKind manifestArtifactKind(BackendOutputKind Output) noexcept;
-[[nodiscard]] Expected<ArtifactKind> cacheArtifactKind(BackendOutputKind Output);
-
} // namespace tooling
} // namespace rcc
diff --git a/backend/include/rcc/Tooling/PipelineDriver.h b/backend/include/rcc/Tooling/PipelineDriver.h
index 5fa4fba..d10fe4d 100644
--- a/backend/include/rcc/Tooling/PipelineDriver.h
+++ b/backend/include/rcc/Tooling/PipelineDriver.h
@@ -77,6 +77,7 @@ runRV64GCPipeline(mir::MIRDocument &Document, const TargetDescription &Target,
const BackendInvocation &Invocation, PipelineControls Controls = {},
MachinePassInstrumentation *Instrumentation = nullptr);
[[nodiscard]] BackendStage stageForFunction(const MachineFunction &Function) noexcept;
+[[nodiscard]] bool isEarlierStage(BackendStage Left, BackendStage Right) noexcept;
[[nodiscard]] std::string_view spelling(BackendStage Stage) noexcept;
[[nodiscard]] Expected<BackendStage> parseBackendStage(std::string_view Value);
diff --git a/backend/lib/Tooling/ArtifactStore.cpp b/backend/lib/Tooling/ArtifactStore.cpp
index 115f58f..9427a6b 100644
--- a/backend/lib/Tooling/ArtifactStore.cpp
+++ b/backend/lib/Tooling/ArtifactStore.cpp
@@ -32,7 +32,9 @@ namespace {
constexpr std::uintmax_t MaximumPackageFileSize = std::uintmax_t{1} << 30U;
std::atomic<std::uint64_t> TemporarySequence = 0;
-[[nodiscard]] bool isMIRArtifact(ArtifactKind Artifact) noexcept {
+} // namespace
+
+bool isMIRArtifact(ArtifactKind Artifact) noexcept {
switch (Artifact) {
case ArtifactKind::PreLegalizerMIR:
case ArtifactKind::LegalizedMIR:
@@ -49,7 +51,7 @@ std::atomic<std::uint64_t> TemporarySequence = 0;
return false;
}
-[[nodiscard]] bool isCacheableArtifact(ArtifactKind Artifact) noexcept {
+bool isCacheableArtifact(ArtifactKind Artifact) noexcept {
switch (Artifact) {
case ArtifactKind::PreLegalizerMIR:
case ArtifactKind::SelectedMIR:
@@ -66,6 +68,8 @@ std::atomic<std::uint64_t> TemporarySequence = 0;
return false;
}
+namespace {
+
[[nodiscard]] std::string_view artifactFileName(ArtifactKind Artifact) noexcept {
switch (Artifact) {
case ArtifactKind::PreLegalizerMIR:
diff --git a/backend/lib/Tooling/BackendDriver.cpp b/backend/lib/Tooling/BackendDriver.cpp
index 0402f5a..fa82c0c 100644
--- a/backend/lib/Tooling/BackendDriver.cpp
+++ b/backend/lib/Tooling/BackendDriver.cpp
@@ -17,36 +17,28 @@
namespace rcc::tooling {
namespace {
-[[nodiscard]] bool isMIR(BackendOutputKind Output) noexcept {
- return Output <= BackendOutputKind::FinalMIR;
-}
-
-[[nodiscard]] BackendStage outputStage(BackendOutputKind Output) noexcept {
+[[nodiscard]] BackendStage outputStage(ArtifactKind Output) noexcept {
switch (Output) {
- case BackendOutputKind::PreLegalizerMIR:
+ case ArtifactKind::PreLegalizerMIR:
return BackendStage::PreLegalizerMIR;
- case BackendOutputKind::LegalizedMIR:
+ case ArtifactKind::LegalizedMIR:
return BackendStage::LegalizedMIR;
- case BackendOutputKind::RegisterBankMIR:
+ case ArtifactKind::RegisterBankMIR:
return BackendStage::RegisterBankMIR;
- case BackendOutputKind::SelectedMIR:
+ case ArtifactKind::SelectedMIR:
return BackendStage::SelectedMIR;
- case BackendOutputKind::PostSSAMIR:
+ case ArtifactKind::PostSSAMIR:
return BackendStage::PostSSAMIR;
- case BackendOutputKind::PostRegisterAllocationMIR:
+ case ArtifactKind::PostRegisterAllocationMIR:
return BackendStage::PostRegisterAllocationMIR;
- case BackendOutputKind::FinalMIR:
- case BackendOutputKind::Assembly:
- case BackendOutputKind::RelocatableObject:
+ case ArtifactKind::FinalMIR:
+ case ArtifactKind::Assembly:
+ case ArtifactKind::RelocatableObject:
return BackendStage::FinalMIR;
}
return BackendStage::FinalMIR;
}
-[[nodiscard]] std::uint8_t ordinal(BackendStage Stage) noexcept {
- return static_cast<std::uint8_t>(Stage);
-}
-
[[nodiscard]] Expected<std::vector<std::uint8_t>> printMIR(const mir::MIRDocument &Document,
const TargetDescription &Target,
const BackendInvocation &Invocation,
@@ -64,13 +56,13 @@ namespace {
} // namespace
std::string_view BackendRunResult::text() const noexcept {
- if (Kind == BackendOutputKind::RelocatableObject || Output.empty())
+ if (Kind == ArtifactKind::RelocatableObject || Output.empty())
return {};
return {reinterpret_cast<const char *>(Output.data()), Output.size()};
}
Expected<BackendRunResult> runBackend(CanonicalMIR Input, const TargetDescription &Target,
- const BackendInvocation &Invocation, BackendOutputKind Output,
+ const BackendInvocation &Invocation, ArtifactKind Output,
PipelineControls Controls,
MachinePassInstrumentation *Instrumentation) {
auto InvocationVerification = verifyRV64GCInvocation(Invocation);
@@ -87,16 +79,16 @@ Expected<BackendRunResult> runBackend(CanonicalMIR Input, const TargetDescriptio
if (Function == nullptr)
return makeUnexpected(ErrorCode::InternalError, "backend input contains a null function");
const BackendStage Stage = stageForFunction(*Function);
- if (Index == 0 || ordinal(Stage) < ordinal(InitialStage))
+ if (Index == 0 || isEarlierStage(Stage, InitialStage))
InitialStage = Stage;
}
const BackendStage RequiredStage = outputStage(Output);
- if (isMIR(Output) && ordinal(RequiredStage) < ordinal(InitialStage)) {
+ if (isMIRArtifact(Output) && isEarlierStage(RequiredStage, InitialStage)) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"backend cannot reconstruct an earlier MIR stage from a later snapshot");
}
- if (isMIR(Output)) {
+ if (isMIRArtifact(Output)) {
if (Controls.StopAtStage && *Controls.StopAtStage != RequiredStage) {
return makeUnexpected(ErrorCode::InvalidInvocation,
"output stage conflicts with the explicit pipeline stop stage");
@@ -115,12 +107,12 @@ Expected<BackendRunResult> runBackend(CanonicalMIR Input, const TargetDescriptio
return std::unexpected(Pipeline.error());
std::vector<std::uint8_t> Bytes;
- if (isMIR(Output)) {
+ if (isMIRArtifact(Output)) {
auto Printed = printMIR(Input.Document, Target, Invocation, SimplifyMIR);
if (!Printed)
return std::unexpected(Printed.error());
Bytes = std::move(*Printed);
- } else if (Output == BackendOutputKind::Assembly) {
+ } else if (Output == ArtifactKind::Assembly) {
auto Assembly = riscv::emitAssembly(Input.Document.unit(), Target);
if (!Assembly)
return std::unexpected(Assembly.error());
@@ -140,75 +132,4 @@ Expected<BackendRunResult> runBackend(CanonicalMIR Input, const TargetDescriptio
};
}
-std::string_view spelling(BackendOutputKind Output) noexcept {
- switch (Output) {
- case BackendOutputKind::PreLegalizerMIR:
- return "prelegalizer-mir";
- case BackendOutputKind::LegalizedMIR:
- return "legalized-mir";
- case BackendOutputKind::RegisterBankMIR:
- return "regbank-mir";
- case BackendOutputKind::SelectedMIR:
- return "selected-mir";
- case BackendOutputKind::PostSSAMIR:
- return "post-ssa-mir";
- case BackendOutputKind::PostRegisterAllocationMIR:
- return "post-ra-mir";
- case BackendOutputKind::FinalMIR:
- return "final-mir";
- case BackendOutputKind::Assembly:
- return "assembly";
- case BackendOutputKind::RelocatableObject:
- return "object";
- }
- return "invalid";
-}
-
-ArtifactKind manifestArtifactKind(BackendOutputKind Output) noexcept {
- switch (Output) {
- case BackendOutputKind::PreLegalizerMIR:
- return ArtifactKind::PreLegalizerMIR;
- case BackendOutputKind::LegalizedMIR:
- return ArtifactKind::LegalizedMIR;
- case BackendOutputKind::RegisterBankMIR:
- return ArtifactKind::RegisterBankMIR;
- case BackendOutputKind::SelectedMIR:
- return ArtifactKind::SelectedMIR;
- case BackendOutputKind::PostSSAMIR:
- return ArtifactKind::PostSSAMIR;
- case BackendOutputKind::PostRegisterAllocationMIR:
- return ArtifactKind::PostRegisterAllocationMIR;
- case BackendOutputKind::FinalMIR:
- return ArtifactKind::FinalMIR;
- case BackendOutputKind::Assembly:
- return ArtifactKind::Assembly;
- case BackendOutputKind::RelocatableObject:
- return ArtifactKind::RelocatableObject;
- }
- return ArtifactKind::FinalMIR;
-}
-
-Expected<ArtifactKind> cacheArtifactKind(BackendOutputKind Output) {
- switch (Output) {
- case BackendOutputKind::PreLegalizerMIR:
- return ArtifactKind::PreLegalizerMIR;
- case BackendOutputKind::SelectedMIR:
- return ArtifactKind::SelectedMIR;
- case BackendOutputKind::PostRegisterAllocationMIR:
- return ArtifactKind::PostRegisterAllocationMIR;
- case BackendOutputKind::FinalMIR:
- return ArtifactKind::FinalMIR;
- case BackendOutputKind::Assembly:
- return ArtifactKind::Assembly;
- case BackendOutputKind::RelocatableObject:
- return ArtifactKind::RelocatableObject;
- case BackendOutputKind::LegalizedMIR:
- case BackendOutputKind::RegisterBankMIR:
- case BackendOutputKind::PostSSAMIR:
- return makeUnexpected(ErrorCode::InvalidInvocation,
- "the selected intermediate stage is not a cache boundary");
- }
- return makeUnexpected(ErrorCode::InvalidInvocation, "invalid backend output kind");
-}
-
} // namespace rcc::tooling
diff --git a/backend/lib/Tooling/MIRFuzzer.cpp b/backend/lib/Tooling/MIRFuzzer.cpp
index 83762c4..467291c 100644
--- a/backend/lib/Tooling/MIRFuzzer.cpp
+++ b/backend/lib/Tooling/MIRFuzzer.cpp
@@ -224,24 +224,24 @@ private:
return true;
}
-[[nodiscard]] BackendOutputKind outputForStage(BackendStage Stage) noexcept {
+[[nodiscard]] ArtifactKind outputForStage(BackendStage Stage) noexcept {
switch (Stage) {
case BackendStage::PreLegalizerMIR:
- return BackendOutputKind::PreLegalizerMIR;
+ return ArtifactKind::PreLegalizerMIR;
case BackendStage::LegalizedMIR:
- return BackendOutputKind::LegalizedMIR;
+ return ArtifactKind::LegalizedMIR;
case BackendStage::RegisterBankMIR:
- return BackendOutputKind::RegisterBankMIR;
+ return ArtifactKind::RegisterBankMIR;
case BackendStage::SelectedMIR:
- return BackendOutputKind::SelectedMIR;
+ return ArtifactKind::SelectedMIR;
case BackendStage::PostSSAMIR:
- return BackendOutputKind::PostSSAMIR;
+ return ArtifactKind::PostSSAMIR;
case BackendStage::PostRegisterAllocationMIR:
- return BackendOutputKind::PostRegisterAllocationMIR;
+ return ArtifactKind::PostRegisterAllocationMIR;
case BackendStage::FinalMIR:
- return BackendOutputKind::FinalMIR;
+ return ArtifactKind::FinalMIR;
}
- return BackendOutputKind::FinalMIR;
+ return ArtifactKind::FinalMIR;
}
[[nodiscard]] Expected<bool> propertyCase(std::string_view Canonical, DeterministicRandom &Random,
@@ -251,10 +251,15 @@ private:
parseAndCanonicalizeMIR("property-fuzz.mir", std::string(Canonical), Target, Invocation);
if (!Parsed)
return std::unexpected(Parsed.error());
- const auto Stage = static_cast<BackendStage>(Random.index(7U));
+ constexpr std::array Stages{
+ BackendStage::PreLegalizerMIR, BackendStage::LegalizedMIR,
+ BackendStage::RegisterBankMIR, BackendStage::SelectedMIR,
+ BackendStage::PostSSAMIR, BackendStage::PostRegisterAllocationMIR,
+ BackendStage::FinalMIR,
+ };
+ const BackendStage Stage = Stages[Random.index(Stages.size())];
const MachineFunction *Function = Parsed->Document.unit().functionAt(0);
- if (Function == nullptr ||
- static_cast<std::uint8_t>(Stage) < static_cast<std::uint8_t>(stageForFunction(*Function))) {
+ if (Function == nullptr || isEarlierStage(Stage, stageForFunction(*Function))) {
return false;
}
auto Run = runBackend(std::move(*Parsed), Target, Invocation, outputForStage(Stage));
@@ -304,8 +309,7 @@ private:
Controls.DetectUnreportedChanges = true;
Invocation.Determinism.ThreadCount = std::array<std::uint32_t, 3>{1, 2, 4}[Random.index(3U)];
const std::string Stop = Controls.StopAfter ? *Controls.StopAfter : "end";
- auto Run =
- runBackend(std::move(*Parsed), Target, Invocation, BackendOutputKind::FinalMIR, Controls);
+ auto Run = runBackend(std::move(*Parsed), Target, Invocation, ArtifactKind::FinalMIR, Controls);
if (!Run)
return std::unexpected(Run.error());
auto RoundTrip = verifyCanonicalRoundTrip(std::string(Run->text()), Target, Invocation);
@@ -479,8 +483,7 @@ using RegisterValues = std::unordered_map<std::uint64_t, std::uint64_t>;
parseAndCanonicalizeMIR("semantic-pipeline.mir", std::string(Canonical), Target, Invocation);
if (!CompiledInput)
return std::unexpected(CompiledInput.error());
- auto Compiled =
- runBackend(std::move(*CompiledInput), Target, Invocation, BackendOutputKind::FinalMIR);
+ auto Compiled = runBackend(std::move(*CompiledInput), Target, Invocation, ArtifactKind::FinalMIR);
if (!Compiled)
return std::unexpected(Compiled.error());
auto Final = parseAndCanonicalizeMIR("semantic-final.mir", std::string(Compiled->text()), Target,
diff --git a/backend/lib/Tooling/PipelineDriver.cpp b/backend/lib/Tooling/PipelineDriver.cpp
index 68cbb57..1a584f7 100644
--- a/backend/lib/Tooling/PipelineDriver.cpp
+++ b/backend/lib/Tooling/PipelineDriver.cpp
@@ -34,8 +34,24 @@ struct FunctionRunResult final {
std::optional<Error> Failure;
};
-[[nodiscard]] unsigned stageOrdinal(BackendStage Stage) noexcept {
- return static_cast<unsigned>(Stage);
+[[nodiscard]] std::uint8_t stageRank(BackendStage Stage) noexcept {
+ switch (Stage) {
+ case BackendStage::PreLegalizerMIR:
+ return 0;
+ case BackendStage::LegalizedMIR:
+ return 1;
+ case BackendStage::RegisterBankMIR:
+ return 2;
+ case BackendStage::SelectedMIR:
+ return 3;
+ case BackendStage::PostSSAMIR:
+ return 4;
+ case BackendStage::PostRegisterAllocationMIR:
+ return 5;
+ case BackendStage::FinalMIR:
+ return 6;
+ }
+ return 0;
}
[[nodiscard]] bool selectorMatches(std::string_view Selector, std::string_view Pass,
@@ -224,7 +240,7 @@ runFunction(MachineFunction &Function, mir::MIRDocument &Document, const TargetD
if (!Captured)
return std::unexpected(Captured.error());
}
- if (Controls.StopAtStage && stageOrdinal(CurrentStage) >= stageOrdinal(*Controls.StopAtStage)) {
+ if (Controls.StopAtStage && !isEarlierStage(CurrentStage, *Controls.StopAtStage)) {
return Result;
}
@@ -289,7 +305,7 @@ runFunction(MachineFunction &Function, mir::MIRDocument &Document, const TargetD
StopMatched = true;
break;
}
- if (Controls.StopAtStage && stageOrdinal(CurrentStage) >= stageOrdinal(*Controls.StopAtStage)) {
+ if (Controls.StopAtStage && !isEarlierStage(CurrentStage, *Controls.StopAtStage)) {
break;
}
}
@@ -314,6 +330,10 @@ runFunction(MachineFunction &Function, mir::MIRDocument &Document, const TargetD
} // namespace
+bool isEarlierStage(BackendStage Left, BackendStage Right) noexcept {
+ return stageRank(Left) < stageRank(Right);
+}
+
BackendStage stageForFunction(const MachineFunction &Function) noexcept {
const MachineFunctionProperties &Properties = Function.properties();
if (Properties.has(MachineFunctionProperty::Selected) &&
diff --git a/backend/tools/MIRTool/MIRToolMain.cpp b/backend/tools/MIRTool/MIRToolMain.cpp
index a932a89..d675f35 100644
--- a/backend/tools/MIRTool/MIRToolMain.cpp
+++ b/backend/tools/MIRTool/MIRToolMain.cpp
@@ -36,7 +36,6 @@ using rcc::ErrorCode;
using rcc::Expected;
using rcc::tooling::ArtifactKind;
using rcc::tooling::BackendInvocation;
-using rcc::tooling::BackendOutputKind;
using rcc::tooling::BackendRunResult;
using rcc::tooling::CanonicalMIR;
@@ -64,7 +63,7 @@ struct CommandLine final {
std::string OutputPath = "-";
std::filesystem::path ReproducerPath;
std::filesystem::path CachePath;
- BackendOutputKind Output = BackendOutputKind::FinalMIR;
+ ArtifactKind Output = ArtifactKind::FinalMIR;
BackendInvocation Invocation = rcc::tooling::defaultRV64GCInvocation();
rcc::tooling::PipelineControls Controls;
rcc::tooling::MIRFuzzOptions FuzzOptions;
@@ -635,17 +634,17 @@ void applyFeatureOverrides(std::vector<std::string> Overrides, std::vector<std::
"-run-pass cannot be used with a limited code-generation pipeline");
}
if (ExplicitPipeline || HasLimitedCodeGenPipeline) {
- Command.Output = BackendOutputKind::FinalMIR;
+ Command.Output = ArtifactKind::FinalMIR;
} else {
switch (CodeGenFlags.FileType) {
case rcc::CodeGenFileType::AssemblyFile:
- Command.Output = BackendOutputKind::Assembly;
+ Command.Output = ArtifactKind::Assembly;
break;
case rcc::CodeGenFileType::ObjectFile:
- Command.Output = BackendOutputKind::RelocatableObject;
+ Command.Output = ArtifactKind::RelocatableObject;
break;
case rcc::CodeGenFileType::Null:
- Command.Output = BackendOutputKind::Assembly;
+ Command.Output = ArtifactKind::Assembly;
Command.DiscardOutput = true;
break;
}
@@ -715,30 +714,6 @@ void applyFeatureOverrides(std::vector<std::string> Overrides, std::vector<std::
return writeOutput(Path, std::span<const std::uint8_t>(Bytes, Text.size()));
}
-[[nodiscard]] Expected<BackendOutputKind> outputFromArtifact(ArtifactKind Artifact) {
- 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) {
for (const rcc::tooling::PipelineSnapshot &Snapshot : Result.Pipeline.Snapshots) {
std::cerr << "*** " << rcc::tooling::spelling(Snapshot.Stage);
@@ -764,9 +739,9 @@ void printActions(const BackendRunResult &Result) {
const rcc::TargetDescription &Target) {
if (Command.ReproducerPath.empty())
return {};
- auto Manifest = rcc::tooling::createBackendManifest(
- rcc::tooling::ManifestKind::Reproducer, rcc::tooling::manifestArtifactKind(Command.Output),
- Command.Invocation, Target, Input.Text);
+ auto Manifest =
+ rcc::tooling::createBackendManifest(rcc::tooling::ManifestKind::Reproducer, Command.Output,
+ Command.Invocation, Target, Input.Text);
if (!Manifest)
return std::unexpected(Manifest.error());
return rcc::tooling::writeReproducer(Command.ReproducerPath, *Manifest, Input.Text);
@@ -779,10 +754,11 @@ runWithCache(const CommandLine &Command, CanonicalMIR Input, const rcc::TargetDe
return rcc::tooling::runBackend(std::move(Input), Target, Command.Invocation, Command.Output,
Command.Controls, Instrumentation);
}
- auto Kind = rcc::tooling::cacheArtifactKind(Command.Output);
- if (!Kind)
- return std::unexpected(Kind.error());
- const ArtifactKind CacheKind = *Kind;
+ if (!rcc::tooling::isCacheableArtifact(Command.Output)) {
+ return rcc::makeUnexpected(ErrorCode::InvalidInvocation,
+ "the selected intermediate stage is not a cache boundary");
+ }
+ const ArtifactKind CacheKind = Command.Output;
if (Command.Cache == CachePolicy::Read || Command.Cache == CachePolicy::ReadWrite) {
auto Cached = rcc::tooling::loadCacheEntry(Command.CachePath, CacheKind, Command.Invocation,
Target, Input.Text);
@@ -827,10 +803,7 @@ runWithCache(const CommandLine &Command, CanonicalMIR Input, const rcc::TargetDe
auto Package = rcc::tooling::loadReproducer(Command.ReproducerPath, *Target);
if (!Package)
return std::unexpected(Package.error());
- auto Output = outputFromArtifact(Package->Manifest.Artifact);
- if (!Output)
- return std::unexpected(Output.error());
- Command.Output = *Output;
+ Command.Output = Package->Manifest.Artifact;
Command.Invocation = Package->Manifest.Invocation;
Command.ReproducerPath.clear();
auto Run = runWithCache(Command, std::move(Package->Input), *Target);
diff --git a/backend/unittests/Tooling/MIRReducerFuzzerTest.cpp b/backend/unittests/Tooling/MIRReducerFuzzerTest.cpp
index 9526a9f..2ffbdfb 100644
--- a/backend/unittests/Tooling/MIRReducerFuzzerTest.cpp
+++ b/backend/unittests/Tooling/MIRReducerFuzzerTest.cpp
@@ -110,7 +110,7 @@ int main() {
if (!RegBankInput)
return tooling_test::fail(RegBankInput.error().message());
auto RegBank = rcc::tooling::runBackend(std::move(*RegBankInput), *Target, Invocation,
- rcc::tooling::BackendOutputKind::RegisterBankMIR);
+ rcc::tooling::ArtifactKind::RegisterBankMIR);
if (!RegBank)
return tooling_test::fail(RegBank.error().message());
rcc::tooling::BackendInvocation FailureInvocation = Invocation;
@@ -123,7 +123,7 @@ int main() {
if (!Input)
return rcc::Expected<bool>(std::unexpected(Input.error()));
auto Run = rcc::tooling::runBackend(std::move(*Input), *Target, Candidate,
- rcc::tooling::BackendOutputKind::SelectedMIR);
+ rcc::tooling::ArtifactKind::SelectedMIR);
return rcc::Expected<bool>(!Run && Run.error().code() == rcc::ErrorCode::VerificationError);
};
rcc::tooling::MIRReducerOptions FailureOptions;
diff --git a/backend/unittests/Tooling/PipelineDriverTest.cpp b/backend/unittests/Tooling/PipelineDriverTest.cpp
index bed09be..32a99c5 100644
--- a/backend/unittests/Tooling/PipelineDriverTest.cpp
+++ b/backend/unittests/Tooling/PipelineDriverTest.cpp
@@ -31,7 +31,7 @@ printDocument(const rcc::mir::MIRDocument &Document, const rcc::TargetDescriptio
[[nodiscard]] rcc::Expected<rcc::tooling::BackendRunResult>
runInput(std::string_view SourceName, std::string SourceText, const rcc::TargetDescription &Target,
- const rcc::tooling::BackendInvocation &Invocation, rcc::tooling::BackendOutputKind Output,
+ const rcc::tooling::BackendInvocation &Invocation, rcc::tooling::ArtifactKind Output,
rcc::tooling::PipelineControls Controls = {}) {
auto Input = rcc::tooling::parseAndCanonicalizeMIR(std::string(SourceName), std::move(SourceText),
Target, Invocation);
@@ -70,15 +70,15 @@ runDeterminismCase(std::string_view Input, const rcc::TargetDescription &Target,
rcc::tooling::BackendInvocation Invocation = rcc::tooling::defaultRV64GCInvocation();
Invocation.Determinism.ThreadCount = ThreadCount;
auto Final = runInput("determinism-final.mir", std::string(Input), Target, Invocation,
- rcc::tooling::BackendOutputKind::FinalMIR);
+ rcc::tooling::ArtifactKind::FinalMIR);
if (!Final)
return std::unexpected(Final.error());
auto Assembly = runInput("determinism-assembly.mir", std::string(Input), Target, Invocation,
- rcc::tooling::BackendOutputKind::Assembly);
+ rcc::tooling::ArtifactKind::Assembly);
if (!Assembly)
return std::unexpected(Assembly.error());
auto Object = runInput("determinism-object.mir", std::string(Input), Target, Invocation,
- rcc::tooling::BackendOutputKind::RelocatableObject);
+ rcc::tooling::ArtifactKind::RelocatableObject);
if (!Object)
return std::unexpected(Object.error());
return DeterministicOutputs{
@@ -108,7 +108,7 @@ int main() {
if (!CanonicalAtomicOnly)
return tooling_test::fail(CanonicalAtomicOnly.error().message());
auto AtomicOnlyRun = runInput("atomic-only.mir", *Source, *Target, AtomicOnlyInvocation,
- rcc::tooling::BackendOutputKind::LegalizedMIR);
+ rcc::tooling::ArtifactKind::LegalizedMIR);
if (!AtomicOnlyRun)
return tooling_test::fail(AtomicOnlyRun.error().message());
@@ -121,19 +121,16 @@ int main() {
return tooling_test::fail("RV64 backend invocation must reject unsupported target features");
constexpr std::array StageCases{
- std::pair{rcc::tooling::BackendOutputKind::PreLegalizerMIR,
+ std::pair{rcc::tooling::ArtifactKind::PreLegalizerMIR,
rcc::tooling::BackendStage::PreLegalizerMIR},
- std::pair{rcc::tooling::BackendOutputKind::LegalizedMIR,
- rcc::tooling::BackendStage::LegalizedMIR},
- std::pair{rcc::tooling::BackendOutputKind::RegisterBankMIR,
+ std::pair{rcc::tooling::ArtifactKind::LegalizedMIR, rcc::tooling::BackendStage::LegalizedMIR},
+ std::pair{rcc::tooling::ArtifactKind::RegisterBankMIR,
rcc::tooling::BackendStage::RegisterBankMIR},
- std::pair{rcc::tooling::BackendOutputKind::SelectedMIR,
- rcc::tooling::BackendStage::SelectedMIR},
- std::pair{rcc::tooling::BackendOutputKind::PostSSAMIR,
- rcc::tooling::BackendStage::PostSSAMIR},
- std::pair{rcc::tooling::BackendOutputKind::PostRegisterAllocationMIR,
+ std::pair{rcc::tooling::ArtifactKind::SelectedMIR, rcc::tooling::BackendStage::SelectedMIR},
+ std::pair{rcc::tooling::ArtifactKind::PostSSAMIR, rcc::tooling::BackendStage::PostSSAMIR},
+ std::pair{rcc::tooling::ArtifactKind::PostRegisterAllocationMIR,
rcc::tooling::BackendStage::PostRegisterAllocationMIR},
- std::pair{rcc::tooling::BackendOutputKind::FinalMIR, rcc::tooling::BackendStage::FinalMIR},
+ std::pair{rcc::tooling::ArtifactKind::FinalMIR, rcc::tooling::BackendStage::FinalMIR},
};
std::optional<std::string> SelectedMIR;
for (const auto &[Output, ExpectedStage] : StageCases) {
@@ -153,18 +150,18 @@ int main() {
"MIR output requested " + std::string(rcc::tooling::spelling(ExpectedStage)) +
" but reparsed as " + std::string(rcc::tooling::spelling(ActualStage)));
}
- if (Output == rcc::tooling::BackendOutputKind::SelectedMIR)
+ if (Output == rcc::tooling::ArtifactKind::SelectedMIR)
SelectedMIR = std::string(Run->text());
}
- auto Assembly = runInput("assembly.mir", *Source, *Target, Invocation,
- rcc::tooling::BackendOutputKind::Assembly);
+ auto Assembly =
+ runInput("assembly.mir", *Source, *Target, Invocation, rcc::tooling::ArtifactKind::Assembly);
if (!Assembly || !Assembly->text().contains("generic_pipeline") ||
!Assembly->text().contains("jalr x0, x1, 0")) {
return tooling_test::fail("assembly output must use the complete RV64GC production pipeline");
}
auto Object = runInput("object.mir", *Source, *Target, Invocation,
- rcc::tooling::BackendOutputKind::RelocatableObject);
+ rcc::tooling::ArtifactKind::RelocatableObject);
constexpr std::array<std::uint8_t, 4> ELFMagic{0x7fU, 'E', 'L', 'F'};
if (!Object || Object->Output.size() < ELFMagic.size() ||
!std::ranges::equal(ELFMagic, std::span<const std::uint8_t>(Object->Output).first(4))) {
@@ -241,13 +238,13 @@ int main() {
if (!LaterInput)
return tooling_test::fail(LaterInput.error().message());
if (rcc::tooling::runBackend(std::move(*LaterInput), *Target, Invocation,
- rcc::tooling::BackendOutputKind::PreLegalizerMIR)) {
+ rcc::tooling::ArtifactKind::PreLegalizerMIR)) {
return tooling_test::fail(
"backend must not reconstruct an earlier stage from a later snapshot");
}
auto RegBankRun = runInput("action-regbank.mir", *Source, *Target, Invocation,
- rcc::tooling::BackendOutputKind::RegisterBankMIR);
+ rcc::tooling::ArtifactKind::RegisterBankMIR);
if (!RegBankRun)
return tooling_test::fail(RegBankRun.error().message());
rcc::tooling::BackendInvocation InstructionSelectInvocation = Invocation;
@@ -269,10 +266,10 @@ int main() {
InstructionSelectInvocation.ActionFuel.reset();
auto AcceptedFirst =
runInput("action-accepted-1.mir", std::string(RegBankRun->text()), *Target,
- InstructionSelectInvocation, rcc::tooling::BackendOutputKind::SelectedMIR);
+ InstructionSelectInvocation, rcc::tooling::ArtifactKind::SelectedMIR);
auto AcceptedSecond =
runInput("action-accepted-2.mir", std::string(RegBankRun->text()), *Target,
- InstructionSelectInvocation, rcc::tooling::BackendOutputKind::SelectedMIR);
+ InstructionSelectInvocation, rcc::tooling::ArtifactKind::SelectedMIR);
if (!AcceptedFirst || !AcceptedSecond || AcceptedFirst->Actions.empty() ||
AcceptedFirst->Actions != AcceptedSecond->Actions ||
AcceptedFirst->Output != AcceptedSecond->Output) {