Skip to content

Commit

Permalink
Add an option to copy structures to skip expanding header unions.
Browse files Browse the repository at this point in the history
Signed-off-by: fruffy <[email protected]>
  • Loading branch information
fruffy committed Aug 30, 2024
1 parent fa7720e commit 32869dc
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 24 deletions.
2 changes: 1 addition & 1 deletion backends/bmv2/pna_nic/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ PnaNicMidEnd::PnaNicMidEnd(CompilerOptions &options, std::ostream *outStream)
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, P4::CopyStructuresConfig()),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
Expand Down
2 changes: 1 addition & 1 deletion backends/bmv2/psa_switch/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ PsaSwitchMidEnd::PsaSwitchMidEnd(CompilerOptions &options, std::ostream *outStre
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, P4::CopyStructuresConfig()),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
Expand Down
2 changes: 1 addition & 1 deletion backends/bmv2/simple_switch/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ SimpleSwitchMidEnd::SimpleSwitchMidEnd(CompilerOptions &options, std::ostream *o
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, P4::CopyStructuresConfig()),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
Expand Down
7 changes: 6 additions & 1 deletion backends/dpdk/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,12 @@ DpdkMidEnd::DpdkMidEnd(CompilerOptions &options, std::ostream *outStream) {
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, false /* errorOnMethodCall */),
new P4::CopyStructures(&refMap, &typeMap,
P4::CopyStructuresConfig{
/*errorOnMethodCall*/ false,
/*copyHeaders*/ false,
/*expandUnions*/ true,
}),
new P4::NestedStructs(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::RemoveSelectBooleans(&refMap, &typeMap),
Expand Down
7 changes: 6 additions & 1 deletion backends/p4test/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ MidEnd::MidEnd(CompilerOptions &options, std::ostream *outStream) {
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, false),
new P4::CopyStructures(&refMap, &typeMap,
P4::CopyStructuresConfig{
/*errorOnMethodCall*/ false,
/*copyHeaders*/ false,
/*expandUnions*/ true,
}),
new P4::NestedStructs(&refMap, &typeMap),
new P4::StrengthReduction(&typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
Expand Down
8 changes: 7 additions & 1 deletion backends/p4tools/common/compiler/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ void MidEnd::addDefaultPasses() {
new P4::SimplifyComparisons(&refMap, &typeMap),
// Expand header and struct assignments into sequences of field assignments.
new PassRepeated({
new P4::CopyStructures(&refMap, &typeMap, false, true, nullptr),
new P4::CopyStructures(&refMap, &typeMap,
{
/*errorOnMethodCall*/ false,
/*copyHeaders*/ true,
/*expandUnions*/ false,
},
nullptr),
}),
new P4::RemoveParserControlFlow(&typeMap),
// Flatten nested list expressions.
Expand Down
2 changes: 1 addition & 1 deletion backends/ubpf/midend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const IR::ToplevelBlock *MidEnd::run(EbpfOptions &options, const IR::P4Program *
new P4::StrengthReduction(&typeMap),
}),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, P4::CopyStructuresConfig()),
new P4::LocalCopyPropagation(&refMap, &typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
new P4::MoveDeclarations(), // more may have been introduced
Expand Down
9 changes: 5 additions & 4 deletions midend/copyStructures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ const IR::Node *DoCopyStructures::postorder(IR::AssignmentStatement *statement)
FIXME: this is not correct for header unions and should be fixed.
The fix bellow, commented-out, causes problems elsewhere.
https://github.com/p4lang/p4c/issues/3842
if (ltype->is<IR::Type_HeaderUnion>())
return statement;
*/
if (!_config.expandUnions && ltype->is<IR::Type_HeaderUnion>()) {
return statement;
}

// Do not copy structures for method calls.
if (statement->right->is<IR::MethodCallExpression>()) {
if (errorOnMethodCall) {
if (_config.errorOnMethodCall) {
::P4::error(ErrorType::ERR_UNSUPPORTED_ON_TARGET,
"%1%: functions or methods returning structures "
"are not supported on this target",
Expand All @@ -98,7 +99,7 @@ const IR::Node *DoCopyStructures::postorder(IR::AssignmentStatement *statement)
retval->push_back(
new IR::AssignmentStatement(statement->srcInfo, left, right->expression));
}
} else if (copyHeaders && ltype->is<IR::Type_Header>()) {
} else if (_config.copyHeaders && ltype->is<IR::Type_Header>()) {
const auto *header = ltype->checkedTo<IR::Type_Header>();
// Build a "src.isValid()" call.
const auto *isSrcValidCall = new IR::MethodCallExpression(
Expand Down
35 changes: 23 additions & 12 deletions midend/copyStructures.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ limitations under the License.

namespace P4 {

struct CopyStructuresConfig {
/// Specific targets may allow functions or methods to return structs.
/// Such methods will not be converted in this pass. Setting the
/// errorOnMethodCall flag will produce an error message if such a
/// method is encountered.
bool errorOnMethodCall = true;

/// Do not only copy normal structures but also perform copy assignments for headers.
bool copyHeaders = false;
/// Also expand header union assignments.
/// TODO: This is only necessary because the copy structure pass does not correctly expand
/// header unions for some back ends.
bool expandUnions = true;
};

/**
* Convert assignments between structures to assignments between fields
*
Expand Down Expand Up @@ -53,19 +68,15 @@ namespace P4 {
*
*/
class DoCopyStructures : public Transform {
/// The type map.
TypeMap *typeMap;
/// Specific targets may allow functions or methods to return structs.
/// Such methods will not be converted in this pass. Setting the
/// errorOnMethodCall flag will produce an error message if such a
/// method is encountered.
bool errorOnMethodCall;

/// Do not only copy normal structures but also perform copy assignments for headers.
bool copyHeaders;
/// Configuration options.
CopyStructuresConfig _config;

public:
explicit DoCopyStructures(TypeMap *typeMap, bool errorOnMethodCall, bool copyHeaders = false)
: typeMap(typeMap), errorOnMethodCall(errorOnMethodCall), copyHeaders(copyHeaders) {
explicit DoCopyStructures(TypeMap *typeMap, CopyStructuresConfig config)
: typeMap(typeMap), _config(config) {
CHECK_NULL(typeMap);
setName("DoCopyStructures");
}
Expand Down Expand Up @@ -111,8 +122,8 @@ class RemoveAliases : public Transform {

class CopyStructures : public PassRepeated {
public:
explicit CopyStructures(ReferenceMap *refMap, TypeMap *typeMap, bool errorOnMethodCall = true,
bool copyHeaders = false, TypeChecking *typeChecking = nullptr)
explicit CopyStructures(ReferenceMap *refMap, TypeMap *typeMap, CopyStructuresConfig config,
TypeChecking *typeChecking = nullptr)
: PassManager({}) {
CHECK_NULL(refMap);
CHECK_NULL(typeMap);
Expand All @@ -123,7 +134,7 @@ class CopyStructures : public PassRepeated {
passes.emplace_back(typeChecking);
passes.emplace_back(new RemoveAliases(refMap, typeMap));
passes.emplace_back(typeChecking);
passes.emplace_back(new DoCopyStructures(typeMap, errorOnMethodCall, copyHeaders));
passes.emplace_back(new DoCopyStructures(typeMap, config));
}
};

Expand Down
2 changes: 1 addition & 1 deletion test/gtest/midend_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ MidEnd::MidEnd(CompilerOptions &options, std::ostream *outStream) {
new P4::StrengthReduction(&typeMap),
new P4::EliminateTuples(&refMap, &typeMap),
new P4::SimplifyComparisons(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap),
new P4::CopyStructures(&refMap, &typeMap, P4::CopyStructuresConfig()),
new P4::NestedStructs(&refMap, &typeMap),
new P4::StrengthReduction(&typeMap),
new P4::SimplifySelectList(&refMap, &typeMap),
Expand Down

0 comments on commit 32869dc

Please sign in to comment.