Skip to content

Commit

Permalink
Remove ReferenceMap from top-level frontend passes (p4lang#4947)
Browse files Browse the repository at this point in the history
* Move unused declarations out of refmap

Signed-off-by: Anton Korobeynikov <[email protected]>

* Switch RemoveUnusedHUDeclarations to UsedSet

Signed-off-by: Anton Korobeynikov <[email protected]>

* Rename UsedSet => UsedDeclsSet

Signed-off-by: Anton Korobeynikov <[email protected]>

* Remove yet another refmap instance

Signed-off-by: Anton Korobeynikov <[email protected]>

* Make ReferenceMap an internal business of Inliner

Signed-off-by: Anton Korobeynikov <[email protected]>

* Move ReferenceMap inside Evaluator and SimplifyDefUse

Signed-off-by: Anton Korobeynikov <[email protected]>

* Add convenient helper to check for shadowing from ResolveReferences

Signed-off-by: Anton Korobeynikov <[email protected]>

* Typo

Signed-off-by: Anton Korobeynikov <[email protected]>

* Address review comments

Signed-off-by: Anton Korobeynikov <[email protected]>

---------

Signed-off-by: Anton Korobeynikov <[email protected]>
  • Loading branch information
asl authored Oct 10, 2024
1 parent 6eaa655 commit d2006d5
Show file tree
Hide file tree
Showing 20 changed files with 217 additions and 110 deletions.
2 changes: 1 addition & 1 deletion backends/bmv2/pna_nic/pnaNic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void PnaNicBackend::convert(const IR::ToplevelBlock *tlb) {
new P4::RemoveComplexExpressions(typeMap,
new ProcessControls(&structure.pipeline_controls)),
new P4::SimplifyControlFlow(typeMap),
new P4::RemoveAllUnusedDeclarations(refMap, P4::RemoveUnusedPolicy()),
new P4::RemoveAllUnusedDeclarations(P4::RemoveUnusedPolicy()),
// Converts the DAG into a TREE (at least for expressions)
// This is important later for conversion to JSON.
new P4::CloneExpressions(),
Expand Down
2 changes: 1 addition & 1 deletion backends/bmv2/psa_switch/psaSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ void PsaSwitchBackend::convert(const IR::ToplevelBlock *tlb) {
new P4::RemoveComplexExpressions(typeMap,
new ProcessControls(&structure.pipeline_controls)),
new P4::SimplifyControlFlow(typeMap),
new P4::RemoveAllUnusedDeclarations(refMap, P4::RemoveUnusedPolicy()),
new P4::RemoveAllUnusedDeclarations(P4::RemoveUnusedPolicy()),
// Converts the DAG into a TREE (at least for expressions)
// This is important later for conversion to JSON.
new P4::CloneExpressions(),
Expand Down
8 changes: 4 additions & 4 deletions backends/bmv2/simple_switch/simpleSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1175,20 +1175,20 @@ void SimpleSwitchBackend::convert(const IR::ToplevelBlock *tlb) {
new P4::SynthesizeActions(refMap, typeMap,
new SkipControls(&structure->non_pipeline_controls)),
new P4::MoveActionsToTables(refMap, typeMap),
new P4::TypeChecking(refMap, typeMap),
new P4::TypeChecking(nullptr, typeMap),
new P4::SimplifyControlFlow(typeMap),
new LowerExpressions(typeMap),
new P4::ConstantFolding(typeMap, false),
new P4::TypeChecking(refMap, typeMap),
new P4::TypeChecking(nullptr, typeMap),
new RemoveComplexExpressions(typeMap, new ProcessControls(&structure->pipeline_controls)),
new P4::SimplifyControlFlow(typeMap),
new P4::RemoveAllUnusedDeclarations(refMap, P4::RemoveUnusedPolicy()),
new P4::RemoveAllUnusedDeclarations(P4::RemoveUnusedPolicy()),
new P4::FlattenLogMsg(typeMap),
// Converts the DAG into a TREE (at least for expressions)
// This is important later for conversion to JSON.
new P4::CloneExpressions(),
new P4::ClearTypeMap(typeMap),
new P4::TypeChecking(refMap, typeMap, true),
new P4::TypeChecking(nullptr, typeMap, true),
evaluator,
[this, evaluator]() { toplevel = evaluator->getToplevelBlock(); },
});
Expand Down
3 changes: 1 addition & 2 deletions backends/dpdk/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ void DpdkBackend::convert(const IR::ToplevelBlock *tlb) {
new DismantleMuxExpressions(typeMap, refMap),
new P4::ConstantFolding(typeMap, false),
new EliminateHeaderCopy(refMap, typeMap),
new P4::TypeChecking(refMap, typeMap),
new P4::RemoveAllUnusedDeclarations(refMap, P4::RemoveUnusedPolicy()),
new P4::RemoveAllUnusedDeclarations(P4::RemoveUnusedPolicy()),
new ConvertActionSelectorAndProfile(refMap, typeMap, &structure),
new CollectTableInfo(&structure),
new CollectAddOnMissTable(refMap, typeMap, &structure),
Expand Down
14 changes: 14 additions & 0 deletions frontends/common/resolveReferences/resolveReferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ limitations under the License.

#include "absl/container/flat_hash_map.h"
#include "absl/container/inlined_vector.h"
#include "frontends/common/parser_options.h"
#include "ir/ir.h"
#include "ir/pass_manager.h"
#include "lib/cstring.h"
#include "lib/iterator_range.h"
#include "referenceMap.h"
Expand Down Expand Up @@ -170,6 +172,18 @@ class ResolveReferences : public Inspector, private ResolutionContext {
void checkShadowing(const IR::INamespace *ns) const;
};

class CheckShadowing : public PassManager {
ReferenceMap refMap;

public:
CheckShadowing() {
refMap.setIsV1(P4CContext::get().options().isv1());

addPasses({new ResolveReferences(&refMap, /* checkShadow */ true)});
setName("CheckShadowing");
}
};

} // namespace P4

#endif /* COMMON_RESOLVEREFERENCES_RESOLVEREFERENCES_H_ */
5 changes: 2 additions & 3 deletions frontends/p4/actionsInlining.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ class InlineActions : public PassManager {
ActionsInlineList actionsToInline;

public:
InlineActions(ReferenceMap *refMap, TypeMap *typeMap, const RemoveUnusedPolicy &policy) {
InlineActions(TypeMap *typeMap, const RemoveUnusedPolicy &policy) {
passes.push_back(new TypeChecking(nullptr, typeMap));
passes.push_back(new DiscoverActionsInlining(&actionsToInline, typeMap));
passes.push_back(new InlineActionsDriver(&actionsToInline, new ActionsInliner()));
passes.push_back(new ResolveReferences(refMap));
passes.push_back(new RemoveAllUnusedDeclarations(refMap, policy));
passes.push_back(new RemoveAllUnusedDeclarations(policy));
setName("InlineActions");
}
};
Expand Down
7 changes: 7 additions & 0 deletions frontends/p4/evaluator/evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
#include "evaluator.h"

#include "frontends/common/constantFolding.h"
#include "frontends/common/parser_options.h"
#include "frontends/common/resolveReferences/referenceMap.h"
#include "frontends/p4/parameterSubstitution.h"
#include "frontends/p4/typeChecking/typeChecker.h"

Expand Down Expand Up @@ -352,6 +354,11 @@ bool Evaluator::preorder(const IR::StructExpression *se) {

EvaluatorPass::EvaluatorPass(ReferenceMap *refMap, TypeMap *typeMap) {
setName("EvaluatorPass");
if (!refMap) {
selfRefMap.reset(new ReferenceMap);
selfRefMap->setIsV1(P4CContext::get().options().isv1());
refMap = selfRefMap.get();
}
evaluator = new P4::Evaluator(refMap, typeMap);
passes.emplace_back(new P4::TypeChecking(refMap, typeMap));
passes.emplace_back(evaluator);
Expand Down
3 changes: 3 additions & 0 deletions frontends/p4/evaluator/evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
#ifndef EVALUATOR_EVALUATOR_H_
#define EVALUATOR_EVALUATOR_H_

#include "frontends/common/resolveReferences/referenceMap.h"
#include "frontends/common/resolveReferences/resolveReferences.h"
#include "frontends/p4/typeMap.h"
#include "ir/ir.h"
Expand Down Expand Up @@ -113,10 +114,12 @@ class Evaluator final : public Inspector, public IHasBlock {
/// high-level constructs.
class EvaluatorPass final : public PassManager, public IHasBlock {
P4::Evaluator *evaluator;
std::unique_ptr<ReferenceMap> selfRefMap;

public:
IR::ToplevelBlock *getToplevelBlock() const override { return evaluator->getToplevelBlock(); }
EvaluatorPass(ReferenceMap *refMap, TypeMap *typeMap);
explicit EvaluatorPass(TypeMap *typeMap) : EvaluatorPass(nullptr, typeMap) {}
};

} // namespace P4
Expand Down
32 changes: 14 additions & 18 deletions frontends/p4/frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,17 +149,13 @@ const IR::P4Program *FrontEnd::run(const CompilerOptions &options, const IR::P4P
std::ostream *outStream) {
if (program == nullptr && options.listFrontendPasses == 0) return nullptr;

bool isv1 = options.isv1();
ReferenceMap refMap;
TypeMap typeMap;
refMap.setIsV1(isv1);

ParseAnnotations *parseAnnotations = policy->getParseAnnotations();
if (!parseAnnotations) parseAnnotations = new ParseAnnotations();

ConstantFoldingPolicy *constantFoldingPolicy = policy->getConstantFoldingPolicy();

auto evaluator = new P4::EvaluatorPass(&refMap, &typeMap);
PassManager passes({
new P4V1::GetV1ModelVersion,
// Parse annotations
Expand All @@ -169,7 +165,7 @@ const IR::P4Program *FrontEnd::run(const CompilerOptions &options, const IR::P4P
new ValidateParsedProgram(),
// Synthesize some built-in constructs
new CreateBuiltins(),
new ResolveReferences(&refMap, /* checkShadow */ true),
new CheckShadowing(),
// First pass of constant folding, before types are known --
// may be needed to compute types.
new ConstantFolding(constantFoldingPolicy),
Expand Down Expand Up @@ -212,7 +208,7 @@ const IR::P4Program *FrontEnd::run(const CompilerOptions &options, const IR::P4P
new SimplifyControlFlow(&typeMap),
new SwitchAddDefault,
new FrontEndDump(), // used for testing the program at this point
new RemoveAllUnusedDeclarations(&refMap, *policy, true),
new RemoveAllUnusedDeclarations(*policy, true),
new SimplifyParsers(),
new ResetHeaders(&typeMap),
new UniqueNames(), // Give each local declaration a unique internal name
Expand All @@ -222,31 +218,31 @@ const IR::P4Program *FrontEnd::run(const CompilerOptions &options, const IR::P4P
new SimplifyControlFlow(&typeMap),
new SimplifySwitch(&typeMap),
new MoveDeclarations(), // Move all local declarations to the beginning
new SimplifyDefUse(&refMap, &typeMap),
new SimplifyDefUse(&typeMap),
new UniqueParameters(&typeMap),
new SimplifyControlFlow(&typeMap),
new SpecializeAll(&refMap, &typeMap, policy),
new SpecializeAll(&typeMap, policy),
new RemoveParserControlFlow(&typeMap),
new RemoveReturns(),
new RemoveDontcareArgs(&typeMap),
new MoveConstructors(),
new RemoveAllUnusedDeclarations(&refMap, *policy),
new RemoveRedundantParsers(&refMap, &typeMap, *policy),
new RemoveAllUnusedDeclarations(*policy),
new RemoveRedundantParsers(&typeMap, *policy),
new ClearTypeMap(&typeMap),
evaluator,
new EvaluatorPass(&typeMap),
});
if (policy->optimize(options)) {
passes.addPasses({
new Inline(&refMap, &typeMap, evaluator, *policy, options.optimizeParserInlining),
new InlineActions(&refMap, &typeMap, *policy),
new LocalizeAllActions(&refMap, *policy),
new Inline(&typeMap, *policy, options.optimizeParserInlining),
new InlineActions(&typeMap, *policy),
new LocalizeAllActions(*policy),
new UniqueNames(),
new UniqueParameters(&typeMap),
// Must be done before inlining functions, to allow
// function calls used as action arguments to be inlined
// in the proper place.
new RemoveActionParameters(&typeMap),
new InlineFunctions(&refMap, &typeMap, *policy),
new InlineFunctions(&typeMap, *policy),
new SetHeaders(&typeMap),
// Check for constants only after inlining
new CheckConstants(&typeMap),
Expand All @@ -256,15 +252,15 @@ const IR::P4Program *FrontEnd::run(const CompilerOptions &options, const IR::P4P
new RemoveParserControlFlow(&typeMap),
new UniqueNames(), // needed again after inlining
new MoveDeclarations(), // needed again after inlining
new SimplifyDefUse(&refMap, &typeMap),
new RemoveAllUnusedDeclarations(&refMap, *policy),
new SimplifyDefUse(&typeMap),
new RemoveAllUnusedDeclarations(*policy),
new SimplifyControlFlow(&typeMap),
});
}
passes.addPasses({
// Check for shadowing after all inlining passes. We disable this
// check during inlining since it significantly slows compilation.
new ResolveReferences(&refMap, /* checkShadow */ true),
new CheckShadowing(),
new HierarchicalNames(),
new FrontEndLast(),
});
Expand Down
12 changes: 6 additions & 6 deletions frontends/p4/functionsInlining.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ class InlineFunctions : public PassManager {
FunctionsInlineList functionsToInline;

public:
InlineFunctions(ReferenceMap *refMap, TypeMap *typeMap, const RemoveUnusedPolicy &policy) {
passes.push_back(new PassRepeated(
{new TypeChecking(nullptr, typeMap),
new DiscoverFunctionsInlining(&functionsToInline, typeMap),
new InlineFunctionsDriver(&functionsToInline, new FunctionsInliner()),
new ResolveReferences(refMap), new RemoveAllUnusedDeclarations(refMap, policy)}));
InlineFunctions(TypeMap *typeMap, const RemoveUnusedPolicy &policy) {
passes.push_back(
new PassRepeated({new TypeChecking(nullptr, typeMap),
new DiscoverFunctionsInlining(&functionsToInline, typeMap),
new InlineFunctionsDriver(&functionsToInline, new FunctionsInliner()),
new RemoveAllUnusedDeclarations(policy)}));
passes.push_back(new CloneVariableDeclarations());
setName("InlineFunctions");
}
Expand Down
24 changes: 16 additions & 8 deletions frontends/p4/inlining.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
#define FRONTENDS_P4_INLINING_H_

#include "commonInlining.h"
#include "frontends/common/parser_options.h"
#include "frontends/common/resolveReferences/referenceMap.h"
#include "frontends/p4/evaluator/evaluator.h"
#include "frontends/p4/evaluator/substituteParameters.h"
Expand Down Expand Up @@ -436,7 +437,7 @@ class InlinePass : public PassManager {
new DiscoverInlining(&toInline, refMap, typeMap, evaluator),
new InlineDriver<InlineList, InlineSummary>(
&toInline, new GeneralInliner(refMap, optimizeParserInlining)),
new RemoveAllUnusedDeclarations(refMap, policy)}) {
new RemoveAllUnusedDeclarations(policy)}) {
setName("InlinePass");
}
};
Expand All @@ -446,16 +447,23 @@ Performs inlining as many times as necessary. Most frequently once
will be enough. Multiple iterations are necessary only when instances are
passed as arguments using constructor arguments.
*/
class Inline : public PassRepeated {
class Inline : public PassManager {
static std::set<cstring> noPropagateAnnotations;
ReferenceMap refMap;

public:
Inline(ReferenceMap *refMap, TypeMap *typeMap, EvaluatorPass *evaluator,
const RemoveUnusedPolicy &policy, bool optimizeParserInlining)
: PassManager({new InlinePass(refMap, typeMap, evaluator, policy, optimizeParserInlining),
// After inlining the output of the evaluator changes, so
// we have to run it again
evaluator}) {
Inline(TypeMap *typeMap, const RemoveUnusedPolicy &policy, bool optimizeParserInlining,
EvaluatorPass *evaluator = nullptr) {
refMap.setIsV1(P4CContext::get().options().isv1());
auto *evInstance = evaluator ? evaluator : new EvaluatorPass(&refMap, typeMap);
addPasses({
evInstance,
new PassRepeated(
{new InlinePass(&refMap, typeMap, evInstance, policy, optimizeParserInlining),
// After inlining the output of the evaluator changes, so we have to
// run it again
evInstance}),
});
setName("Inline");
}

Expand Down
5 changes: 2 additions & 3 deletions frontends/p4/localizeActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,16 +168,15 @@ class LocalizeAllActions : public PassManager {
ActionReplacement localReplacements;

public:
explicit LocalizeAllActions(ReferenceMap *refMap, const RemoveUnusedPolicy &policy) {
explicit LocalizeAllActions(const RemoveUnusedPolicy &policy) {
passes.emplace_back(new TagGlobalActions());
passes.emplace_back(new PassRepeated{
new FindGlobalActionUses(&globalReplacements),
new LocalizeActions(&globalReplacements),
});
passes.emplace_back(new FindRepeatedActionUses(&localReplacements));
passes.emplace_back(new DuplicateActions(&localReplacements));
passes.emplace_back(new ResolveReferences(refMap));
passes.emplace_back(new RemoveAllUnusedDeclarations(refMap, policy));
passes.emplace_back(new RemoveAllUnusedDeclarations(policy));
setName("LocalizeAllActions");
}
};
Expand Down
4 changes: 2 additions & 2 deletions frontends/p4/redundantParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const IR::Node *EliminateSubparserCalls::postorder(IR::MethodCallStatement *mcs)
// will be reported in later passes (i.e. DiscoverInlining).
if (!findContext<IR::ParserState>()) return mcs;

auto mi = MethodInstance::resolve(mcs->methodCall, refMap, typeMap, true);
auto mi = MethodInstance::resolve(mcs->methodCall, this, typeMap, true);
if (!mi->isApply()) return mcs;

auto apply = mi->to<ApplyMethod>()->applyObject;
Expand All @@ -52,7 +52,7 @@ const IR::Node *EliminateSubparserCalls::postorder(IR::MethodCallStatement *mcs)
auto declInstance = mi->object->to<IR::Declaration_Instance>();
if (!declInstance) return mcs;

auto decl = refMap->getDeclaration(declInstance->type->to<IR::Type_Name>()->path);
auto decl = getDeclaration(declInstance->type->to<IR::Type_Name>()->path);
auto p4parser = decl->to<IR::P4Parser>();
if (!p4parser || !redundantParsers.count(p4parser)) return mcs;

Expand Down
16 changes: 8 additions & 8 deletions frontends/p4/redundantParsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
#ifndef FRONTENDS_P4_REDUNDANTPARSERS_H_
#define FRONTENDS_P4_REDUNDANTPARSERS_H_

#include "frontends/common/resolveReferences/resolveReferences.h"
#include "frontends/p4/typeChecking/typeChecker.h"
#include "frontends/p4/unusedDeclarations.h"
#include "ir/ir.h"
Expand All @@ -38,27 +39,26 @@ class FindRedundantParsers : public Inspector {
/** Find .apply() calls on parsers that are on redundantParsers, and
* eliminate them.
*/
class EliminateSubparserCalls : public Transform {
class EliminateSubparserCalls : public Transform, public ResolutionContext {
const std::set<const IR::P4Parser *> &redundantParsers;
ReferenceMap *refMap;
TypeMap *typeMap;
const IR::Node *postorder(IR::MethodCallStatement *methodCallStmt) override;

public:
EliminateSubparserCalls(const std::set<const IR::P4Parser *> &redundantParsers,
ReferenceMap *refMap, TypeMap *typeMap)
: redundantParsers(redundantParsers), refMap(refMap), typeMap(typeMap) {}
TypeMap *typeMap)
: redundantParsers(redundantParsers), typeMap(typeMap) {}
};

class RemoveRedundantParsers : public PassManager {
std::set<const IR::P4Parser *> redundantParsers;

public:
RemoveRedundantParsers(ReferenceMap *refMap, TypeMap *typeMap, const RemoveUnusedPolicy &policy)
: PassManager{new TypeChecking(refMap, typeMap, true),
RemoveRedundantParsers(TypeMap *typeMap, const RemoveUnusedPolicy &policy)
: PassManager{new TypeChecking(nullptr, typeMap, true),
new FindRedundantParsers(redundantParsers),
new EliminateSubparserCalls(redundantParsers, refMap, typeMap),
new RemoveAllUnusedDeclarations(refMap, policy)} {
new EliminateSubparserCalls(redundantParsers, typeMap),
new RemoveAllUnusedDeclarations(policy)} {
setName("RemoveRedundantParsers");
}
};
Expand Down
Loading

0 comments on commit d2006d5

Please sign in to comment.