Skip to content

Commit 99eede9

Browse files
authored
Revert "Optimize BOX+UNBOX for "T? -> T" and "T -> T?" (#104931)" (#105515)
* Revert "Optimize BOX+UNBOX for "T? -> T" and "T -> T?" (#104931)" This reverts commit 9df4f7f. * Add back eeIsSharedInst
1 parent eedf30e commit 99eede9

File tree

4 files changed

+12
-124
lines changed

4 files changed

+12
-124
lines changed

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3468,7 +3468,7 @@ class Compiler
34683468

34693469
GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd);
34703470

3471-
GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset, ClassLayout* layout = nullptr);
3471+
GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset);
34723472
GenTreeRetExpr* gtNewInlineCandidateReturnExpr(GenTreeCall* inlineCandidate, var_types type);
34733473

34743474
GenTreeFieldAddr* gtNewFieldAddrNode(var_types type,
@@ -4512,10 +4512,7 @@ class Compiler
45124512
MakeInlineObservation = 2,
45134513
};
45144514

4515-
GenTree* impStoreNullableFields(CORINFO_CLASS_HANDLE nullableCls,
4516-
GenTree* value);
45174515
GenTree* impInlineUnboxNullable(CORINFO_CLASS_HANDLE nullableCls, GenTree* nullableClsNode, GenTree* obj);
4518-
void impLoadNullableFields(GenTree* nullableObj, CORINFO_CLASS_HANDLE nullableCls, GenTree** hasValueFld, GenTree** valueFld);
45194516

45204517
int impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,
45214518
const BYTE* codeAddr,

src/coreclr/jit/gentree.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8284,9 +8284,9 @@ GenTreeConditional* Compiler::gtNewConditionalNode(
82848284
return node;
82858285
}
82868286

8287-
GenTreeLclFld* Compiler::gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset, ClassLayout* layout)
8287+
GenTreeLclFld* Compiler::gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset)
82888288
{
8289-
GenTreeLclFld* node = new (this, GT_LCL_FLD) GenTreeLclFld(GT_LCL_FLD, type, lnum, offset, layout);
8289+
GenTreeLclFld* node = new (this, GT_LCL_FLD) GenTreeLclFld(GT_LCL_FLD, type, lnum, offset, nullptr);
82908290
return node;
82918291
}
82928292

@@ -15073,7 +15073,8 @@ GenTree* Compiler::gtOptimizeEnumHasFlag(GenTree* thisOp, GenTree* flagOp)
1507315073

