Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Incorporate review feedback
Browse files Browse the repository at this point in the history
Removed legacy special-casing, verified legacy path works fine with
the intrinsics and opts fully enabled.
  • Loading branch information
AndyAyersMS committed Oct 3, 2017
1 parent 9b20ecd commit f4b39a2
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5010,7 +5010,7 @@ class Compiler
TPK_Other = 4 // RuntimeType via other means
};

TypeProducerKind gtCanOptimizeTypeEquality(GenTreePtr tree);
TypeProducerKind gtGetTypeProducerKind(GenTree* tree);
bool gtIsTypeHandleToRuntimeTypeHelper(GenTreeCall* call);
bool gtIsActiveCSE_Candidate(GenTreePtr tree);

Expand Down
21 changes: 8 additions & 13 deletions src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12189,7 +12189,7 @@ GenTree* Compiler::gtFoldTypeEqualityCall(CorInfoIntrinsics methodID, GenTree* o
// The method must be be a type equality intrinsic
assert(methodID == CORINFO_INTRINSIC_TypeEQ || methodID == CORINFO_INTRINSIC_TypeNEQ);

if ((gtCanOptimizeTypeEquality(op1) == TPK_Unknown) && (gtCanOptimizeTypeEquality(op2) == TPK_Unknown))
if ((gtGetTypeProducerKind(op1) == TPK_Unknown) && (gtGetTypeProducerKind(op2) == TPK_Unknown))
{
return nullptr;
}
Expand Down Expand Up @@ -12306,23 +12306,23 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree)

// Screen for the right kinds of operands
GenTree* const op1 = tree->gtOp.gtOp1;
const TypeProducerKind op1Kind = gtCanOptimizeTypeEquality(op1);
const TypeProducerKind op1Kind = gtGetTypeProducerKind(op1);
if (op1Kind == TPK_Unknown)
{
return tree;
}

GenTree* const op2 = tree->gtOp.gtOp2;
const TypeProducerKind op2Kind = gtCanOptimizeTypeEquality(op2);
const TypeProducerKind op2Kind = gtGetTypeProducerKind(op2);
if (op2Kind == TPK_Unknown)
{
return tree;
}

// We must have a handle on one side or the other here to optimize,
// otherwise we can't be sure that optimizing is sound.
const bool op1IsFromHandle = op1Kind == TPK_Handle;
const bool op2IsFromHandle = op2Kind == TPK_Handle;
const bool op1IsFromHandle = (op1Kind == TPK_Handle);
const bool op2IsFromHandle = (op2Kind == TPK_Handle);

if (!(op1IsFromHandle || op2IsFromHandle))
{
Expand Down Expand Up @@ -12432,13 +12432,8 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree)
// opHandleArgument is the method table we're looking for.
GenTree* const knownMT = opHandleArgument;

#ifdef LEGACY_BACKEND
// Fetch object method table from the object itself
GenTree* const objMT = gtNewOperNode(GT_IND, TYP_I_IMPL, opOther->gtCall.gtCallObjp);
#else
// Fetch object method table from the object itself
GenTree* const objMT = gtNewOperNode(GT_IND, TYP_I_IMPL, opOther->gtUnOp.gtOp1);
#endif

// Update various flags
objMT->gtFlags |= GTF_EXCEPT;
Expand Down Expand Up @@ -15416,8 +15411,8 @@ void Compiler::gtCheckQuirkAddrExposedLclVar(GenTreePtr tree, GenTreeStack* pare
}

//------------------------------------------------------------------------
// gtCanOptimizeTypeEquality: check if tree is a suitable input for type
// equality optimization
// gtGetTypeProducerKind: determine if a tree produces a runtime type, and
// if so, how.
//
// Arguments:
// tree - tree to examine
Expand All @@ -15443,7 +15438,7 @@ void Compiler::gtCheckQuirkAddrExposedLclVar(GenTreePtr tree, GenTreeStack* pare
//
// into a method call.

Compiler::TypeProducerKind Compiler::gtCanOptimizeTypeEquality(GenTree* tree)
Compiler::TypeProducerKind Compiler::gtGetTypeProducerKind(GenTree* tree)
{
if (tree->gtOper == GT_CALL)
{
Expand Down
5 changes: 1 addition & 4 deletions src/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3522,7 +3522,6 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
// Call the regular function.
break;

#ifndef LEGACY_BACKEND
case CORINFO_INTRINSIC_Object_GetType:
{
op1 = impPopStack().val;
Expand All @@ -3532,9 +3531,7 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
{
if (op1->IsBoxedValue())
{
#ifdef DEBUG
JITDUMP("Attempting to optimize box(...).getType() to direct type construction\n");
#endif

// Try and clean up the box. Obtain the handle we
// were going to pass to the newobj.
Expand Down Expand Up @@ -3576,7 +3573,7 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
}
break;
}
#endif

// Implement ByReference Ctor. This wraps the assignment of the ref into a byref-like field
// in a value type. The canonical example of this is Span<T>. In effect this is just a
// substitution. The parameter byref will be assigned into the newly allocated object.
Expand Down
16 changes: 8 additions & 8 deletions src/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11964,16 +11964,16 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
}
break;

case GT_EQ:
case GT_NE:
{
GenTree* optimizedTree = gtFoldTypeCompare(tree);
case GT_EQ:
case GT_NE:
{
GenTree* optimizedTree = gtFoldTypeCompare(tree);

if (optimizedTree != tree)
{
return fgMorphTree(optimizedTree);
}
if (optimizedTree != tree)
{
return fgMorphTree(optimizedTree);
}
}

__fallthrough;

Expand Down

0 comments on commit f4b39a2

Please sign in to comment.