-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[MachinePipeliner] Add an abstract layer to manipulate Data Dependenc… #109918
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
Merged
kasuga-fj
merged 5 commits into
llvm:main
from
kasuga-fj:machinepipeliner-ddg-abstract-layer
Dec 24, 2024
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
65c5f46
[MachinePipeliner] Add an abstract layer to manipulate Data Dependenc…
kasuga-fj f0e1625
fixup! [MachinePipeliner] Add an abstract layer to manipulate Data De…
kasuga-fj c0e1750
Fix typo
kasuga-fj 32feeba
Add const qualifier to an `addEdge` argument
kasuga-fj f6f6c72
Remove unnecessary includes and forward declarations
kasuga-fj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think there is a bug here, this "Pred" changing caused the querying of
isAntiDep()
below to be incorrect.Can you fix it?
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.
Could you elaborate the problem?
Here the dependency type is changed from Anti to Data only when the source of the edge is PHI. IIUIC, the anti dependency from a PHI node is used to represent a back-edge. In this patch, the code that handles the back-edges has been completely changed, and the anti-dependencies for physical registers are left in place. So I don't think this part doesn't is a problem. As far as I have tested on my local with llvm-test-suite, there are no differences between generated binaries built with and without this patch. Do you have any cases where it causes problems?
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 found the issue I think.
I had a bug (compiler crash on assertion) on an offline target (not in LLVM community).
I investigated and got to a conclusion that this is the issue.
You changed the phi anti-dep handling.
So when originally having,
some_instruction -> phi; anti dep
You have in your new DAG:
some_instruction -> phi, data dep
In the original consideration, some_instruction is a successor of the phi with anit-dep.

and it was missed out in succ_l.
See my fix, does it make sense to you?
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.
Thanks for your investigation. I see, so there are actual cases where the compiler crashes. Hmm, but I'm not sure what the root cause is.
anti
todata
only if the source instruction is PHI. So, in your example, the dependence type is not intended to be replaced unless thesome_instr
is PHI.data
, the source and the destination is swapped at the same time. In your case, theDDG
behaves as if there is an edge from thephi
to thesome_instr
. Therefore, this edge should be handled in the previous loopfor (const auto &OE : DDG->getOutEdges(SU)) { ... }
.So I'm not sure why your fix changes the behavior. Could you give me more details of your case (e.g., what exactly are
phi
andsome_instr
)?Uh oh!
There was an error while loading. Please reload this page.
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.
Let's track what happens when sending this edge to your DDGEdge constructor:
Input:
some_instruction -> phi; anti dep
When evaluating the phi's successor to initialize the edge, DDGEdge will be called with the following arguments:

PredOrSucc: phi
IsSucc = true,
Dep: some_instruction; anti dep
First you swap Src and Dst:

Meaning now we have:
Src = phi
Dst = some_instruction
Pred's SUnit will be: phi
Then this code will be executed:

Meaning the edge lost its "anti" kind and now we model it as data.
My problem is that now we don't consider that
some_instruction is a successor of the phi in some parts of the pipeliner's code:
computeNodeOrder
succ_L
I believe that, in addition to checking the anti-deps on the input edges, we need to check edges that have a non-zero distance.
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.
And, pred_L. Probably other cases too. I think the check for isAntiDep() can be replaced by getDistance(). That is, with the check for getDistance(), isAntiDep() isn't needed anymore.
Where does the assertion occur? With some more details it might be possible to create a test case. I assume some invalid node order is created? Would it be possible to show the pipeliner debug output for the use case (with and without the check for getDistance())?
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 anti dependence from
some_instr
tophi
becomes the data dependence fromphi
tosome_instr
, as I intended. And now, the vector returned by something likeDDG->getOutEdges(phi)
should contain that edge. That is, in your case, thesome_instr
should be appended toSuccs
in the for loop at line 1921.https://github.com/kasuga-fj/llvm-project/blob/f6f6c72322bfef93e21e3b043b4c4fc4f8a13fba/llvm/lib/CodeGen/MachinePipeliner.cpp#L1921
I suspect that the
DDG
is not constructed as I intended, if your change (adding the distance check) fixes the problem. I think there is another issue where we should really address.Yes, I agree with this.
I don't think so. Before this patch was merged, the
pred_L
was defined as follows:The inline comment says that the second loop handles back-edges, but actually the loop body only checks if the edge is anti dependence. That is, in
pred_L
, anti forward-edges (I think many of them are WAR dependencies for some physical register) are handled as predecessors. The same goes forsucc_L
. I suspect this is a mishandling of back-edges, but to keep the original behavior, the anti dependence check is still needed.Anyway, I also want to see some more details in this case.
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.
Hi, I'll send you a debug log but before I need to understand your change a bit more.

You said and I quote:
"The anti dependence from some_instr to phi becomes the data dependence from phi to some_instr, as I intended."
By looking at this code:
Src will be some_instr
Dst will be the phi.
So I believe you meant to tell me that data dep is from some_instr to phi?
Uh oh!
There was an error while loading. Please reload this page.
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.
Yes, I meant that, but now I think something is incorrect. In your previous comment, you said:
Also
This seems to be wrong. IIUIC,
isSucc
should befalse
in this case. This argument doesn't mean the "actual semantics" of the dependency. It just indicates whether theDep
is contained inPredOrSucc->Preds
orPredOrSucc->Succs
. Inserting some validation code like the following at the top of the ctor might be helpful (I don't check if this code works fine).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.
@mmarjieh Is the problem still occurring?