Exemple #1
0
        private static LiveVariables ComputeLiveness(ControlFlowGraph function, Edges edges)
        {
            var blocks = new Queue <BasicBlock>();

            blocks.EnqueueRange(function.ExitBlocks);
            var liveVariables     = new LiveVariables(function);
            var numberOfVariables = function.VariableDeclarations.Count;

            while (blocks.TryDequeue(out var block))
            {
                var liveBeforeBlock = new BitArray(liveVariables.Before(block.Statements.First()));

                var liveAfterBlock = new BitArray(numberOfVariables);
                foreach (var successor in edges.From(block))
                {
                    liveAfterBlock.Or(liveVariables.Before(successor.Statements.Last()));
                }

                var liveAfterStatement = liveAfterBlock;

                foreach (var statement in block.Statements.Reverse())
                {
                    var liveSet = liveVariables.Before(statement);
                    liveSet.Or(liveAfterStatement);
                    switch (statement)
                    {
                    case AssignmentStatement assignment:
                        KillVariables(liveSet, assignment.Place);
                        EnlivenVariables(liveSet, assignment.Value);
                        break;

                    case ActionStatement action:
                        EnlivenVariables(liveSet, action.Value);
                        break;

                    case DeleteStatement _:
                        throw new InvalidOperationException("Delete statements are supposed to be added after liveness analysis");

                    //liveSet[deleteStatement.Place.CoreVariable()] = true;
                    //break;
                    case IfStatement _:
                    case GotoStatement _:
                        // We already or'ed together the live variables from successor blocks
                        break;

                    case ReturnStatement _:
                        // No effect on variables?
                        // TODO should we check the liveSet is empty?
                        break;

                    default:
                        throw NonExhaustiveMatchException.For(statement);
                    }

                    // For the next statement
                    liveAfterStatement = liveSet;
                }

                if (!liveBeforeBlock.ValuesEqual(liveVariables.Before(block.Statements.First())))
                {
                    foreach (var basicBlock in edges.To(block)
                             .Where(fromBlock => !blocks.Contains(fromBlock)).ToList())
                    {
                        blocks.Enqueue(basicBlock);
                    }
                }
            }
            return(liveVariables);
        }