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

Function call CSE pass #45

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft

Conversation

arrangabriel
Copy link
Collaborator

Adds a pass that hoists repeated function calls with equivalent arguments in and between equations into new equations, so they are only computed once.

@arrangabriel
Copy link
Collaborator Author

It would be nice if you could take a look @mscuttari and see what you think.

As you asked it does not currently handle equations with induction variables.

Additionally I was unsure whether calls in the initial equations had to be handled differently, so for not they are ignored.

There is also just one test. I read the page on filecheck tests for mlir, and they mention that one should try to make the tests as isolated as possible. I tried to do that for the one I have made, so please let me know if something can be improved about that. I'll add some more before finishing the PR.

Copy link
Member

@mscuttari mscuttari left a comment

Choose a reason for hiding this comment

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

I've left some comments about possible code improvements. Some of them are mostly stylistic, others a little bit less.

bmodelica.variable @y : !bmodelica.variable<f64>
bmodelica.variable @z : !bmodelica.variable<f64>

//%t0 = bmodelica.equation_template inductions = [] {
Copy link
Member

Choose a reason for hiding this comment

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

Missing CHECK commands for FileCheck


//%t0 = bmodelica.equation_template inductions = [] {
// %0 = bmodelica.variable_get @x : f64
// %lhs = bmodelica.equation_side %0 : tuple<f64>
Copy link
Member

Choose a reason for hiding this comment

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

Don't rely on some numbering or naming. Capture the actual SSA variable names using the double square bracket operator.

public:
using CallCSEPassBase<CallCSEPass>::CallCSEPassBase;
using CallCSEPassBase::CallCSEPassBase;
Copy link
Member

Choose a reason for hiding this comment

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

Keep the template argument explicit so to be resilient to any possible change in the code automatically generated with Tablegen.

@@ -1,6 +1,8 @@
#include "marco/Dialect/BaseModelica/Transforms/CallCSE.h"
#include "marco/Dialect/BaseModelica/IR/BaseModelica.h"

#include <marco/AST/Node/Operation.h>
Copy link
Member

Choose a reason for hiding this comment

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

Not clear why is the AST library is being imported here. At this point in the pipeline the AST is already gone.

@@ -29,16 +53,16 @@ void CallCSEPass::runOnOperation() {
}
});

if (mlir::failed(mlir::failableParallelForEach(
if (failed(failableParallelForEach(
Copy link
Member

Choose a reason for hiding this comment

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

Keep the mlir namespace explicit


/// Get all callOps in the model.
static void collectCallOps(ModelOp modelOp,
llvm::SmallVector<CallOp> &callOps);
Copy link
Member

Choose a reason for hiding this comment

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

Use llvm::SmallVectorImpl so not to force a particular amount of elements on the stack.


auto *equivalenceGroup =
find_if(callEquivalenceGroups, [&](llvm::SmallVector<CallOp> &group) {
// front() is safe as there are no empty groups
Copy link
Member

Choose a reason for hiding this comment

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

Still, an assert would be nice to have.

mlir::IRMapping &mapping,
mlir::RewriterBase &rewriter) {
std::vector<mlir::Operation *> toClone;
std::vector worklist({op});
Copy link
Member

Choose a reason for hiding this comment

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

Use llvm::SmallVector.

rewriter.setInsertionPointToStart(modelOp.getBody());
auto cseVariable = rewriter.create<VariableOp>(
rewriter.getUnknownLoc(), "_cse" + std::to_string(emittedCSEs),
VariableType::wrap(representative.getResult(0).getType()));
Copy link
Member

Choose a reason for hiding this comment

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

What happens if the function has multiple results?

templateOp->walk([&](CallOp callOp) {
callOps.push_back(callOp);
});
int emittedCSEs = 0;
Copy link
Member

Choose a reason for hiding this comment

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

It should be possible - and would be nice - to add this measurement to the pass statistics.

@mscuttari mscuttari linked an issue Oct 14, 2024 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CSE to avoid repeated pure function calls with the same argument
2 participants