private Func <int, Node> GetLocalMapper(ResolvedMethod <Node> method) { var localToGlobalIndicesMap = new Dictionary <int, Node>(); Node Map(int local) { var exists = localToGlobalIndicesMap.TryGetValue(local, out var global); if (!exists) { global = myProgram.CreateNode(); method.AddOwnedNode(global); localToGlobalIndicesMap.Add(local, global); } return(global); } return(Map); }
public void Transform( INodeBasedProgram <int> sourceMethod, GraphStructuredProgram <TNode> targetProgram, ResolvedMethod <TNode> targetMethod, Func <int, TNode> mapper) { int counter = -1; TNode CreateNewNode() { var newNode = mapper(counter--); targetMethod.AddOwnedNode(newNode); return(newNode); } var visited = new HashSet <int>(); var localStarts = sourceMethod.GetStarts(); var queued = new Stack <(TNode source, int target)>(); foreach (var localStart in localStarts) { queued.Push((targetMethod.Start, localStart)); } if (queued.Count == 0) { targetProgram.AddOperation(targetMethod.Start, new Operation <TNode>(myNop, targetMethod.Final)); } while (queued.Count > 0) { var(source, rawTarget) = queued.Pop(); var statement = sourceMethod.StatementAt(rawTarget); var target = mapper(rawTarget); InternalStep(targetProgram, targetMethod, source, statement, target, CreateNewNode); if (visited.Contains(rawTarget)) { continue; } if (sourceMethod.IsFinal(rawTarget)) { targetProgram.AddOperation(target, new Operation <TNode>(myReturn, targetMethod.Final)); } else { var transitions = sourceMethod.Transitions(rawTarget).ToList(); foreach (var transition in transitions) { queued.Push((target, transition)); } } visited.Add(rawTarget); } }