/// <summary>
        /// Compues the liveness for the given control flow graph
        /// </summary>
        /// <param name="controlFlowGraph">The control flow graph</param>
        public static IList<LiveInterval> ComputeLiveness(VirtualControlFlowGraph controlFlowGraph)
        {
            var liveIntervals = new List<LiveInterval>();
            var virtualRegisters = GetVirtualRegisters(controlFlowGraph);

            //Get the register usage
            IDictionary<VirtualRegister, IList<UsageSite>> useSites;
            IDictionary<VirtualRegister, IList<UsageSite>> assignSites;
            GetRegisterUsage(controlFlowGraph, out useSites, out assignSites);

            //Get the backflow graph
            var backflowGraph = GetBackflow(controlFlowGraph);

            //Perform the analysis for one register at a time
            foreach (var reg in virtualRegisters)
            {
                IList<UsageSite> registerUseSites;

                if (useSites.TryGetValue(reg, out registerUseSites))
                {
                    var aliveAt = new HashSet<int>();
                    ComputeLiveness(backflowGraph, reg, registerUseSites, aliveAt);
                    liveIntervals.Add(GetLiveInterval(reg, aliveAt));
                }
                else
                {
                    //This mean that the register is not used. Atm, we do not remove write-only virtual registers.
                    //So we need to compute the liveness information, else there won't exist any liveness information for the register.
                    var aliveAt = new HashSet<int>();
                    foreach (var assignSite in assignSites[reg])
                    {
                        aliveAt.ElementAt(assignSite.Block.StartOffset + assignSite.Offset);
                    }

                    liveIntervals.Add(GetLiveInterval(reg, aliveAt));
                }
            }

            return liveIntervals;
        }
        /// <summary>
        /// Returns the virtual register usage from the registers in the given control flow graph
        /// </summary>
        /// <param name="controlFlowGraph">The control flow graph</param>
        /// <param name="useSites">The use sites</param>
        /// <param name="assignSites">The assign sites</param>
        private static void GetRegisterUsage(VirtualControlFlowGraph controlFlowGraph,
            out IDictionary<VirtualRegister, IList<UsageSite>> useSites, out IDictionary<VirtualRegister, IList<UsageSite>> assignSites)
        {
            useSites = new Dictionary<VirtualRegister, IList<UsageSite>>();
            assignSites = new Dictionary<VirtualRegister, IList<UsageSite>>();

            foreach (var block in controlFlowGraph.Vertices)
            {
                int offset = 0;
                foreach (var instruction in block.Instructions)
                {
                    if (instruction.AssignRegister != null)
                    {
                        var register = instruction.AssignRegister.Value;
                        IList<UsageSite> assigns;
                        if (!useSites.TryGetValue(register, out assigns))
                        {
                            assigns = new List<UsageSite>();
                            useSites.Add(register, assigns);
                        }

                        assigns.Add(new UsageSite()
                        {
                            Block = block,
                            Offset = offset
                        });
                    }

                    foreach (var register in instruction.UsesRegisters)
                    {
                        IList<UsageSite> uses;
                        if (!useSites.TryGetValue(register, out uses))
                        {
                            uses = new List<UsageSite>();
                            useSites.Add(register, uses);
                        }

                        uses.Add(new UsageSite()
                        {
                            Block = block,
                            Offset = offset
                        });
                    }

                    offset++;
                }
            }
        }
        /// <summary>
        /// Computes the number of virtual registers in the given control flow graph
        /// </summary>
        /// <param name="controlFlowGraph">The control flow graph</param>
        private static int NumVirtualRegister(VirtualControlFlowGraph controlFlowGraph)
        {
            var virtualRegisters = new HashSet<VirtualRegister>();
            foreach (var block in controlFlowGraph.Vertices)
            {
                foreach (var instruction in block.Instructions)
                {
                    if (instruction.AssignRegister.HasValue)
                    {
                        virtualRegisters.Add(instruction.AssignRegister.Value);
                    }

                    foreach (var register in instruction.UsesRegisters)
                    {
                        virtualRegisters.Add(register);
                    }
                }
            }

            return virtualRegisters.Count;
        }
        /// <summary>
        /// Returns the backflow for the given control flow graph
        /// </summary>
        /// <param name="controlFlowGraph">The control flow graph</param>
        private static BackflowGraph GetBackflow(VirtualControlFlowGraph controlFlowGraph)
        {
            var backflowEdges = new Dictionary<VirtualBasicBlock, ISet<VirtualBasicBlock>>();

            foreach (var edgeList in controlFlowGraph.NeighborLists.Values)
            {
                foreach (var edge in edgeList)
                {
                    ISet<VirtualBasicBlock> edges;
                    if (!backflowEdges.TryGetValue(edge.To, out edges))
                    {
                        edges = new HashSet<VirtualBasicBlock>();
                        backflowEdges.Add(edge.To, edges);
                    }

                    edges.Add(edge.From);
                }
            }

            return new BackflowGraph()
            {
                Edges = backflowEdges
            };
        }