diff options
Diffstat (limited to 'backend')
| -rw-r--r-- | backend/include/rcc/Tooling/ArtifactStore.h | 3 | ||||
| -rw-r--r-- | backend/include/rcc/Tooling/BackendDriver.h | 20 | ||||
| -rw-r--r-- | backend/include/rcc/Tooling/PipelineDriver.h | 1 | ||||
| -rw-r--r-- | backend/lib/Tooling/ArtifactStore.cpp | 8 | ||||
| -rw-r--r-- | backend/lib/Tooling/BackendDriver.cpp | 113 | ||||
| -rw-r--r-- | backend/lib/Tooling/MIRFuzzer.cpp | 35 | ||||
| -rw-r--r-- | backend/lib/Tooling/PipelineDriver.cpp | 28 | ||||
| -rw-r--r-- | backend/tools/MIRTool/MIRToolMain.cpp | 55 | ||||
| -rw-r--r-- | backend/unittests/Tooling/MIRReducerFuzzerTest.cpp | 4 | ||||
| -rw-r--r-- | backend/unittests/Tooling/PipelineDriverTest.cpp | 43 |
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) { |
