aboutsummaryrefslogtreecommitdiff
path: root/backend/lib
diff options
context:
space:
mode:
Diffstat (limited to 'backend/lib')
-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
4 files changed, 66 insertions, 118 deletions
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) &&