Skip to content

Commit

Permalink
JIT: enable removal of try/catch if the try can't throw. (#110273)
Browse files Browse the repository at this point in the history
If no tree in the try region of a try/catch can throw, then
we can remove the try and delete the catch.

If no tree in the try region of a try/finally can throw, we can
remove the try and inline the finally. This slightly generalizes
the empty-try/finally opt we have been doing for a long time.
(We should do something similar for try/fault, but don't, yet).

Since these optimization passes are cheap, and opportunities
for them arise after other optimizations and unblock subsequent
optimizations, run them early, middle, and late.

Resolves #107191.

I expect we'll see more of these cases in the future, say if
we unblock cloning of loops with EH.
  • Loading branch information
AndyAyersMS authored Dec 2, 2024
1 parent 5b9b8d3 commit 7ccf491
Show file tree
Hide file tree
Showing 7 changed files with 501 additions and 94 deletions.
29 changes: 27 additions & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4637,10 +4637,14 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
DoPhase(this, PHASE_SWIFT_ERROR_RET, &Compiler::fgAddSwiftErrorReturns);
#endif // SWIFT_SUPPORT

// Remove empty try regions
// Remove empty try regions (try/finally)
//
DoPhase(this, PHASE_EMPTY_TRY, &Compiler::fgRemoveEmptyTry);

// Remove empty try regions (try/catch)
//
DoPhase(this, PHASE_EMPTY_TRY_CATCH, &Compiler::fgRemoveEmptyTryCatch);

// Remove empty finally regions
//
DoPhase(this, PHASE_EMPTY_FINALLY, &Compiler::fgRemoveEmptyFinally);
Expand Down Expand Up @@ -4810,6 +4814,18 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_UNROLL_LOOPS, &Compiler::optUnrollLoops);

// Try again to remove empty try finally/fault clauses
//
DoPhase(this, PHASE_EMPTY_FINALLY_2, &Compiler::fgRemoveEmptyFinally);

// Remove empty try regions (try/finally)
//
DoPhase(this, PHASE_EMPTY_TRY_2, &Compiler::fgRemoveEmptyTry);

// Remove empty try regions (try/catch)
//
DoPhase(this, PHASE_EMPTY_TRY_CATCH_2, &Compiler::fgRemoveEmptyTryCatch);

// Compute dominators and exceptional entry blocks
//
DoPhase(this, PHASE_COMPUTE_DOMINATORS, &Compiler::fgComputeDominators);
Expand Down Expand Up @@ -5039,7 +5055,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
#endif

// Try again to remove empty try finally/fault clauses
DoPhase(this, PHASE_EMPTY_FINALLY_2, &Compiler::fgRemoveEmptyFinally);
//
DoPhase(this, PHASE_EMPTY_FINALLY_3, &Compiler::fgRemoveEmptyFinally);

// Remove empty try regions (try/finally)
//
DoPhase(this, PHASE_EMPTY_TRY_3, &Compiler::fgRemoveEmptyTry);

// Remove empty try regions (try/catch)
//
DoPhase(this, PHASE_EMPTY_TRY_CATCH_3, &Compiler::fgRemoveEmptyTryCatch);

if (UsesFunclets())
{
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5270,7 +5270,6 @@ class Compiler

bool fgModified = false; // True if the flow graph has been modified recently
bool fgPredsComputed = false; // Have we computed the bbPreds list
bool fgOptimizedFinally = false; // Did we optimize any try-finallys?

bool fgHasSwitch = false; // any BBJ_SWITCH jumps?

Expand Down Expand Up @@ -5352,12 +5351,16 @@ class Compiler

PhaseStatus fgRemoveEmptyTry();

PhaseStatus fgRemoveEmptyTryCatch();

PhaseStatus fgRemoveEmptyFinally();

PhaseStatus fgMergeFinallyChains();

PhaseStatus fgCloneFinally();

void fgUpdateACDsBeforeEHTableEntryRemoval(unsigned XTnum);

void fgCleanupContinuation(BasicBlock* continuation);

PhaseStatus fgTailMergeThrows();
Expand Down
8 changes: 7 additions & 1 deletion src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ CompPhaseNameMacro(PHASE_MORPH_ADD_INTERNAL, "Morph - Add internal block
CompPhaseNameMacro(PHASE_SWIFT_ERROR_RET, "Add Swift error returns", false, -1, true)
CompPhaseNameMacro(PHASE_ALLOCATE_OBJECTS, "Allocate Objects", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY, "Remove empty try", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY_CATCH, "Remove empty try/catch", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_FINALLY, "Remove empty finally", false, -1, false)
CompPhaseNameMacro(PHASE_MERGE_FINALLY_CHAINS, "Merge callfinally chains", false, -1, false)
CompPhaseNameMacro(PHASE_CLONE_FINALLY, "Clone finally", false, -1, false)
Expand Down Expand Up @@ -74,6 +75,9 @@ CompPhaseNameMacro(PHASE_FIND_LOOPS, "Find loops",
CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", false, -1, false)
CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", false, -1, false)
CompPhaseNameMacro(PHASE_MORPH_MDARR, "Morph array ops", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_FINALLY_2, "Remove empty finally 2", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY_2, "Remove empty try 2", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY_CATCH_2, "Remove empty try-catch 2", false, -1, false)
CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", false, -1, false)
CompPhaseNameMacro(PHASE_MARK_LOCAL_VARS, "Mark local vars", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_BOOLS, "Optimize bools", false, -1, false)
Expand All @@ -96,7 +100,9 @@ CompPhaseNameMacro(PHASE_OPTIMIZE_BRANCHES, "Redundant branch opts",
CompPhaseNameMacro(PHASE_ASSERTION_PROP_MAIN, "Assertion prop", false, -1, false)
CompPhaseNameMacro(PHASE_IF_CONVERSION, "If conversion", false, -1, false)
CompPhaseNameMacro(PHASE_VN_BASED_DEAD_STORE_REMOVAL,"VN-based dead store removal", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_FINALLY_2, "Remove empty finally 2", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_FINALLY_3, "Remove empty finally 3", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY_3, "Remove empty try 3", false, -1, false)
CompPhaseNameMacro(PHASE_EMPTY_TRY_CATCH_3, "Remove empty try-catch 3", false, -1, false)
CompPhaseNameMacro(PHASE_OPT_UPDATE_FLOW_GRAPH, "Update flow graph opt pass", false, -1, false)
CompPhaseNameMacro(PHASE_STRESS_SPLIT_TREE, "Stress gtSplitTree", false, -1, false)
CompPhaseNameMacro(PHASE_EXPAND_RTLOOKUPS, "Expand runtime lookups", false, -1, true)
Expand Down
Loading

0 comments on commit 7ccf491

Please sign in to comment.