Ejemplo n.º 1
0
        /// <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));
            }
        }
Ejemplo n.º 2
0
        /// <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);
        }