private void Propagate(CFGNode node, PathEdges pathEdge, LinkedList <CFGNode> workList) { PathEdges nodePaths; m_PathEdges.TryGetValue(node, out nodePaths); if (pathEdge != null) { List <PathEdgesPartition> newPaths = pathEdge.PathEdgesByLength; int index = 0; bool updated = false; while (index < newPaths.Count) { if (nodePaths.AddPathEdge(newPaths[index], m_BddManager)) { updated = true; newPaths[index].PathEdges.UnfreeBdd(); } index++; } if (updated) { workList.AddLast(node); } } }
private PathEdges Join(PathEdges pathEdge, Bdd TransitionBdd, Variables localVariables) { PathEdges tempPathEdge = new PathEdges(); List <PathEdgesPartition> Partitions = pathEdge.PathEdgesByLength; foreach (PathEdgesPartition part in Partitions) { Bdd tempBdd = Join(part.PathEdges, TransitionBdd, localVariables); tempPathEdge.AddPathEdge(new PathEdgesPartition(part.Length + 1, tempBdd), m_BddManager); // tempBdd.FreeBdd(); } return(tempPathEdge); }
private PathEdges SelfLoop(PathEdges pathEdge, Variables localVariables1, Variables localVariables2) { List <PathEdgesPartition> Partitions = pathEdge.PathEdgesByLength; PathEdges tempPathEdge = new PathEdges(); //Bdd tempBdd; foreach (PathEdgesPartition part in Partitions) { //tempBdd = part.PathEdges; //part.PathEdges = SelfLoop(tempBdd, localVariables1, localVariables2); //tempBdd.FreeBdd(); tempPathEdge.AddPathEdge(new PathEdgesPartition(part.Length, SelfLoop(part.PathEdges, localVariables1, localVariables2)), m_BddManager); } //return pathEdge; return(tempPathEdge); }
public void Reachable(debugPrintDelegate debugPrint) { if (ProgramCFG.CfgNodes.Count <= 1) { debugPrint("Invalid Program, unable to proceed!\n"); return; } m_PathEdges.Clear(); m_SummaryEdges.Clear(); BuildTransferFunctions(); LinkedList <CFGNode> workList = new LinkedList <CFGNode>(); CFGNodeProcedure tempNodeProc; CFGNode tempNode; Bdd bddLift, bddSummaryEdges, bddNew; PathEdges bddSelfLoop, bddJoin, bddPathEdges; Bdd [] array = new Bdd[3]; foreach (CFGNode node in ProgramCFG.CfgNodes) { m_PathEdges.Add(node, new PathEdges()); m_SummaryEdges.Add(node, m_BddManager.CreateBddZero()); } ProgramCFG.ProcedureNameToNode().TryGetValue("main", out tempNodeProc); workList.AddFirst(tempNodeProc.FirstStmtOf); m_PathEdges.Remove(tempNodeProc.FirstStmtOf); PathEdges firstMain = new PathEdges(); firstMain.AddPathEdge(new PathEdgesPartition(0, HelperFunctions.BuildIdentityTransfer (m_BddManager, tempNodeProc.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId)), m_BddManager); m_PathEdges.Add(tempNodeProc.FirstStmtOf, firstMain); #region Debug part of the reachability algorithm /* * ///////Debug //////////// * Dictionary<string, int>.ValueCollection valCollection = tempNodeProc.LocalVariables.VariablesToId.Values; * foreach (int id in valCollection) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalXnor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalOr(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * array[0] = tempBdd; * tempBdd = m_BddManager.CreateBddOne(); * * foreach (int id in valCollection) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalAnd(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalNor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * * foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) * { * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalImplies(tempBdd, m_BddManager.GetBddVariableWithID(id)); * tempBdd1.FreeBdd(); * tempBdd1 = tempBdd; * tempBdd = m_BddManager.LogicalXor(tempBdd, m_BddManager.GetBddVariableWithID(id + 2)); * tempBdd1.FreeBdd(); * } * array[1] = tempBdd; * * //array[2] = Join(array[0], array[1], tempNodeProc.LocalVariables); * array[2] = SelfLoop(array[1], tempNodeProc.LocalVariables, tempNodeProc.LocalVariables); * m_BddManager.ForceGarbageCollection(); * return array; * //////////////////////// */ #endregion while (workList.Count != 0) { tempNode = workList.First.Value; debugPrint("Processing Node: " + tempNode.ToString() + ".\n"); workList.RemoveFirst(); if (tempNode is CFGNodeStmtProcCall) { CFGNodeStmtProcCall procCall = tempNode as CFGNodeStmtProcCall; m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, procCall.Transfer, procCall.ProcOf.LocalVariables); bddSelfLoop = SelfLoop(bddJoin, procCall.ProcOf.LocalVariables, (procCall.Succesor as CFGNodeStatement).ProcOf.LocalVariables); Propagate(procCall.Succesor, bddSelfLoop, workList); bddJoin.FreeAllBdd(); bddSelfLoop.FreeAllBdd(); m_PathEdges.TryGetValue(tempNode, out bddPathEdges); m_SummaryEdges.TryGetValue(tempNode, out bddSummaryEdges); if (bddSummaryEdges != null) { bddJoin = Join(bddPathEdges, bddSummaryEdges, procCall.ProcOf.LocalVariables); Propagate(procCall.ReturnPoint, bddJoin, workList); bddJoin.FreeAllBdd(); } } else if (tempNode is CFGNodeProcedure) { foreach (CFGNodeStmtSkip node in (tempNode as CFGNodeProcedure).Succesor) { bddLift = Lift(node.previousProcCall, tempNode as CFGNodeProcedure); m_SummaryEdges.TryGetValue(node.previousProcCall, out bddSummaryEdges); m_PathEdges.TryGetValue(node.previousProcCall, out bddPathEdges); if (bddSummaryEdges != null) { bddNew = m_BddManager.LogicalOr(bddLift, bddSummaryEdges); bddLift.FreeBdd(); } else { bddNew = bddLift; } if (bddSummaryEdges != bddNew) { m_SummaryEdges.Remove(node.previousProcCall); m_SummaryEdges.Add(node.previousProcCall, bddNew); bddSummaryEdges.FreeBdd(); bddJoin = Join(bddPathEdges, bddNew, (node as CFGNodeStmtSkip).previousProcCall.ProcOf.LocalVariables); Propagate(node, bddJoin, workList); bddJoin.FreeAllBdd(); } } } else if (tempNode is CFGNodeStmtConditional) { CFGNodeStmtConditional tempNode1 = tempNode as CFGNodeStmtConditional; m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, tempNode1.TransferTrue, tempNode1.ProcOf.LocalVariables); Propagate(tempNode1.TrueSuccesor, bddJoin, workList); bddJoin.FreeAllBdd(); m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, tempNode1.TransferFalse, tempNode1.ProcOf.LocalVariables); Propagate(tempNode1.FalseSuccesor, bddJoin, workList); bddJoin.FreeAllBdd(); } else { if (!(tempNode is CFGNodeError)) { m_PathEdges.TryGetValue(tempNode, out bddPathEdges); bddJoin = Join(bddPathEdges, (tempNode as CFGNodeStatement).Transfer, (tempNode as CFGNodeStatement).ProcOf.LocalVariables); Propagate(tempNode.Succesor, bddJoin, workList); bddJoin.FreeAllBdd(); } } } m_BddManager.ForceGarbageCollection(); }