Skip to content
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

Constant folding for RuntimeInformation.IsOSPlatform(OSPlatform) #83308

Merged
merged 3 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/coreclr/jit/importervectorization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,8 @@ GenTree* Compiler::impStringEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO
GenTreeLclVar* varStrLcl = gtNewLclvNode(varStrTmp, varStr->TypeGet());

// Create a tree representing string's Length:
// TODO-Unroll-CQ: Consider using ARR_LENGTH here, but we'll have to modify QMARK to propagate BBF_HAS_IDX_LEN
int strLenOffset = OFFSETOF__CORINFO_String__stringLen;
GenTree* lenOffset = gtNewIconNode(strLenOffset, TYP_I_IMPL);
GenTree* lenNode = gtNewIndir(TYP_INT, gtNewOperNode(GT_ADD, TYP_BYREF, varStrLcl, lenOffset));
GenTree* lenNode = gtNewArrLen(TYP_INT, varStrLcl, strLenOffset, compCurBB);
varStrLcl = gtClone(varStrLcl)->AsLclVar();

GenTree* unrolled = impExpandHalfConstEquals(varStrLcl, lenNode, needsNullcheck, startsWith, (WCHAR*)str, cnsLength,
Expand Down
12 changes: 9 additions & 3 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14544,8 +14544,10 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, Statement* stmt)
// if they are going to be cleared by fgSplitBlockAfterStatement(). We currently only do this only
// for the GC safe point bit, the logic being that if 'block' was marked gcsafe, then surely
// remainderBlock will still be GC safe.
BasicBlockFlags propagateFlags = block->bbFlags & BBF_GC_SAFE_POINT;
BasicBlock* remainderBlock = fgSplitBlockAfterStatement(block, stmt);
BasicBlockFlags propagateFlagsToRemainder = block->bbFlags & BBF_GC_SAFE_POINT;
// Conservatively mark all blocks as having IDX_LEN since we don't know where exactly it went
BasicBlockFlags propagateFlagsToAll = block->bbFlags & BBF_HAS_IDX_LEN;
Copy link
Member

Choose a reason for hiding this comment

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

This should use BBF_COPY_PROPAGATE

Copy link
Member Author

@EgorBo EgorBo Mar 13, 2023

Choose a reason for hiding this comment

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

This should use BBF_COPY_PROPAGATE

That will decrease throughput at this moment for no benefit - e.g. we'll mark 4 blocks with "has nullcheck" and will have to visit them all in earlyprop. Ideally, QmarkGenTree should store BB flags it needs to propagate IMO. I propose we add flags on demand here since we use QMARK only in a few specific cases (none of them need to propagate flags atm except string-unrolling)

Copy link
Member

@jakobbotsch jakobbotsch Mar 13, 2023

Choose a reason for hiding this comment

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

How bad is it?

If that's the case I think we should have comment about it. Also, can you add asserts that check for GT_NULLCHECK, GT_MDARR_LENGTH, GT_ALLOCOBJ at least then (can use gtTreeContainsOper for this)?

Copy link
Member Author

@EgorBo EgorBo Mar 13, 2023

Choose a reason for hiding this comment

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

can you add asserts that check for GT_NULLCHECK, GT_MDARR_LENGTH, GT_ALLOCOBJ at least then (can use gtTreeContainsOper for this)?

It will assert anyway if we have a block without e.g. HAS_NULLCHECK with an actuall nullcheck, so no need in an extra assert - if someone adds a new kind of qmark with a need to propagate a new block flag (prior my PR it was never needed) they will hit it. The extra regression from BBF_COPY_PROPAGATE is another +0.02% or so

Copy link
Member

Choose a reason for hiding this comment

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

Ok, will leave it up to you -- although I don't think 0.02% is that much to have this be always correct

Copy link
Member Author

Choose a reason for hiding this comment

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

It's not urgent, let's have a CI run with BBF_COPY_PROPAGATE

BasicBlock* remainderBlock = fgSplitBlockAfterStatement(block, stmt);
fgRemoveRefPred(remainderBlock, block); // We're going to put more blocks between block and remainderBlock.

BasicBlock* condBlock = fgNewBBafter(BBJ_COND, block, true);
Expand All @@ -14561,14 +14563,17 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, Statement* stmt)
elseBlock->bbFlags |= BBF_IMPORTED;
}

remainderBlock->bbFlags |= propagateFlags;
remainderBlock->bbFlags |= (propagateFlagsToRemainder | propagateFlagsToAll);

condBlock->inheritWeight(block);

fgAddRefPred(condBlock, block);
fgAddRefPred(elseBlock, condBlock);
fgAddRefPred(remainderBlock, elseBlock);

condBlock->bbFlags |= propagateFlagsToAll;
elseBlock->bbFlags |= propagateFlagsToAll;

BasicBlock* thenBlock = nullptr;
if (hasTrueExpr && hasFalseExpr)
{
Expand All @@ -14585,6 +14590,7 @@ void Compiler::fgExpandQmarkStmt(BasicBlock* block, Statement* stmt)

thenBlock = fgNewBBafter(BBJ_ALWAYS, condBlock, true);
thenBlock->bbJumpDest = remainderBlock;
thenBlock->bbFlags |= propagateFlagsToAll;
if ((block->bbFlags & BBF_INTERNAL) == 0)
{
thenBlock->bbFlags &= ~BBF_INTERNAL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;

Expand Down Expand Up @@ -115,6 +116,7 @@ public string VersionString
/// Indicates whether the current application is running on the specified platform.
/// </summary>
/// <param name="platform">Case-insensitive platform name. Examples: Browser, Linux, FreeBSD, Android, iOS, macOS, tvOS, watchOS, Windows.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsOSPlatform(string platform)
{
ArgumentNullException.ThrowIfNull(platform);
Expand Down