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