Skip to content

Commit

Permalink
Optimize call indirect for R2R, Arm and Arm64 scenarios (#35675)
Browse files Browse the repository at this point in the history
* Use a different approach to optimize the indirect calls for R2R

During lowering, don't create a controlExpr for indirect call. Instead use
temp register for such calls and during codegen, load the indirect from x11
into that temp register before calling the address in that temp register.
  • Loading branch information
kunalspathak authored May 20, 2020
1 parent e9c272c commit 3fda6ef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
21 changes: 21 additions & 0 deletions src/coreclr/src/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2523,6 +2523,27 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, target->GetRegNum());
}
#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH)
else if (call->IsR2RRelativeIndir())
{
// Generate a direct call to a non-virtual user defined or helper method
assert(callType == CT_HELPER || callType == CT_USER_FUNC);
assert(call->gtEntryPoint.accessType == IAT_PVALUE);
assert(call->gtControlExpr == nullptr);

regNumber tmpReg = call->GetSingleTempReg();
GetEmitter()->emitIns_R_R(ins_Load(TYP_I_IMPL), emitActualTypeSize(TYP_I_IMPL), tmpReg, REG_R2R_INDIRECT_PARAM);

// We have now generated code for gtControlExpr evaluating it into `tmpReg`.
// We just need to emit "call tmpReg" in this case.
//
assert(genIsValidIntReg(tmpReg));

genEmitCall(emitter::EC_INDIR_R, methHnd,
INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, tmpReg);
}
#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH
else
{
// Generate a direct call to a non-virtual user defined or helper method
Expand Down
18 changes: 13 additions & 5 deletions src/coreclr/src/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3287,11 +3287,19 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)

case IAT_PVALUE:
{
// Non-virtual direct calls to addresses accessed by
// a single indirection.
GenTree* cellAddr = AddrGen(addr);
GenTree* indir = Ind(cellAddr);
result = indir;
bool isR2RRelativeIndir = false;
#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH)
isR2RRelativeIndir = call->IsR2RRelativeIndir();
#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH

if (!isR2RRelativeIndir)
{
// Non-virtual direct calls to addresses accessed by
// a single indirection.
GenTree* cellAddr = AddrGen(addr);
GenTree* indir = Ind(cellAddr);
result = indir;
}
break;
}

Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/src/jit/lsraarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ int LinearScan::BuildCall(GenTreeCall* call)
ctrlExprCandidates = RBM_FASTTAILCALL_TARGET;
}
}
#if defined(FEATURE_READYTORUN_COMPILER) && defined(TARGET_ARMARCH)
else if (call->IsR2RRelativeIndir())
{
buildInternalIntRegisterDefForNode(call);
}
#endif // FEATURE_READYTORUN_COMPILER && TARGET_ARMARCH
#ifdef TARGET_ARM
else
{
Expand Down

0 comments on commit 3fda6ef

Please sign in to comment.