From bfb4f08bf8ce13351be95bd2d3233675b2ef263d Mon Sep 17 00:00:00 2001 From: Chris Dodd Date: Mon, 10 Feb 2025 21:16:45 +0000 Subject: [PATCH] @command_line annotation - per-target selectable support, though most should want it Signed-off-by: Chris Dodd --- backends/bmv2/pna_nic/main.cpp | 2 +- backends/bmv2/psa_switch/main.cpp | 2 +- backends/bmv2/simple_switch/main.cpp | 2 +- backends/dpdk/main.cpp | 2 +- backends/ebpf/p4c-ebpf.cpp | 2 +- backends/graphs/p4c-graphs.cpp | 2 +- backends/p4test/p4test.cpp | 2 +- .../p4tools/common/compiler/compiler_target.cpp | 2 +- backends/tc/tc.cpp | 2 +- backends/tofino/bf-p4c/bf-p4c-options.h | 3 +++ frontends/common/applyOptionsPragmas.cpp | 16 ++++++++++++++++ frontends/common/applyOptionsPragmas.h | 4 ++++ frontends/p4/parseAnnotations.cpp | 3 +++ test/gtest/helpers.cpp | 2 +- 14 files changed, 36 insertions(+), 10 deletions(-) diff --git a/backends/bmv2/pna_nic/main.cpp b/backends/bmv2/pna_nic/main.cpp index 2f6872ec86e..b1fe62a00c0 100644 --- a/backends/bmv2/pna_nic/main.cpp +++ b/backends/bmv2/pna_nic/main.cpp @@ -65,7 +65,7 @@ int main(int argc, char *const argv[]) { if (program == nullptr || ::P4::errorCount() > 0) return 1; try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; diff --git a/backends/bmv2/psa_switch/main.cpp b/backends/bmv2/psa_switch/main.cpp index 767fa312212..ecbead9033c 100644 --- a/backends/bmv2/psa_switch/main.cpp +++ b/backends/bmv2/psa_switch/main.cpp @@ -65,7 +65,7 @@ int main(int argc, char *const argv[]) { if (program == nullptr || ::P4::errorCount() > 0) return 1; try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; diff --git a/backends/bmv2/simple_switch/main.cpp b/backends/bmv2/simple_switch/main.cpp index aaaa5aa0b44..bfa8c1b7c49 100644 --- a/backends/bmv2/simple_switch/main.cpp +++ b/backends/bmv2/simple_switch/main.cpp @@ -68,7 +68,7 @@ int main(int argc, char *const argv[]) { if (program == nullptr || ::P4::errorCount() > 0) return 1; try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; diff --git a/backends/dpdk/main.cpp b/backends/dpdk/main.cpp index 6feba253855..91ea4ff9edf 100644 --- a/backends/dpdk/main.cpp +++ b/backends/dpdk/main.cpp @@ -86,7 +86,7 @@ int main(int argc, char *const argv[]) { if (program == nullptr || ::P4::errorCount() > 0) return 1; try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; diff --git a/backends/ebpf/p4c-ebpf.cpp b/backends/ebpf/p4c-ebpf.cpp index 9c64fd411b1..563ff1c669a 100644 --- a/backends/ebpf/p4c-ebpf.cpp +++ b/backends/ebpf/p4c-ebpf.cpp @@ -66,7 +66,7 @@ void compile(EbpfOptions &options) { program = P4::parseP4File(options); if (::P4::errorCount() > 0) return; - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; diff --git a/backends/graphs/p4c-graphs.cpp b/backends/graphs/p4c-graphs.cpp index d131ec0fa6e..a1d50612bf1 100644 --- a/backends/graphs/p4c-graphs.cpp +++ b/backends/graphs/p4c-graphs.cpp @@ -162,7 +162,7 @@ int main(int argc, char *const argv[]) { if (program == nullptr || ::P4::errorCount() > 0) return 1; try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(false); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd fe; diff --git a/backends/p4test/p4test.cpp b/backends/p4test/p4test.cpp index 82d85a13a14..a94834a4894 100644 --- a/backends/p4test/p4test.cpp +++ b/backends/p4test/p4test.cpp @@ -135,7 +135,7 @@ int main(int argc, char *const argv[]) { info.emitInfo("PARSER"); if (program != nullptr && ::P4::errorCount() == 0) { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); info.emitInfo("PASS P4COptionPragmaParser"); diff --git a/backends/p4tools/common/compiler/compiler_target.cpp b/backends/p4tools/common/compiler/compiler_target.cpp index 96a05c29fb7..54d29c2a81b 100644 --- a/backends/p4tools/common/compiler/compiler_target.cpp +++ b/backends/p4tools/common/compiler/compiler_target.cpp @@ -65,7 +65,7 @@ const IR::P4Program *CompilerTarget::runParser(const ParserOptions &options) { const IR::P4Program *CompilerTarget::runFrontend(const CompilerOptions &options, const IR::P4Program *program) const { - P4COptionPragmaParser optionsPragmaParser; + P4COptionPragmaParser optionsPragmaParser(false); program->apply(ApplyOptionsPragmas(optionsPragmaParser)); auto frontEnd = mkFrontEnd(); diff --git a/backends/tc/tc.cpp b/backends/tc/tc.cpp index ece7ec7a3f8..a3c938ef8f9 100644 --- a/backends/tc/tc.cpp +++ b/backends/tc/tc.cpp @@ -55,7 +55,7 @@ int main(int argc, char *const argv[]) { return 1; } try { - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); P4::FrontEnd frontend; frontend.addDebugHook(hook); diff --git a/backends/tofino/bf-p4c/bf-p4c-options.h b/backends/tofino/bf-p4c/bf-p4c-options.h index f4f0217c01e..48c8c33e045 100644 --- a/backends/tofino/bf-p4c/bf-p4c-options.h +++ b/backends/tofino/bf-p4c/bf-p4c-options.h @@ -223,6 +223,9 @@ class BFNOptionPragmaParser : public P4::P4COptionPragmaParser { public: std::optional tryToParse(const IR::Annotation *annotation) override; + BFNOptionPragmaParser() : P4::P4COptionPragmaParser(false) {} + // FIXME -- should remove the tofino @command_line stuff and use the base class + private: std::optional parseCompilerOption(const IR::Annotation *annotation); }; diff --git a/frontends/common/applyOptionsPragmas.cpp b/frontends/common/applyOptionsPragmas.cpp index fab308c2844..bcd6b76dead 100644 --- a/frontends/common/applyOptionsPragmas.cpp +++ b/frontends/common/applyOptionsPragmas.cpp @@ -51,6 +51,22 @@ std::optional P4COptionPragmaParser::tr const IR::Annotation *annotation) { auto pragmaName = annotation->name.name; if (pragmaName == "diagnostic") return parseDiagnostic(annotation); + if (supportCommandLinePragma && pragmaName == "command_line") { + IOptionPragmaParser::CommandLineOptions options; + auto *args = annotation->needsParsing() + ? P4ParserDriver::parseExpressionList(annotation->srcInfo, + annotation->getUnparsed()) + : &annotation->getExpr(); + for (auto *arg : *args) { + if (auto *a = arg->to()) { + options.push_back(a->value.c_str()); + } else { + // can this happen? annotation parser should require only strings + warning("ignoring non-string %1% in @command_line", a); + } + } + return options; + } return std::nullopt; } diff --git a/frontends/common/applyOptionsPragmas.h b/frontends/common/applyOptionsPragmas.h index e2c4c55f4db..d79ead6d5d3 100644 --- a/frontends/common/applyOptionsPragmas.h +++ b/frontends/common/applyOptionsPragmas.h @@ -76,9 +76,13 @@ class ApplyOptionsPragmas : public Inspector { * they're unable to parse a pragma. */ class P4COptionPragmaParser : public IOptionPragmaParser { + bool supportCommandLinePragma; + public: std::optional tryToParse(const IR::Annotation *annotation) override; + explicit P4COptionPragmaParser(bool sCLP) : supportCommandLinePragma(sCLP) {} + private: std::optional parseDiagnostic(const IR::Annotation *annotation); }; diff --git a/frontends/p4/parseAnnotations.cpp b/frontends/p4/parseAnnotations.cpp index b6d8ab12459..14500c2891b 100644 --- a/frontends/p4/parseAnnotations.cpp +++ b/frontends/p4/parseAnnotations.cpp @@ -51,6 +51,9 @@ ParseAnnotations::HandlerMap ParseAnnotations::standardHandlers() { // @match has an expression argument PARSE(IR::Annotation::matchAnnotation, Expression), + + // @command_line to add to the command line + PARSE_STRING_LITERAL_LIST("command_line"_cs), }; } diff --git a/test/gtest/helpers.cpp b/test/gtest/helpers.cpp index 2beb6c3125a..6ba789b269f 100644 --- a/test/gtest/helpers.cpp +++ b/test/gtest/helpers.cpp @@ -178,7 +178,7 @@ namespace P4::Test { return std::nullopt; } - P4::P4COptionPragmaParser optionsPragmaParser; + P4::P4COptionPragmaParser optionsPragmaParser(true); program->apply(P4::ApplyOptionsPragmas(optionsPragmaParser)); if (::P4::errorCount() > 0) { std::cerr << "Encountered " << ::P4::errorCount()