Skip to content

Commit

Permalink
Make FailFast blocks cold (GS cookies) (#93429)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo authored Oct 16, 2023
1 parent bf10b61 commit c836f5a
Show file tree
Hide file tree
Showing 10 changed files with 29 additions and 33 deletions.
7 changes: 2 additions & 5 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,11 +631,8 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
// Compare with the GC cookie constant
GetEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue);

BasicBlock* gsCheckBlk = genCreateTempLabel();
inst_JMP(EJ_eq, gsCheckBlk);
// regGSConst and regGSValue aren't needed anymore, we can use them for helper call
genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst);
genDefineTempLabel(gsCheckBlk);
Compiler::AddCodeDsc* codeDsc = compiler->fgFindExcptnTarget(SpecialCodeKind::SCK_FAIL_FAST, 0);
inst_JMP(EJ_ne, codeDsc->acdDstBlk);
}

//---------------------------------------------------------------------
Expand Down
8 changes: 2 additions & 6 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5192,12 +5192,8 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
GetEmitter()->emitIns_R_S(INS_ld_d, EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);

// Compare with the GC cookie constant
BasicBlock* gsCheckBlk = genCreateTempLabel();
GetEmitter()->emitIns_J_cond_la(INS_beq, gsCheckBlk, regGSConst, regGSValue);

// regGSConst and regGSValue aren't needed anymore, we can use them for helper call
genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst);
genDefineTempLabel(gsCheckBlk);
Compiler::AddCodeDsc* codeDsc = compiler->fgFindExcptnTarget(SpecialCodeKind::SCK_FAIL_FAST, 0);
GetEmitter()->emitIns_J_cond_la(INS_bne, codeDsc->acdDstBlk, regGSConst, regGSValue);
}

//---------------------------------------------------------------------
Expand Down
8 changes: 2 additions & 6 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4958,12 +4958,8 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
GetEmitter()->emitIns_R_S(INS_ld, EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);

// Compare with the GC cookie constant
BasicBlock* gsCheckBlk = genCreateTempLabel();
GetEmitter()->emitIns_J_cond_la(INS_beq, gsCheckBlk, regGSConst, regGSValue);

// regGSConst and regGSValue aren't needed anymore, we can use them for helper call
genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst);
genDefineTempLabel(gsCheckBlk);
Compiler::AddCodeDsc* codeDsc = compiler->fgFindExcptnTarget(SpecialCodeKind::SCK_FAIL_FAST, 0);
GetEmitter()->emitIns_J_cond_la(INS_bne, codeDsc->acdDstBlk, regGSConst, regGSValue);
}

//---------------------------------------------------------------------
Expand Down
7 changes: 2 additions & 5 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,8 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
GetEmitter()->emitIns_S_R(INS_cmp, EA_PTRSIZE, regGSCheck, compiler->lvaGSSecurityCookie, 0);
}

BasicBlock* gsCheckBlk = genCreateTempLabel();
inst_JMP(EJ_je, gsCheckBlk);
genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN);
genDefineTempLabel(gsCheckBlk);

Compiler::AddCodeDsc* codeDsc = compiler->fgFindExcptnTarget(SpecialCodeKind::SCK_FAIL_FAST, 0);
inst_JMP(EJ_jne, codeDsc->acdDstBlk);
genPopRegs(pushedRegs, byrefPushedRegs, norefPushedRegs);
}

Expand Down
1 change: 0 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6117,7 +6117,6 @@ class Compiler

AddCodeDsc* fgAddCodeList;
bool fgAddCodeModf;
bool fgRngChkThrowAdded;
AddCodeDsc* fgExcptnTargetCache[SCK_COUNT];

BasicBlock* fgRngChkTarget(BasicBlock* block, SpecialCodeKind kind);
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3095,6 +3095,7 @@ inline bool Compiler::fgIsThrowHlpBlk(BasicBlock* block)

if (!((call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_RNGCHKFAIL)) ||
(call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWDIVZERO)) ||
(call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_FAIL_FAST)) ||
(call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROW_ARGUMENTEXCEPTION)) ||
(call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION)) ||
(call->AsCall()->gtCallMethHnd == eeFindHelper(CORINFO_HELP_OVERFLOW))))
Expand All @@ -3111,7 +3112,7 @@ inline bool Compiler::fgIsThrowHlpBlk(BasicBlock* block)
if (block == add->acdDstBlk)
{
return add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN;
add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN || add->acdKind == SCK_FAIL_FAST;
}
}

