public static bool Parse(ControlFlowGraph cfg, SharedData data)
        {
            List<AALocalDecl> usedLocals = GetUsedLocals.Parse(cfg.Method.GetBlock(), data);

            List<ControlFlowGraph.Node> modifications = new List<ControlFlowGraph.Node>();
            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                if (node.Statement is ALocalDeclStm)
                {
                    AALocalDecl decl = (AALocalDecl) ((ALocalDeclStm) node.Statement).GetLocalDecl();
                    if (!usedLocals.Contains(decl))
                    {
                        modifications.Add(node);
                    }
                }
                else
                {
                    break;
                }
            }
            foreach (ControlFlowGraph.Node node in modifications)
            {
                cfg.Remove(node);
                node.Statement.Parent().RemoveChild(node.Statement);
            }
            return modifications.Count > 0;
        }
 private static void Join(ControlFlowGraph.Node node)
 {
     foreach (ControlFlowGraph.Node successor in node.Successors)
     {
         node.LiveVariables.Union(successor.LiveVariables);
     }
 }
        public static void CalculateLiveVariables(ControlFlowGraph cfg, SharedData data)
        {
            //First, generate lists of what is used in each node
            Dictionary<ControlFlowGraph.Node, List<AALocalDecl>> usedVars = new Dictionary<ControlFlowGraph.Node, List<AALocalDecl>>();
            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                node.LiveVariables.Clear();

                PExp exp = node.Expression;
                if (exp == null)
                    usedVars[node] = new List<AALocalDecl>();
                else
                {
                    GetUsedVariables variableFinder = new GetUsedVariables(data);
                    exp.Apply(variableFinder);
                    usedVars[node] = variableFinder.UsedLocals;
                }
            }

            bool changed = true;
            while (changed)
            {
                changed = false;
                foreach (ControlFlowGraph.Node node in cfg.Nodes)
                {

                    int count = node.LiveVariables.Count;
                    Join(node);
                    node.LiveVariables.Subtract(GetAssignedTo(node, data));
                    node.LiveVariables.Union(usedVars[node]);
                    changed |= count != node.LiveVariables.Count;
                }
            }
        }
 public static ControlFlowGraph Create(AMethodDecl method)
 {
     ControlFlowGraph graph = new ControlFlowGraph(method);
     CFGGenerator generator = new CFGGenerator();
     method.GetBlock().Apply(generator);
     graph.Nodes = new List<Node>(generator.Nodes.Count);
     graph.Nodes.AddRange(generator.Nodes);
     return graph;
 }
 public static bool Parse(ControlFlowGraph cfg, SharedData data, out bool redoLivenessAnalysis)
 {
     bool changed = false;
     redoLivenessAnalysis = false;
     Dictionary<ControlFlowGraph.Node, List<ASimpleInvokeExp>> Modifications = new Dictionary<ControlFlowGraph.Node, List<ASimpleInvokeExp>>();
     foreach (ControlFlowGraph.Node node in cfg.Nodes)
     {
         if (node.Expression is AAssignmentExp)
         {
             AAssignmentExp exp = (AAssignmentExp) node.Expression;
             if (exp.GetLvalue() is ALocalLvalue)
             {
                 AALocalDecl decl = data.LocalLinks[(ALocalLvalue) exp.GetLvalue()];
                 //If the variable is not live at any successors, remove this assignment
                 bool inUse = false;
                 foreach (ControlFlowGraph.Node successor in node.Successors)
                 {
                     if (successor.LiveVariables.Contains(decl))
                     {
                         inUse = true;
                         break;
                     }
                 }
                 if (!inUse)
                 {
                     //Move method invokes out
                     GetMethodInvokes getter = new GetMethodInvokes();
                     exp.GetExp().Apply(getter);
                     //Might also have to redo because we removed a reference to a variable in the right side
                     //if (getter.Invokes.Count > 0)
                         redoLivenessAnalysis = true;
                     Modifications[node] = getter.Invokes;
                     changed = true;
                 }
             }
         }
     }
     foreach (KeyValuePair<ControlFlowGraph.Node, List<ASimpleInvokeExp>> pair in Modifications)
     {
         ControlFlowGraph.Node node = pair.Key;
         foreach (ASimpleInvokeExp invoke in pair.Value)
         {
             AExpStm stm = new AExpStm(new TSemicolon(";"), invoke);
             AABlock pBlock = (AABlock) node.Statement.Parent();
             pBlock.GetStatements().Insert(pBlock.GetStatements().IndexOf(node.Statement), stm);
             cfg.Insert(node, stm);
         }
         cfg.Remove(node);
         node.Statement.Parent().RemoveChild(node.Statement);
     }
     return changed;
 }
 public static void Parse(ControlFlowGraph graph )
 {
     for (int i = 1; i < graph.Nodes.Count; i++)
     {
         ControlFlowGraph.Node n = graph.Nodes[i];
         if (n.Predecessors.Count == 0)
         {
             n.Statement.Parent().RemoveChild(n.Statement);
             graph.Remove(n);
             i--;
         }
     }
 }
 private static List<AALocalDecl> GetAssignedTo(ControlFlowGraph.Node node, SharedData data)
 {
     if (node.Statement is ALocalDeclStm)
         return new List<AALocalDecl>(){(AALocalDecl) ((ALocalDeclStm)node.Statement).GetLocalDecl()};
     PExp exp = node.Expression;
     if (exp != null && exp is AAssignmentExp)
     {
         AAssignmentExp aExp = (AAssignmentExp) exp;
         if (aExp.GetLvalue() is ALocalLvalue)
             return new List<AALocalDecl>(){data.LocalLinks[(ALocalLvalue) aExp.GetLvalue()]};
     }
     return new List<AALocalDecl>();
 }
