diff options
author | Andy Ayers <andya@microsoft.com> | 2017-02-15 11:11:13 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-15 11:11:13 -0800 |
commit | 0fae96e0973d09b907124ddc3c62bdad3160f27d (patch) | |
tree | 6ee10fa3cc92c4a0ef1d519b6352f8d6f193017c /src/jit/compiler.h | |
parent | 995b8694a55a2c7a9f05a8a46d63afe267be5b9d (diff) | |
download | coreclr-0fae96e0973d09b907124ddc3c62bdad3160f27d.tar.gz coreclr-0fae96e0973d09b907124ddc3c62bdad3160f27d.tar.bz2 coreclr-0fae96e0973d09b907124ddc3c62bdad3160f27d.zip |
JIT: Finally chain merging (#8810)
Add an optimization that performs a specialized tail merge for chains
of callfinallys. These can arise from try-finallys where there are
multiple exit points from the try that have the same continuation.
When the jit generates a callfinally, it does so without considering
whether some previously generated callfinally might invoke the same
handler and then continue on to the same continuation.
This optimization looks for callfinallys that invoke the same handler
and have the same continuation and effectively merges them into one
canonical callfinally.
This optimization is done bottom-up (from outermost handler invocation
to innermost) to allow the merging done at an outer levels to enable
merging at inner levels.
This optimization saves code size and also results in more compact EH
reporting, since the callfinallies are reported to the runtime as
duplicate EH regions.
When run upstream of finally cloning, finally chain merging also allows
more of the paths exiting the try to exit via the clone.
Also fix an issue in block ref count maintenance during empty try
removal that caused an assert during finally chain merging.
Diffstat (limited to 'src/jit/compiler.h')
-rw-r--r-- | src/jit/compiler.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/jit/compiler.h b/src/jit/compiler.h index b9bace42c5..1cbd3e3195 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -3562,12 +3562,18 @@ public: void fgRemoveEmptyFinally(); + void fgMergeFinallyChains(); + void fgCloneFinally(); void fgCleanupContinuation(BasicBlock* continuation); void fgUpdateFinallyTargetFlags(); + bool fgRetargetBranchesToCanonicalCallFinally(BasicBlock* block, + BasicBlock* handler, + BlockToBlockMap& continuationMap); + GenTreePtr fgGetCritSectOfStaticMethod(); #if !defined(_TARGET_X86_) |