Skip to content

Check that we don't create null checks on an address that is not null. - #44059

Merged
sandreenko merged 2 commits into
dotnet:masterfrom
sandreenko:dontAllowNullCheckOnKnownNotNull
Nov 3, 2020
Merged

Check that we don't create null checks on an address that is not null.#44059
sandreenko merged 2 commits into
dotnet:masterfrom
sandreenko:dontAllowNullCheckOnKnownNotNull

Conversation

@sandreenko

Copy link
Copy Markdown
Contributor

@EgorBo in his previous Pr gave me an idea that it could be useful to check that we don't create a null check on an address that is known to be not null.

crossgenpmi
x64 windows0-15
arm64 windows13613
x64 linux-59-32

The biggest number of diffs involves methods on arm64 windows:

Top file regressions (bytes):
136 : System.Private.CoreLib.dasm (0.00% of base)
1 total files with Code Size differences (0 improved, 1 regressed), 267 unchanged.
Top method regressions (bytes):
28 ( 1.40% of base) : System.Private.CoreLib.dasm - GenericEqualityComparer`1:IndexOf(ref,ValueTuple`8,int,int):int:this (7 methods)
28 ( 1.38% of base) : System.Private.CoreLib.dasm - GenericEqualityComparer`1:LastIndexOf(ref,ValueTuple`8,int,int):int:this (7 methods)
16 total methods with Code Size differences (0 improved, 16 regressed), 195786 unchanged.

they all are in IndexOf or LastindexOf and are due to a new loop hoisting that is a size regression but a performance improvement.

@sandreenkosandreenko added enhancement Product code improvement that does NOT require public API changes/additions area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Oct 30, 2020

inline GenTree* Compiler::gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock)
{
assert(fgAddrCouldBeNull(addr));

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

It is questionable if it should be an assert or

if (!fgAddrCouldBeNull(addr))
{
// No need for a null-check.
return addr;
}

or something else.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it'd be weird for gtNewNullCheck to return something other than null-check 🙂

@sandreenko

Copy link
Copy Markdown
ContributorAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib

@am11

am11 commented Oct 30, 2020

Copy link
Copy Markdown
Member

@sandreenko, would it also fix #1368, since fgAddrCouldBeNull has:

elseif (addr->OperIs(GT_CNS_STR))
{
returnfalse;
}

@EgorBo

EgorBo commented Oct 30, 2020

Copy link
Copy Markdown
Member

@sandreenko, would it also fix #1368, since fgAddrCouldBeNull has:

elseif (addr->OperIs(GT_CNS_STR))
{
returnfalse;
}

yeah that one is already fixed

@EgorBo

EgorBo commented Oct 30, 2020

Copy link
Copy Markdown
Member

@sandreenko Since you touch it, could you please address #37245 (comment) as part of this PR? 🙂

@sandreenko

Copy link
Copy Markdown
ContributorAuthor

@sandreenko Since you touch it, could you please address #37245 (comment) as part of this PR? 🙂

Sure, done

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if we can do something similar over in gtTryRemoveBoxUpstreamEffects -- it currently create an implicit null check, and does not check for the same "can optimize away the check" cases that the importer pattern match does.

@erozenfeld may have already tried this.

@sandreenko

Copy link
Copy Markdown
ContributorAuthor

I wonder if we can do something similar over in gtTryRemoveBoxUpstreamEffects -- it currently create an implicit null check, and does not check for the same "can optimize away the check" cases that the importer pattern match does.

I pushed a change with the same check for gtChangeOperToNullCheck. It should cover all cases where we create null-checks. So we will see missed-optimization opportunities as asserts if they appear.

@sandreenko
sandreenkoforce-pushed the dontAllowNullCheckOnKnownNotNull branch from 9e13842 to 72ee330CompareNovember 2, 2020 20:54
@sandreenko

Copy link
Copy Markdown
ContributorAuthor

I pushed a change with the same check for gtChangeOperToNullCheck. It should cover all cases where we create null-checks. So we will see missed-optimization opportunities as asserts if they appear.

Actually, I remember that I was trying to do that in the past and it did not work.
We call TransformUnusedIndirection that changes 'IND' to 'NULLCHECK' from different phases and each phase requires different transformations to delete IND and ADDR when ADDR can't be null. I have dropped the check in gtChangeOperToNullCheck, @AndyAyersMS should I open an issue to track this possible optimization in the future?

@AndyAyersMS

Copy link
Copy Markdown
Member

should I open an issue to track this possible optimization

Seems like a good idea. Would be good to note more details on why it's not as simple as it might seem.

@sandreenko
sandreenko merged commit a5c194e into dotnet:masterNov 3, 2020
@sandreenko
sandreenko deleted the dontAllowNullCheckOnKnownNotNull branch November 3, 2020 22:42
@ghostghost locked as resolved and limited conversation to collaborators Dec 6, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@sandreenko@am11@EgorBo@AndyAyersMS