1507415074
// If we have a shared type instance we can't safely check type
1507515075
// equality, so bail.
15076-
if (eeIsSharedInst(thisHnd))
15076+
DWORD classAttribs = info.compCompHnd->getClassAttribs(thisHnd);
15077+
if (classAttribs & CORINFO_FLG_SHAREDINST)
1507715078
{
1507815079
JITDUMP("bailing, have shared instance type\n");
1507915080
return nullptr;
@@ -18884,7 +18885,8 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTree* tree, bool* pIsExact, b
1888418885
// processing the call, but we could/should apply
1888518886
// similar sharpening to the argument and local types
1888618887
// of the inlinee.
18887-
if (eeIsSharedInst(objClass))
18888+
const unsigned retClassFlags = info.compCompHnd->getClassAttribs(objClass);
18889+
if (retClassFlags & CORINFO_FLG_SHAREDINST)
1888818890
{
1888918891
CORINFO_CONTEXT_HANDLE context = inlInfo->exactContextHnd;
1889018892

src/coreclr/jit/importer.cpp

Lines changed: 4 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,84 +2979,6 @@ GenTree* Compiler::impInlineUnboxNullable(CORINFO_CLASS_HANDLE nullableCls, GenT
29792979
return gtNewLclvNode(resultTmp, TYP_STRUCT);
29802980
}
29812981

2982-
//------------------------------------------------------------------------
2983-
// impStoreNullableFields: create a Nullable<T> object and store
2984-
// 'hasValue' (always true) and the given value for 'value' field
2985-
//
2986-
// Arguments:
2987-
// nullableCls - class handle for the Nullable<T> class
2988-
// value - value to store in 'value' field
2989-
//
2990-
// Return Value:
2991-
// A local node representing the created Nullable<T> object
2992-
//
2993-
GenTree* Compiler::impStoreNullableFields(CORINFO_CLASS_HANDLE nullableCls, GenTree* value)
2994-
{
2995-
assert(info.compCompHnd->isNullableType(nullableCls) == TypeCompareState::Must);
2996-
2997-
CORINFO_FIELD_HANDLE valueFldHnd = info.compCompHnd->getFieldInClass(nullableCls, 1);
2998-
CORINFO_CLASS_HANDLE valueStructCls;
2999-
var_types valueType = JITtype2varType(info.compCompHnd->getFieldType(valueFldHnd, &valueStructCls));
3000-
3001-
// We still make some assumptions about the layout of Nullable<T> in JIT
3002-
static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0);
3003-
unsigned hasValOffset = OFFSETOF__CORINFO_NullableOfT__hasValue;
3004-
unsigned valueOffset = info.compCompHnd->getFieldOffset(valueFldHnd);
3005-
3006-
// Define the resulting Nullable<T> local
3007-
unsigned resultTmp = lvaGrabTemp(true DEBUGARG("Nullable<T> tmp"));
3008-
lvaSetStruct(resultTmp, nullableCls, false);
3009-
3010-
// Now do two stores:
3011-
GenTree* hasValueStore = gtNewStoreLclFldNode(resultTmp, TYP_UBYTE, hasValOffset, gtNewIconNode(1));
3012-
ClassLayout* layout = valueType == TYP_STRUCT ? typGetObjLayout(valueStructCls) : nullptr;
3013-
GenTree* valueStore = gtNewStoreLclFldNode(resultTmp, valueType, layout, valueOffset, value);
3014-
3015-
impAppendTree(hasValueStore, CHECK_SPILL_ALL, impCurStmtDI);
3016-
impAppendTree(valueStore, CHECK_SPILL_ALL, impCurStmtDI);
3017-
return gtNewLclvNode(resultTmp, TYP_STRUCT);
3018-
}
3019-
3020-
//------------------------------------------------------------------------
3021-
// impLoadNullableFields: get 'hasValue' and 'value' field loads for Nullable<T> object
3022-
//
3023-
// Arguments:
3024-
// nullableObj - tree representing the Nullable<T> object
3025-
// nullableCls - class handle for the Nullable<T> class
3026-
// hasValueFld - pointer to store the 'hasValue' field load tree
3027-
// valueFld - pointer to store the 'value' field load tree
3028-
//
3029-
void Compiler::impLoadNullableFields(GenTree* nullableObj,
3030-
CORINFO_CLASS_HANDLE nullableCls,
3031-
GenTree** hasValueFld,
3032-
GenTree** valueFld)
3033-
{
3034-
assert(info.compCompHnd->isNullableType(nullableCls) == TypeCompareState::Must);
3035-
3036-
CORINFO_FIELD_HANDLE valueFldHnd = info.compCompHnd->getFieldInClass(nullableCls, 1);
3037-
CORINFO_CLASS_HANDLE valueStructCls;
3038-
var_types valueType = JITtype2varType(info.compCompHnd->getFieldType(valueFldHnd, &valueStructCls));
3039-
ClassLayout* valueLayout = valueType == TYP_STRUCT ? typGetObjLayout(valueStructCls) : nullptr;
3040-
3041-
static_assert_no_msg(OFFSETOF__CORINFO_NullableOfT__hasValue == 0);
3042-
unsigned hasValOffset = OFFSETOF__CORINFO_NullableOfT__hasValue;
3043-
unsigned valueOffset = info.compCompHnd->getFieldOffset(valueFldHnd);
3044-
3045-
unsigned objTmp;
3046-
if (!nullableObj->OperIs(GT_LCL_VAR))
3047-
{
3048-
objTmp = lvaGrabTemp(true DEBUGARG("Nullable<T> tmp"));
3049-
impStoreToTemp(objTmp, nullableObj, CHECK_SPILL_ALL);
3050-
}
3051-
else
3052-
{
3053-
objTmp = nullableObj->AsLclVarCommon()->GetLclNum();
3054-
}
3055-
3056-
*hasValueFld = gtNewLclFldNode(objTmp, TYP_UBYTE, hasValOffset);
3057-
*valueFld = gtNewLclFldNode(objTmp, valueType, valueOffset, valueLayout);
3058-
}
3059-
30602982
//------------------------------------------------------------------------
30612983
// impBoxPatternMatch: match and import common box idioms
30622984
//
@@ -3122,40 +3044,6 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,
31223044
{
31233045
optimize = true;
31243046
}
3125-
//
3126-
// Also, try to optimize (T)(object)nullableT
3127-
//
3128-
else if (!eeIsSharedInst(unboxResolvedToken.hClass) &&
3129-
(info.compCompHnd->isNullableType(pResolvedToken->hClass) == TypeCompareState::Must) &&
3130-
(info.compCompHnd->getTypeForBox(pResolvedToken->hClass) == unboxResolvedToken.hClass))
3131-
{
3132-
GenTree* hasValueFldTree;
3133-
GenTree* valueFldTree;
3134-
impLoadNullableFields(impPopStack().val, pResolvedToken->hClass, &hasValueFldTree,
3135-
&valueFldTree);
3136-
3137-
// Push "hasValue == 0 ? throw new NullReferenceException() : NOP" qmark
3138-
GenTree* fallback = gtNewHelperCallNode(CORINFO_HELP_THROWNULLREF, TYP_VOID);
3139-
GenTree* cond = gtNewOperNode(GT_EQ, TYP_INT, hasValueFldTree, gtNewIconNode(0));
3140-
GenTreeColon* colon = gtNewColonNode(TYP_VOID, fallback, gtNewNothingNode());
3141-
GenTree* qmark = gtNewQmarkNode(TYP_VOID, cond, colon);
3142-
impAppendTree(qmark, CHECK_SPILL_ALL, impCurStmtDI);
3143-
3144-
// Now push the value field
3145-
impPushOnStack(valueFldTree, typeInfo(valueFldTree->TypeGet()));
3146-
optimize = true;
3147-
}
3148-
//
3149-
// Vice versa, try to optimize (T?)(object)nonNullableT
3150-
//
3151-
else if (!eeIsSharedInst(pResolvedToken->hClass) &&
3152-
(info.compCompHnd->isNullableType(unboxResolvedToken.hClass) == TypeCompareState::Must) &&
3153-
(info.compCompHnd->getTypeForBox(unboxResolvedToken.hClass) == pResolvedToken->hClass))
3154-
{
3155-
GenTree* result = impStoreNullableFields(unboxResolvedToken.hClass, impPopStack().val);
3156-
impPushOnStack(result, typeInfo(result->TypeGet()));
3157-
optimize = true;
3158-
}
31593047
}
31603048

