diff options
Diffstat (limited to 'backend/lib/CodeGen')
| -rw-r--r-- | backend/lib/CodeGen/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | backend/lib/CodeGen/CommandFlags.cpp | 233 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachinePseudoExpansion.cpp | 2 | ||||
| -rw-r--r-- | backend/lib/CodeGen/MachineSSAExit.cpp | 4 | ||||
| -rw-r--r-- | backend/lib/CodeGen/PostRAScheduler.cpp | 2 | ||||
| -rw-r--r-- | backend/lib/CodeGen/PrologueEpilogueInsertion.cpp | 2 |
6 files changed, 242 insertions, 5 deletions
diff --git a/backend/lib/CodeGen/CMakeLists.txt b/backend/lib/CodeGen/CMakeLists.txt index d25d164..e584131 100644 --- a/backend/lib/CodeGen/CMakeLists.txt +++ b/backend/lib/CodeGen/CMakeLists.txt @@ -3,6 +3,7 @@ set( RCCBackendCodeGenSources CompilationUnit.cpp + CommandFlags.cpp GlobalObject.cpp GenericOpcodes.cpp GenericConstant.cpp @@ -83,6 +84,7 @@ set( set( RCCBackendCodeGenHeaders "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/CompilationUnit.h" + "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/CommandFlags.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GlobalObject.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GenericOpcodes.h" "${RCC_BACKEND_SOURCE_DIR}/include/rcc/CodeGen/GenericConstant.h" @@ -204,6 +206,7 @@ install( rcc_backend_register_format_files( "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/CommandFlags.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GlobalObject.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GenericOpcodes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GenericConstant.cpp" @@ -285,6 +288,7 @@ rcc_backend_register_format_files( ) rcc_backend_register_tidy_files( "${CMAKE_CURRENT_SOURCE_DIR}/CompilationUnit.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/CommandFlags.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GlobalObject.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GenericOpcodes.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GenericConstant.cpp" diff --git a/backend/lib/CodeGen/CommandFlags.cpp b/backend/lib/CodeGen/CommandFlags.cpp new file mode 100644 index 0000000..dfbaadc --- /dev/null +++ b/backend/lib/CodeGen/CommandFlags.cpp @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "rcc/CodeGen/CommandFlags.h" + +#include <optional> +#include <string> +#include <utility> + +namespace rcc { +namespace { + +[[nodiscard]] Expected<std::optional<std::string_view>> +takeValue(std::span<const std::string_view> Arguments, std::size_t &Index, std::string_view Name) { + const std::string_view Argument = Arguments[Index]; + const std::string LongName = + Name.starts_with('-') && !Name.starts_with("--") ? "-" + std::string(Name) : std::string(); + if (Argument == Name || (!LongName.empty() && Argument == LongName)) { + if (Index + 1U >= Arguments.size()) { + return makeUnexpected(ErrorCode::InvalidInvocation, + "missing value for command-line option '" + std::string(Name) + "'"); + } + return Arguments[++Index]; + } + std::string Prefix(Name); + 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; +} + +template <typename ValueT, typename ParserT> +[[nodiscard]] Expected<bool> parseValueFlag(std::span<const std::string_view> Arguments, + std::size_t &Index, std::string_view Name, + std::optional<ValueT> &Destination, ParserT Parser) { + auto Value = takeValue(Arguments, Index, Name); + if (!Value) + return std::unexpected(Value.error()); + if (!*Value) + return false; + auto Parsed = Parser(**Value); + if (!Parsed) + return std::unexpected(Parsed.error()); + Destination = std::move(*Parsed); + return true; +} + +} // namespace + +std::string_view spelling(RelocationModel Value) noexcept { + switch (Value) { + case RelocationModel::Static: + return "static"; + case RelocationModel::PositionIndependent: + return "pic"; + } + return "invalid"; +} + +std::string_view spelling(CodeModel Value) noexcept { + switch (Value) { + case CodeModel::Small: + return "small"; + case CodeModel::Medium: + return "medium"; + case CodeModel::Large: + return "large"; + } + return "invalid"; +} + +std::string_view spelling(OptimizationLevel Value) noexcept { + switch (Value) { + case OptimizationLevel::O0: + return "O0"; + case OptimizationLevel::O1: + return "O1"; + case OptimizationLevel::O2: + return "O2"; + case OptimizationLevel::O3: + return "O3"; + case OptimizationLevel::Os: + return "Os"; + case OptimizationLevel::Oz: + return "Oz"; + } + return "invalid"; +} + +std::string_view spelling(CodeGenFileType Value) noexcept { + switch (Value) { + case CodeGenFileType::AssemblyFile: + return "asm"; + case CodeGenFileType::ObjectFile: + return "obj"; + case CodeGenFileType::Null: + return "null"; + } + return "invalid"; +} + +Expected<RelocationModel> parseRelocationModel(std::string_view Value) { + if (Value == "static") + return RelocationModel::Static; + if (Value == "pic") + return RelocationModel::PositionIndependent; + return makeUnexpected(ErrorCode::InvalidInvocation, "unknown relocation model"); +} + +Expected<CodeModel> parseCodeModel(std::string_view Value) { + if (Value == "small") + return CodeModel::Small; + if (Value == "medium") + return CodeModel::Medium; + if (Value == "large") + return CodeModel::Large; + return makeUnexpected(ErrorCode::InvalidInvocation, "unknown code model"); +} + +Expected<OptimizationLevel> parseOptimizationLevel(std::string_view Value) { + if (Value == "O0") + return OptimizationLevel::O0; + if (Value == "O1") + return OptimizationLevel::O1; + if (Value == "O2") + return OptimizationLevel::O2; + if (Value == "O3") + return OptimizationLevel::O3; + if (Value == "Os") + return OptimizationLevel::Os; + if (Value == "Oz") + return OptimizationLevel::Oz; + return makeUnexpected(ErrorCode::InvalidInvocation, "unknown optimization level"); +} + +Expected<CodeGenFileType> parseCodeGenFileType(std::string_view Value) { + if (Value == "asm") + return CodeGenFileType::AssemblyFile; + if (Value == "obj") + return CodeGenFileType::ObjectFile; + if (Value == "null") + return CodeGenFileType::Null; + return makeUnexpected(ErrorCode::InvalidInvocation, "unknown file type"); +} + +Expected<bool> parseCodeGenCommandFlag(std::span<const std::string_view> Arguments, + std::size_t &Index, CodeGenCommandFlags &Flags) { + const std::string_view Argument = Arguments[Index]; + const std::string_view Optimization = Argument.starts_with("--") ? Argument.substr(2) + : Argument.starts_with('-') ? Argument.substr(1) + : std::string_view{}; + if ((Argument.starts_with('-') && !Argument.starts_with("---")) && + (Optimization == "O0" || Optimization == "O1" || Optimization == "O2" || + Optimization == "O3" || Optimization == "Os" || Optimization == "Oz")) { + auto Level = parseOptimizationLevel(Optimization); + if (!Level) + return std::unexpected(Level.error()); + Flags.Optimization = *Level; + return true; + } + + const auto ParseString = [&](std::string_view Name, + std::optional<std::string> &Destination) -> Expected<bool> { + auto Value = takeValue(Arguments, Index, Name); + if (!Value) + return std::unexpected(Value.error()); + if (!*Value) + return false; + Destination = std::string(**Value); + return true; + }; + for (const auto &[Name, Destination] : + {std::pair{"-mtriple", &Flags.Triple}, std::pair{"-mcpu", &Flags.CPU}, + std::pair{"-mtune", &Flags.TuneCPU}, std::pair{"-target-abi", &Flags.ABI}}) { + auto Parsed = ParseString(Name, *Destination); + if (!Parsed) + return std::unexpected(Parsed.error()); + if (*Parsed) + return true; + } + + auto Features = takeValue(Arguments, Index, "-mattr"); + if (!Features) + return std::unexpected(Features.error()); + if (*Features) { + std::size_t Begin = 0; + while (Begin <= (**Features).size()) { + const std::size_t Comma = (**Features).find(',', Begin); + const std::size_t End = Comma == std::string_view::npos ? (**Features).size() : Comma; + if (End == Begin) { + return makeUnexpected(ErrorCode::InvalidInvocation, + "target feature list contains an empty element"); + } + Flags.FeatureOverrides.emplace_back((**Features).substr(Begin, End - Begin)); + if (Comma == std::string_view::npos) + break; + Begin = Comma + 1U; + } + return true; + } + + auto Relocation = + parseValueFlag(Arguments, Index, "-relocation-model", Flags.Relocation, parseRelocationModel); + if (!Relocation) + return std::unexpected(Relocation.error()); + if (*Relocation) + return true; + auto Code = parseValueFlag(Arguments, Index, "-code-model", Flags.Code, parseCodeModel); + if (!Code) + return std::unexpected(Code.error()); + if (*Code) + return true; + + auto FileType = takeValue(Arguments, Index, "-filetype"); + if (!FileType) + return std::unexpected(FileType.error()); + if (*FileType) { + auto Parsed = parseCodeGenFileType(**FileType); + if (!Parsed) + return std::unexpected(Parsed.error()); + Flags.FileType = *Parsed; + Flags.FileTypeWasSpecified = true; + return true; + } + return false; +} + +} // namespace rcc diff --git a/backend/lib/CodeGen/MachinePseudoExpansion.cpp b/backend/lib/CodeGen/MachinePseudoExpansion.cpp index 924c515..022c63e 100644 --- a/backend/lib/CodeGen/MachinePseudoExpansion.cpp +++ b/backend/lib/CodeGen/MachinePseudoExpansion.cpp @@ -154,7 +154,7 @@ using BlockSizeSnapshot = std::vector<std::pair<MachineBlockStableID, std::uint6 }(); static const MachinePassContract PostRA = [] { MachinePassContract Value{ - .Name = "expand-post-ra-pseudos", + .Name = "postrapseudos", .Requires = {MachineFunctionProperty::Selected, MachineFunctionProperty::NoPHIs, MachineFunctionProperty::NoVRegs, MachineFunctionProperty::TracksLiveness, MachineFunctionProperty::FrameFinalized, diff --git a/backend/lib/CodeGen/MachineSSAExit.cpp b/backend/lib/CodeGen/MachineSSAExit.cpp index f2b0102..76963ea 100644 --- a/backend/lib/CodeGen/MachineSSAExit.cpp +++ b/backend/lib/CodeGen/MachineSSAExit.cpp @@ -776,7 +776,7 @@ placePhiCopiesOnEdge(MachineFunction &Function, const TargetDescription &Target, const MachinePassContract &PHIEliminationPass::contract() const noexcept { static const MachinePassContract Contract{ - .Name = "PHIElimination", + .Name = "phi-node-elimination", .Requires = {MachineFunctionProperty::IsSSA, MachineFunctionProperty::Selected, MachineFunctionProperty::RegBankSelected}, .Sets = {MachineFunctionProperty::NoPHIs}, @@ -912,7 +912,7 @@ Expected<MachinePassResult> PHIEliminationPass::runImplementation(MachineFunctio const MachinePassContract &TwoAddressRewritePass::contract() const noexcept { static const MachinePassContract Contract{ - .Name = "TwoAddressRewrite", + .Name = "twoaddressinstruction", .Requires = {MachineFunctionProperty::Selected, MachineFunctionProperty::NoPHIs}, .Sets = {MachineFunctionProperty::TiedOpsRewritten}, .Clears = {MachineFunctionProperty::IsSSA}, diff --git a/backend/lib/CodeGen/PostRAScheduler.cpp b/backend/lib/CodeGen/PostRAScheduler.cpp index 6a91239..38fd582 100644 --- a/backend/lib/CodeGen/PostRAScheduler.cpp +++ b/backend/lib/CodeGen/PostRAScheduler.cpp @@ -31,7 +31,7 @@ namespace { [[nodiscard]] const MachinePassContract &postRASchedulerContract() { static const MachinePassContract Contract = [] { MachinePassContract Value{ - .Name = "post-ra-machine-scheduler", + .Name = "postmisched", .Requires = {MachineFunctionProperty::Selected, MachineFunctionProperty::NoPHIs, MachineFunctionProperty::TiedOpsRewritten, MachineFunctionProperty::NoVRegs, MachineFunctionProperty::TracksLiveness}, diff --git a/backend/lib/CodeGen/PrologueEpilogueInsertion.cpp b/backend/lib/CodeGen/PrologueEpilogueInsertion.cpp index acbcbcf..36315f7 100644 --- a/backend/lib/CodeGen/PrologueEpilogueInsertion.cpp +++ b/backend/lib/CodeGen/PrologueEpilogueInsertion.cpp @@ -31,7 +31,7 @@ namespace { const MachinePassContract &PrologueEpilogueInsertionPass::contract() const noexcept { static const MachinePassContract Contract = [] { MachinePassContract Value{ - .Name = "PrologueEpilogueInsertion", + .Name = "prologepilog", .Requires = {MachineFunctionProperty::Selected, MachineFunctionProperty::NoPHIs, MachineFunctionProperty::TiedOpsRewritten, MachineFunctionProperty::NoVRegs}, .Sets = {MachineFunctionProperty::FrameFinalized, MachineFunctionProperty::NoFrameIndices}, |
