/// <summary>
        /// Inject a call to the coverage function with the id of a basic block
        /// before its first instruction.
        /// </summary>
        /// <param name="function">Function being instrumented.</param>
        /// <param name="coverageVisit">
        /// Coverage function to call before each block.
        /// </param>
        /// <param name="block">
        /// The id of the block to pass to the coverage function.
        /// </param>
        /// <param name="blockStartInstruction">
        /// First instruction of the basic block.
        /// </param>
        private static void InjectCoverageCall(Phx.FunctionUnit function, Phx.Symbols.FunctionSymbol coverageVisit, uint block, Phx.IR.Instruction blockStartInstruction)
        {
            Phx.Types.Table typeTable = function.ParentUnit.TypeTable;
            if (function.FlowGraph == null)
            {
                function.BuildFlowGraph();
            }

            // Create the instructions
            Phx.IR.Operand     blockOperand = Phx.IR.ImmediateOperand.New(function, typeTable.UInt32Type, (uint)block);
            Phx.IR.Instruction loadBlock    = Phx.IR.ValueInstruction.NewUnaryExpression(function, Phx.Targets.Architectures.Msil.Opcode.ldc, typeTable.UInt32Type, blockOperand);
            loadBlock.DestinationOperand.Register = Phx.Targets.Architectures.Msil.Register.SR0;
            Phx.IR.Instruction callCoverage = Phx.IR.CallInstruction.New(function, Phx.Targets.Architectures.Msil.Opcode.call, coverageVisit);

            // Insert the instructions
            blockStartInstruction.InsertBefore(loadBlock);
            callCoverage.AppendSource(loadBlock.DestinationOperand);
            loadBlock.DestinationOperand.BreakExpressionTemporary();
            loadBlock.DebugTag = blockStartInstruction.DebugTag;
            blockStartInstruction.InsertBefore(callCoverage);
        }
        /// <summary>
        /// Splits the BasicBlock in <paramref name="functionUnit"/> that contains a user-defined
        /// label with the name <paramref name="name"/>, and returns the new BasicBlock as a
        /// result of the split.
        /// </summary>
        ///
        /// <param name="functionUnit">Function unit that contains the label.</param>
        /// <param name="name">Name of the user-defined label to find.</param>
        /// <returns>New BasicBlock in <paramref name="functionUnit"/>
        /// that results from a split at the user-defined label with the name
        /// <paramref name="name"/>; null otherwise.</returns>
        /// <remarks>Precondition: There is only one user-defined label with
        /// the name <paramref name="name"/>.</remarks>
        public static Phx.Graphs.BasicBlock SplitAtUserLabel(Phx.FunctionUnit functionUnit,
                                                             string name)
        {
            Phx.Graphs.FlowGraph  flowGraph = functionUnit.FlowGraph;
            Phx.Graphs.BasicBlock result    = null;

            foreach (Phx.IR.Instruction instruction in functionUnit.Instructions)
            {
                if (instruction.Opcode == Phx.Common.Opcode.UserLabel)
                {
                    Phx.IR.Operand userLabelOperand = instruction.SourceOperand;
                    string         operandName      = userLabelOperand.ToString();

                    /* Fix the label name, if needed. */
                    if (operandName.StartsWith("$"))
                    {
                        operandName = operandName.Substring(1);
                    }

                    if (operandName == name)
                    {
                        Phx.Graphs.BasicBlock block = instruction.BasicBlock;
                        result = flowGraph.SplitBlock(block, instruction);
                        break;
                    }
                }
            }

            if (result == null)
            {
                Console.Out.WriteLine("PHOENIX: Cannot find user-defined label: " + name);
                Console.Out.WriteLine("Exiting GameTime.");
                Environment.Exit(1);
            }

            return(result);
        }