aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/include/rcc/Target/RISCV/RISCVPipeline.h5
-rw-r--r--backend/lib/Target/RISCV/RISCVPipeline.cpp14
-rw-r--r--backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp168
-rw-r--r--backend/tools/AssemblyEmitter/AssemblyPipelineTest.cmake57
-rw-r--r--backend/tools/AssemblyEmitter/CMakeLists.txt59
-rw-r--r--backend/tools/AssemblyEmitter/ObjectPipelineTest.cmake88
-rw-r--r--backend/tools/CMakeLists.txt1
7 files changed, 0 insertions, 392 deletions
diff --git a/backend/include/rcc/Target/RISCV/RISCVPipeline.h b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
index fa2cb45..9d871a9 100644
--- a/backend/include/rcc/Target/RISCV/RISCVPipeline.h
+++ b/backend/include/rcc/Target/RISCV/RISCVPipeline.h
@@ -30,11 +30,6 @@ createCanonicalPipelinePass(std::string_view Name);
createCanonicalPipelinePass(std::string_view Name, RISCVSubtargetFeatures Features);
[[nodiscard]] Expected<std::vector<std::string>>
canonicalPipelinePassNames(const MachineFunction &Function);
-[[nodiscard]] Expected<void>
-runCanonicalPipeline(MachineFunction &Function, const TargetDescription &Target,
- MachinePassManagerOptions Options = {},
- MachinePassInstrumentation *Instrumentation = nullptr);
-
} // namespace riscv
} // namespace rcc
diff --git a/backend/lib/Target/RISCV/RISCVPipeline.cpp b/backend/lib/Target/RISCV/RISCVPipeline.cpp
index d995060..3665db5 100644
--- a/backend/lib/Target/RISCV/RISCVPipeline.cpp
+++ b/backend/lib/Target/RISCV/RISCVPipeline.cpp
@@ -166,18 +166,4 @@ Expected<std::vector<std::string>> canonicalPipelinePassNames(const MachineFunct
return Result;
}
-Expected<void> runCanonicalPipeline(MachineFunction &Function, const TargetDescription &Target,
- MachinePassManagerOptions Options,
- MachinePassInstrumentation *Instrumentation) {
- MachinePassManager Pipeline(Options);
- auto Added = addCanonicalPipeline(Pipeline, Function);
- if (!Added)
- return std::unexpected(Added.error());
- MachineAnalysisManager Analyses;
- auto Registered = registerMachineOptimizationAnalyses(Analyses);
- if (!Registered)
- return std::unexpected(Registered.error());
- return Pipeline.run(Function, Target, Analyses, Instrumentation);
-}
-
} // namespace rcc::riscv
diff --git a/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp b/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp
deleted file mode 100644
index 21567b3..0000000
--- a/backend/tools/AssemblyEmitter/AssemblyEmitterMain.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include "rcc/CodeGen/MachineFunction.h"
-#include "rcc/MIR/MIRDocument.h"
-#include "rcc/Support/TextDiagnostic.h"
-#include "rcc/Target/RISCV/RISCVAssemblyPrinter.h"
-#include "rcc/Target/RISCV/RISCVObjectFile.h"
-#include "rcc/Target/RISCV/RISCVPipeline.h"
-#include "rcc/Target/RISCV/RISCVTarget.h"
-
-#include <cstdint>
-#include <fstream>
-#include <iostream>
-#include <iterator>
-#include <string>
-#include <string_view>
-#include <vector>
-
-namespace {
-
-enum class OutputKind : std::uint8_t {
- Assembly,
- Object,
-};
-
-struct CommandLine final {
- std::string InputPath;
- std::string OutputPath = "-";
- OutputKind Kind = OutputKind::Assembly;
-};
-
-void printUsage() {
- std::cerr << "usage: rcc-backend-asm --input <mir-file|-> "
- "[--filetype asm|obj] [--output <file|->]\n";
-}
-
-[[nodiscard]] bool parseCommandLine(int ArgumentCount, char *Arguments[], CommandLine &Result) {
- for (int Index = 1; Index < ArgumentCount; ++Index) {
- const std::string_view Argument(Arguments[Index]);
- if (Argument == "--input" && Index + 1 < ArgumentCount) {
- Result.InputPath = Arguments[++Index];
- continue;
- }
- if ((Argument == "--output" || Argument == "-o") && Index + 1 < ArgumentCount) {
- Result.OutputPath = Arguments[++Index];
- continue;
- }
- if (Argument == "--filetype" && Index + 1 < ArgumentCount) {
- const std::string_view Value(Arguments[++Index]);
- if (Value == "asm" || Value == "assembly") {
- Result.Kind = OutputKind::Assembly;
- } else if (Value == "obj" || Value == "object") {
- Result.Kind = OutputKind::Object;
- } else {
- printUsage();
- return false;
- }
- continue;
- }
- {
- printUsage();
- return false;
- }
- }
- if (Result.InputPath.empty()) {
- printUsage();
- return false;
- }
- return true;
-}
-
-[[nodiscard]] bool writeOutput(const CommandLine &Command, std::span<const std::uint8_t> Contents) {
- if (Command.OutputPath == "-") {
- std::cout.write(reinterpret_cast<const char *>(Contents.data()),
- static_cast<std::streamsize>(Contents.size()));
- return static_cast<bool>(std::cout);
- }
- std::ofstream Output(Command.OutputPath, std::ios::binary);
- if (!Output) {
- std::cerr << "rcc-backend-asm: cannot open output '" << Command.OutputPath << "'\n";
- return false;
- }
- Output.write(reinterpret_cast<const char *>(Contents.data()),
- static_cast<std::streamsize>(Contents.size()));
- if (!Output) {
- std::cerr << "rcc-backend-asm: cannot write output '" << Command.OutputPath << "'\n";
- return false;
- }
- return true;
-}
-
-[[nodiscard]] bool writeOutput(const CommandLine &Command, std::string_view Contents) {
- const auto *Data = reinterpret_cast<const std::uint8_t *>(Contents.data());
- return writeOutput(Command, std::span<const std::uint8_t>(Data, Contents.size()));
-}
-
-[[nodiscard]] bool readInput(const CommandLine &Command, std::string &Contents) {
- if (Command.InputPath == "-") {
- Contents.assign(std::istreambuf_iterator<char>(std::cin), std::istreambuf_iterator<char>());
- return true;
- }
- std::ifstream Input(Command.InputPath, std::ios::binary);
- if (!Input) {
- std::cerr << "rcc-backend-asm: cannot open input '" << Command.InputPath << "'\n";
- return false;
- }
- Contents.assign(std::istreambuf_iterator<char>(Input), std::istreambuf_iterator<char>());
- return true;
-}
-
-} // namespace
-
-int main(int ArgumentCount, char *Arguments[]) {
- CommandLine Command;
- if (!parseCommandLine(ArgumentCount, Arguments, Command))
- return 1;
-
- std::string SourceText;
- if (!readInput(Command, SourceText))
- return 1;
-
- auto Target = rcc::riscv::createTargetDescription();
- if (!Target) {
- std::cerr << "rcc-backend-asm: cannot create RV64GC target: " << Target.error().message()
- << '\n';
- return 1;
- }
- rcc::mir::MIRDocumentParserOptions Options;
- Options.DataLayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
- auto Parsed =
- rcc::mir::parseMIRDocument(*Target, Command.InputPath, std::move(SourceText), Options);
- if (!Parsed.succeeded()) {
- for (const rcc::TextDiagnostic &Diagnostic : Parsed.diagnostics())
- std::cerr << rcc::formatTextDiagnostic(Diagnostic, Parsed.source()) << '\n';
- return 1;
- }
-
- rcc::CompilationUnit &Unit = Parsed.document()->unit();
- for (std::size_t Index = 0; Index < Unit.functionCount(); ++Index) {
- rcc::MachineFunction *Function = Unit.functionAt(Index);
- if (Function == nullptr) {
- std::cerr << "rcc-backend-asm: parsed document contains a null function\n";
- return 1;
- }
- auto Run = rcc::riscv::runCanonicalPipeline(*Function, *Target);
- if (!Run) {
- std::cerr << "rcc-backend-asm: backend pipeline failed for '" << Function->name()
- << "': " << Run.error().message() << '\n';
- return 1;
- }
- }
-
- if (Command.Kind == OutputKind::Object) {
- auto Object = rcc::riscv::emitObject(Unit, *Target);
- if (!Object) {
- std::cerr << "rcc-backend-asm: object emission failed: " << Object.error().message() << '\n';
- return 1;
- }
- return writeOutput(Command, *Object) ? 0 : 1;
- }
- auto Assembly = rcc::riscv::emitAssembly(Unit, *Target);
- if (!Assembly) {
- std::cerr << "rcc-backend-asm: assembly emission failed: " << Assembly.error().message()
- << '\n';
- return 1;
- }
- return writeOutput(Command, *Assembly) ? 0 : 1;
-}
diff --git a/backend/tools/AssemblyEmitter/AssemblyPipelineTest.cmake b/backend/tools/AssemblyEmitter/AssemblyPipelineTest.cmake
deleted file mode 100644
index 85977df..0000000
--- a/backend/tools/AssemblyEmitter/AssemblyPipelineTest.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-if(NOT DEFINED EMITTER OR NOT DEFINED INPUT OR NOT DEFINED OUTPUT)
- message(FATAL_ERROR "assembly pipeline test is missing a required path")
-endif()
-
-execute_process(
- COMMAND "${EMITTER}" --input "${INPUT}"
- RESULT_VARIABLE FirstResult
- OUTPUT_VARIABLE FirstAssembly
- ERROR_VARIABLE FirstDiagnostics
-)
-if(NOT FirstResult EQUAL 0)
- message(FATAL_ERROR "assembly pipeline failed: ${FirstDiagnostics}")
-endif()
-if(NOT FirstAssembly MATCHES "\\.attribute arch, \"rv64gc\"" OR
- NOT FirstAssembly MATCHES "jalr x0, x1, 0")
- message(FATAL_ERROR "assembly pipeline output is missing required RV64GC content")
-endif()
-if(INPUT MATCHES "RISCVDataPipeline" AND
- (NOT FirstAssembly MATCHES "\\.LCPI[0-9]+_0:" OR
- NOT FirstAssembly MATCHES "\\.LJTI[0-9]+_0:"))
- message(FATAL_ERROR "assembly pipeline did not emit its constant pool and jump table")
-endif()
-if(INPUT MATCHES "RISCVStackFramePipeline" AND
- (NOT FirstAssembly MATCHES "addi x2, x2, -32" OR
- NOT FirstAssembly MATCHES "addi x2, x2, 32"))
- message(FATAL_ERROR "assembly pipeline did not balance its stack frame")
-endif()
-
-execute_process(
- COMMAND "${EMITTER}" --input "${INPUT}"
- RESULT_VARIABLE SecondResult
- OUTPUT_VARIABLE SecondAssembly
- ERROR_VARIABLE SecondDiagnostics
-)
-if(NOT SecondResult EQUAL 0)
- message(FATAL_ERROR "repeated assembly pipeline failed: ${SecondDiagnostics}")
-endif()
-if(NOT FirstAssembly STREQUAL SecondAssembly)
- message(FATAL_ERROR "assembly pipeline output is not deterministic")
-endif()
-
-if(DEFINED LLVM_MC AND NOT LLVM_MC STREQUAL "LLVM_MC-NOTFOUND" AND
- NOT LLVM_MC STREQUAL "")
- file(WRITE "${OUTPUT}" "${FirstAssembly}")
- execute_process(
- COMMAND "${LLVM_MC}" -triple=riscv64-unknown-linux-gnu -filetype=null "${OUTPUT}"
- RESULT_VARIABLE AssemblerResult
- OUTPUT_VARIABLE AssemblerOutput
- ERROR_VARIABLE AssemblerDiagnostics
- )
- file(REMOVE "${OUTPUT}")
- if(NOT AssemblerResult EQUAL 0)
- message(FATAL_ERROR "LLVM MC rejected generated assembly: ${AssemblerDiagnostics}")
- endif()
-endif()
diff --git a/backend/tools/AssemblyEmitter/CMakeLists.txt b/backend/tools/AssemblyEmitter/CMakeLists.txt
deleted file mode 100644
index 01c99aa..0000000
--- a/backend/tools/AssemblyEmitter/CMakeLists.txt
+++ /dev/null
@@ -1,59 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-add_executable(RCCBackendAssemblyEmitter AssemblyEmitterMain.cpp)
-rcc_backend_configure_target(RCCBackendAssemblyEmitter)
-target_link_libraries(
- RCCBackendAssemblyEmitter
- PRIVATE
- RCCBackend::MIR
- RCCBackend::RISCV
-)
-
-set_target_properties(
- RCCBackendAssemblyEmitter
- PROPERTIES
- OUTPUT_NAME rcc-backend-asm
-)
-
-install(
- TARGETS RCCBackendAssemblyEmitter
- EXPORT RCCBackendTargets
- RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
-)
-
-find_program(RCCBackendLLVMMC NAMES llvm-mc-20 llvm-mc)
-find_program(RCCBackendLLVMReadELF NAMES llvm-readelf-20 llvm-readelf)
-find_program(RCCBackendLLVMObjdump NAMES llvm-objdump-20 llvm-objdump)
-foreach(
- InputName
- IN ITEMS
- RISCVGenericPipeline
- RISCVWideConstantPipeline
- RISCVDataPipeline
- RISCVStackFramePipeline
-)
- add_test(
- NAME RCCBackend.AssemblyEmitter.${InputName}
- COMMAND
- "${CMAKE_COMMAND}"
- "-DEMITTER=$<TARGET_FILE:RCCBackendAssemblyEmitter>"
- "-DINPUT=${RCC_BACKEND_SOURCE_DIR}/unittests/Target/Inputs/${InputName}.mir"
- "-DOUTPUT=${CMAKE_CURRENT_BINARY_DIR}/${InputName}.s"
- "-DLLVM_MC=${RCCBackendLLVMMC}"
- -P "${CMAKE_CURRENT_SOURCE_DIR}/AssemblyPipelineTest.cmake"
- )
- add_test(
- NAME RCCBackend.ObjectEmitter.${InputName}
- COMMAND
- "${CMAKE_COMMAND}"
- "-DEMITTER=$<TARGET_FILE:RCCBackendAssemblyEmitter>"
- "-DINPUT=${RCC_BACKEND_SOURCE_DIR}/unittests/Target/Inputs/${InputName}.mir"
- "-DOUTPUT=${CMAKE_CURRENT_BINARY_DIR}/${InputName}.o"
- "-DLLVM_READELF=${RCCBackendLLVMReadELF}"
- "-DLLVM_OBJDUMP=${RCCBackendLLVMObjdump}"
- -P "${CMAKE_CURRENT_SOURCE_DIR}/ObjectPipelineTest.cmake"
- )
-endforeach()
-
-rcc_backend_register_format_files("${CMAKE_CURRENT_SOURCE_DIR}/AssemblyEmitterMain.cpp")
-rcc_backend_register_tidy_files("${CMAKE_CURRENT_SOURCE_DIR}/AssemblyEmitterMain.cpp")
diff --git a/backend/tools/AssemblyEmitter/ObjectPipelineTest.cmake b/backend/tools/AssemblyEmitter/ObjectPipelineTest.cmake
deleted file mode 100644
index 5ba800c..0000000
--- a/backend/tools/AssemblyEmitter/ObjectPipelineTest.cmake
+++ /dev/null
@@ -1,88 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-if(NOT DEFINED EMITTER OR NOT DEFINED INPUT OR NOT DEFINED OUTPUT)
- message(FATAL_ERROR "object pipeline test is missing a required path")
-endif()
-
-set(RepeatedOutput "${OUTPUT}.repeat")
-execute_process(
- COMMAND "${EMITTER}" --input "${INPUT}" --filetype obj --output "${OUTPUT}"
- RESULT_VARIABLE FirstResult
- ERROR_VARIABLE FirstDiagnostics
-)
-if(NOT FirstResult EQUAL 0)
- message(FATAL_ERROR "object pipeline failed: ${FirstDiagnostics}")
-endif()
-
-execute_process(
- COMMAND "${EMITTER}" --input "${INPUT}" --filetype obj --output "${RepeatedOutput}"
- RESULT_VARIABLE SecondResult
- ERROR_VARIABLE SecondDiagnostics
-)
-if(NOT SecondResult EQUAL 0)
- message(FATAL_ERROR "repeated object pipeline failed: ${SecondDiagnostics}")
-endif()
-
-execute_process(
- COMMAND "${CMAKE_COMMAND}" -E compare_files "${OUTPUT}" "${RepeatedOutput}"
- RESULT_VARIABLE ComparisonResult
-)
-if(NOT ComparisonResult EQUAL 0)
- message(FATAL_ERROR "object pipeline output is not deterministic")
-endif()
-
-file(READ "${OUTPUT}" ObjectMagic OFFSET 0 LIMIT 4 HEX)
-if(NOT ObjectMagic STREQUAL "7f454c46")
- message(FATAL_ERROR "object pipeline did not produce an ELF file")
-endif()
-
-if(DEFINED LLVM_READELF AND NOT LLVM_READELF STREQUAL "LLVM_READELF-NOTFOUND" AND
- NOT LLVM_READELF STREQUAL "")
- execute_process(
- COMMAND "${LLVM_READELF}" -h -S -s -r "${OUTPUT}"
- RESULT_VARIABLE ReadELFResult
- OUTPUT_VARIABLE ReadELFOutput
- ERROR_VARIABLE ReadELFDiagnostics
- )
- if(NOT ReadELFResult EQUAL 0)
- message(FATAL_ERROR "LLVM readelf rejected generated object: ${ReadELFDiagnostics}")
- endif()
- if(NOT ReadELFOutput MATCHES "Type:[ \t]+REL" OR
- NOT ReadELFOutput MATCHES "Machine:[ \t]+RISC-V" OR
- NOT ReadELFOutput MATCHES "Flags:[ \t]+0x5" OR
- NOT ReadELFOutput MATCHES "\\.text" OR
- NOT ReadELFOutput MATCHES "\\.eh_frame" OR
- NOT ReadELFOutput MATCHES "\\.riscv\\.attributes")
- message(FATAL_ERROR "generated object is missing required RV64GC ELF metadata")
- endif()
- if(INPUT MATCHES "RISCVDataPipeline" AND
- (NOT ReadELFOutput MATCHES "\\.rodata" OR
- NOT ReadELFOutput MATCHES "\\.rela\\.text" OR
- NOT ReadELFOutput MATCHES "R_RISCV_64"))
- message(FATAL_ERROR "data pipeline object is missing data or relocation sections")
- endif()
-endif()
-
-if(DEFINED LLVM_OBJDUMP AND NOT LLVM_OBJDUMP STREQUAL "LLVM_OBJDUMP-NOTFOUND" AND
- NOT LLVM_OBJDUMP STREQUAL "")
- execute_process(
- COMMAND "${LLVM_OBJDUMP}" -dr --no-show-raw-insn "${OUTPUT}"
- RESULT_VARIABLE ObjdumpResult
- OUTPUT_VARIABLE ObjdumpOutput
- ERROR_VARIABLE ObjdumpDiagnostics
- )
- if(NOT ObjdumpResult EQUAL 0)
- message(FATAL_ERROR "LLVM objdump rejected generated object: ${ObjdumpDiagnostics}")
- endif()
- if(NOT ObjdumpOutput MATCHES "file format elf64-littleriscv" OR
- NOT ObjdumpOutput MATCHES "ret")
- message(FATAL_ERROR "generated object does not contain RV64GC function code")
- endif()
- if(INPUT MATCHES "RISCVStackFramePipeline" AND
- (NOT ObjdumpOutput MATCHES "addi[ \t]+sp, sp, -0x20" OR
- NOT ObjdumpOutput MATCHES "addi[ \t]+sp, sp, 0x20"))
- message(FATAL_ERROR "stack-frame object does not balance its stack pointer")
- endif()
-endif()
-
-file(REMOVE "${OUTPUT}" "${RepeatedOutput}")
diff --git a/backend/tools/CMakeLists.txt b/backend/tools/CMakeLists.txt
index 4c6b7f6..009b0ae 100644
--- a/backend/tools/CMakeLists.txt
+++ b/backend/tools/CMakeLists.txt
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-3.0-or-later
add_subdirectory(DescriptionGenerator)
-add_subdirectory(AssemblyEmitter)
add_subdirectory(MIRTool)