In particular those done by profile instrumentation.
Fixes #82275.
void fgAddFinallyTargetFlags();
+ void fgFixFinallyTargetFlags(BasicBlock* pred, BasicBlock* succ, BasicBlock* newBlock);
+
#endif // defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
PhaseStatus fgTailMergeThrows();
void fgTailMergeThrowsFallThroughHelper(BasicBlock* predBlock,
unreached();
break;
}
+
+#if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
+ fgFixFinallyTargetFlags(block, oldTarget, newTarget);
+#endif
}
//------------------------------------------------------------------------
fgAddRefPred(newBlock, curr);
}
+#if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
+ fgFixFinallyTargetFlags(curr, succ, newBlock);
+#endif
+
// This isn't accurate, but it is complex to compute a reasonable number so just assume that we take the
// branch 50% of the time.
//
}
}
+//------------------------------------------------------------------------
+// fgFixFinallyTargetFlags: Update BBF_FINALLY_TARGET bits after redirecting flow
+//
+// Arguments:
+// pred - source of flow
+// succ - original target of flow from pred
+// newSucc - new target of flow from pred
+//
+void Compiler::fgFixFinallyTargetFlags(BasicBlock* pred, BasicBlock* succ, BasicBlock* newSucc)
+{
+ if (pred->isBBCallAlwaysPairTail())
+ {
+ assert(succ->bbFlags & BBF_FINALLY_TARGET);
+ newSucc->bbFlags |= BBF_FINALLY_TARGET;
+ succ->bbFlags &= ~BBF_FINALLY_TARGET;
+
+ for (BasicBlock* const pred : succ->PredBlocks())
+ {
+ if (pred->isBBCallAlwaysPairTail())
+ {
+ succ->bbFlags |= BBF_FINALLY_TARGET;
+ break;
+ }
+ }
+ }
+}
#endif // defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
//------------------------------------------------------------------------
{
m_comp->fgRemoveRefPred(pred, block);
m_comp->fgAddRefPred(intermediary, block);
+
+#if defined(FEATURE_EH_FUNCLETS) && defined(TARGET_ARM)
+ m_comp->fgFixFinallyTargetFlags(pred, block, intermediary);
+#endif
}
}
}