/// <summary> /// Traverses all nodes in the control flow graph, and synchronizes the structure of the graph with the contents /// of each basic block within the traversed nodes. /// </summary> /// <param name="graph">The graph to synchronize.</param> /// <param name="successorResolver">The object to use for resolving successors of a single instruction.</param> /// <param name="flags">Flags indicating several options for updating the control flow graph.</param> /// <typeparam name="TInstruction">The type of instructions stored in the control flow graph.</typeparam> /// <returns><c>true</c> if any changes were made, <c>false</c> otherwise.</returns> public static bool UpdateFlowControl <TInstruction>( this ControlFlowGraph <TInstruction> graph, IStaticSuccessorResolver <TInstruction> successorResolver, FlowControlSynchronizationFlags flags) { var synchronizer = new FlowControlSynchronizer <TInstruction>(graph, successorResolver, flags); return(synchronizer.UpdateFlowControl()); }
/// <summary> /// Creates a new instance of the <see cref="FlowControlSynchronizer{TInstruction}"/> class. /// </summary> /// <param name="cfg">The control flow graph to update.</param> /// <param name="successorResolver">The object responsible for resolving successors of a single instruction.</param> /// <param name="flags">The flags that dictate the strategy used for pulling basic block updates into a control flow graph.</param> public FlowControlSynchronizer( ControlFlowGraph <TInstruction> cfg, IStaticSuccessorResolver <TInstruction> successorResolver, FlowControlSynchronizationFlags flags) { ControlFlowGraph = cfg ?? throw new ArgumentNullException(nameof(cfg)); SuccessorResolver = successorResolver ?? throw new ArgumentNullException(nameof(successorResolver)); Flags = flags; }
/// <summary> /// Pulls any updates from the basic block embedded in the node, and updates the parent control flow graph /// accordingly. /// </summary> /// <param name="node">The node to pull updates from.</param> /// <param name="successorResolver">The object to use for resolving successors of a single instruction.</param> /// <param name="flags">Flags indicating several options for updating the control flow graph.</param> /// <typeparam name="TInstruction">The type of instructions stored in the control flow graph.</typeparam> /// <returns><c>true</c> if any changes were made, <c>false</c> otherwise.</returns> public static bool UpdateFlowControl <TInstruction>( this ControlFlowNode <TInstruction> node, IStaticSuccessorResolver <TInstruction> successorResolver, FlowControlSynchronizationFlags flags) { var synchronizer = new FlowControlSynchronizer <TInstruction>(node.ParentGraph, successorResolver, flags); return(synchronizer.UpdateFlowControl(node)); }