-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Question/issue about GT_COMMA on rhs of GT_ASG. #1699
Comments
PTAL @CarolEidt @mikedn @dotnet/jit-contrib |
I think that morph is probably the main source of the issue. If either the source or destination of a block op is a promoted struct, The method Ideally, it would be good to see these commas eliminated, but IIRC trying to do so resulted in worse code (and more temps). However, if we don't do that, then I think that these methods need to use something stronger than |
Well, the expectancy is that if a local becomes address taken after
Otherwise it's relatively rare for a variable to become address taken/exposed after
Removal of Luckily
|
Thanks, @CarolEidt and @mikedn, for the detailed analysis.
That will allow is to keep independent promotion and enregister the fields, that is obviously good, but it will require a lot of work.
This approach would be easier and safer, at least as an assert() check if we don't prove that we want to allow IR like this.
From what I found it is done in exactly one place without a reason, so that can be fixed easily 17cec7c That IR doesn't make sense for me as well, it is why we get rid of it right after we create it 49bc2b2 |
Hmm, not familiar with that. The LHS |
We currently cut off generic recursion at two spots: 1. When there's a direct call to something that causes a recursion (e.g. `Method<T>` calls `Method<Gen<T>>` and `Gen` is a struct). 2. When there's recursion in the generic dictionary (e.g. the sample above but `Gen` is a class). There's yet another variation of this - indirect call to something that causes a recursion. Above two won't capture this because indirect calls don't go through the codepath 1, and codepath 2 is already too late (the recursion happens within the canonical code we already generated and invalidating dictionary entries is too late). This adds one more spot to cut things off. This is hit in Npgsql, but only on Linux, for whatever reason.
@SingleAccretion is there a tracking issue for all the bits and pieces needed to get rid of ADDR/ASG? |
|
Eliminate commas early in block morphing, before the rest of the transformation needs to look at it. Do this by extracting their side effects and adding them on top of the returned result instead. This allows us to handle arbitrary COMMAs on destination operand in a general manner. Prerequisite to dotnet#83388. Fix dotnet#1699.
Eliminate commas early in block morphing, before the rest of the transformation needs to look at it. Do this by extracting their side effects and adding them on top of the returned result instead. This allows us to handle arbitrary COMMAs on destination operand in a general manner. Prerequisite to #83388. Fix #1699.
If somehow
import
generates a tree like this:then when we come to
fgMorph
next events happen:LocalAddressVisitor
visits [02], but doesn't mark it as address taken or do-not-enregister (because it is not);fgMorphBlkNode
tranforms it into:creating address node after
LocalAddressVisitor
is finished;runtime/src/coreclr/src/jit/morph.cpp
Lines 9442 to 9450 in 0812d49
lvaDoNotEnreg
orlvaAddressTaken
);ADDR(LCL_VAR V01)
is replaced byLCL_VAR_ADDR
,ASG(OBJ)
is replaced bySTORE_OBJ
;lvaComputeRefCounts
visitsLCL_VAR_ADDR
and marks only promoted fields as referenced,not the variable itself, because the promotion is
PROMOTION_TYPE_INDEPENDENT
:https://github.com/dotnet/runtime/blob/master/src/coreclr/src/jit/compiler.hpp#L1754-L1756
genCodeForStoreBlk
fails because V01 doesn't have a stack location because we think it is unreferenced:;* V05 tmp3 [V05 ] ( 0, 0 ) struct (16) zero-ref "fgInsertCommaFormTemp is creating a new local variable"
the actual assert that is firing is
assert((varDsc->lvIsParam && !varDsc->lvIsRegArg) || isPrespilledArg);
inlvaFrameAddress
called fromemitIns_R_R_S_S
.The final tree will look like:
So, in short, our IR doesn't accept
COMMA
asRHS
onASG
(asLHS
as well, but it is another story) and we have a few workarounds for that, for example:dotnet/coreclr#23141
or
runtime/src/coreclr/src/jit/optcse.cpp
Lines 2633 to 2638 in 0812d49
If we don't want to fix it, then we could add a few checks that prevent it earlier and more obviously.
Also, the fact that
ADDR
node can appear afterLocalAddressVisitor
looks dangerous to me, does anybody have an idea how can it be made safer?Note: I do not have an example where we create trees like the described in the master branch; that is from one of my struct changes. However, I thought it would be useful to open an issue and make sure that we are aware of such behavior.
category:design
theme:ir
skill-level:intermediate
cost:small
The text was updated successfully, but these errors were encountered: