private void BuildTransferFunctions() { foreach (CFGNode node in ProgramCFG.CfgNodes) { if (node is CFGNodeStatement) { if ((node is CFGNodeStmtSkip) || (node is CFGNodeStmtPrint) || (node is CFGNodeStmtGoto) || (node is CFGNodeStmtReturn)) { (node as CFGNodeStatement).Transfer = HelperFunctions.BuildIdentityTransfer(m_BddManager, (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId); } else if (node is CFGNodeStmtAssignment) { (node as CFGNodeStmtAssignment).Transfer = CFGNodeStmtAssignment.BuildAssignmentTransfer(node.GetAST(), m_BddManager, (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId); } else if (node is CFGNodeStmtConditional) { Bdd TransferTrue, TransferFalse; CommonAST decider = node.GetAST().getFirstChild() as CommonAST; HelperFunctions.BuildDeciderTransfers(decider, m_BddManager, (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId, out TransferTrue, out TransferFalse); (node as CFGNodeStmtConditional).TransferTrue = TransferTrue; (node as CFGNodeStmtConditional).TransferFalse = TransferFalse; } else if (node is CFGNodeStmtProcCall) { CFGNodeProcedure procedureCalled; if (!(ProgramCFG.ProcedureNameToNode().TryGetValue( node.GetAST().getFirstChild().getText(), out procedureCalled))) { System.Diagnostics.Debug.Assert(false); } (node as CFGNodeStmtProcCall).Transfer = CFGNodeStmtProcCall.buildProcCallTransfer(node.GetAST(), procedureCalled, m_BddManager, (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId); } } } }
public Trajectory BuildTrajectory(CFGNode node) { int len, i; Trajectory tempTrajectory = new Trajectory(); PathEdges paths, predecessorPaths; PathEdgesPartition pathPart; Bdd pathBdd = null; m_PathEdges.TryGetValue(node, out paths); if (paths.PathEdgesByLength.Count != 0) { pathPart = paths.PathEdgesByLength[0]; len = pathPart.Length; pathBdd = BuildRandomPath(pathPart.PathEdges); while (len > 0) { tempTrajectory.Add(new TrajectoryItem(node, pathBdd)); #region Node is not first statement of procedure if ((node is CFGNodeProcedure) || ((node is CFGNodeStatement) && (node as CFGNodeStatement).ProcOf.FirstStmtOf != node)) { Bdd tempPathEdges, reverseJoin, bddOK; if (((node is CFGNodeStmtSkip) && (node as CFGNodeStmtSkip).previousProcCall != null)) { CFGNodeStmtProcCall nodePredecessor = (node as CFGNodeStmtSkip).previousProcCall; Bdd[] bddArray = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 4 + ProgramCFG.GlobalVariables.Length * 4]; Bdd summaryEdges, summaryEdgesReverse; m_PathEdges.TryGetValue(nodePredecessor as CFGNode, out predecessorPaths); m_SummaryEdges.TryGetValue(nodePredecessor as CFGNode, out summaryEdges); tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1); if (tempPathEdges != null) { i = -1; foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id); } foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id); } summaryEdgesReverse = summaryEdges.Replace(bddArray); reverseJoin = Join(pathBdd, summaryEdgesReverse, nodePredecessor.ProcOf.LocalVariables); summaryEdgesReverse.FreeBdd(); bddOK = m_BddManager.LogicalAnd(reverseJoin, tempPathEdges); reverseJoin.FreeBdd(); pathBdd = BuildRandomPath(bddOK); bddOK.FreeBdd(); node = nodePredecessor as CFGNode; len--; } } else { foreach (CFGNode tempNode in node.Predecessor) { CFGNodeStatement nodePredecessor = tempNode as CFGNodeStatement; Bdd[] bddArray = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 4 + ProgramCFG.GlobalVariables.Length * 4]; Bdd transferReverse; m_PathEdges.TryGetValue(tempNode, out predecessorPaths); tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1); if (tempPathEdges != null) { i = -1; foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id); } foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id + 2); bddArray[++i] = m_BddManager.GetBddVariableWithID(id); } if (nodePredecessor is CFGNodeStmtConditional) { if ((nodePredecessor as CFGNodeStmtConditional).TrueSuccesor == node) { transferReverse = (nodePredecessor as CFGNodeStmtConditional).TransferTrue.Replace(bddArray); reverseJoin = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables); transferReverse.FreeBdd(); } else { transferReverse = (nodePredecessor as CFGNodeStmtConditional).TransferFalse.Replace(bddArray); reverseJoin = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables); transferReverse.FreeBdd(); } } else { transferReverse = nodePredecessor.Transfer.Replace(bddArray); reverseJoin = Join(pathBdd, transferReverse, nodePredecessor.ProcOf.LocalVariables); transferReverse.FreeBdd(); } bddOK = m_BddManager.LogicalAnd(reverseJoin, tempPathEdges); if (bddOK.ReturnBddType() != BddType.Zero) { pathBdd = BuildRandomPath(bddOK); bddOK.FreeBdd(); node = tempNode; len--; break; } else { bddOK.FreeBdd(); } } } } } #endregion #region Node is first statement of procedure else { Bdd[] bddArray = new Bdd[(node as CFGNodeStatement).ProcOf.LocalVariables.Length + ProgramCFG.GlobalVariables.Length]; Bdd[] bddArrayForTransfer = new Bdd[(node as CFGNodeStatement).ProcOf.LocalVariables.Length + ProgramCFG.GlobalVariables.Length]; Bdd bddExist, tempPathEdges, bddAndWithTransfer, bddAndWithProcCall, bddExistTransfer, bddReplaceTransfer; i = -1; foreach (int id in (node as CFGNodeStatement).ProcOf.LocalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArrayForTransfer[i] = m_BddManager.GetBddVariableWithID(id + 2); } foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) { bddArray[++i] = m_BddManager.GetBddVariableWithID(id); bddArrayForTransfer[i] = m_BddManager.GetBddVariableWithID(id + 2); } bddExist = pathBdd.Exists(bddArray); foreach (CFGNodeStmtProcCall nodePredecessor in node.Predecessor) { m_PathEdges.TryGetValue(nodePredecessor, out predecessorPaths); tempPathEdges = predecessorPaths.GetPathEdgesOfLength(len - 1); Bdd[] bddArrayReplace = new Bdd[nodePredecessor.ProcOf.LocalVariables.Length * 2 + ProgramCFG.GlobalVariables.Length * 2]; if (tempPathEdges != null) { bddAndWithTransfer = m_BddManager.LogicalAnd(nodePredecessor.Transfer, bddExist); bddExistTransfer = bddAndWithTransfer.Exists(bddArrayForTransfer); bddAndWithTransfer.FreeBdd(); i = -1; foreach (int id in nodePredecessor.ProcOf.LocalVariables.VariablesToId.Values) { bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id); bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id + 2); } foreach (int id in ProgramCFG.GlobalVariables.VariablesToId.Values) { bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id); bddArrayReplace[++i] = m_BddManager.GetBddVariableWithID(id + 2); } bddReplaceTransfer = bddExistTransfer.Replace(bddArrayReplace); bddExistTransfer.FreeBdd(); bddAndWithProcCall = m_BddManager.LogicalAnd(bddReplaceTransfer, tempPathEdges); bddReplaceTransfer.FreeBdd(); if (bddAndWithProcCall.GetBddRootVariable().ReturnBddType() != BddType.Zero) { pathBdd = BuildRandomPath(bddAndWithProcCall); bddAndWithProcCall.FreeBdd(); node = nodePredecessor as CFGNode; len--; break; } else { bddAndWithProcCall.FreeBdd(); } } } } #endregion } } tempTrajectory.Add(new TrajectoryItem(node, pathBdd)); tempTrajectory.TrajectoryList.Reverse(); return(tempTrajectory); }
private Bdd Lift(CFGNodeStmtProcCall procCallNode, CFGNodeProcedure exitNode) { int i = 0; int id; Bdd[] bddArrayFormalsNot = new Bdd[2 * exitNode.LocalVariables.Length - exitNode.FormalParameters.Length]; //Bdd[] bddArrayFormals = new Bdd[2 * exitNode.FormalParameters.Length]; Bdd[] bddArrayForSubstitution = new Bdd[2 * exitNode.FormalParameters.Length]; Bdd tempBdd, tempBddAnd, tempBddXnor, tempBddReplace; Bdd var, exp, identity; CommonAST walkerVar = exitNode.GetAST().getFirstChild() as CommonAST; CommonAST walkerExp = procCallNode.GetAST().getFirstChild().getFirstChild() as CommonAST; foreach (string varName in exitNode.LocalVariables.VariablesToId.Keys) { exitNode.LocalVariables.VariablesToId.TryGetValue(varName, out id); if (exitNode.FormalParameters.VariablesToId.ContainsKey(varName) == false) { bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id); bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id + 2); } else { bddArrayFormalsNot[i++] = m_BddManager.GetBddVariableWithID(id + 2); } } PathEdges tempPath; m_PathEdges.TryGetValue(exitNode, out tempPath); tempBdd = tempPath.GetJointPaths(m_BddManager); tempBdd = tempBdd.Exists(bddArrayFormalsNot); i = 0; while (walkerVar.Type == BoolParserTokenTypes.ID) { exitNode.LocalVariables.VariablesToId.TryGetValue(walkerVar.getText(), out id); exp = HelperFunctions.ExprToBdd(walkerExp, m_BddManager, procCallNode.ProcOf.LocalVariables.VariablesToId, ProgramCFG.GlobalVariables.VariablesToId); var = m_BddManager.GetBddVariableWithID(id); bddArrayForSubstitution[i++] = var; bddArrayForSubstitution[i++] = exp; /* * tempBddXnor = m_BddManager.LogicalXnor(exp, var); * tempBddAnd = m_BddManager.LogicalAnd(tempBddXnor, tempBdd); * * tempBdd.FreeBdd(); * exp.FreeBdd(); * tempBdd = tempBddAnd; */ walkerExp = walkerExp.getNextSibling() as CommonAST; walkerVar = walkerVar.getNextSibling() as CommonAST; } i = 0; /* * foreach (int bddId in exitNode.FormalParameters.VariablesToId.Values) * { * bddArrayFormals[i++] = m_BddManager.GetBddVariableWithID(bddId); * bddArrayFormals[i++] = m_BddManager.GetBddVariableWithID(bddId + 2); * }*/ tempBddReplace = tempBdd.Replace(bddArrayForSubstitution); tempBdd.FreeBdd(); tempBdd = tempBddReplace; identity = HelperFunctions.BuildIdentityTransfer(m_BddManager, procCallNode.ProcOf.LocalVariables.VariablesToId, null); tempBddAnd = m_BddManager.LogicalAnd(tempBdd, identity); tempBdd.FreeBdd(); identity.FreeBdd(); tempBdd = tempBddAnd; return(tempBdd); }
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(); }