Skip to content

Commit

Permalink
Generalize the "BOX(nullable) cmp null" opt (#69961)
Browse files Browse the repository at this point in the history
We can obtain the "Nullable<T>" class handle from the helper's arg.
  • Loading branch information
SingleAccretion authored Jun 6, 2022
1 parent e64eb55 commit c61db46
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,7 @@ struct CORINFO_VarArgInfo
#define OFFSETOF__CORINFO_String__stringLen SIZEOF__CORINFO_Object
#define OFFSETOF__CORINFO_String__chars (OFFSETOF__CORINFO_String__stringLen + sizeof(uint32_t) /* stringLen */)

#define OFFSETOF__CORINFO_NullableOfT__hasValue 0

/* data to optimize delegate construction */
struct DelegateCtorArgs
Expand Down
36 changes: 15 additions & 21 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13516,32 +13516,26 @@ GenTree* Compiler::gtFoldBoxNullable(GenTree* tree)
return tree;
}

JITDUMP("\nAttempting to optimize BOX_NULLABLE(&x) %s null [%06u]\n", GenTree::OpName(oper), dspTreeID(tree));
JITDUMP("\nReplacing BOX_NULLABLE(&x) %s null [%06u] with x.hasValue\n", GenTree::OpName(oper), dspTreeID(tree));

// Get the address of the struct being boxed
GenTree* const arg = call->gtArgs.GetArgByIndex(1)->GetNode();
GenTree* nullableHndNode = call->gtArgs.GetArgByIndex(0)->GetNode();
CORINFO_CLASS_HANDLE nullableClassHnd = gtGetHelperArgClassHandle(nullableHndNode);
CORINFO_FIELD_HANDLE hasValueFieldHnd = info.compCompHnd->getFieldInClass(nullableClassHnd, 0);

if (arg->OperIs(GT_ADDR))
{
CORINFO_CLASS_HANDLE nullableHnd = gtGetStructHandle(arg->AsOp()->gtOp1);
CORINFO_FIELD_HANDLE fieldHnd = info.compCompHnd->getFieldInClass(nullableHnd, 0);

// Replace the box with an access of the nullable 'hasValue' field.
JITDUMP("\nSuccess: replacing BOX_NULLABLE(&x) [%06u] with x.hasValue\n", dspTreeID(op));
GenTree* newOp = gtNewFieldRef(TYP_BOOL, fieldHnd, arg, 0);
GenTree* srcAddr = call->gtArgs.GetArgByIndex(1)->GetNode();
GenTree* fieldNode = gtNewFieldRef(TYP_BOOL, hasValueFieldHnd, srcAddr, OFFSETOF__CORINFO_NullableOfT__hasValue);

if (op == op1)
{
tree->AsOp()->gtOp1 = newOp;
}
else
{
tree->AsOp()->gtOp2 = newOp;
}

cons->gtType = TYP_INT;
if (op == op1)
{
tree->AsOp()->gtOp1 = fieldNode;
}
else
{
tree->AsOp()->gtOp2 = fieldNode;
}

cons->gtType = TYP_INT;

return tree;
}

Expand Down

0 comments on commit c61db46

Please sign in to comment.