31613049
if (optimize)
@@ -5814,7 +5702,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(GenTree* op1,
58145702
// We can convert constant-ish tokens of nullable to its underlying type.
58155703
// However, when the type is shared generic parameter like Nullable<Struct<__Canon>>, the actual type will require
58165704
// runtime lookup. It's too complex to add another level of indirection in op2, fallback to the cast helper instead.
5817-
if (isClassExact && !eeIsSharedInst(pResolvedToken->hClass))
5705+
if (isClassExact && !(info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST))
58185706
{
58195707
CORINFO_CLASS_HANDLE hClass = info.compCompHnd->getTypeForBox(pResolvedToken->hClass);
58205708
if (hClass != pResolvedToken->hClass)
@@ -5860,7 +5748,7 @@ GenTree* Compiler::impCastClassOrIsInstToTree(GenTree* op1,
58605748
!compCurBB->isRunRarely())
58615749
{
58625750
// It doesn't make sense to instrument "x is T" or "(T)x" for shared T
5863-
if (!eeIsSharedInst(pResolvedToken->hClass))
5751+
if ((info.compCompHnd->getClassAttribs(pResolvedToken->hClass) & CORINFO_FLG_SHAREDINST) == 0)
58645752
{
58655753
HandleHistogramProfileCandidateInfo* pInfo =
58665754
new (this, CMK_Inlining) HandleHistogramProfileCandidateInfo;
@@ -9736,7 +9624,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
97369624
CORINFO_FIELD_INFO fi;
97379625
eeGetFieldInfo(&fldToken, CORINFO_ACCESS_SET, &fi);
97389626
unsigned flagsToCheck = CORINFO_FLG_FIELD_STATIC | CORINFO_FLG_FIELD_FINAL;
9739-
if (((fi.fieldFlags & flagsToCheck) == flagsToCheck) && !eeIsSharedInst(info.compClassHnd))
9627+
if (((fi.fieldFlags & flagsToCheck) == flagsToCheck) &&
9628+
((info.compCompHnd->getClassAttribs(info.compClassHnd) & CORINFO_FLG_SHAREDINST) == 0))
97409629
{
97419630
#ifdef FEATURE_READYTORUN
97429631
if (opts.IsReadyToRun())

src/coreclr/jit/valuenum.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12255,7 +12255,7 @@ void Compiler::fgValueNumberTree(GenTree* tree)
1225512255
{
1225612256
JITDUMP("IND(obj) is actually a class handle for %s\n", eeGetClassName(handle));
1225712257
// Filter out all shared generic instantiations
12258-
if (!eeIsSharedInst(handle))
12258+
if ((info.compCompHnd->getClassAttribs(handle) & CORINFO_FLG_SHAREDINST) == 0)
1225912259
{
1226012260
void* pEmbedClsHnd;
1226112261
void* embedClsHnd = (void*)info.compCompHnd->embedClassHandle(handle, &pEmbedClsHnd);

0 commit comments

Comments
 (0)