-
Notifications
You must be signed in to change notification settings - Fork 397
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
Changes in RegDepCopyRemoval for splitPostGRA block splitter #5219
Changes in RegDepCopyRemoval for splitPostGRA block splitter #5219
Conversation
@andrewcraik @Leonardo2718 Can I please get a review on these changes? I have added changes to RegDepCopyRemoval. So now instead of following tree,
We will have following tree
This will work well if we try to split the block after this opt has run. Marking this WIP while I am verifying that there is no perf impact of these changes. |
Change seems reasonable - will wait for unWIP and I'll continue the review then. |
c967f9f
to
efa37c8
Compare
efa37c8
to
e9b81e5
Compare
@r30shah any further update on this? |
@andrewcraik Thanks for reminding me. I did fix the issue but could not get the large batch of performance runs due to no free time one machine. Let me book it and get the performance numbers. |
e9b81e5
to
1a8205d
Compare
I ran a liberty Daytrader benchmark on x86 and here are the results (Only pasting relative performance of average throughput of 20 runs)
@andrewcraik Changes does not impact the performance impact we have with the RegDepCopyRemoval optimization. Removed WIP. This one is good for review. |
@@ -105,7 +106,7 @@ class RegDepCopyRemoval : public TR::Optimization | |||
NodeChoice &getNodeChoice(TR_GlobalRegisterNumber reg); | |||
|
|||
void discardAllNodeChoices(); | |||
void discardNodeChoice(TR_GlobalRegisterNumber reg); | |||
void discardNodeChoice(TR_GlobalRegisterNumber reg, bool clearRegStore = false); |
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 don't like this boolean flag - could we have discardNodeChoice
and something like discardNodeChoiceAndClearStore
or something like that? it will be easier to follow the logic rather than having a random bool flag.
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.
As the only case when we need to clear up the Node Choice completely is when we start walking new block which is not extension, at that point it cleans up all the data structures that was filled for previous analysis. I renamed this to clearNodeChoice
.
@r30shah not sure what to make of the failures... could you have a look? |
@andrewcraik I believe it is failing because of this guy, https://github.com/eclipse/omr/blob/cd259de5afc5c80fdc42491c7201564275bb718e/compiler/ras/ILValidationRules.cpp#L436-L470, seems like it is checking the children of the regStore node and fails when child is PassThrough which does not have a type. EDIT: I can probably make change to this validator to expect such kind of node under pass through. Just wanted to confirm that is the right way and we can make an exception for PassThrough under regstore. |
@r30shah I think the validator needs to be updated to handle the specific case it is tripping on - I think we need to be careful not to allow PassThroughs too generally so I think you need to make the exception fairly specific. FYI @Leonardo2718 given your interest in the validator. |
@andrewcraik Change I was thinking of was to get the real child (Iterate through the child of PassThrough till child is not passthrough) and get validator check the real child. I agree, we should not allow PassThrough too generally |
I agree that adding a special case to the validator for a PassThrough under a RegStore is the reasonable thing to do right now. I also like @r30shah's suggestion of checking the type of the "real" (non-passthrough) child in those special cases. To avoid cluttering the validation code, I suggest implementing that check in a separate function and modifying if (childOpcode.getOpCodeValue() != TR::GlRegDeps)
{
const auto expChildType = opcode.expectedChildType(i);
const auto expChildTypeName = (expChildType >= TR::NumTypes) ?
"UnspecifiedChildType" :
TR::DataType::getName(expChildType);
if (opcode.isRegStore() && childOpcode.getOpCodeValue() == TR::PassThrough)
{
checkPassThroughChildRecursively(expChildType, expChildTypeName, node->getChild(i))
}
else
{
const auto actChildType = childOpcode.getDataType().getDataType();
const auto actChildTypeName = TR::DataType::getName(actChildType);
TR::checkILCondition(node, (expChildType >= TR::NumTypes || actChildType == expChildType),
comp(), "Child %d has unexpected type %s (expected %s)",
i, actChildTypeName, expChildTypeName);
}
} Also, just as an FYI, #5250 still needs to be undone/reverted in order to re-enable regDepCopyRemoval when value types are enabled. |
compiler/ras/ILValidationRules.cpp
Outdated
@@ -446,6 +446,20 @@ void TR::ValidateChildTypes::validate(TR::Node *node) | |||
auto childOpcode = node->getChild(i)->getOpCode(); | |||
if (childOpcode.getOpCodeValue() != TR::GlRegDeps) | |||
{ | |||
/** |
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.
@Leonardo2718 Can I get review on this change? I just saw the code you recommended, but before that did try following changes and test is passing with 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.
Isn't this effectively allowing a PassThrough to appear anywhere, as long as the final child is the correct type? My understanding was that it should only be allowed in this one specific case (i.e. under a regStore).
The structure of the code itself looks fine, although I would suggest moving the code bellow the const variable definitions so you can just use those instead of having to call childOpcode.getDataType().getDataType()
, etc.
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.
My understanding for the PassThrough is as its name suggests, it is just a pass through node and it is OK to have passthrough child as long as real child under passthrough matches the expected child type. Although I can not find anywhere in OMR and OpenJ9 where it uses it like this.
In https://github.com/eclipse/omr/compare/c20ca06dcf272a1aa1fae1082612c7f5bb8b28c4..e2bb845af7cf4df7240431d864af758e3afee04c Made the changes to keep it limited to PassThrough under regStore only,.
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.
In general the compiler will minimize PassThroughs - they are more a transient effect of transformation - if they are allowed to proliferate then we can have a problem because the pattern matching in the compiler will begin to fail. Allowing this only under a regStore makes sense.
6c17a6b
to
51075a6
Compare
RegDepCopyRemoval is the last ran optimization which intends to reduce register shuffling due to global register dependencies. It was generating tree where we have a PassThrough Child under PassThrough to copy node to new virtual register. This tree was not working well with the post GRA block splitter. Issue was that PassThrough child encountered in GlRegDeps was anchored to tree top. In postGRA block splitter, it records the regStores encountered before the GlRegDeps in extended basic block to guide decision on which register to chose for the node after split point.In this commit, adding changes to both splitPostGRA block splitter and RegDepCopyRemoval optimization so that we can split the blocks after later has run. Signed-off-by: Rahil Shah <[email protected]>
51075a6
to
c20ca06
Compare
It is possible to have a PassThrough as a child node of regular node. When we are validating the children of a node, we need to make sure that when we see a PassThrough child, it gets real child that represents the node and check its type with parent. Signed-off-by: Rahil Shah <[email protected]>
c20ca06
to
e2bb845
Compare
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.
LGTM 👍
@genie-omr build all |
All the tests have been passed. @andrewcraik If you are OK with the changes, we can merge this. |
RegDepCopyRemoval is the last ran optimization which intends to reduce register shuffling due to global register dependencies. It was generating tree where we have a PassThrough Child under PassThrough to copy node to new virtual register. This tree was not working well with the post GRA block splitter. Issue was that PassThrough child encountered in GlRegDeps was anchored to tree top. In postGRA block splitter, it records the regStores encountered before the GlRegDeps in extended basic block to guide decision on which register to chose for the node after split point.In this commit, adding changes to both splitPostGRA block splitter and RegDepCopyRemoval optimization so that we can split the blocks after later has run.
Signed-off-by: Rahil Shah [email protected]