From b7535230371568bf93a7a53c48650b385985fb8f Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 14 Jun 2023 23:46:37 +0200 Subject: [PATCH 01/27] Optimize GetType with known type --- src/coreclr/jit/importercalls.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 43ad185b63e8a..fde3e74f7812b 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3635,6 +3635,25 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, } } + // Load handle directly for known types + if (retNode == nullptr) + { + bool isExact = false; + bool notNull = false; + CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); + if ((typeHnd != NO_CLASS_HANDLE) && isExact) + { + JITDUMP("Optimizing object.GetType() with known type to typeof\n"); + op1 = impPopStack().val; + if (!notNull && fgAddrCouldBeNull(op1)) + { + impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); + } + GenTree* handle = gtNewIconEmbClsHndNode(typeHnd); + retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); + } + } + #ifdef DEBUG if (retNode != nullptr) { From 5862a59150584cb12dd06a64639d70d85d9be591 Mon Sep 17 00:00:00 2001 From: petris Date: Thu, 15 Jun 2023 00:16:40 +0200 Subject: [PATCH 02/27] Keep side effects --- src/coreclr/jit/importercalls.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index fde3e74f7812b..a0b22aad6013e 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3649,8 +3649,12 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); } + else if ((op1->gtFlags & (GTF_SIDE_EFFECT | GTF_IND_VOLATILE)) != 0) + { + impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); + } GenTree* handle = gtNewIconEmbClsHndNode(typeHnd); - retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); + retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); } } From 41f70ed3874774edd48d96b3a015fb56d00ee8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 15 Jun 2023 00:22:21 +0200 Subject: [PATCH 03/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index a0b22aad6013e..0668f6846d9ee 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3649,7 +3649,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); } - else if ((op1->gtFlags & (GTF_SIDE_EFFECT | GTF_IND_VOLATILE)) != 0) + else if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) { impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); } From 7448b59408bcf0013b7c58b15f649fd6427d9cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:48:29 +0200 Subject: [PATCH 04/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 0668f6846d9ee..6203c786228ee 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3649,7 +3649,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); } - else if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + else { impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); } From 929d18fd58177cd96bebd8b2472f219f29c11fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:17:38 +0200 Subject: [PATCH 05/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 6203c786228ee..32d31aae765dc 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,7 +3641,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact) + if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) != 0)) { JITDUMP("Optimizing object.GetType() with known type to typeof\n"); op1 = impPopStack().val; @@ -3649,7 +3649,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); } - else + else ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) { impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); } From 779a799187071ebf2faf2e8ffe7eb04fe3734eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:36:28 +0200 Subject: [PATCH 06/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 32d31aae765dc..4559752d90ca3 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3649,7 +3649,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, { impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); } - else ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) + else if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) { impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); } From 4de198eeb3daec94ae4b5e6b3781bd24482c7319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Thu, 15 Jun 2023 20:20:58 +0200 Subject: [PATCH 07/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 4559752d90ca3..56cb99ef11113 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,7 +3641,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) != 0)) + if ((typeHnd != NO_CLASS_HANDLE) && isExact && + ((info.compCompHnd->getClassAttribs(typeHnd) & (CORINFO_FLG_SHAREDINST | CORINFO_FLG_GENERIC_TYPE_VARIABLE)) != 0)) { JITDUMP("Optimizing object.GetType() with known type to typeof\n"); op1 = impPopStack().val; From 7f44e8f5b528b59919ddceab5e4506b10704d1ce Mon Sep 17 00:00:00 2001 From: petris Date: Fri, 16 Jun 2023 02:03:32 +0200 Subject: [PATCH 08/27] Check if box is at fault here --- src/coreclr/jit/importer.cpp | 3 ++- src/coreclr/jit/importercalls.cpp | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index de914ea0bdfdc..97e907822597a 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3145,7 +3145,8 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) lvaTable[impBoxTemp].lvType = TYP_REF; lvaTable[impBoxTemp].lvSingleDef = 1; JITDUMP("Marking V%02u as a single def local\n", impBoxTemp); - const bool isExact = true; + const bool isExact = + (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE)) == 0; lvaSetClass(impBoxTemp, pResolvedToken->hClass, isExact); } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 56cb99ef11113..0668f6846d9ee 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,8 +3641,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact && - ((info.compCompHnd->getClassAttribs(typeHnd) & (CORINFO_FLG_SHAREDINST | CORINFO_FLG_GENERIC_TYPE_VARIABLE)) != 0)) + if ((typeHnd != NO_CLASS_HANDLE) && isExact) { JITDUMP("Optimizing object.GetType() with known type to typeof\n"); op1 = impPopStack().val; From 127bd47742d2a504a3d66ced2b6458f9880dcf2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Fri, 16 Jun 2023 02:21:48 +0200 Subject: [PATCH 09/27] Update importer.cpp --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 97e907822597a..050ba8ee6fdda 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3146,7 +3146,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) lvaTable[impBoxTemp].lvSingleDef = 1; JITDUMP("Marking V%02u as a single def local\n", impBoxTemp); const bool isExact = - (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE)) == 0; + (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0; lvaSetClass(impBoxTemp, pResolvedToken->hClass, isExact); } From 0e624293c26dbe56f59040265538ed544147ebd5 Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 21 Jun 2023 17:42:23 +0200 Subject: [PATCH 10/27] Sprinkle some asserts --- src/coreclr/jit/gentree.cpp | 25 +++++++++++++++++++++++++ src/coreclr/jit/importer.cpp | 3 +-- src/coreclr/jit/importercalls.cpp | 1 + src/coreclr/jit/lclvars.cpp | 7 +++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index ea50cb24b231b..13718e537940e 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17853,6 +17853,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b var_types treeType = tree->TypeGet(); if (treeType != TYP_REF) { + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } @@ -17876,6 +17877,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17889,6 +17891,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // if we managed to get a class handle it's definitely not null *pIsNonNull = true; *pIsExact = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } break; @@ -17900,6 +17903,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // return value expression. GenTree* retExpr = obj->AsRetExpr()->gtInlineCandidate; objClass = gtGetClassHandle(retExpr, pIsExact, pIsNonNull); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17912,6 +17916,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if ((ni == NI_System_Array_Clone) || (ni == NI_System_Object_MemberwiseClone)) { objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17921,6 +17926,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = specialObjClass; *pIsExact = true; *pIsNonNull = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } @@ -17936,6 +17942,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // Grab it as our first cut at a return type. assert(inlInfo->methInfo.args.retType == CORINFO_TYPE_CLASS); objClass = inlInfo->methInfo.args.retTypeClass; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); // If the method is shared, the above may not capture // the most precise return type information (that is, @@ -17961,6 +17968,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b eeGetMethodSig(call->gtCallMethHnd, &sig, exactClass); assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -17982,16 +17990,19 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = info.compCompHnd->getMethodClass(method); *pIsExact = true; *pIsNonNull = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else { assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (call->gtCallType == CT_HELPER) { objClass = gtGetHelperCallClassHandle(call, pIsExact, pIsNonNull); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18009,6 +18020,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = runtimeType; *pIsExact = false; *pIsNonNull = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18021,6 +18033,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = impGetStringClass(); *pIsExact = true; *pIsNonNull = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -18038,6 +18051,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b const unsigned objLcl = base->AsLclVarCommon()->GetLclNum(); objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperIs(GT_INDEX_ADDR, GT_ARR_ELEM)) { @@ -18054,6 +18068,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b *pIsExact = false; *pIsNonNull = false; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperGet() == GT_ADD) { @@ -18080,6 +18095,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if (fieldType == TYP_REF) { objClass = fieldClass; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -18092,11 +18108,13 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { CORINFO_FIELD_HANDLE fldHandle = base->AsIntCon()->gtFieldSeq->GetFieldHandle(); objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (base->OperIs(GT_FIELD_ADDR)) { objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; } @@ -18113,15 +18131,19 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[boxTempLcl].lvClassHnd; *pIsExact = lvaTable[boxTempLcl].lvClassIsExact; *pIsNonNull = true; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } default: { + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + if ((objClass != NO_CLASS_HANDLE) && !*pIsExact && JitConfig.JitEnableExactDevirtualization()) { CORINFO_CLASS_HANDLE exactClass; @@ -18129,9 +18151,12 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { *pIsExact = true; objClass = exactClass; + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + return objClass; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 050ba8ee6fdda..de914ea0bdfdc 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3145,8 +3145,7 @@ void Compiler::impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken) lvaTable[impBoxTemp].lvType = TYP_REF; lvaTable[impBoxTemp].lvSingleDef = 1; JITDUMP("Marking V%02u as a single def local\n", impBoxTemp); - const bool isExact = - (info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0; + const bool isExact = true; lvaSetClass(impBoxTemp, pResolvedToken->hClass, isExact); } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 0668f6846d9ee..6e94aa6143501 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3643,6 +3643,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); if ((typeHnd != NO_CLASS_HANDLE) && isExact) { + assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); JITDUMP("Optimizing object.GetType() with known type to typeof\n"); op1 = impPopStack().val; if (!notNull && fgAddrCouldBeNull(op1)) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 80d9493daca42..f0c97728c5823 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3008,6 +3008,7 @@ void Compiler::lvaSetStruct(unsigned varNum, ClassLayout* layout, bool unsafeVal // void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck) { + assert((typeHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); lvaSetStruct(varNum, typGetObjLayout(typeHnd), unsafeValueClsCheck); } @@ -3106,6 +3107,7 @@ void Compiler::lvaSetStructUsedAsVarArg(unsigned varNum) void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { + assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); noway_assert(varNum < lvaCount); if (clsHnd != NO_CLASS_HANDLE && !isExact && JitConfig.JitEnableExactDevirtualization()) @@ -3150,9 +3152,11 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { + assert((stackHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); + assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { @@ -3194,6 +3198,7 @@ void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { + assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); assert(varNum < lvaCount); // Else we should have a class handle to consider @@ -3268,9 +3273,11 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool void Compiler::lvaUpdateClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { + assert((stackHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); + assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { From cde9a24416c0c5399435f7aa799623c3a893d27f Mon Sep 17 00:00:00 2001 From: petris Date: Wed, 21 Jun 2023 17:56:27 +0200 Subject: [PATCH 11/27] Fix building --- src/coreclr/jit/gentree.cpp | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 13718e537940e..5848daebbf3ed 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17853,7 +17853,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b var_types treeType = tree->TypeGet(); if (treeType != TYP_REF) { - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } @@ -17877,7 +17877,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17891,7 +17891,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // if we managed to get a class handle it's definitely not null *pIsNonNull = true; *pIsExact = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } break; @@ -17903,7 +17903,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // return value expression. GenTree* retExpr = obj->AsRetExpr()->gtInlineCandidate; objClass = gtGetClassHandle(retExpr, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17916,7 +17916,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if ((ni == NI_System_Array_Clone) || (ni == NI_System_Object_MemberwiseClone)) { objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17926,7 +17926,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = specialObjClass; *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } @@ -17942,7 +17942,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // Grab it as our first cut at a return type. assert(inlInfo->methInfo.args.retType == CORINFO_TYPE_CLASS); objClass = inlInfo->methInfo.args.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); // If the method is shared, the above may not capture // the most precise return type information (that is, @@ -17968,7 +17968,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b eeGetMethodSig(call->gtCallMethHnd, &sig, exactClass); assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -17990,19 +17990,19 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = info.compCompHnd->getMethodClass(method); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else { assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (call->gtCallType == CT_HELPER) { objClass = gtGetHelperCallClassHandle(call, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18020,7 +18020,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = runtimeType; *pIsExact = false; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18033,7 +18033,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = impGetStringClass(); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -18051,7 +18051,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b const unsigned objLcl = base->AsLclVarCommon()->GetLclNum(); objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperIs(GT_INDEX_ADDR, GT_ARR_ELEM)) { @@ -18068,7 +18068,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b *pIsExact = false; *pIsNonNull = false; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperGet() == GT_ADD) { @@ -18095,7 +18095,7 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if (fieldType == TYP_REF) { objClass = fieldClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -18108,13 +18108,13 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { CORINFO_FIELD_HANDLE fldHandle = base->AsIntCon()->gtFieldSeq->GetFieldHandle(); objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (base->OperIs(GT_FIELD_ADDR)) { objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; } @@ -18131,18 +18131,18 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[boxTempLcl].lvClassHnd; *pIsExact = lvaTable[boxTempLcl].lvClassIsExact; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } default: { - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if ((objClass != NO_CLASS_HANDLE) && !*pIsExact && JitConfig.JitEnableExactDevirtualization()) { @@ -18151,11 +18151,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { *pIsExact = true; objClass = exactClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } From dcf25a815d17b03256c3124151f3cd77ed8cc67b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Fri, 23 Jun 2023 03:58:39 +0200 Subject: [PATCH 12/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 6e94aa6143501..59aefe59e1af3 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,7 +3641,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact) + if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) != 0)) { assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); JITDUMP("Optimizing object.GetType() with known type to typeof\n"); From 6abbd7b2faed16d06aca6078f79a89ee614d05ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Fri, 23 Jun 2023 05:02:53 +0200 Subject: [PATCH 13/27] Update importercalls.cpp --- src/coreclr/jit/importercalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 59aefe59e1af3..d892578507657 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,7 +3641,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) != 0)) + if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) == 0)) { assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); JITDUMP("Optimizing object.GetType() with known type to typeof\n"); From 4b35aa9d1eb5aa7c5d2122d0f959013fc7b11b6a Mon Sep 17 00:00:00 2001 From: petris Date: Fri, 23 Jun 2023 20:38:33 +0200 Subject: [PATCH 14/27] Format code --- src/coreclr/jit/gentree.cpp | 69 ++++++++++++++++++++----------- src/coreclr/jit/importercalls.cpp | 3 +- src/coreclr/jit/lclvars.cpp | 21 ++++++---- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 5848daebbf3ed..8a076672b8307 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17853,7 +17853,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b var_types treeType = tree->TypeGet(); if (treeType != TYP_REF) { - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } @@ -17877,7 +17878,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17891,7 +17893,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // if we managed to get a class handle it's definitely not null *pIsNonNull = true; *pIsExact = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } break; @@ -17903,7 +17906,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // return value expression. GenTree* retExpr = obj->AsRetExpr()->gtInlineCandidate; objClass = gtGetClassHandle(retExpr, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17916,7 +17920,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if ((ni == NI_System_Array_Clone) || (ni == NI_System_Object_MemberwiseClone)) { objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17926,7 +17931,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = specialObjClass; *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } @@ -17942,7 +17948,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // Grab it as our first cut at a return type. assert(inlInfo->methInfo.args.retType == CORINFO_TYPE_CLASS); objClass = inlInfo->methInfo.args.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); // If the method is shared, the above may not capture // the most precise return type information (that is, @@ -17968,7 +17975,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b eeGetMethodSig(call->gtCallMethHnd, &sig, exactClass); assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & + CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -17990,19 +17998,22 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = info.compCompHnd->getMethodClass(method); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else { assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (call->gtCallType == CT_HELPER) { objClass = gtGetHelperCallClassHandle(call, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18020,7 +18031,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = runtimeType; *pIsExact = false; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18033,7 +18045,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = impGetStringClass(); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -18051,7 +18064,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b const unsigned objLcl = base->AsLclVarCommon()->GetLclNum(); objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperIs(GT_INDEX_ADDR, GT_ARR_ELEM)) { @@ -18068,7 +18082,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b *pIsExact = false; *pIsNonNull = false; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperGet() == GT_ADD) { @@ -18095,7 +18110,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if (fieldType == TYP_REF) { objClass = fieldClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & + CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -18108,13 +18124,15 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { CORINFO_FIELD_HANDLE fldHandle = base->AsIntCon()->gtFieldSeq->GetFieldHandle(); objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (base->OperIs(GT_FIELD_ADDR)) { objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; } @@ -18131,18 +18149,21 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[boxTempLcl].lvClassHnd; *pIsExact = lvaTable[boxTempLcl].lvClassIsExact; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } default: { - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if ((objClass != NO_CLASS_HANDLE) && !*pIsExact && JitConfig.JitEnableExactDevirtualization()) { @@ -18151,11 +18172,13 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { *pIsExact = true; objClass = exactClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((objClass == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index d892578507657..a0e249f4d443b 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3641,7 +3641,8 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) == 0)) + if ((typeHnd != NO_CLASS_HANDLE) && isExact && + ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) == 0)) { assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); JITDUMP("Optimizing object.GetType() with known type to typeof\n"); diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index f0c97728c5823..f493844495bd4 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3008,7 +3008,8 @@ void Compiler::lvaSetStruct(unsigned varNum, ClassLayout* layout, bool unsafeVal // void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck) { - assert((typeHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((typeHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); lvaSetStruct(varNum, typGetObjLayout(typeHnd), unsafeValueClsCheck); } @@ -3107,7 +3108,8 @@ void Compiler::lvaSetStructUsedAsVarArg(unsigned varNum) void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { - assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((clsHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); noway_assert(varNum < lvaCount); if (clsHnd != NO_CLASS_HANDLE && !isExact && JitConfig.JitEnableExactDevirtualization()) @@ -3152,11 +3154,13 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { - assert((stackHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((stackHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); - assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((clsHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { @@ -3198,7 +3202,8 @@ void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { - assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((clsHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); assert(varNum < lvaCount); // Else we should have a class handle to consider @@ -3273,11 +3278,13 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool void Compiler::lvaUpdateClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { - assert((stackHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((stackHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); - assert((clsHnd == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); + assert((clsHnd == NO_CLASS_HANDLE) || + ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { From 6a60fc03be38ac6015f1c1d43f6488fd231f9205 Mon Sep 17 00:00:00 2001 From: petris Date: Fri, 23 Jun 2023 21:53:44 +0200 Subject: [PATCH 15/27] Try fixing the r2r test --- src/tests/readytorun/tests/main.cs | 4 +++- src/tests/readytorun/tests/test.cs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/readytorun/tests/main.cs b/src/tests/readytorun/tests/main.cs index 04314860d48ca..b88e7a7fdf792 100644 --- a/src/tests/readytorun/tests/main.cs +++ b/src/tests/readytorun/tests/main.cs @@ -278,7 +278,9 @@ static void TestChangingHFAStruct() [MethodImplAttribute(MethodImplOptions.NoInlining)] static void TestGetType() { - new MyClass().GetType().ToString(); + Use(new MyClass().GetType().ToString()); + [MethodImplAttribute(MethodImplOptions.NoInlining)] + static void Use(object o) { } } [MethodImplAttribute(MethodImplOptions.NoInlining)] diff --git a/src/tests/readytorun/tests/test.cs b/src/tests/readytorun/tests/test.cs index 73e4dfb7a2bef..53d5165efb07f 100644 --- a/src/tests/readytorun/tests/test.cs +++ b/src/tests/readytorun/tests/test.cs @@ -729,7 +729,9 @@ static void TestChangingHFAStruct() [MethodImplAttribute(MethodImplOptions.NoInlining)] static void TestGetType() { - new MyClass().GetType().ToString(); + Use(new MyClass().GetType().ToString()); + [MethodImplAttribute(MethodImplOptions.NoInlining)] + static void Use(object o) { } } [MethodImplAttribute(MethodImplOptions.NoInlining)] @@ -1012,4 +1014,4 @@ public static void RunAllTests(Assembly assembly) } static int s; -} \ No newline at end of file +} From cbe32bf272d3f69f1aaf76e90618684bdde2920a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:26:16 +0200 Subject: [PATCH 16/27] Update test.cs --- src/tests/readytorun/tests/test.cs | 40 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/tests/readytorun/tests/test.cs b/src/tests/readytorun/tests/test.cs index 53d5165efb07f..c434101755b9b 100644 --- a/src/tests/readytorun/tests/test.cs +++ b/src/tests/readytorun/tests/test.cs @@ -14,13 +14,17 @@ public static class Assert { public static bool HasAssertFired; + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void AreEqual(Object actual, Object expected) { - if (!(actual == null && expected == null) && !actual.Equals(expected)) + if (ReferenceEquals(expected, actual)) + return; + + if (ReferenceEquals(expected, null) || !expected.Equals(actual)) { Console.WriteLine("Not equal!"); - Console.WriteLine("actual = " + actual.ToString()); - Console.WriteLine("expected = " + expected.ToString()); + Console.WriteLine("expected = " + expected?.ToString()); + Console.WriteLine("actual = " + actual?.ToString()); HasAssertFired = true; } } @@ -623,8 +627,6 @@ static void TestMovedGenericVirtualMethod() Assert.AreEqual(o.ChangedToVirtual(), typeof(List).ToString()); } - - [MethodImplAttribute(MethodImplOptions.NoInlining)] static void TestMovedGenericVirtualMethodOnNullReference() { @@ -729,9 +731,9 @@ static void TestChangingHFAStruct() [MethodImplAttribute(MethodImplOptions.NoInlining)] static void TestGetType() { - Use(new MyClass().GetType().ToString()); + NoInline(new MyClass()).GetType().ToString(); [MethodImplAttribute(MethodImplOptions.NoInlining)] - static void Use(object o) { } + static object NoInline(object o) => o; } [MethodImplAttribute(MethodImplOptions.NoInlining)] @@ -850,17 +852,17 @@ static void TestGenericLdtokenFields() string expectedDllField4 = "System.Collections.Generic.KeyValuePair`2[???,System.Int32] MyGeneric`2[???,???]::m_Field4".Replace("???", instArg.ToString()); string expectedDllField5 = "System.Int32 MyGeneric`2[???,???]::m_Field5".Replace("???", instArg.ToString()); - Assert.AreEqual(expectedField1, FieldFullName(getter.GetGenT_Field1())); - Assert.AreEqual(expectedField2, FieldFullName(getter.GetGenT_Field2())); - Assert.AreEqual(expectedField3, FieldFullName(getter.GetGenT_Field3())); - Assert.AreEqual(expectedField4, FieldFullName(getter.GetGenT_Field4())); - Assert.AreEqual(expectedField5, FieldFullName(getter.GetGenT_Field5())); - - Assert.AreEqual(expectedDllField1, FieldFullName(getter.GetGenDllT_Field1())); - Assert.AreEqual(expectedDllField2, FieldFullName(getter.GetGenDllT_Field2())); - Assert.AreEqual(expectedDllField3, FieldFullName(getter.GetGenDllT_Field3())); - Assert.AreEqual(expectedDllField4, FieldFullName(getter.GetGenDllT_Field4())); - Assert.AreEqual(expectedDllField5, FieldFullName(getter.GetGenDllT_Field5())); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field1()), expectedField1); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field2()), expectedField2); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field3()), expectedField3); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field4()), expectedField4); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field5()), expectedField5); + + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field1()), expectedDllField1); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field2()), expectedDllField2); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field3()), expectedDllField3); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field4()), expectedDllField4); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field5()), expectedDllField5); } } @@ -890,7 +892,7 @@ private static void ValidateTestHasCrossModuleImplementation(string testName, Li found = true; } Console.WriteLine($"Found:{found}"); - Assert.AreEqual(expectedToBePresent, found); + Assert.AreEqual(found, expectedToBePresent); } public static void RunAllTests(Assembly assembly) From a12885645b61776c87f11a3557d33f2938aabac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:31:44 +0200 Subject: [PATCH 17/27] Update main.cs --- src/tests/readytorun/tests/main.cs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/tests/readytorun/tests/main.cs b/src/tests/readytorun/tests/main.cs index b88e7a7fdf792..3fe94bb692eeb 100644 --- a/src/tests/readytorun/tests/main.cs +++ b/src/tests/readytorun/tests/main.cs @@ -278,9 +278,9 @@ static void TestChangingHFAStruct() [MethodImplAttribute(MethodImplOptions.NoInlining)] static void TestGetType() { - Use(new MyClass().GetType().ToString()); + NoInline(new MyClass()).GetType().ToString(); [MethodImplAttribute(MethodImplOptions.NoInlining)] - static void Use(object o) { } + static object NoInline(object o) => o; } [MethodImplAttribute(MethodImplOptions.NoInlining)] @@ -395,17 +395,17 @@ static void GenericLdtokenFieldsTest() string expectedDllField4 = "System.Collections.Generic.KeyValuePair`2[???,System.Int32] MyGeneric`2[???,???]::m_Field4".Replace("???", instArg.ToString()); string expectedDllField5 = "System.Int32 MyGeneric`2[???,???]::m_Field5".Replace("???", instArg.ToString()); - Assert.AreEqual(expectedField1, FieldFullName(getter.GetGenT_Field1())); - Assert.AreEqual(expectedField2, FieldFullName(getter.GetGenT_Field2())); - Assert.AreEqual(expectedField3, FieldFullName(getter.GetGenT_Field3())); - Assert.AreEqual(expectedField4, FieldFullName(getter.GetGenT_Field4())); - Assert.AreEqual(expectedField5, FieldFullName(getter.GetGenT_Field5())); - - Assert.AreEqual(expectedDllField1, FieldFullName(getter.GetGenDllT_Field1())); - Assert.AreEqual(expectedDllField2, FieldFullName(getter.GetGenDllT_Field2())); - Assert.AreEqual(expectedDllField3, FieldFullName(getter.GetGenDllT_Field3())); - Assert.AreEqual(expectedDllField4, FieldFullName(getter.GetGenDllT_Field4())); - Assert.AreEqual(expectedDllField5, FieldFullName(getter.GetGenDllT_Field5())); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field1()), expectedField1); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field2()), expectedField2); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field3()), expectedField3); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field4()), expectedField4); + Assert.AreEqual(FieldFullName(getter.GetGenT_Field5()), expectedField5); + + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field1()), expectedDllField1); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field2()), expectedDllField2); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field3()), expectedDllField3); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field4()), expectedDllField4); + Assert.AreEqual(FieldFullName(getter.GetGenDllT_Field5()), expectedDllField5); } } @@ -440,7 +440,7 @@ static void TestILBodyChange() { int actualMethodCallResult = (int)typeof(ILInliningTest).GetMethod("TestDifferentIntValue").Invoke(null, new object[]{}); Console.WriteLine(actualMethodCallResult); - Assert.AreEqual(ILInliningTest.TestDifferentIntValue(), actualMethodCallResult); + Assert.AreEqual(actualMethodCallResult, ILInliningTest.TestDifferentIntValue()); } static void RunAllTests() From f5730517c38c770f0251d5833e80e5066a6658cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:34:59 +0200 Subject: [PATCH 18/27] Update newarray.cs --- src/tests/readytorun/tests/newarray.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/readytorun/tests/newarray.cs b/src/tests/readytorun/tests/newarray.cs index 6aa4409458cdd..da175102b59ae 100644 --- a/src/tests/readytorun/tests/newarray.cs +++ b/src/tests/readytorun/tests/newarray.cs @@ -112,13 +112,17 @@ public static class Assert { public static bool HasAssertFired; + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void AreEqual(Object actual, Object expected) { - if (!(actual == null && expected == null) && !actual.Equals(expected)) + if (ReferenceEquals(expected, actual)) + return; + + if (ReferenceEquals(expected, null) || !expected.Equals(actual)) { Console.WriteLine("Not equal!"); - Console.WriteLine("actual = " + actual.ToString()); - Console.WriteLine("expected = " + expected.ToString()); + Console.WriteLine("expected = " + expected?.ToString()); + Console.WriteLine("actual = " + actual?.ToString()); HasAssertFired = true; } } From f2dad1d4d31e61ca16c65eb6992d10f3dcda4d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:35:05 +0200 Subject: [PATCH 19/27] Update generics.cs --- src/tests/readytorun/tests/generics.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/readytorun/tests/generics.cs b/src/tests/readytorun/tests/generics.cs index d4dc2acd79cc2..233b377a4f89a 100644 --- a/src/tests/readytorun/tests/generics.cs +++ b/src/tests/readytorun/tests/generics.cs @@ -3073,13 +3073,17 @@ public static class Assert { public static bool HasAssertFired; + [MethodImplAttribute(MethodImplOptions.NoInlining)] public static void AreEqual(Object actual, Object expected) { - if (!(actual == null && expected == null) && !actual.Equals(expected)) + if (ReferenceEquals(expected, actual)) + return; + + if (ReferenceEquals(expected, null) || !expected.Equals(actual)) { Console.WriteLine("Not equal!"); - Console.WriteLine("actual = " + actual.ToString()); - Console.WriteLine("expected = " + expected.ToString()); + Console.WriteLine("expected = " + expected?.ToString()); + Console.WriteLine("actual = " + actual?.ToString()); HasAssertFired = true; } } From a1b6fd7357afee5f6cee026a32eb106313f566c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 27 Jun 2023 19:32:54 +0200 Subject: [PATCH 20/27] Update gentree.cpp --- src/coreclr/jit/gentree.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index bebf78170118f..f83216f5b2e50 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18211,8 +18211,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } + else + { + *pIsExact = (info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_FINAL) != 0; + } } - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); From b61f1e1fed122c6dc9bf390c3d6e916eec7e6259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 27 Jun 2023 22:52:18 +0200 Subject: [PATCH 21/27] Update gentree.cpp --- src/coreclr/jit/gentree.cpp | 49 +------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index f83216f5b2e50..fbf20ac40bebd 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -17889,8 +17889,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b var_types treeType = tree->TypeGet(); if (treeType != TYP_REF) { - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } @@ -17914,8 +17912,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17929,8 +17925,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // if we managed to get a class handle it's definitely not null *pIsNonNull = true; *pIsExact = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } break; @@ -17942,8 +17936,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // return value expression. GenTree* retExpr = obj->AsRetExpr()->gtInlineCandidate; objClass = gtGetClassHandle(retExpr, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17956,8 +17948,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if ((ni == NI_System_Array_Clone) || (ni == NI_System_Object_MemberwiseClone)) { objClass = gtGetClassHandle(call->gtArgs.GetThisArg()->GetNode(), pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -17967,8 +17957,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = specialObjClass; *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } @@ -17984,8 +17972,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b // Grab it as our first cut at a return type. assert(inlInfo->methInfo.args.retType == CORINFO_TYPE_CLASS); objClass = inlInfo->methInfo.args.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); // If the method is shared, the above may not capture // the most precise return type information (that is, @@ -18011,8 +17997,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b eeGetMethodSig(call->gtCallMethHnd, &sig, exactClass); assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & - CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -18034,22 +18018,16 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = info.compCompHnd->getMethodClass(method); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else { assert(sig.retType == CORINFO_TYPE_CLASS); objClass = sig.retTypeClass; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (call->gtCallType == CT_HELPER) { objClass = gtGetHelperCallClassHandle(call, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18067,8 +18045,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = runtimeType; *pIsExact = false; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; @@ -18081,8 +18057,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = impGetStringClass(); *pIsExact = true; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } @@ -18100,8 +18074,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b const unsigned objLcl = base->AsLclVarCommon()->GetLclNum(); objClass = lvaTable[objLcl].lvClassHnd; *pIsExact = lvaTable[objLcl].lvClassIsExact; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperIs(GT_INDEX_ADDR, GT_ARR_ELEM)) { @@ -18118,8 +18090,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b *pIsExact = false; *pIsNonNull = false; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else if (base->OperGet() == GT_ADD) { @@ -18146,8 +18116,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b if (fieldType == TYP_REF) { objClass = fieldClass; - assert((objClass == NO_CLASS_HANDLE) || ((info.compCompHnd->getClassAttribs(objClass) & - CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } } @@ -18160,15 +18128,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { CORINFO_FIELD_HANDLE fldHandle = base->AsIntCon()->gtFieldSeq->GetFieldHandle(); objClass = gtGetFieldClassHandle(fldHandle, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } } else if (base->OperIs(GT_FIELD_ADDR)) { objClass = gtGetFieldClassHandle(base->AsFieldAddr()->gtFldHnd, pIsExact, pIsNonNull); - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } break; } @@ -18185,22 +18149,15 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b objClass = lvaTable[boxTempLcl].lvClassHnd; *pIsExact = lvaTable[boxTempLcl].lvClassIsExact; *pIsNonNull = true; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } default: { - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); break; } } - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); - if ((objClass != NO_CLASS_HANDLE) && !*pIsExact && JitConfig.JitEnableExactDevirtualization()) { CORINFO_CLASS_HANDLE exactClass; @@ -18208,16 +18165,12 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b { *pIsExact = true; objClass = exactClass; - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); } else { - *pIsExact = (info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_FINAL) != 0; + *pIsExact = impIsClassExact(objClass); } } - assert((objClass == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(objClass) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); return objClass; } From be56999c2fb462deb6c752074f880579ff4bb608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 27 Jun 2023 23:02:35 +0200 Subject: [PATCH 22/27] Update lclvars.cpp --- src/coreclr/jit/lclvars.cpp | 46 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index f493844495bd4..47b73f27aa209 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3008,8 +3008,6 @@ void Compiler::lvaSetStruct(unsigned varNum, ClassLayout* layout, bool unsafeVal // void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck) { - assert((typeHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); lvaSetStruct(varNum, typGetObjLayout(typeHnd), unsafeValueClsCheck); } @@ -3108,8 +3106,6 @@ void Compiler::lvaSetStructUsedAsVarArg(unsigned varNum) void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { - assert((clsHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); noway_assert(varNum < lvaCount); if (clsHnd != NO_CLASS_HANDLE && !isExact && JitConfig.JitEnableExactDevirtualization()) @@ -3120,6 +3116,10 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is isExact = true; clsHnd = exactClass; } + else + { + isExact = impIsClassExact(clsHnd); + } } // Else we should have a type handle. @@ -3154,13 +3154,9 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { - assert((stackHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); - assert((clsHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { @@ -3202,8 +3198,6 @@ void Compiler::lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact) { - assert((clsHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); assert(varNum < lvaCount); // Else we should have a class handle to consider @@ -3225,18 +3219,32 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool const bool isNewClass = (clsHnd != varDsc->lvClassHnd); bool shouldUpdate = false; - // Are we attempting to update the class? Only check this when we have - // an new type and the existing class is inexact... we should not be - // updating exact classes. - if (!varDsc->lvClassIsExact && isNewClass) + if (!isExact && JitConfig.JitEnableExactDevirtualization()) { - shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); + CORINFO_CLASS_HANDLE exactClass; + if (info.compCompHnd->getExactClasses(clsHnd, 1, &exactClass) == 1) + { + isExact = true; + clsHnd = exactClass; + } + else + { + isExact = impIsClassExact(clsHnd); + } } - // Else are we attempting to update exactness? - else if (isExact && !varDsc->lvClassIsExact && !isNewClass) + + // Are we attempting to update exactness? + if (isExact && !varDsc->lvClassIsExact) { shouldUpdate = true; } + // Are we attempting to update the class? Only check this when we have + // an new type and the existing class is inexact... we should not be + // updating exact classes + else if (isNewClass && !varDsc->lvClassIsExact) + { + shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); + } #if DEBUG if (isNewClass || (isExact != varDsc->lvClassIsExact)) @@ -3278,13 +3286,9 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool void Compiler::lvaUpdateClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHnd) { - assert((stackHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(stackHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); bool isExact = false; bool isNonNull = false; CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull); - assert((clsHnd == NO_CLASS_HANDLE) || - ((info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0)); if (clsHnd != nullptr) { From c95231a40881d35d3ee4787004aeb94f55aa2328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 27 Jun 2023 23:24:44 +0200 Subject: [PATCH 23/27] Update lclvars.cpp --- src/coreclr/jit/lclvars.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 47b73f27aa209..e6009f853a4f7 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3213,7 +3213,7 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool assert(varDsc->lvSingleDef); // Now see if we should update. - // + // New information may not always be "better" so do some // simple analysis to decide if the update is worthwhile. const bool isNewClass = (clsHnd != varDsc->lvClassHnd); @@ -3232,7 +3232,7 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = impIsClassExact(clsHnd); } } - + // Are we attempting to update exactness? if (isExact && !varDsc->lvClassIsExact) { From ff1adcdc5a87ff1f6bcc4790513b09d099302a42 Mon Sep 17 00:00:00 2001 From: petris Date: Mon, 10 Jul 2023 21:17:19 +0200 Subject: [PATCH 24/27] Revert separated changes --- src/coreclr/jit/gentree.cpp | 4 ---- src/coreclr/jit/lclvars.cpp | 34 ++++++++-------------------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 668b9139929f6..66943d25d631b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18261,10 +18261,6 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b *pIsExact = true; objClass = exactClass; } - else - { - *pIsExact = impIsClassExact(objClass); - } } return objClass; diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index b5b9089385e9f..5f6352d8fc2e6 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -3076,10 +3076,6 @@ void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool is isExact = true; clsHnd = exactClass; } - else - { - isExact = impIsClassExact(clsHnd); - } } // Else we should have a type handle. @@ -3173,38 +3169,24 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool assert(varDsc->lvSingleDef); // Now see if we should update. - + // // New information may not always be "better" so do some // simple analysis to decide if the update is worthwhile. const bool isNewClass = (clsHnd != varDsc->lvClassHnd); bool shouldUpdate = false; - if (!isExact && JitConfig.JitEnableExactDevirtualization()) - { - CORINFO_CLASS_HANDLE exactClass; - if (info.compCompHnd->getExactClasses(clsHnd, 1, &exactClass) == 1) - { - isExact = true; - clsHnd = exactClass; - } - else - { - isExact = impIsClassExact(clsHnd); - } - } - - // Are we attempting to update exactness? - if (isExact && !varDsc->lvClassIsExact) - { - shouldUpdate = true; - } // Are we attempting to update the class? Only check this when we have // an new type and the existing class is inexact... we should not be - // updating exact classes - else if (isNewClass && !varDsc->lvClassIsExact) + // updating exact classes. + if (!varDsc->lvClassIsExact && isNewClass) { shouldUpdate = !!info.compCompHnd->isMoreSpecificType(varDsc->lvClassHnd, clsHnd); } + // Else are we attempting to update exactness? + else if (isExact && !varDsc->lvClassIsExact && !isNewClass) + { + shouldUpdate = true; + } #if DEBUG if (isNewClass || (isExact != varDsc->lvClassIsExact)) From cf9e77170b2d31e9e9a48647669b062f307f3830 Mon Sep 17 00:00:00 2001 From: petris Date: Mon, 10 Jul 2023 21:22:08 +0200 Subject: [PATCH 25/27] Cleanup --- src/coreclr/jit/compiler.h | 3 +++ src/coreclr/jit/importer.cpp | 38 +++++++++++++++++++++++++++++++ src/coreclr/jit/importercalls.cpp | 18 +++------------ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8a2d862d1fe2c..2d246597ce2e0 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4068,6 +4068,9 @@ class Compiler GenTree** clone, unsigned curLevel, Statement** pAfterStmt DEBUGARG(const char* reason)); + + CORINFO_CLASS_HANDLE impImportHandleFromTree(GenTree* tree, bool allowShared); + GenTree* impStoreStruct(GenTree* store, unsigned curLevel, Statement** pAfterStmt = nullptr, diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e745bce1bd037..e1d68f6744a01 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -2039,6 +2039,44 @@ GenTree* Compiler::impCloneExpr(GenTree* tree, return gtNewLclvNode(temp, type); } +//------------------------------------------------------------------------ +// impImportHandleFromTree: Imports a tree that's only used for obtaining a type handle +// to its value +// +// Arguments: +// tree - imported tree +// allowShared - whether shared types are considered as valid handles +// +// Return Value: +// The extracted handle, or NO_CLASS_HANDLE if no handle could be extracted +// +CORINFO_CLASS_HANDLE Compiler::impImportHandleFromTree(GenTree* tree, bool allowShared) +{ + bool isExact = false; + bool notNull = false; + CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(tree, &isExact, ¬Null); + if ((typeHnd != NO_CLASS_HANDLE) && isExact) + { + assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); + if (!allowShared && ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) != 0)) + { + return NO_CLASS_HANDLE; + } + + JITDUMP("Retuning a constant handle from imported tree\n"); + if (!notNull && fgAddrCouldBeNull(tree)) + { + impAppendTree(gtNewNullCheck(tree, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); + } + else if ((tree->gtFlags & GTF_SIDE_EFFECT) != 0) + { + impAppendTree(gtUnusedValNode(tree), CHECK_SPILL_ALL, impCurStmtDI); + } + return typeHnd; + } + return NO_CLASS_HANDLE; +} + //------------------------------------------------------------------------ // impCreateDIWithCurrentStackInfo: Create a DebugInfo instance with the // specified IL offset and 'is call' bit, using the current stack to determine diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 1010453eb7a28..142524cfbe127 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3564,23 +3564,11 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // Load handle directly for known types if (retNode == nullptr) { - bool isExact = false; - bool notNull = false; - CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(op1, &isExact, ¬Null); - if ((typeHnd != NO_CLASS_HANDLE) && isExact && - ((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_SHAREDINST) == 0)) + CORINFO_CLASS_HANDLE typeHnd = impImportHandleFromTree(op1, false); + if (typeHnd != NO_CLASS_HANDLE) { - assert((info.compCompHnd->getClassAttribs(typeHnd) & CORINFO_FLG_GENERIC_TYPE_VARIABLE) == 0); JITDUMP("Optimizing object.GetType() with known type to typeof\n"); - op1 = impPopStack().val; - if (!notNull && fgAddrCouldBeNull(op1)) - { - impAppendTree(gtNewNullCheck(op1, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); - } - else if ((op1->gtFlags & GTF_SIDE_EFFECT) != 0) - { - impAppendTree(gtUnusedValNode(op1), CHECK_SPILL_ALL, impCurStmtDI); - } + impPopStack(); GenTree* handle = gtNewIconEmbClsHndNode(typeHnd); retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); } From 32c2b3aa800652ee4f2064ff0e5cef6be9fc1e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:29:46 +0000 Subject: [PATCH 26/27] Fix the helper --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/importer.cpp | 9 +++++---- src/coreclr/jit/importercalls.cpp | 3 +-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2d246597ce2e0..8dfb9d413b4b4 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -4069,7 +4069,7 @@ class Compiler unsigned curLevel, Statement** pAfterStmt DEBUGARG(const char* reason)); - CORINFO_CLASS_HANDLE impImportHandleFromTree(GenTree* tree, bool allowShared); + CORINFO_CLASS_HANDLE impImportHandleFromStack(bool allowShared); GenTree* impStoreStruct(GenTree* store, unsigned curLevel, diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e1d68f6744a01..62168679c6eee 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -2040,18 +2040,18 @@ GenTree* Compiler::impCloneExpr(GenTree* tree, } //------------------------------------------------------------------------ -// impImportHandleFromTree: Imports a tree that's only used for obtaining a type handle -// to its value +// impImportHandleFromTree: Imports the tree on the top of the stack +// and extracts the handle from it // // Arguments: -// tree - imported tree // allowShared - whether shared types are considered as valid handles // // Return Value: // The extracted handle, or NO_CLASS_HANDLE if no handle could be extracted // -CORINFO_CLASS_HANDLE Compiler::impImportHandleFromTree(GenTree* tree, bool allowShared) +CORINFO_CLASS_HANDLE Compiler::impImportHandleFromStack(bool allowShared) { + GenTree* tree = impStackTop().val; bool isExact = false; bool notNull = false; CORINFO_CLASS_HANDLE typeHnd = gtGetClassHandle(tree, &isExact, ¬Null); @@ -2064,6 +2064,7 @@ CORINFO_CLASS_HANDLE Compiler::impImportHandleFromTree(GenTree* tree, bool allow } JITDUMP("Retuning a constant handle from imported tree\n"); + impPopStack(); if (!notNull && fgAddrCouldBeNull(tree)) { impAppendTree(gtNewNullCheck(tree, compCurBB), CHECK_SPILL_ALL, impCurStmtDI); diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 142524cfbe127..cb4f1d24f9ffb 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3564,11 +3564,10 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, // Load handle directly for known types if (retNode == nullptr) { - CORINFO_CLASS_HANDLE typeHnd = impImportHandleFromTree(op1, false); + CORINFO_CLASS_HANDLE typeHnd = impImportHandleFromStack(false); if (typeHnd != NO_CLASS_HANDLE) { JITDUMP("Optimizing object.GetType() with known type to typeof\n"); - impPopStack(); GenTree* handle = gtNewIconEmbClsHndNode(typeHnd); retNode = gtNewHelperCallNode(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, TYP_REF, handle); } From 75163fde83b1ab613f1c6206ff0ea93243d6949e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Petryka?= <35800402+MichalPetryka@users.noreply.github.com> Date: Wed, 12 Jul 2023 01:59:40 +0200 Subject: [PATCH 27/27] Update src/coreclr/jit/importer.cpp Co-authored-by: Jan Kotas --- src/coreclr/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 62168679c6eee..82dfc863b2139 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -2040,7 +2040,7 @@ GenTree* Compiler::impCloneExpr(GenTree* tree, } //------------------------------------------------------------------------ -// impImportHandleFromTree: Imports the tree on the top of the stack +// impImportHandleFromStack: Imports the tree on the top of the stack // and extracts the handle from it // // Arguments: