/// <summary> /// Inserts phi functions for all variables in every block, /// which contains 2 predesessors /// </summary> /// <param name="inputGraph"></param> /// <returns></returns> private CFGraph InsertPhiFunctions(CFGraph inputGraph) { CFGraph ssaGraph = inputGraph; //HashSet<BaseBlock> blocksWithPhi = new HashSet<BaseBlock>(); foreach (var variable in variables) { foreach (var node in inputGraph.graph.Vertices) { if (node.ParentsNodes.Count >= 2) { IValue phiLabel = new IdentificatorValue("phi" + phiCounter); var newAssign = new LinearRepresentation(Operation.Assign, variable , phiLabel, null); node.Value.AppendFirst(newAssign); foreach (var parentNode in node.ParentsNodes) { var phiFunc = new LinearRepresentation(Operation.Phi, phiLabel as StringValue , variable, parentNode.Value.Enumerate().Last().Label); node.Value.InsertAfter(newAssign, phiFunc); } phiCounter++; } } } return(ssaGraph); }
private void GenName(IdentificatorValue v) { if (variableStacks[v] == null) { variableStacks[v] = new Stack <int>(); } var i = counters[v]; variableStacks[v].Push(i); counters[v] = i + 1; }
public void VisitBinOp(BinOp n) { var result = new LinearRepresentation(operatorToOperation(n.Op)); n.Lhs.AcceptVisit(this); result.LeftOperand = idOrNum; n.Rhs.AcceptVisit(this); result.RightOperand = idOrNum; var identificator = new IdentificatorValue(CONSTANT_PREFIX + valueCounter++.ToString()); idOrNum = identificator; result.Destination = identificator; evaluatedExpression.Add(result); }
private bool isPhi(IdentificatorValue ident) { return(ident != null && ident.Value.Count() >= 3 && ident.Value.Substring(0, 3) == "phi"); }
private void Rename(CFGNode currentNode) { //Если уже посетили этот блок, выходим if (visitedNodes.Contains(currentNode)) { return; } foreach (var str in currentNode.Value.Enumerate()) { //Если встретили фи-функцию, переименовываем ее левую часть if (Utilities.IsPhiAssignment(str)) { IdentificatorValue curVar = str.Destination as IdentificatorValue; GenName(curVar); int varCounter = variableStacks[curVar].Peek(); str.Destination = new IdentificatorValue(str.Destination.Value + varCounter.ToString()); } //Переименовываем use переменные в правой части присваиваний if (!Utilities.IsPhiIdentificator(str.LeftOperand as IdentificatorValue) && str.Operation != Operation.Phi) { if (str.RightOperand is IdentificatorValue) { IdentificatorValue curVar = str.RightOperand as IdentificatorValue; int varCounter = variableStacks[curVar].Peek(); str.RightOperand = new IdentificatorValue(str.RightOperand.Value + varCounter.ToString()); } if (str.LeftOperand is IdentificatorValue) { IdentificatorValue curVar = str.LeftOperand as IdentificatorValue; int varCounter = variableStacks[curVar].Peek(); str.LeftOperand = new IdentificatorValue(str.LeftOperand.Value + varCounter.ToString()); } if (str.Destination is IdentificatorValue) { IdentificatorValue curVar = str.Destination as IdentificatorValue; GenName(curVar); int varCounter = variableStacks[curVar].Peek(); str.Destination = new IdentificatorValue(str.Destination.Value + varCounter.ToString()); } } } var children = new List <CFGNode>() { currentNode.directChild, currentNode.gotoNode }; foreach (var child in children) { if (child == null) { continue; } foreach (var s in child.Value.Enumerate()) { //Если встретили фи-функцию, переименовываем ее левую часть if (Utilities.IsPhiAssignment(s)) { //Ищем строку соответствующей фи-функции и переименовываем переменную в ее левой части foreach (var line in child.Value.Enumerate() .Select(str => str).Where(str => str.Operation == Operation.Phi && str.Destination == s.LeftOperand)) { if (line.RightOperand == currentNode.Value.Enumerate().Last().Label) { IdentificatorValue curVar = line.LeftOperand as IdentificatorValue; int varCounter = variableStacks[curVar].Peek(); line.LeftOperand = new IdentificatorValue(line.LeftOperand.Value + varCounter.ToString()); } } } } } if (!visitedNodes.Contains(currentNode)) { visitedNodes.Add(currentNode); } foreach (var child in children) { if (child != null) { Rename(child); } } //Очищаем стек от переменных данного блока foreach (var str in currentNode.Value.Enumerate()) { if (str.LeftOperand is IdentificatorValue) { IdentificatorValue curVar = str.LeftOperand as IdentificatorValue; if (variableStacks.Keys.Contains(curVar)) { variableStacks[curVar].Pop(); } } } }
public static bool IsPhiIdentificator(IdentificatorValue ident) { return(ident != null && ident.Value.Count() >= 3 && ident.Value.Substring(0, 3) == "phi"); }