-
Notifications
You must be signed in to change notification settings - Fork 13
Implement parser inlining #241
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
Conversation
|
Tagging @fruffy for visibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lack of E2E testing and reference files makes it quite hard to tell whether the resulting semantic behavior is correct. Would be really nice to have a packet testing framework for this at some point.
|
@fruffy I'm afraid this will only be possible if / when we will have some backend implementation... |
asl
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made first sweep, check the comments below and above
lib/Transforms/IRUtils.cpp
Outdated
| llvm::StringRef varName = "promoted_local") { | ||
| // Create new variable to hold `val`. | ||
| auto newVar = rewriter.create<P4HIR::VariableOp>( | ||
| val.getLoc(), P4HIR::ReferenceType::get(val.getType()), varName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add init attribute as the variable will be immediately initialized.
lib/Transforms/IRUtils.cpp
Outdated
| P4HIR::ParserStateOp IRUtils::createSubState(mlir::RewriterBase &rewriter, | ||
| P4HIR::ParserStateOp state, llvm::StringRef suffix) { | ||
| auto parser = state->getParentOfType<P4HIR::ParserOp>(); | ||
| std::string basename = (llvm::Twine(state.getSymName()) + "_" + suffix).str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need Twine here? I'd suggest using SmallString here with pre-allocated buffer
lib/Transforms/IRUtils.cpp
Outdated
| std::string name = basename; | ||
|
|
||
| size_t counter = 0; | ||
| while (parser.lookupSymbol(name)) name = basename + "_" + std::to_string(counter++); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use mlir::SymbolTable::generateSymbolName. There are examples of usage in P4C/translate.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This made me realize that I merged an outdated version of IRUtils in this new branch. I will update it to the correct one.
lib/Transforms/InlineParsers.cpp
Outdated
| void InlineParsersPass::runOnOperation() { | ||
| mlir::IRRewriter rewriter(&getContext()); | ||
|
|
||
| // P4 guarantees that subparser definitions come before their use so inlining them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is true for P4 input source. But technically since we're referring things via symbols and symbol tables this might be not true anymore and this is not enforced in P4HIR. I would explicitly have a worklist and iterate until it is not empty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I will re-evaluate the assumption and change the implementation as needed.
| status = ssr->init(); | ||
| if (status.failed()) break; | ||
|
|
||
| std::string prefix = instName.str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use SmallString here
lib/Transforms/InlineParsers.cpp
Outdated
|
|
||
| // Move inlined operation `op` to its desired position. | ||
| void proccessInlinedOp(size_t index, mlir::Operation *op) { | ||
| // Remmap parser locals if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Remmap parser locals if needed. | |
| // Remap parser locals if needed. |
|
|
||
| // Make the subparser's accept transition to the "post" state. | ||
| if (stateOp.isAccept()) { | ||
| auto acceptOp = mlir::cast<P4HIR::ParserAcceptOp>(stateOp.getNextTransition()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we just userewriter.replaceOpWithNewOp<P4HIR::ParserTransitionOp>(acceptOp, ...)?
lib/Transforms/InlineParsers.cpp
Outdated
| } | ||
| } | ||
|
|
||
| // Move inlined operation `op` to its desired position. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably suggest to expand the comment specifying the IR before this function (e..g how the states were split and where everything went into) and what should be do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll add more details.
Signed-off-by: Manolis Tsamis <[email protected]>
Signed-off-by: Manolis Tsamis <[email protected]>
Signed-off-by: Manolis Tsamis <[email protected]>
Signed-off-by: Manolis Tsamis <[email protected]>
20299e1 to
6e60de6
Compare
|
In latest version:
|
|
Superseded by #246. |
This PR implements parser inlining (#100).
The changes include generic infrastructure found in IRUtils and an inlining pass based on MLIR
InliningUtilsand the newSplitStateRewriterto handle parser rewrites. The implementation makes sure to leave the IR in its original state if the inlining fails at any part (e.g. due to an apply call being inside an if statement).Although not necessary for correctness, parser locals are shared per instantiation to avoid creating too many new locals that will be hard to eliminate later on.
A number of tests are added, including the parser inlining tests from P4C. The latter are there only to check against potential crashes.