/// <summary> /// Tells if a particular value is strictly dominated by another value, /// that is, if control cannot flow to the value unless it first flowed /// through the dominator value. /// </summary> /// <param name="value"> /// An value that might be dominated by <paramref name="dominator"/>. /// </param> /// <param name="dominator"> /// An value that might dominate <paramref name="value"/>. /// </param> /// <param name="graph"> /// A graph that defines both values. /// </param> /// <returns> /// <c>true</c> if <paramref name="value"/> is strictly dominated by /// <paramref name="dominator"/>; otherwise, <c>false</c>. /// </returns> public bool IsStrictlyDominatedBy(ValueTag value, ValueTag dominator, FlowGraph graph) { var valueBlock = graph.GetValueParent(value); var dominatorBlock = graph.GetValueParent(dominator); if (valueBlock.Tag == dominatorBlock.Tag) { if (graph.ContainsBlockParameter(dominator)) { return(!graph.ContainsBlockParameter(value)); } else if (graph.ContainsBlockParameter(value)) { return(false); } else { var valueInsn = graph.GetInstruction(value); var domInsn = graph.GetInstruction(dominator); return(valueInsn.InstructionIndex > domInsn.InstructionIndex); } } else { return(IsStrictlyDominatedBy(valueBlock, dominatorBlock)); } }
/// <summary> /// Tries to move an instruction from its /// current location to just before another instruction. /// </summary> /// <param name="instruction"> /// The instruction to try and move. /// </param> /// <param name="block"> /// The block that defines the insertion point. /// </param> /// <param name="insertionPoint"> /// An instruction to which the instruction should /// be moved. It must be defined in the same basic /// block as <paramref name="instruction"/>. /// </param> /// <param name="graph"> /// The graph that defines both instructions. /// </param> /// <returns> /// <c>true</c> if <paramref name="instruction"/> was /// successfully reordered; otherwise, <c>false</c>. /// </returns> private static bool TryReorder( ValueTag instruction, BasicBlockTag block, ref LinkedListNode <ValueTag> insertionPoint, FlowGraph graph) { if (graph.GetValueParent(instruction).Tag != block || !graph.ContainsInstruction(instruction)) { return(false); } // Grab the ordering to which we should adhere. var ordering = graph.GetAnalysisResult <InstructionOrdering>(); // Start at the linked list node belonging to the instruction // to move and work our way toward the insertion point. // Check the must-run-before relation as we traverse the list. var instructionNode = GetInstructionNode(instruction, insertionPoint); var currentNode = instructionNode; while (currentNode != insertionPoint) { if (ordering.MustRunBefore(instruction, currentNode.Value)) { // Aw snap, we encountered a dependency. // Time to abandon ship. return(false); } currentNode = currentNode.Next; } // Looks like we can reorder the instruction! if (insertionPoint != instructionNode) { insertionPoint.List.Remove(instructionNode); insertionPoint.List.AddBefore(insertionPoint, instructionNode); } insertionPoint = instructionNode; return(true); }