Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: Late expansion for casts #97075

Merged
merged 17 commits into from
Jan 19, 2024
24 changes: 13 additions & 11 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4764,17 +4764,14 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal
{
return optAssertionProp_Update(call, call, stmt);
}
else if (!optLocalAssertionProp && (call->gtCallType == CT_HELPER))
{
if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFINTERFACE) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFARRAY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTINTERFACE) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTARRAY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTANY) ||
call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS_SPECIAL))
else if (!optLocalAssertionProp && call->IsHelperCall())
{
const CorInfoHelpFunc helper = eeGetHelperNum(call->gtCallMethHnd);
if ((helper == CORINFO_HELP_ISINSTANCEOFINTERFACE) || (helper == CORINFO_HELP_ISINSTANCEOFARRAY) ||
(helper == CORINFO_HELP_ISINSTANCEOFCLASS) || (helper == CORINFO_HELP_ISINSTANCEOFANY) ||
(helper == CORINFO_HELP_CHKCASTINTERFACE) || (helper == CORINFO_HELP_CHKCASTARRAY) ||
(helper == CORINFO_HELP_CHKCASTCLASS) || (helper == CORINFO_HELP_CHKCASTANY) ||
(helper == CORINFO_HELP_CHKCASTCLASS_SPECIAL))
{
GenTree* arg1 = call->gtArgs.GetArgByIndex(1)->GetNode();
if (arg1->gtOper != GT_LCL_VAR)
Expand Down Expand Up @@ -4804,6 +4801,11 @@ GenTree* Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCal

return optAssertionProp_Update(arg1, call, stmt);
}

// TODO-InlineCast: check optAssertionIsNonNull for the object argument and replace
// the helper with its nonnull version, e.g.:
// CORINFO_HELP_ISINSTANCEOFANY -> CORINFO_HELP_ISINSTANCEOFANY_NONNULL
// so then fgLateCastExpansion can skip the null check.
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5046,6 +5046,9 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Expand thread local access
DoPhase(this, PHASE_EXPAND_TLS, &Compiler::fgExpandThreadLocalAccess);

// Expand casts
DoPhase(this, PHASE_EXPAND_CASTS, &Compiler::fgLateCastExpansion);
EgorBo marked this conversation as resolved.
Show resolved Hide resolved

// Insert GC Polls
DoPhase(this, PHASE_INSERT_GC_POLLS, &Compiler::fgInsertGCPolls);

Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5832,6 +5832,9 @@ class Compiler
bool fgVNBasedIntrinsicExpansionForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
bool fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);

PhaseStatus fgLateCastExpansion();
bool fgLateCastExpansionForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);

PhaseStatus fgInsertGCPolls();
BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block);

Expand Down Expand Up @@ -7519,6 +7522,7 @@ class Compiler
#define OMF_HAS_TLS_FIELD 0x00010000 // Method contains TLS field access
#define OMF_HAS_SPECIAL_INTRINSICS 0x00020000 // Method contains special intrinsics expanded in late phases
#define OMF_HAS_RECURSIVE_TAILCALL 0x00040000 // Method contains recursive tail call
#define OMF_HAS_EXPANDABLE_CAST 0x00080000 // Method contains casts eligible for late expansion

// clang-format on

Expand Down Expand Up @@ -7559,6 +7563,16 @@ class Compiler
optMethodFlags |= OMF_HAS_STATIC_INIT;
}

bool doesMethodHaveExpandableCasts()
{
return (optMethodFlags & OMF_HAS_EXPANDABLE_CAST) != 0;
}

void setMethodHasExpandableCasts()
{
optMethodFlags |= OMF_HAS_EXPANDABLE_CAST;
}

bool doesMethodHaveGuardedDevirtualization() const
{
return (optMethodFlags & OMF_HAS_GUARDEDDEVIRT) != 0;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS2, "Compute edge weights (2, f
CompPhaseNameMacro(PHASE_STRESS_SPLIT_TREE, "Stress gtSplitTree", false, -1, false)
CompPhaseNameMacro(PHASE_EXPAND_RTLOOKUPS, "Expand runtime lookups", false, -1, true)
CompPhaseNameMacro(PHASE_EXPAND_STATIC_INIT, "Expand static init", false, -1, true)
CompPhaseNameMacro(PHASE_EXPAND_CASTS, "Expand casts", false, -1, true)
CompPhaseNameMacro(PHASE_EXPAND_TLS, "Expand TLS access", false, -1, true)
CompPhaseNameMacro(PHASE_INSERT_GC_POLLS, "Insert GC Polls", false, -1, true)
CompPhaseNameMacro(PHASE_CREATE_THROW_HELPERS, "Create throw helper blocks", false, -1, true)
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4080,6 +4080,7 @@ enum GenTreeCallFlags : unsigned int
GTF_CALL_M_EXPANDED_EARLY = 0x00800000, // the Virtual Call target address is expanded and placed in gtControlExpr in Morph rather than in Lower
GTF_CALL_M_HAS_LATE_DEVIRT_INFO = 0x01000000, // this call has late devirtualzation info
GTF_CALL_M_LDVIRTFTN_INTERFACE = 0x02000000, // ldvirtftn on an interface type
GTF_CALL_M_CAST_CAN_BE_EXPANDED = 0x04000000, // this cast (helper call) can be expanded if it's profitable. To be removed.
};

inline constexpr GenTreeCallFlags operator ~(GenTreeCallFlags a)
Expand Down Expand Up @@ -5588,8 +5589,9 @@ struct GenTreeCall final : public GenTree

CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
union {
void* gtStubCallStubAddr; // GTF_CALL_VIRT_STUB - these are never inlined
CORINFO_CLASS_HANDLE gtInitClsHnd; // Used by static init helpers, represents a class they init
void* gtStubCallStubAddr; // GTF_CALL_VIRT_STUB - these are never inlined
CORINFO_CLASS_HANDLE gtInitClsHnd; // Used by static init helpers, represents a class they init
IL_OFFSET gtCastHelperILOffset; // Used by cast helpers to save corresponding IL offset
};

union {
Expand Down
Loading
Loading