Skip to content

Commit

Permalink
Pass compiler options as argument instead of retrieving them from the…
Browse files Browse the repository at this point in the history
… context. (p4lang#4833)

Signed-off-by: fruffy <[email protected]>
  • Loading branch information
fruffy authored Jul 30, 2024
1 parent b3fc5e2 commit 1a0fc15
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 52 deletions.
46 changes: 21 additions & 25 deletions backends/p4tools/common/compiler/compiler_target.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include "backends/p4tools/common/compiler/compiler_target.h"

#include <functional>
#include <string>
#include <utility>
#include <vector>

#include "backends/p4tools/common/compiler/context.h"
Expand All @@ -27,37 +25,41 @@ std::vector<const char *> *CompilerTarget::initCompiler(std::string_view toolNam
return get(toolName).initCompilerImpl(argc, argv);
}

CompilerResultOrError CompilerTarget::runCompiler(std::string_view toolName) {
const auto *program = P4Tools::CompilerTarget::runParser();
CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options,
std::string_view toolName) {
const auto *program = P4Tools::CompilerTarget::runParser(options);
if (program == nullptr) {
return std::nullopt;
}

return runCompiler(toolName, program);
return runCompiler(options, toolName, program);
}

CompilerResultOrError CompilerTarget::runCompiler(std::string_view toolName,
CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options,
std::string_view toolName,
const std::string &source) {
const auto *program = P4::parseP4String(source, P4CContext::get().options().langVersion);
const auto *program = P4::parseP4String(source, options.langVersion);
if (program == nullptr) {
return std::nullopt;
}

return runCompiler(toolName, program);
return runCompiler(options, toolName, program);
}

CompilerResultOrError CompilerTarget::runCompiler(std::string_view toolName,
CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options,
std::string_view toolName,
const IR::P4Program *program) {
return get(toolName).runCompilerImpl(program);
return get(toolName).runCompilerImpl(options, program);
}

CompilerResultOrError CompilerTarget::runCompilerImpl(const IR::P4Program *program) const {
program = runFrontend(program);
CompilerResultOrError CompilerTarget::runCompilerImpl(const CompilerOptions &options,
const IR::P4Program *program) const {
program = runFrontend(options, program);
if (program == nullptr) {
return std::nullopt;
}

program = runMidEnd(program);
program = runMidEnd(options, program);
if (program == nullptr) {
return std::nullopt;
}
Expand All @@ -70,24 +72,20 @@ ICompileContext *CompilerTarget::makeContextImpl() const {
}

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

const IR::P4Program *CompilerTarget::runParser() {
auto &options = P4CContext::get().options();

const IR::P4Program *CompilerTarget::runParser(const ParserOptions &options) {
const auto *program = P4::parseP4File(options);
if (::errorCount() > 0) {
return nullptr;
}
return program;
}

const IR::P4Program *CompilerTarget::runFrontend(const IR::P4Program *program) const {
// Dynamic cast to get the CompilerOptions from ParserOptions
auto &options = dynamic_cast<CompilerOptions &>(P4CContext::get().options());

const IR::P4Program *CompilerTarget::runFrontend(const CompilerOptions &options,
const IR::P4Program *program) const {
P4::P4COptionPragmaParser optionsPragmaParser;
program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser));

Expand All @@ -109,10 +107,8 @@ MidEnd CompilerTarget::mkMidEnd(const CompilerOptions &options) const {
return midEnd;
}

const IR::P4Program *CompilerTarget::runMidEnd(const IR::P4Program *program) const {
// Dynamic cast to get the CompilerOptions from ParserOptions
auto &options = dynamic_cast<CompilerOptions &>(P4CContext::get().options());

const IR::P4Program *CompilerTarget::runMidEnd(const CompilerOptions &options,
const IR::P4Program *program) const {
auto midEnd = mkMidEnd(options);
midEnd.addDebugHook(options.getDebugHook(), true);
return program->apply(midEnd);
Expand Down
22 changes: 15 additions & 7 deletions backends/p4tools/common/compiler/compiler_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
#include <vector>

#include "backends/p4tools/common/compiler/compiler_result.h"
#include "backends/p4tools/common/compiler/context.h"
#include "backends/p4tools/common/compiler/midend.h"
#include "backends/p4tools/common/core/target.h"
#include "frontends/common/options.h"
#include "frontends/common/parser_options.h"
#include "frontends/p4/frontend.h"
#include "ir/ir.h"
#include "lib/compile_context.h"
Expand All @@ -30,25 +32,29 @@ class CompilerTarget : public Target {
/// program.
///
/// @returns std::nullopt if an error occurs during compilation.
static CompilerResultOrError runCompiler(std::string_view toolName);
static CompilerResultOrError runCompiler(const CompilerOptions &options,
std::string_view toolName);

/// Runs the P4 compiler to produce an IR and other information for the given source code.
///
/// @returns std::nullopt if an error occurs during compilation.
static CompilerResultOrError runCompiler(std::string_view toolName, const std::string &source);
static CompilerResultOrError runCompiler(const CompilerOptions &options,
std::string_view toolName, const std::string &source);

private:
/// Runs the front and mid ends on the given parsed program.
///
/// @returns std::nullopt if an error occurs during compilation.
static CompilerResultOrError runCompiler(std::string_view toolName, const IR::P4Program *);
static CompilerResultOrError runCompiler(const CompilerOptions &options,
std::string_view toolName, const IR::P4Program *);

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

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

/// This implementation just forwards the given arguments to the compiler.
///
Expand All @@ -58,12 +64,13 @@ class CompilerTarget : public Target {
/// Parses the P4 program specified on the command line.
///
/// @returns nullptr if an error occurs during parsing.
static const IR::P4Program *runParser();
static const IR::P4Program *runParser(const ParserOptions &options);

/// Runs the front end of the P4 compiler on the given program.
///
/// @returns nullptr if an error occurs during compilation.
const IR::P4Program *runFrontend(const IR::P4Program *program) const;
const IR::P4Program *runFrontend(const CompilerOptions &options,
const IR::P4Program *program) const;

/// A factory method for providing a target-specific mid end implementation.
[[nodiscard]] virtual MidEnd mkMidEnd(const CompilerOptions &options) const;
Expand All @@ -74,7 +81,8 @@ class CompilerTarget : public Target {
/// Runs the mid end provided by @mkMidEnd on the given program.
///
/// @returns nullptr if an error occurs during compilation.
const IR::P4Program *runMidEnd(const IR::P4Program *program) const;
const IR::P4Program *runMidEnd(const CompilerOptions &options,
const IR::P4Program *program) const;

explicit CompilerTarget(std::string_view toolName, const std::string &deviceName,
const std::string &archName);
Expand Down
12 changes: 6 additions & 6 deletions backends/p4tools/common/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,18 @@ class AbstractP4cToolOptions : protected Util::Options {
/// @returns a compilation context on success, std::nullopt on error.
std::optional<ICompileContext *> process(const std::vector<const char *> &args);

// No copy constructor and no self-assignments.
AbstractP4cToolOptions(const AbstractP4cToolOptions &) = delete;

AbstractP4cToolOptions &operator=(const AbstractP4cToolOptions &) = delete;

protected:
/// Command-line arguments to be sent to the compiler. Populated by @process.
std::vector<const char *> compilerArgs;

/// Hook for customizing options processing.
std::vector<const char *> *process(int argc, char *const argv[]) override;

protected:
// Self-assignments and copy constructor can only be used by other options.
AbstractP4cToolOptions &operator=(const AbstractP4cToolOptions &) = default;
AbstractP4cToolOptions(const AbstractP4cToolOptions &) = default;
AbstractP4cToolOptions(AbstractP4cToolOptions &&) = default;

[[nodiscard]] bool validateOptions() const override;

/// The name of the tool associated with these options.
Expand Down
5 changes: 4 additions & 1 deletion backends/p4tools/common/p4ctool.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
#include <vector>

#include "backends/p4tools/common/compiler/compiler_target.h"
#include "backends/p4tools/common/compiler/context.h"
#include "backends/p4tools/common/lib/logging.h"
#include "backends/p4tools/common/options.h"
#include "frontends/common/options.h"

namespace P4Tools {

Expand Down Expand Up @@ -54,7 +56,8 @@ class AbstractP4cTool {
}

// Run the compiler to get an IR and invoke the tool.
const auto compilerResult = P4Tools::CompilerTarget::runCompiler(toolName);
const auto compilerResult = P4Tools::CompilerTarget::runCompiler(
CompileContext<CompilerOptions>::get().options(), toolName);
if (!compilerResult.has_value()) {
return EXIT_FAILURE;
}
Expand Down
7 changes: 4 additions & 3 deletions backends/p4tools/modules/testgen/core/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,14 @@ CmdStepper *TestgenTarget::getCmdStepper(ExecutionState &state, AbstractSolver &
return get().getCmdStepperImpl(state, solver, programInfo);
}

CompilerResultOrError TestgenTarget::runCompilerImpl(const IR::P4Program *program) const {
program = runFrontend(program);
CompilerResultOrError TestgenTarget::runCompilerImpl(const CompilerOptions &options,
const IR::P4Program *program) const {
program = runFrontend(options, program);
if (program == nullptr) {
return std::nullopt;
}

program = runMidEnd(program);
program = runMidEnd(options, program);
if (program == nullptr) {
return std::nullopt;
}
Expand Down
3 changes: 2 additions & 1 deletion backends/p4tools/modules/testgen/core/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class TestgenTarget : public CompilerTarget {

explicit TestgenTarget(const std::string &deviceName, const std::string &archName);

CompilerResultOrError runCompilerImpl(const IR::P4Program *program) const override;
CompilerResultOrError runCompilerImpl(const CompilerOptions &options,
const IR::P4Program *program) const override;
};

} // namespace P4Tools::P4Testgen
Expand Down
6 changes: 3 additions & 3 deletions backends/p4tools/modules/testgen/targets/bmv2/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ void Bmv2V1ModelTestgenTarget::make() {
}

CompilerResultOrError Bmv2V1ModelTestgenTarget::runCompilerImpl(
const IR::P4Program *program) const {
program = runFrontend(program);
const CompilerOptions &options, const IR::P4Program *program) const {
program = runFrontend(options, program);
if (program == nullptr) {
return std::nullopt;
}
Expand All @@ -54,7 +54,7 @@ CompilerResultOrError Bmv2V1ModelTestgenTarget::runCompilerImpl(
return std::nullopt;
}

program = runMidEnd(program);
program = runMidEnd(options, program);
if (program == nullptr) {
return std::nullopt;
}
Expand Down
3 changes: 2 additions & 1 deletion backends/p4tools/modules/testgen/targets/bmv2/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ class Bmv2V1ModelTestgenTarget : public TestgenTarget {

[[nodiscard]] MidEnd mkMidEnd(const CompilerOptions &options) const override;

CompilerResultOrError runCompilerImpl(const IR::P4Program *program) const override;
CompilerResultOrError runCompilerImpl(const CompilerOptions &options,
const IR::P4Program *program) const override;
};

} // namespace P4Tools::P4Testgen::Bmv2
Expand Down
5 changes: 3 additions & 2 deletions backends/p4tools/modules/testgen/test/gtest_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ std::optional<const P4ToolsTestCase> P4ToolsTestCase::create(
P4Tools::CompilerTarget::makeContext(P4Tools::P4Testgen::TOOL_NAME));
P4CContext::get().options().langVersion = langVersion;

auto compilerResults =
P4Tools::CompilerTarget::runCompiler(P4Tools::P4Testgen::TOOL_NAME, source);
auto compilerResults = P4Tools::CompilerTarget::runCompiler(
P4Tools::CompileContext<CompilerOptions>::get().options(), P4Tools::P4Testgen::TOOL_NAME,
source);
if (!compilerResults.has_value()) {
return std::nullopt;
}
Expand Down
6 changes: 3 additions & 3 deletions backends/p4tools/modules/testgen/testgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,15 @@ std::optional<AbstractTestList> generateTestsImpl(std::optional<std::string_view
CompilerResultOrError compilerResultOpt;
if (program.has_value()) {
// Run the compiler to get an IR and invoke the tool.
compilerResultOpt =
P4Tools::CompilerTarget::runCompiler(TOOL_NAME, std::string(program.value()));
compilerResultOpt = P4Tools::CompilerTarget::runCompiler(compilerOptions, TOOL_NAME,
std::string(program.value()));
} else {
if (compilerOptions.file.empty()) {
::error("Expected a file input.");
return std::nullopt;
}
// Run the compiler to get an IR and invoke the tool.
compilerResultOpt = P4Tools::CompilerTarget::runCompiler(TOOL_NAME);
compilerResultOpt = P4Tools::CompilerTarget::runCompiler(compilerOptions, TOOL_NAME);
}

if (!compilerResultOpt.has_value()) {
Expand Down

0 comments on commit 1a0fc15

Please sign in to comment.