Skip to content

Commit

Permalink
Allow contained indirections in tailcalls on x64 (#58686)
Browse files Browse the repository at this point in the history
This adds support for contained indirections in tailcalls on x64. The
significant diff of this change is refactoring to be able to reuse the
code for generating call instructions when generating tailcalls as well.
Other than that, the main change is to allow contained indirs in
lowering and to ensure LSRA uses volatile registers for the addressing
mode so that the registers are not overridden by the epilog sequence.

To be sure we insert rex. prefix correctly I also refactored the emitter
to base the decision on a new instruction (INS_i_jmp) and emit it when
necessary. The rex. prefix is necessary because the unwinder uses it to
determine that a tail jmp is non-local and thus part of the epilog.

Finally, unlike the OS unwinder our unwinder needs to compute the size
of the epilog. This computation was wrong for jmp [foo] for addressing
modes/rip-relative addressing, so fix this as well. Presumably that has
not been a problem before since we did not generate these instructions
in managed code (although native code may have had these instructions --
not sure if we use that unwinder for native code).
  • Loading branch information
jakobbotsch committed Sep 21, 2021
1 parent de6efa9 commit 59d7ede
Show file tree
Hide file tree
Showing 15 changed files with 617 additions and 601 deletions.
25 changes: 14 additions & 11 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,19 +453,20 @@ class CodeGen final : public CodeGenInterface
emitAttr retSize
MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
IL_OFFSETX ilOffset,
regNumber base = REG_NA,
bool isJump = false);
regNumber base,
bool isJump);
// clang-format on

// clang-format off
void genEmitCall(int callType,
CORINFO_METHOD_HANDLE methHnd,
INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
GenTreeIndir* indir
X86_ARG(int argSize),
emitAttr retSize
MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
IL_OFFSETX ilOffset);
void genEmitCallIndir(int callType,
CORINFO_METHOD_HANDLE methHnd,
INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
GenTreeIndir* indir
X86_ARG(int argSize),
emitAttr retSize
MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
IL_OFFSETX ilOffset,
bool isJump);
// clang-format on

//
Expand Down Expand Up @@ -1260,7 +1261,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void genCodeForArrOffset(GenTreeArrOffs* treeNode);
instruction genGetInsForOper(genTreeOps oper, var_types type);
bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data);
void genCallInstruction(GenTreeCall* call);
GenTree* getCallTarget(const GenTreeCall* call, CORINFO_METHOD_HANDLE* methHnd);
void genCall(GenTreeCall* call);
void genCallInstruction(GenTreeCall* call X86_ARG(target_ssize_t stackArgBytes));
void genJmpMethod(GenTree* jmp);
BasicBlock* genCallFinally(BasicBlock* block);
void genCodeForJumpTrue(GenTreeOp* jtrue);
Expand Down
Loading

0 comments on commit 59d7ede

Please sign in to comment.