Skip to content

Conversation

MathiasVP
Copy link
Contributor

In #11198 Tom added phi nodes for uses in the shared SSA library, but we haven't yet reaped the benefit of those in C++ since we've been using the backwards compatibility wrappers he made. This PR makes use of those new phi nodes for uses. It should give us a small performance boost 🤞.

The first commit does the real work, and the second commit fixes a bug exposed by the tests.

@MathiasVP MathiasVP requested a review from a team as a code owner March 1, 2023 20:48
@github-actions github-actions bot added the C++ label Mar 1, 2023
@MathiasVP MathiasVP added the no-change-note-required This PR does not need a change note label Mar 1, 2023
@MathiasVP
Copy link
Contributor Author

Hmmm... I don't understand why we gain so many new results from this, but they look like TPs to me 😮. The two results on openjdk-jdk doesn't even involve global variables, so d845cd7#diff-e96bb3af46f5cc3580be03e17e599c937b020235aa92af08b77b1b2697d37d3cR560-R564 can't even be attributed to that 🤔.

@jketema
Copy link
Contributor

jketema commented Mar 2, 2023

Hmmm... I don't understand why we gain so many new results from this, but they look like TPs to me 😮. The two results on openjdk-jdk doesn't even involve global variables, so d845cd7#diff-e96bb3af46f5cc3580be03e17e599c937b020235aa92af08b77b1b2697d37d3cR560-R564 can't even be attributed to that 🤔.

You also fixed a bug. Does that have something to do with it?

@MathiasVP
Copy link
Contributor Author

You also fixed a bug. Does that have something to do with it?

Good point. I had the exact same thought, so I actually made a PR with just that fix here and ran a DCA on that, but as you can see from the DCA run, that did not actually produce any new results.

@MathiasVP
Copy link
Contributor Author

MathiasVP commented Mar 2, 2023

I may understand part of the issue now. I've found the step that's responsible for the new results on cpp/path-injection here: We now step from the output argument buffer to a new phi-read node and further to the sink here.

Notice that buffer is a static variable. This means we don't actually have proper dataflow support for it right now (static locals are missing an initial definition). Before this PR, there would be no step from the argument node to the sink, but on this PR there's a new SSA phi-read node for the read of the argument. This new SSA phi-read node is a definition (because phi nodes are definitions), so the buffer variable now has a definition, and thus we get SSA flow that reach the sink 🎉.

The reason I'm saying tht I may understand part of the issue now is that I can't seem to reproduce the above in a local test file 😕. So there may be something else going on.

Now, am I happy with the fact that this is how we're getting the flow? No, not really 😂. But we would have gotten this result anyway once we implement proper support for static locals, so I don't really mind the fact that we're getting this result now. This explains the two new results on cpp/path-injection. I'll continue investigating the other results as well and see if we get those for similar reasons.

@MathiasVP
Copy link
Contributor Author

I'm seeing the exact same situation on the new cpp/uncontrolled-process-operation result where this static local variable receives flow from an out argument.

There's a small fix to the mapping from 'global def -> use'.

Finally, this commit also accepts a test failure related to new missing
types for phi nodes. The fix for that is in the next commit.
@MathiasVP
Copy link
Contributor Author

MathiasVP commented Mar 2, 2023

I manage to reproduce the above situation in a QL test 🎉. I've rebased the PR to make it follow the usual "add test", "write QL", "accept tests" workflow. No actual QL code has changed in the force-push!

I've looked through a couple of the new results on vim/vim and they're also due to the same pattern added in b3f92fc. All in all, I think this PR is good to go!

Comment on lines +560 to +563
exists(PhiNode phi |
lastRefRedefExt(_, bb1, i1, phi) and
useOrPhi.asPhi() = phi and
phi.getSourceVariable() = pragma[only_bind_into](v)
Copy link
Contributor

Choose a reason for hiding this comment

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

PR mostly looks sensible. This is the only part I have trouble wrapping my head around. What does this do?

Copy link
Contributor Author

@MathiasVP MathiasVP Mar 3, 2023

Choose a reason for hiding this comment

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

lastRefRedefExt(_, bb1, i1, phi) says that the last reference to the variable defined by phi was at index i1 in basic block bb1. This means that (bb1, i1) is an input to phi. Does that help?

It's basically the same pattern as here. We should probably factor that out into a common predicate in another PR.

@MathiasVP MathiasVP merged commit 16e817c into github:mathiasvp/replace-ast-with-ir-use-usedataflow Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++ no-change-note-required This PR does not need a change note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants