diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index 17ece972ac11a5..6718fcaad3dc64 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -3416,7 +3416,7 @@ void Compiler::fgFindBasicBlocks() /* Now create the basic blocks */ - unsigned retBlocks = fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget); + fgReturnCount = fgMakeBasicBlocks(info.compCode, info.compILCodeSize, jumpTarget); if (compIsForInlining()) { @@ -3425,7 +3425,7 @@ void Compiler::fgFindBasicBlocks() // If fgFindJumpTargets marked the call as "no return" there // really should be no BBJ_RETURN blocks in the method. bool markedNoReturn = (impInlineInfo->iciCall->gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0; - assert((markedNoReturn && (retBlocks == 0)) || (!markedNoReturn && (retBlocks >= 1))); + assert((markedNoReturn && (fgReturnCount == 0)) || (!markedNoReturn && (fgReturnCount >= 1))); #endif // DEBUG if (compInlineResult->IsFailure()) @@ -3442,7 +3442,7 @@ void Compiler::fgFindBasicBlocks() // Use a spill temp for the return value if there are multiple return blocks, // or if the inlinee has GC ref locals. - if ((info.compRetNativeType != TYP_VOID) && ((retBlocks > 1) || impInlineInfo->HasGcRefLocals())) + if ((info.compRetNativeType != TYP_VOID) && ((fgReturnCount > 1) || impInlineInfo->HasGcRefLocals())) { // If we've spilled the ret expr to a temp we can reuse the temp // as the inlinee return spill temp. @@ -3461,7 +3461,7 @@ void Compiler::fgFindBasicBlocks() // We may have co-opted an existing temp for the return spill. // We likely assumed it was single-def at the time, but now // we can see it has multiple definitions. - if ((retBlocks > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1)) + if ((fgReturnCount > 1) && (lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef == 1)) { // Make sure it is no longer marked single def. This is only safe // to do if we haven't ever updated the type. @@ -3483,7 +3483,7 @@ void Compiler::fgFindBasicBlocks() if (info.compRetType == TYP_REF) { // The return spill temp is single def only if the method has a single return block. - if (retBlocks == 1) + if (fgReturnCount == 1) { lvaTable[lvaInlineeReturnSpillTemp].lvSingleDef = 1; JITDUMP("Marked return spill temp V%02u as a single def temp\n", lvaInlineeReturnSpillTemp); diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp index f411bb31dfdb63..405de24f6c4e9b 100644 --- a/src/coreclr/jit/fgprofile.cpp +++ b/src/coreclr/jit/fgprofile.cpp @@ -859,8 +859,23 @@ void Compiler::WalkSpanningTree(SpanningTreeVisitor* visitor) } break; - case BBJ_RETURN: case BBJ_THROW: + + // Ignore impact of throw blocks on flow, if we're doing minimal + // method profiling, and it appears the method can return without throwing. + // + // fgReturnCount is provisionally set in fgFindBasicBlocks based on + // the raw IL stream prescan. + // + if (JitConfig.JitMinimalJitProfiling() && (fgReturnCount > 0)) + { + break; + } + + __fallthrough; + + case BBJ_RETURN: + { // Pseudo-edge back to method entry. //