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(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<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; }
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 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--; } } }
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); }
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) { 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; }