/// <summary> /// Helper method that merges state with the target block and determines whether to continue by visiting the target block. /// </summary> /// <param name="edgeLabel">Label identifying incoming edge.</param> /// <param name="state">Locals state in which we are entering the target.</param> /// <param name="target">Target block.</param> /// <remarks>Only for traversing into blocks within the same routine (same type context).</remarks> private void TraverseToBlock(object edgeLabel, FlowState /*!*/ state, BoundBlock /*!*/ target) { Contract.ThrowIfNull(state); // state should be already set by previous block var targetState = target.FlowState; if (targetState != null) { Debug.Assert(targetState.FlowContext == state.FlowContext); // block was visited already, // merge and check whether state changed state = state.Merge(targetState); // merge states into new one if (state.Equals(targetState) && !target.ForceRepeatedAnalysis) { // state converged, we don't have to analyse the target block again // unless it is specially needed (e.g. ExitBlock) return; } } else { // block was not visited yet state = state.Clone(); // copy state into new one } // update target block state target.FlowState = state; // _worklist.Enqueue(target); }
/// <summary> /// Helper method that merges state with the target block and determines whether to continue by visiting the target block. /// </summary> /// <param name="state">Locals state in which we are entering the target.</param> /// <param name="target">Target block.</param> /// <remarks>Only for traversing into blocks within the same routine (same type context).</remarks> private void TraverseToBlock(FlowState /*!*/ state, BoundBlock /*!*/ target) { Contract.ThrowIfNull(state); // state should be already set by previous block var targetState = target.FlowState; if (targetState != null) { Debug.Assert(targetState.Common == state.Common); // block was visited already, // merge and check whether state changed state = state.Merge(targetState); // merge states into new one if (state.Equals(targetState)) { return; // state convergated, we don't have to analyse target block again } } else { // block was not visited yet state = state.Clone(); // copy state into new one } // update target block state target.FlowState = state; // _worklist.Enqueue(target); }