Example #8
0
        public static bool Parse(ControlFlowGraph cfg, SharedData data)
        {
            //List of locals by type
            List <List <AALocalDecl> > locals = new List <List <AALocalDecl> >();
            //Locals -> cfg node
            Dictionary <AALocalDecl, ControlFlowGraph.Node> localNodes = new Dictionary <AALocalDecl, ControlFlowGraph.Node>();

            foreach (AALocalDecl formal in cfg.Method.GetFormals())
            {
                bool added = false;
                foreach (List <AALocalDecl> list in locals)
                {
                    if (Util.TypesEqual(list[0].GetType(), formal.GetType(), data))
                    {
                        list.Add(formal);
                        added = true;
                        break;
                    }
                }
                if (!added)
                {
                    locals.Add(new List <AALocalDecl>()
                    {
                        formal
                    });
                }
            }
            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                //Locals have been moved to the top
                if (!(node.Statement is ALocalDeclStm))
                {
                    break;
                }

                AALocalDecl decl = (AALocalDecl)((ALocalDeclStm)node.Statement).GetLocalDecl();

                localNodes[decl] = node;

                bool added = false;
                foreach (List <AALocalDecl> list in locals)
                {
                    if (Util.TypesEqual(list[0].GetType(), decl.GetType(), data))
                    {
                        list.Add(decl);
                        added = true;
                        break;
                    }
                }
                if (!added)
                {
                    locals.Add(new List <AALocalDecl>()
                    {
                        decl
                    });
                }
            }


            bool joinedSomething = false;

            foreach (List <AALocalDecl> list in locals)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    for (int j = i + 1; j < list.Count; j++)
                    {
                        //Can't join if both are formals
                        if (list[i].Parent() is AMethodDecl &&
                            list[j].Parent() is AMethodDecl)
                        {
                            continue;
                        }

                        //Can't join if both are live at the same time
                        bool canJoin = true;
                        foreach (ControlFlowGraph.Node cfgNode in cfg.Nodes)
                        {
                            if (cfgNode.LiveVariables.Contains(list[i]) &&
                                cfgNode.LiveVariables.Contains(list[j]))
                            {
                                canJoin = false;
                                break;
                            }
                        }
                        if (!canJoin)
                        {
                            continue;
                        }

                        joinedSomething = true;
                        Join(list[i], list[j], cfg, localNodes, data);
                        list.RemoveAt(j);
                        j--;
                    }
                }
            }
            return(joinedSomething);
        }
 private static void Join(AALocalDecl decl1, AALocalDecl decl2, ControlFlowGraph cfg, Dictionary<AALocalDecl, ControlFlowGraph.Node> localNodes, SharedData data)
 {
     //Remove decl2 from cfg
     //decl2 can't be a formal, since formals was first in the list, and two formals wont be joined.
     ControlFlowGraph.Node cfgNode2 = localNodes[decl2];
     cfg.Remove(cfgNode2);
     //Remove decl2 from the ast
     cfgNode2.Statement.Parent().RemoveChild(cfgNode2.Statement);
     //Go through cfg and make live decl2 variables become live decl1 variables.));
     foreach (ControlFlowGraph.Node cfgNode in cfg.Nodes)
     {
         if (cfgNode.LiveVariables.Contains(decl2))
         {
             cfgNode.LiveVariables.Remove(decl2);
             cfgNode.LiveVariables.Add(decl1);
         }
     }
     //Rename all refferences to decl2 to be decl1
     LinkedList<ALocalLvalue> keys = new LinkedList<ALocalLvalue>();
     foreach (KeyValuePair<ALocalLvalue, AALocalDecl> pair in data.LocalLinks)
     {
         if (pair.Value == decl2)
             keys.AddLast(pair.Key);
     }
     foreach (ALocalLvalue key in keys)
     {
         data.LocalLinks[key] = decl1;
     }
 }
        public static bool Parse(ControlFlowGraph cfg, SharedData data)
        {
            //List of locals by type
            List<List<AALocalDecl>> locals = new List<List<AALocalDecl>>();
            //Locals -> cfg node
            Dictionary<AALocalDecl, ControlFlowGraph.Node> localNodes = new Dictionary<AALocalDecl, ControlFlowGraph.Node>();
            foreach (AALocalDecl formal in cfg.Method.GetFormals())
            {
                bool added = false;
                foreach (List<AALocalDecl> list in locals)
                {
                    if (Util.TypesEqual(list[0].GetType(), formal.GetType(), data))
                    {
                        list.Add(formal);
                        added = true;
                        break;
                    }
                }
                if (!added)
                    locals.Add(new List<AALocalDecl>(){formal});
            }
            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                //Locals have been moved to the top
                if (!(node.Statement is ALocalDeclStm))
                    break;

                AALocalDecl decl = (AALocalDecl) ((ALocalDeclStm) node.Statement).GetLocalDecl();

                localNodes[decl] = node;

                bool added = false;
                foreach (List<AALocalDecl> list in locals)
                {
                    if (Util.TypesEqual(list[0].GetType(), decl.GetType(), data))
                    {
                        list.Add(decl);
                        added = true;
                        break;
                    }
                }
                if (!added)
                    locals.Add(new List<AALocalDecl>() {decl});
            }

            bool joinedSomething = false;
            foreach (List<AALocalDecl> list in locals)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    for (int j = i + 1; j < list.Count; j++)
                    {
                        //Can't join if both are formals
                        if (list[i].Parent() is AMethodDecl &&
                            list[j].Parent() is AMethodDecl)
                            continue;

                        //Can't join if both are live at the same time
                        bool canJoin = true;
                        foreach (ControlFlowGraph.Node cfgNode in cfg.Nodes)
                        {
                            if (cfgNode.LiveVariables.Contains(list[i]) &&
                                cfgNode.LiveVariables.Contains(list[j]))
                            {
                                canJoin = false;
                                break;
                            }
                        }
                        if (!canJoin)
                            continue;

                        joinedSomething = true;
                        Join(list[i], list[j], cfg, localNodes, data);
                        list.RemoveAt(j);
                        j--;
                    }
                }
            }
            return joinedSomething;
        }
        public static bool Parse(ControlFlowGraph cfg, SharedData data)
        {
            Dictionary<PStm, ControlFlowGraph.Node> statementNodes = new Dictionary<PStm, ControlFlowGraph.Node>();
            //Dictionary<ControlFlowGraph.Node, List<AALocalDecl>> uses = new Dictionary<ControlFlowGraph.Node, List<AALocalDecl>>();
            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                statementNodes[node.Statement] = node;

                /*GetUses getUses = new GetUses();
                node.Statement.Apply(getUses);
                uses[node] = getUses.Uses;*/
            }

            foreach (ControlFlowGraph.Node node in cfg.Nodes)
            {
                if (node.Expression is AAssignmentExp)
                {
                    AAssignmentExp exp = (AAssignmentExp) node.Expression;

                    if (exp.GetLvalue() is ALocalLvalue)
                    {
                        AALocalDecl decl = data.LocalLinks[(ALocalLvalue) exp.GetLvalue()];
                        bool dontMove = false;

                        LocalChecker.ModifyData declModData = LocalChecker.GetLocalData(node.Expression, data);

                        /*1: Search for unique use of decl
                         *  Stop if you find an assignment to decl
                         *  Stop if decl is not live
                         *  Cancel if you find two uses of decl (also within one statement)
                         */
                        ControlFlowGraph.Node useNode = null;
                        LinkedList<ControlFlowGraph.Node> nextNodes = new LinkedList<ControlFlowGraph.Node>();
                        LinkedList<ControlFlowGraph.Node> visitedNodes = new LinkedList<ControlFlowGraph.Node>();
                        foreach (var successor in node.Successors)
                        {
                            nextNodes.AddLast(successor);
                        }
                        while (nextNodes.Count > 0)
                        {
                            ControlFlowGraph.Node successor = nextNodes.First.Value;
                            nextNodes.RemoveFirst();
                            visitedNodes.AddLast(successor);
                            LocalChecker.ModifyData succData = LocalChecker.GetLocalData(successor.Expression, data);

                            //Stop if decl is not live
                            if (!successor.LiveVariables.Contains(decl))
                                continue;

                            //Check if this node uses it)
                            if (succData.Locals.ContainsKey(decl))
                            {
                                var val = succData.Locals[decl];
                                if (val.Reads)
                                {
                                    if (useNode == null)
                                    {
                                        useNode = successor;
                                    }
                                    else
                                    {
                                        //Cancel if we found two uses
                                        dontMove = true;
                                        break;
                                    }
                                }
                                //Stop if it writes to the variable
                                if (val.Writes)
                                    continue;
                            }

                            foreach (ControlFlowGraph.Node nextSucc in successor.Successors)
                            {
                                if (visitedNodes.Contains(nextSucc))
                                    continue;
                                nextNodes.AddLast(nextSucc);
                            }
                        }

                        ALocalLvalue usedLvalue;
                        if (dontMove ||
                            useNode == null ||
                            //Cancel if there are two uses of the local within same statement
                            GetUses.HasMoreThanOneUses(useNode.Statement, decl, data, out usedLvalue))
                            continue;

                        /*2: Search back from found statement, to ensure unique assignment
                         *  Stop if assignment reached
                         *  Cancel if start of method is reached
                         *  Cancel if any statement reads/writes to a variable used in the statement (where one of them writes)
                         *  Cancel if another assignment to x is found (including local decls)
                         */
                        visitedNodes.Clear();
                        nextNodes.Clear();
                        foreach (ControlFlowGraph.Node predecessor in useNode.Predecessors)
                        {
                            nextNodes.AddLast(predecessor);
                        }
                        while (nextNodes.Count > 0)
                        {
                            ControlFlowGraph.Node predecessor = nextNodes.First.Value;
                            nextNodes.RemoveFirst();
                            visitedNodes.AddLast(predecessor);
                            LocalChecker.ModifyData predData = LocalChecker.GetLocalData(predecessor.Expression, data);

                            //Stop if assignment reached
                            if (predecessor == node)
                                continue;

                            //Cancel if this statement writes to decl
                            if (predData.Locals.ContainsKey(decl) &&
                                predData.Locals[decl].Writes ||
                                predecessor.Statement is ALocalDeclStm &&
                                ((ALocalDeclStm)predecessor.Statement).GetLocalDecl() == decl)
                            {
                                dontMove = true;
                                break;
                            }

                            //Cancel if any statement reads/writes to a variable used in the statement (where one of them writes)
                            if (declModData.Conflicts(predData))
                            {
                                dontMove = true;
                                break;
                            }

                            //Cancel if start of method is reached
                            if (predecessor.Predecessors.Count == 0)
                            {
                                dontMove = true;
                                break;
                            }

                            foreach (ControlFlowGraph.Node nextPred in predecessor.Predecessors)
                            {
                                if (visitedNodes.Contains(nextPred))
                                    continue;
                                nextNodes.AddLast(nextPred);
                            }
                        }

                        if (dontMove)
                            continue;

                        //Move it
                        cfg.Remove(node);
                        node.Statement.Parent().RemoveChild(node.Statement);
                        usedLvalue.Parent().ReplaceBy(exp.GetExp());

                        //We now need to redo liveness analysis
                        return true;
                    }
                }
            }
            return false;
        }