public static Dictionary <BasicBlock <IRInstrList>, BlockLiveness> ComputeLiveness(
            IList <BasicBlock <IRInstrList> > blocks)
        {
            var liveness    = new Dictionary <BasicBlock <IRInstrList>, BlockLiveness>();
            var entryBlocks = blocks.Where(block => block.Sources.Count == 0).ToList();
            var order       = new List <BasicBlock <IRInstrList> >();
            var visited     = new HashSet <BasicBlock <IRInstrList> >();

            foreach (var entry in entryBlocks)
            {
                PostorderTraversal(entry, visited, block => order.Add(block));
            }

            var worked = false;

            do
            {
                foreach (var currentBlock in order)
                {
                    var blockLiveness = BlockLiveness.Empty();

                    foreach (var successor in currentBlock.Targets)
                    {
                        BlockLiveness successorLiveness;
                        if (!liveness.TryGetValue(successor, out successorLiveness))
                        {
                            continue;
                        }
                        blockLiveness.OutLive.UnionWith(successorLiveness.InLive);
                    }

                    var live = new HashSet <IRVariable>(blockLiveness.OutLive);
                    for (var i = currentBlock.Content.Count - 1; i >= 0; i--)
                    {
                        var instr = currentBlock.Content[i];
                        ComputeInstrLiveness(instr, live);
                    }
                    blockLiveness.InLive.UnionWith(live);

                    BlockLiveness prevLiveness;
                    if (!worked && liveness.TryGetValue(currentBlock, out prevLiveness))
                    {
                        worked = !prevLiveness.InLive.SetEquals(blockLiveness.InLive) ||
                                 !prevLiveness.OutLive.SetEquals(blockLiveness.OutLive);
                    }
                    liveness[currentBlock] = blockLiveness;
                }
            } while(worked);

            return(liveness);
        }
        public static Dictionary <IRInstruction, HashSet <IRVariable> > ComputeLiveness(
            BasicBlock <IRInstrList> block, BlockLiveness liveness)
        {
            var ret  = new Dictionary <IRInstruction, HashSet <IRVariable> >();
            var live = new HashSet <IRVariable>(liveness.OutLive);

            for (var i = block.Content.Count - 1; i >= 0; i--)
            {
                var instr = block.Content[i];
                ComputeInstrLiveness(instr, live);
                ret[instr] = new HashSet <IRVariable>(live);
            }
            Debug.Assert(live.SetEquals(liveness.InLive));
            return(ret);
        }