Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[P4Testgen] Run typechecking after front and mid end. #4834

Merged
merged 1 commit into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions backends/p4tools/common/compiler/compiler_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "frontends/common/parseInput.h"
#include "frontends/common/parser_options.h"
#include "frontends/p4/frontend.h"
#include "lib/compile_context.h"
#include "lib/error.h"

namespace P4::P4Tools {
Expand All @@ -27,7 +26,7 @@ CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options
CompilerResultOrError CompilerTarget::runCompiler(const CompilerOptions &options,
std::string_view toolName,
const std::string &source) {
const auto *program = P4::parseP4String(source, options.langVersion);
const auto *program = parseP4String(source, options.langVersion);
if (program == nullptr) {
return std::nullopt;
}
Expand Down Expand Up @@ -57,7 +56,7 @@ CompilerResultOrError CompilerTarget::runCompilerImpl(const CompilerOptions &opt
}

const IR::P4Program *CompilerTarget::runParser(const ParserOptions &options) {
const auto *program = P4::parseP4File(options);
const auto *program = parseP4File(options);
if (errorCount() > 0) {
return nullptr;
}
Expand All @@ -66,12 +65,16 @@ const IR::P4Program *CompilerTarget::runParser(const ParserOptions &options) {

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

auto frontEnd = mkFrontEnd();
frontEnd.addDebugHook(options.getDebugHook());
program = frontEnd.run(options, program);
ReferenceMap refMap;
TypeMap typeMap;
// Perform a last round of type checking.
program = program->apply(TypeChecking(&refMap, &typeMap, true));
if ((program == nullptr) || errorCount() > 0) {
return nullptr;
}
Expand Down
12 changes: 10 additions & 2 deletions backends/p4tools/common/compiler/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,23 @@ void MidEnd::addDefaultPasses() {
new P4::EliminateTuples(&typeMap),
new P4::ConstantFolding(&typeMap),
new P4::SimplifyControlFlow(&typeMap),
// Perform a last round of type-checking before passes which do not type-check begin.
new P4::TypeChecking(&refMap, &typeMap, true),
});
addNonTypeCheckingPasses();
}

void MidEnd::addNonTypeCheckingPasses() {
addPasses({
// Simplify header stack assignments with runtime indices into conditional statements.
new P4::HSIndexSimplifier(&typeMap),
// Convert Type_Varbits into a type that contains information about the assigned width.
// Convert Type_Varbits into a type that contains information about the assigned
// width.
new ConvertVarbits(),
// Convert any StructExpressions with Type_Header into a HeaderExpression.
new ConvertStructExpr(&typeMap),
// Cast all boolean table keys with a bit<1>.
new P4::CastBooleanTableKeys(),
});
}

} // namespace P4::P4Tools
6 changes: 5 additions & 1 deletion backends/p4tools/common/compiler/midend.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ class MidEnd : public PassManager {

/// Add the list of default passes to the mid end. This is not part of the initializer because
/// some targets may add their own passes to the beginning of the pass list.
void addDefaultPasses();
virtual void addDefaultPasses();

/// Add passes that break type checking. These passes may involve IR modifications the front
/// end type checker does not recognize.
virtual void addNonTypeCheckingPasses();
Comment on lines +69 to +71
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the problem here? It seems very suspicious to have IR that does not type check. If this is because of custom IR nodes, it might be better to use a derived type check that supports them. Or at least (for now?) comment more on the reasons why this does not type check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the passes contained in this list perform transformations that are useful for the interpreter but TypeChecking can fail on.

The two most problematic ones is the HSIndexSimplifier which converts array indices to members and ConvertVarbits which creates a new varbit type that is not recognized.

CastBooleanTableKeys converts boolean table keys to bit<1>, which type checking also might not support (I have not checked).

All these passes could be handled in the interpreter but it might be a fair bit of work.

};

} // namespace P4::P4Tools
Expand Down
Loading