Expand All @@ -3136,7 +3137,7 @@ inline unsigned Compiler::fgThrowHlpBlkStkLevel(BasicBlock* block)
// Compute assert cond separately as assert macro cannot have conditional compilation directives.
bool cond =
(add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN);
add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN || add->acdKind == SCK_FAIL_FAST);
assert(cond);

// TODO: bbTgtStkDepth is DEBUG-only.
Expand Down
3 changes: 0 additions & 3 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,6 @@ void Compiler::fgInit()
/* This global flag is set whenever we remove a statement */
fgStmtRemoved = false;

/* This global flag is set whenever we add a throw block for a RngChk */
fgRngChkThrowAdded = false; /* reset flag for fgIsCodeAdded() */

/* Keep track of whether or not EH statements have been optimized */
fgOptimizedFinally = false;

Expand Down
20 changes: 15 additions & 5 deletions src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3584,6 +3584,8 @@ unsigned Compiler::acdHelper(SpecialCodeKind codeKind)
return CORINFO_HELP_THROWDIVZERO;
case SCK_ARITH_EXCPN:
return CORINFO_HELP_OVERFLOW;
case SCK_FAIL_FAST:
return CORINFO_HELP_FAIL_FAST;
default:
assert(!"Bad codeKind");
return 0;
Expand All @@ -3608,8 +3610,10 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
// arg slots on the stack frame if there are no other calls.
compUsesThrowHelper = true;

if (!fgUseThrowHelperBlocks())
if (!fgUseThrowHelperBlocks() && (kind != SCK_FAIL_FAST))
{
// We'll create a throw block in-place then (for better debugging)
// It's not needed for fail fast, since it's not recoverable anyway.
return nullptr;
}

Expand All @@ -3620,6 +3624,7 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
BBJ_THROW, // SCK_ARITH_EXCP, SCK_OVERFLOW
BBJ_THROW, // SCK_ARG_EXCPN
BBJ_THROW, // SCK_ARG_RNG_EXCPN
BBJ_THROW, // SCK_FAIL_FAST
};

noway_assert(sizeof(jumpKinds) == SCK_COUNT); // sanity check
Expand Down Expand Up @@ -3695,6 +3700,9 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
case SCK_ARG_RNG_EXCPN:
msg = " for ARG_RNG_EXCPN";
break;
case SCK_FAIL_FAST:
msg = " for FAIL_FAST";
break;
default:
msg = " for ??";
break;
Expand All @@ -3712,8 +3720,7 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special

/* Remember that we're adding a new basic block */

fgAddCodeModf = true;
fgRngChkThrowAdded = true;
fgAddCodeModf = true;

/* Now figure out what code to insert */

Expand Down Expand Up @@ -3743,6 +3750,10 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
helper = CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION;
break;

case SCK_FAIL_FAST:
helper = CORINFO_HELP_FAIL_FAST;
break;

default:
noway_assert(!"unexpected code addition kind");
return nullptr;
Expand All @@ -3759,7 +3770,6 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
tree = fgMorphArgs(tree);

// Store the tree in the new basic block.
assert(!srcBlk->isEmpty());
if (!srcBlk->IsLIR())
{
fgInsertStmtAtEnd(newBlk, fgNewStmtFromTree(tree));
Expand All @@ -3781,7 +3791,7 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special

Compiler::AddCodeDsc* Compiler::fgFindExcptnTarget(SpecialCodeKind kind, unsigned refData)
{
assert(fgUseThrowHelperBlocks());
assert(fgUseThrowHelperBlocks() || (kind == SCK_FAIL_FAST));
if (!(fgExcptnTargetCache[kind] && // Try the cached value first
fgExcptnTargetCache[kind]->acdData == refData))
{
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum SpecialCodeKind
SCK_OVERFLOW = SCK_ARITH_EXCPN, // target on overflow
SCK_ARG_EXCPN, // target on ArgumentException (currently used only for SIMD intrinsics)
SCK_ARG_RNG_EXCPN, // target on ArgumentOutOfRangeException (currently used only for SIMD intrinsics)
SCK_FAIL_FAST, // target for fail fast exception
SCK_COUNT
};

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/jit/gschecks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ PhaseStatus Compiler::gsPhase()
unsigned const prevBBCount = fgBBcount;
gsGSChecksInitCookie();

fgAddCodeRef(fgLastBB, 0, SCK_FAIL_FAST);

if (compGSReorderStackLayout)
{
gsCopyShadowParams();
Expand Down

0 comments on commit c836f5a

Please sign in to comment.