未验证 提交 30529056 编写于 作者: E Egor Bogatov 提交者: GitHub

Propagate typeof() during inlining (#71778)

Co-authored-by: NAndy Ayers <andya@microsoft.com>
上级 26ec70b1
......@@ -1633,21 +1633,12 @@ Statement* Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
}
else
{
/* The argument is either not used or a const or lcl var */
// The argument is either not used or a const or lcl var
noway_assert(!argInfo.argIsUsed || argInfo.argIsInvariant || argInfo.argIsLclVar);
/* Make sure we didnt change argNode's along the way, or else
subsequent uses of the arg would have worked with the bashed value */
if (argInfo.argIsInvariant)
{
assert(argNode->OperIsConst() || argNode->gtOper == GT_ADDR);
}
noway_assert((argInfo.argIsLclVar == 0) ==
(argNode->gtOper != GT_LCL_VAR || (argNode->gtFlags & GTF_GLOB_REF)));
/* If the argument has side effects, append it */
// If the argument has side effects, append it
if (argInfo.argHasSideEff)
{
noway_assert(argInfo.argIsUsed == false);
......
......@@ -12825,6 +12825,7 @@ GenTree* Compiler::gtCreateHandleCompare(genTreeOps oper,
// Checks for
// typeof(...) == obj.GetType()
// typeof(...) == typeof(...)
// typeof(...) == null
// obj1.GetType() == obj2.GetType()
//
// And potentially optimizes away the need to obtain actual
......@@ -12842,17 +12843,19 @@ GenTree* Compiler::gtFoldTypeCompare(GenTree* tree)
// Screen for the right kinds of operands
GenTree* const op1 = tree->AsOp()->gtOp1;
const TypeProducerKind op1Kind = gtGetTypeProducerKind(op1);
if (op1Kind == TPK_Unknown)
{
return tree;
}
GenTree* const op2 = tree->AsOp()->gtOp2;
const TypeProducerKind op1Kind = gtGetTypeProducerKind(op1);
const TypeProducerKind op2Kind = gtGetTypeProducerKind(op2);
if (op2Kind == TPK_Unknown)
// Fold "typeof(handle) cmp null"
if (((op2Kind == TPK_Null) && (op1Kind == TPK_Handle)) || ((op1Kind == TPK_Null) && (op2Kind == TPK_Handle)))
{
return tree;
GenTree* call = op1Kind == TPK_Handle ? op1 : op2;
GenTree* handle = call->AsCall()->gtArgs.GetArgByIndex(0)->GetNode();
if (gtGetHelperArgClassHandle(handle) != NO_CLASS_HANDLE)
{
return oper == GT_EQ ? gtNewFalse() : gtNewTrue();
}
}
// If both types are created via handles, we can simply compare
......
......@@ -20256,6 +20256,16 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo,
return;
}
}
else
{
if (curArgVal->IsHelperCall() && gtIsTypeHandleToRuntimeTypeHelper(curArgVal->AsCall()) &&
(gtGetHelperArgClassHandle(curArgVal->AsCall()->gtArgs.GetArgByIndex(0)->GetEarlyNode()) !=
NO_CLASS_HANDLE))
{
inlCurArgInfo->argIsInvariant = true;
inlCurArgInfo->argHasSideEff = false;
}
}
bool isExact = false;
bool isNonNull = false;
......@@ -20292,7 +20302,7 @@ void Compiler::impInlineRecordArgInfo(InlineInfo* pInlineInfo,
}
if (inlCurArgInfo->argIsInvariant)
{
printf(" is a constant");
printf(" is a constant or invariant");
}
if (inlCurArgInfo->argHasGlobRef)
{
......@@ -20560,8 +20570,7 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
// Try to fold the node in case we have constant arguments.
if (inlArgInfo[i].argIsInvariant)
{
inlArgNode = gtFoldExprConst(inlArgNode);
assert(inlArgNode->OperIsConst());
inlArgNode = gtFoldExpr(inlArgNode);
}
*pInlArgNode = inlArgNode;
}
......@@ -20573,12 +20582,10 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
inlArgInfo[i].argIsLclVar = false;
/* Try to fold the node in case we have constant arguments */
// Try to fold the node in case we have constant arguments.
if (inlArgInfo[i].argIsInvariant)
{
inlArgNode = gtFoldExprConst(inlArgNode);
assert(inlArgNode->OperIsConst());
inlArgNode = gtFoldExpr(inlArgNode);
}
*pInlArgNode = inlArgNode;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册