Esempio n. 1
0
        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;
            }
        }
Esempio n. 2
0
        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>());
        }
Esempio n. 3
0
 private static void Join(ControlFlowGraph.Node node)
 {
     foreach (ControlFlowGraph.Node successor in node.Successors)
     {
         node.LiveVariables.Union(successor.LiveVariables);
     }
 }
        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);
        }
Esempio n. 5
0
 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--;
         }
     }
 }
        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);
        }