Skip to content

Commit

Permalink
Options refactor.
Browse files Browse the repository at this point in the history
Signed-off-by: fruffy <fruffy@nyu.edu>
  • Loading branch information
fruffy committed Jul 31, 2024
1 parent 1a0fc15 commit cf25391
Show file tree
Hide file tree
Showing 55 changed files with 509 additions and 608 deletions.
20 changes: 0 additions & 20 deletions backends/p4tools/common/compiler/compiler_target.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#include "backends/p4tools/common/compiler/compiler_target.h"

#include <string>
#include <vector>

#include "backends/p4tools/common/compiler/context.h"
#include "backends/p4tools/common/compiler/midend.h"
#include "backends/p4tools/common/core/target.h"
#include "frontends/common/applyOptionsPragmas.h"
Expand All @@ -16,15 +14,6 @@

namespace P4Tools {

ICompileContext *CompilerTarget::makeContext(std::string_view toolName) {
return get(toolName).makeContextImpl();
}

std::vector<const char *> *CompilerTarget::initCompiler(std::string_view toolName, int argc,
char **argv) {
return get(toolName).initCompilerImpl(argc, argv);
}

CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options,
std::string_view toolName) {
const auto *program = P4Tools::CompilerTarget::runParser(options);
Expand Down Expand Up @@ -67,15 +56,6 @@ CompilerResultOrError CompilerTarget::runCompilerImpl(const CompilerOptions &opt
return *new CompilerResult(*program);
}

ICompileContext *CompilerTarget::makeContextImpl() const {
return new CompileContext<CompilerOptions>();
}

std::vector<const char *> *CompilerTarget::initCompilerImpl(int argc, char **argv) const {
auto *result = CompileContext<CompilerOptions>::get().options().process(argc, argv);
return ::errorCount() > 0 ? nullptr : result;
}

const IR::P4Program *CompilerTarget::runParser(const ParserOptions &options) {
const auto *program = P4::parseP4File(options);
if (::errorCount() > 0) {
Expand Down
18 changes: 0 additions & 18 deletions backends/p4tools/common/compiler/compiler_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#define BACKENDS_P4TOOLS_COMMON_COMPILER_COMPILER_TARGET_H_

#include <string>
#include <vector>

#include "backends/p4tools/common/compiler/compiler_result.h"
#include "backends/p4tools/common/compiler/context.h"
Expand All @@ -19,15 +18,6 @@ namespace P4Tools {
/// Encapsulates the details of invoking the P4 compiler for a target device and architecture.
class CompilerTarget : public Target {
public:
/// @returns a new compilation context for the compiler.
static ICompileContext *makeContext(std::string_view toolName);

/// Initializes the P4 compiler with the given compiler-specific command-line arguments.
///
/// @returns any unprocessed arguments, or nullptr if there was an error.
static std::vector<const char *> *initCompiler(std::string_view toolName, int argc,
char **argv);

/// Runs the P4 compiler to produce an IR and various other kinds of information on the input
/// program.
///
Expand All @@ -49,18 +39,10 @@ class CompilerTarget : public Target {
std::string_view toolName, const IR::P4Program *);

protected:
/// @see @makeContext.
[[nodiscard]] virtual ICompileContext *makeContextImpl() const;

/// @see runCompiler.
virtual CompilerResultOrError runCompilerImpl(const CompilerOptions &options,
const IR::P4Program *) const;

/// This implementation just forwards the given arguments to the compiler.
///
/// @see @initCompiler.
virtual std::vector<const char *> *initCompilerImpl(int argc, char **argv) const;

/// Parses the P4 program specified on the command line.
///
/// @returns nullptr if an error occurs during parsing.
Expand Down
8 changes: 4 additions & 4 deletions backends/p4tools/common/compiler/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define BACKENDS_P4TOOLS_COMMON_COMPILER_CONTEXT_H_

#include "backends/p4tools/common/compiler/configuration.h"
#include "frontends/common/options.h"
#include "frontends/common/parser_options.h"

namespace P4Tools {

Expand All @@ -18,17 +18,17 @@ class CompileContext : public virtual P4CContext {

template <typename OptionsDerivedType>
explicit CompileContext(CompileContext<OptionsDerivedType> &context)
: optionsInstance(context.options()) {}
: _optionsInstance(context.options()) {}

/// @return the compiler options for this compilation context.
OptionsType &options() override { return optionsInstance; }
OptionsType &options() override { return _optionsInstance; }

protected:
const CompilerConfiguration &getConfigImpl() override { return CompilerConfiguration::get(); }

private:
/// The compiler options for this compilation context.
OptionsType optionsInstance;
OptionsType _optionsInstance;
};

} // namespace P4Tools
Expand Down
98 changes: 84 additions & 14 deletions backends/p4tools/common/core/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
#include <map>
#include <optional>
#include <string>
#include <utility>

#include "backends/p4tools/common/lib/variables.h"
#include "ir/irutils.h"

namespace P4Tools {

Target::Spec::Spec(std::string deviceName, std::string archName)
: deviceName(std::move(deviceName)), archName(std::move(archName)) {
Target::Spec::Spec(std::string_view deviceName, std::string_view archName)
: deviceName(deviceName), archName(archName) {
// Convert names to lower case.
std::transform(this->archName.begin(), this->archName.end(), this->archName.begin(), ::tolower);
std::transform(this->deviceName.begin(), this->deviceName.end(), this->deviceName.begin(),
Expand All @@ -37,8 +36,8 @@ std::map<Target::Spec, std::map<std::string, const Target *, std::less<>>> Targe
std::map<std::string, std::string, std::less<>> Target::defaultArchByDevice = {};
std::map<std::string, std::string, std::less<>> Target::defaultDeviceByArch = {};

bool Target::init(std::string deviceName, std::string archName) {
Spec spec(std::move(deviceName), std::move(archName));
bool Target::init(std::string_view deviceName, std::string_view archName) {
Spec spec(deviceName, archName);

if (registry.count(spec) != 0U) {
curTarget = spec;
Expand All @@ -48,23 +47,95 @@ bool Target::init(std::string deviceName, std::string archName) {
return false;
}

bool Target::setDevice(std::string deviceName) {
std::transform(deviceName.begin(), deviceName.end(), deviceName.begin(), ::tolower);
if (defaultArchByDevice.count(deviceName) == 0U) {
std::optional<ICompileContext *> Target::initializeTarget(std::string_view toolName,
std::string_view target,
std::string_view arch) {
// Establish a dummy compilation context so that we can use ::error to report errors while
// processing target and arch.
class DummyCompileContext : public BaseCompileContext {
} dummyContext;
AutoCompileContext autoDummyContext(&dummyContext);
if (!P4Tools::Target::setDevice(target)) {
::error("Unsupported device: %s", target);
return std::nullopt;
}
if (!P4Tools::Target::setArch(arch)) {
::error("Unsupported architecture: %s", arch);
return std::nullopt;
}
const auto &instances = registry.at(*curTarget);
auto instance = instances.find(toolName);
BUG_CHECK(instance != instances.end(), "Architecture %1% on device %2% not supported for %3%",
curTarget->archName, curTarget->deviceName, toolName);

return instance->second->makeContext();
}

std::optional<ICompileContext *> Target::initializeTarget(std::string_view toolName,
const std::vector<const char *> &args) {
// Establish a dummy compilation context so that we can use ::error to report errors while
// processing target and arch.
class DummyCompileContext : public BaseCompileContext {
} dummyContext;
AutoCompileContext autoDummyContext(&dummyContext);
if (args.size() < 3) {
::error("Missing --target and --arch arguments");
return std::nullopt;
}
std::optional<std::string> target;
std::optional<std::string> arch;
// Loop through arguments (skip the program name)
for (size_t i = 1; i < args.size(); ++i) {
const std::string &arg = args[i];
if (arg == "--arch") {
if (i + 1 < args.size()) {
arch = args[i + 1];
} else {
::error("Missing architecture name after --arch");
return std::nullopt;
}
}
if (arg == "--target") {
if (i + 1 < args.size()) {
target = args[i + 1];
} else {
::error("Missing device name after --target");
return std::nullopt;
}
}
}
if (!target) {
::error("Missing --target argument");
return std::nullopt;
}
if (!arch) {
::error("Missing --arch argument");
return std::nullopt;
}
return initializeTarget(toolName, target.value(), arch.value());
}

bool Target::setDevice(std::string_view deviceName) {
std::string lowerCaseDeviceName(deviceName);
std::transform(lowerCaseDeviceName.begin(), lowerCaseDeviceName.end(),
lowerCaseDeviceName.begin(), ::tolower);
if (defaultArchByDevice.count(lowerCaseDeviceName) == 0U) {
return false;
}

auto archName = curTarget ? curTarget->archName : defaultArchByDevice.at(deviceName);
auto archName = curTarget ? curTarget->archName : defaultArchByDevice.at(deviceName.data());
return init(deviceName, archName);
}

bool Target::setArch(std::string archName) {
std::transform(archName.begin(), archName.end(), archName.begin(), ::tolower);
if (defaultDeviceByArch.count(archName) == 0U) {
bool Target::setArch(std::string_view archName) {
std::string lowerCaseArchName(archName);
std::transform(lowerCaseArchName.begin(), lowerCaseArchName.end(), lowerCaseArchName.begin(),
::tolower);
if (defaultDeviceByArch.count(lowerCaseArchName) == 0U) {
return false;
}

auto deviceName = curTarget ? curTarget->deviceName : defaultDeviceByArch.at(archName);
auto deviceName = curTarget ? curTarget->deviceName : defaultDeviceByArch.at(archName.data());
return init(deviceName, archName);
}

Expand Down Expand Up @@ -92,5 +163,4 @@ Target::Target(std::string_view toolName, const std::string &deviceName,
defaultArchByDevice[spec.deviceName] = spec.archName;
}
}

} // namespace P4Tools
21 changes: 17 additions & 4 deletions backends/p4tools/common/core/target.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#ifndef BACKENDS_P4TOOLS_COMMON_CORE_TARGET_H_
#define BACKENDS_P4TOOLS_COMMON_CORE_TARGET_H_

#include <cstdlib>
#include <map>
#include <optional>
#include <string>

#include "ir/ir.h"
#include "lib/compile_context.h"
#include "lib/exceptions.h"

namespace P4Tools {
Expand All @@ -22,7 +24,7 @@ class Target {
std::string archName;

/// Names provided to this constructor are converted to lower case.
Spec(std::string deviceName, std::string archName);
Spec(std::string_view deviceName, std::string_view archName);

/// Lexicographic ordering on (deviceName, archName).
bool operator<(const Spec &) const;
Expand All @@ -32,23 +34,23 @@ class Target {
///
/// @returns true on success. If initialization fails, false is returned, and nothing is
/// changed.
static bool init(std::string deviceName, std::string archName);
static bool init(std::string_view deviceName, std::string_view archName);

/// Initializes the global target device to @deviceName without changing the architecture. If
/// no architecture was previously selected, then the first architecture registered for the
/// device is chosen.
///
/// @returns true on success. If initialization fails, false is returned, and nothing is
/// changed.
static bool setDevice(std::string deviceName);
static bool setDevice(std::string_view deviceName);

/// Initializes the global target architecture to @archName without changing the device. If no
/// device was previously selected, then the first device registered for the architecture is
/// chosen.
///
/// @returns true on success. If initialization fails, false is returned, and nothing is
/// changed.
static bool setArch(std::string archName);
static bool setArch(std::string_view archName);

/// The name of the tool supported by this instance.
std::string toolName;
Expand All @@ -67,11 +69,22 @@ class Target {
virtual const IR::Expression *createTargetUninitialized(const IR::Type *type,
bool forceTaint) const;

/// Initializes the global target device and architecture to @deviceName and @archName.
/// Returns 0 on success. If initialization fails, returns -1.
static std::optional<ICompileContext *> initializeTarget(std::string_view toolName,
const std::vector<const char *> &args);
static std::optional<ICompileContext *> initializeTarget(std::string_view toolName,
std::string_view target,
std::string_view arch);

protected:
/// Creates and registers a new Target instance for the given @toolName, @deviceName, and
/// @archName.
Target(std::string_view toolName, const std::string &deviceName, const std::string &archName);

/// @returns a new compilation context for the compiler.
[[nodiscard]] virtual ICompileContext *makeContext() const = 0;

/// @returns the target instance for the given tool and active target, as selected by @init.
//
// Implemented here because of limitations of templates.
Expand Down
Loading

0 comments on commit cf25391

Please sign in to comment.