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

JIT: Unroll Equals and StartsWith for constant strings and spans. [0..32] chars #65288

Merged
merged 38 commits into from
Mar 2, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
41a57d2
Unroll & vectorize String.Equals
EgorBo Feb 13, 2022
e7106d6
fix bug
EgorBo Feb 13, 2022
2985162
StartsWith, clean up
EgorBo Feb 14, 2022
4047ce5
Update importer.cpp
EgorBo Feb 14, 2022
7d88960
fix build errors
EgorBo Feb 14, 2022
486d384
formatting
EgorBo Feb 14, 2022
8d4bc7e
Add Spans, move everything to a separate file
EgorBo Feb 16, 2022
87fa3bf
Clean up, more comments
EgorBo Feb 16, 2022
8dc111b
fix typos, clean up
EgorBo Feb 16, 2022
c9658dc
Address feedback
EgorBo Feb 16, 2022
6f29646
Use IND for simd loads
EgorBo Feb 16, 2022
210c4f1
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 16, 2022
c8826ee
Address feedback
EgorBo Feb 16, 2022
9c8033f
fix assert
EgorBo Feb 16, 2022
08ab8e2
formatting
EgorBo Feb 16, 2022
4cf0b96
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 17, 2022
39b6151
How is MemoryExtensions.AsSpan(string,int) also gets recognized as [I…
EgorBo Feb 18, 2022
52c54a5
fix AsSpan and op_Implicit intrinsics
EgorBo Feb 18, 2022
f4bac1f
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 18, 2022
de2faa9
Fix r2r assert
EgorBo Feb 18, 2022
da4135f
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 19, 2022
6252775
minor clean up
EgorBo Feb 20, 2022
f35da70
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 21, 2022
a45c705
Fix bug with s.StartsWith("", Ordinal) - it should be optimized to CO…
EgorBo Feb 22, 2022
40550e9
Clean up
EgorBo Feb 22, 2022
a524530
Update UnrollEqualsStartsWIth.cs
EgorBo Feb 22, 2022
eadc97e
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Feb 26, 2022
411af86
Update src/coreclr/jit/importer_vectorization.cpp
EgorBo Feb 26, 2022
6581fa8
Merge branch 'jit-unroll-equals' of https://github.com/EgorBo/runtime…
EgorBo Feb 26, 2022
aa48801
Address feedback
EgorBo Feb 26, 2022
abaf73a
Address feedback
EgorBo Feb 26, 2022
f42ae58
Address feedback
EgorBo Feb 26, 2022
9c64132
Apply suggestions from code review
EgorBo Feb 26, 2022
afb814d
Update src/coreclr/jit/importer_vectorization.cpp
EgorBo Feb 26, 2022
345246c
fix cast type
EgorBo Feb 26, 2022
ab5af13
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Mar 1, 2022
d42a006
Remove redundant cast
EgorBo Mar 1, 2022
971629c
Merge branch 'main' of https://github.com/dotnet/runtime into jit-unr…
EgorBo Mar 2, 2022
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
1 change: 1 addition & 0 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ set( JIT_SOURCES
hostallocator.cpp
indirectcalltransformer.cpp
importer.cpp
importer_vectorization.cpp
inline.cpp
inlinepolicy.cpp
instr.cpp
Expand Down
14 changes: 13 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3014,6 +3014,7 @@ class Compiler
// For binary opers.
GenTree* gtNewOperNode(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2);

GenTreeColon* gtNewColonNode(var_types type, GenTree* elseNode, GenTree* thenNode);
GenTreeQmark* gtNewQmarkNode(var_types type, GenTree* cond, GenTreeColon* colon);

GenTree* gtNewLargeOperNode(genTreeOps oper,
Expand All @@ -3023,6 +3024,9 @@ class Compiler

GenTreeIntCon* gtNewIconNode(ssize_t value, var_types type = TYP_INT);
GenTreeIntCon* gtNewIconNode(unsigned fieldOffset, FieldSeqNode* fieldSeq);
GenTreeIntCon* gtNewNull();
GenTreeIntCon* gtNewTrue();
GenTreeIntCon* gtNewFalse();
EgorBo marked this conversation as resolved.
Show resolved Hide resolved

GenTree* gtNewPhysRegNode(regNumber reg, var_types type);

Expand Down Expand Up @@ -4392,6 +4396,14 @@ class Compiler
void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
GenTree* impTypeIsAssignable(GenTree* typeTo, GenTree* typeFrom);

GenTree* impStringEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO* sig, unsigned methodFlags);
GenTree* impSpanEqualsOrStartsWith(bool startsWith, CORINFO_SIG_INFO* sig, unsigned methodFlags);
GenTree* impExpandHalfConstEquals(
GenTree* data, GenTree* lengthFld, bool checkForNull, bool startsWith, WCHAR* cnsData, int len, int dataOffset);
GenTree* impExpandHalfConstEqualsSWAR(GenTree* data, WCHAR* cns, int len, int dataOffset);
GenTree* impExpandHalfConstEqualsSIMD(GenTree* data, WCHAR* cns, int len, int dataOffset);
GenTreeStrCon* impGetStrConFromSpan(GenTree* span);

GenTree* impIntrinsic(GenTree* newobjThis,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
Expand Down Expand Up @@ -4508,7 +4520,7 @@ class Compiler
void impInsertTreeBefore(GenTree* tree, const DebugInfo& di, Statement* stmtBefore);
void impAssignTempGen(unsigned tmp,
GenTree* val,
unsigned curLevel,
unsigned curLevel = (unsigned)CHECK_SPILL_NONE,
Statement** pAfterStmt = nullptr,
const DebugInfo& di = DebugInfo(),
BasicBlock* block = nullptr);
Expand Down
20 changes: 20 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5685,6 +5685,11 @@ GenTree* Compiler::gtNewOperNode(genTreeOps oper, var_types type, GenTree* op1,
return node;
}

GenTreeColon* Compiler::gtNewColonNode(var_types type, GenTree* elseNode, GenTree* thenNode)
{
return new (this, GT_COLON) GenTreeColon(TYP_INT, elseNode, thenNode);
}

GenTreeQmark* Compiler::gtNewQmarkNode(var_types type, GenTree* cond, GenTreeColon* colon)
{
compQmarkUsed = true;
Expand All @@ -5703,6 +5708,21 @@ GenTreeIntCon* Compiler::gtNewIconNode(ssize_t value, var_types type)
return new (this, GT_CNS_INT) GenTreeIntCon(type, value);
}

GenTreeIntCon* Compiler::gtNewNull()
{
return gtNewIconNode(0, TYP_REF);
}

GenTreeIntCon* Compiler::gtNewTrue()
{
return gtNewIconNode(1, TYP_INT);
}

GenTreeIntCon* Compiler::gtNewFalse()
{
return gtNewIconNode(0, TYP_INT);
}

GenTreeIntCon* Compiler::gtNewIconNode(unsigned fieldOffset, FieldSeqNode* fieldSeq)
{
GenTreeIntCon* node = new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, static_cast<ssize_t>(fieldOffset));
Expand Down
58 changes: 57 additions & 1 deletion src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3860,6 +3860,31 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
retNode = impArrayAccessIntrinsic(clsHnd, sig, memberRef, readonlyCall, ni);
break;

case NI_System_String_Equals:
EgorBo marked this conversation as resolved.
Show resolved Hide resolved
{
retNode = impStringEqualsOrStartsWith(/*startsWith:*/ false, sig, methodFlags);
break;
}

case NI_System_MemoryExtensions_Equals:
case NI_System_MemoryExtensions_SequenceEqual:
{
retNode = impSpanEqualsOrStartsWith(/*startsWith:*/ false, sig, methodFlags);
break;
}

case NI_System_String_StartsWith:
{
retNode = impStringEqualsOrStartsWith(/*startsWith:*/ true, sig, methodFlags);
break;
}

case NI_System_MemoryExtensions_StartsWith:
{
retNode = impSpanEqualsOrStartsWith(/*startsWith:*/ true, sig, methodFlags);
break;
}

case NI_System_String_get_Chars:
{
GenTree* op2 = impPopStack().val;
Expand Down Expand Up @@ -5176,14 +5201,45 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
}
else if (strcmp(className, "String") == 0)
{
if (strcmp(methodName, "get_Chars") == 0)
if (strcmp(methodName, "Equals") == 0)
{
result = NI_System_String_Equals;
}
else if (strcmp(methodName, "get_Chars") == 0)
{
result = NI_System_String_get_Chars;
}
else if (strcmp(methodName, "get_Length") == 0)
{
result = NI_System_String_get_Length;
}
else if (strcmp(methodName, "op_Implicit") == 0)
{
result = NI_System_String_op_Implicit;
}
else if (strcmp(methodName, "StartsWith") == 0)
{
result = NI_System_String_StartsWith;
}
}
else if (strcmp(className, "MemoryExtensions") == 0)
{
if (strcmp(methodName, "AsSpan") == 0)
{
result = NI_System_MemoryExtensions_AsSpan;
}
if (strcmp(methodName, "SequenceEqual") == 0)
{
result = NI_System_MemoryExtensions_SequenceEqual;
}
else if (strcmp(methodName, "Equals") == 0)
{
result = NI_System_MemoryExtensions_Equals;
}
else if (strcmp(methodName, "StartsWith") == 0)
{
result = NI_System_MemoryExtensions_StartsWith;
}
}
else if (strcmp(className, "Span`1") == 0)
{
Expand Down
Loading