예제 #1
0
        public virtual void Run()
        {
            foreach (var b in graph.GetVertices())
            {
                Out[b] = Top;
            }

            var nodes = new HashSet <CFGNode>(graph.GetVertices());
            //nodes.Remove(graph.GetRoot());

            var cont = true;

            while (cont)
            {
                cont = false;
                foreach (var node in nodes)
                {
                    In[node] = MeetOp(node.ParentsNodes);
                    var prevOut = Out[node];
                    var newOut  = Out[node] = TransferFunc(node);
                    if (ContCond(prevOut, newOut))
                    {
                        cont = true;
                    }
                }
            }
        }
예제 #2
0
        public void analyze()
        {
            var firstBlock = cfg.GetVertices().First();
            var vertces    = cfg.GetVertices();

            // Инициализируем для кажлого ББЛ кроме прервого список выходных выражений равный U (множество всех выражений)
            foreach (var vertce in vertces)
            {
                if (firstBlock != vertce.Value)
                {
                    OutBlocks[vertce.Value] = new List <Expression>(genKills.AllExpressions);
                }
            }

            bool hasChanges = true;

            while (hasChanges)
            {
                hasChanges = false;

                foreach (var vertce in vertces)
                {
                    if (firstBlock != vertce.Value)
                    {
                        // Добавляем во входные выражения все выражения, которые выходят из родительских блоков
                        foreach (var parent in vertce.ParentsNodes)
                        {
                            InBlocks[vertce.Value] = UnionNodes(InBlocks[vertce.Value], OutBlocks[parent.Value]);
                        }

                        //Копируем старый список выходных выражений для сравнения в будущем
                        var oldOut = new List <Expression>(OutBlocks[vertce.Value]);

                        // IN[B] - e_kill_B - убиваем в списке входных выражений те, которые будут убиты в текущем базовом блоке
                        var resNodes = ResidualNodes(InBlocks[vertce.Value], genKills.Remove[vertce.Value]);

                        // объединяем оставшиеся IN[B] с e_gen_B, т.е. все что осталось после кровавой резни между IN и e_kill объединяем с тем, что родилось в данном ББЛ
                        // Cохраняем это все как выходные выражения для текущего базового блока
                        OutBlocks[vertce.Value] = UnionNodes(genKills.Gen[vertce.Value], resNodes);

                        // Если мы поменяли список выходных вырожений, то мы обязаны снова пройти по всем блокам и пересчитать вход/выход, ибо наш вход опирается на выходы других блоков, которые могли быть изменены
                        if (!EqualNodes(OutBlocks[vertce.Value], oldOut))
                        {
                            hasChanges = true;
                        }
                    }
                }
            }
        }
예제 #3
0
파일: RegionSequence.cs 프로젝트: koyre/b8
        public RegionSequence(CFGraph cfg)
        {
            regions = new List <Region>();
            // Get all nodes of cfg
            List <CFGNode> allNodes = cfg.GetVertices().ToList();
            // All edges in cfg
            List <Edge <CFGNode> > edges = cfg.EdgeTypes.Select(e => e.Key).ToList();

            // Each node in cfg is leaf region
            foreach (var node in cfg.GetVertices())
            {
                var edgesFromNode = edges.FindAll(e => e.Target == node);
                regions.Add(new LeafRegion(node, edges, NextName()));
            }
            var nc = cfg.getNaturalCyclesForBackwardEdges();
            // Nodes which are headers of natural cycles
            HashSet <CFGNode> cyclesHeaders = new HashSet <CFGNode>(nc.Select(c => c[0]));
            // Headers of cycles. These cycles are added to list of regions
            HashSet <CFGNode> addedCyclesHeaders = new HashSet <CFGNode>();

            while (nc.Count > 0)
            {
                // List of cycles we can add into regions (there are no nonadded cycles inside)
                List <List <CFGNode> > cyclesToAdd = nc.FindAll(c => c.Skip(1).All(node =>
                {
                    // If node is header of cycle then it should be added in list of regions
                    return(cyclesHeaders.Contains(node) ? addedCyclesHeaders.Contains(node) : true);
                }));
                foreach (var cycle in cyclesToAdd)
                {
                    var nodes = new HashSet <CFGNode>(cycle);
                    AddCycle(cycle, edges, nodes);
                    addedCyclesHeaders.Add(cycle[0]);
                }
                nc.RemoveAll(c => addedCyclesHeaders.Contains(c[0]));
            }
            // cfg is natural cycle if there is cycle header equals first node of cfg
            bool cfgIsNaturalCycle = cyclesHeaders.Contains(allNodes[0]);

            // If cfg isn't natural cycle then add region contains all nodes and edges
            if (!cfgIsNaturalCycle)
            {
                regions.Add(new BodyRegion(allNodes[0], allNodes, edges, NextName()));
            }
        }
예제 #4
0
        public AvailableExprAnalyzer(CFGraph _cfg)
        {
            cfg = _cfg;
            // Генерируем e_gen и e_kills
            genKills = new GenKillExprs(cfg);

            // Инициализируем для всех ББЛ пустые списки с входными выражениями
            foreach (var vertice in cfg.GetVertices())
            {
                InBlocks.Add(vertice.Value, new List <Expression>());
            }
        }