Пример #1
0
int CFAnalyzer::reduceBlockBeginNodes(Flow& flow) {
  LabelSet labs=flow.nodeLabels();
  int cnt=0;
  for(LabelSet::iterator i=labs.begin();i!=labs.end();++i) {
	if(isSgBasicBlock(getNode(*i))) {
	  cnt++;
	  Flow inFlow=flow.inEdges(*i);
	  Flow outFlow=flow.outEdges(*i);

	  // multiple out-edges not supported yet
	  assert(outFlow.size()<=1); 

	  /* description of essential operations:
	   *   inedges: (n_i,b)
	   *   outedge: (b,n2) 
	   *   remove(n_i,b)
	   *   remove(b,n2)
	   *   insert(n1,n2)
	   */
	  for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
		Edge e1=*initer;
		Edge e2=*outFlow.begin();
		Edge newEdge=Edge(e1.source,e1.types(),e2.target);
		flow.erase(e1);
		flow.erase(e2);
		flow.insert(newEdge);
	  }
	}
  }
  return cnt;
}
Пример #2
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0)
    return 0;

  if(inFlow.size()==0 || outFlow.size()==0) {
    Flow edges=inFlow+outFlow;
    flow.deleteEdges(edges);
    return 1;
  }

  for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e1=*initer;
      Edge e2=*outiter;
      Edge newEdge=Edge(e1.source,e1.types(),e2.target);
      flow.erase(e1);
      flow.erase(e2);
      flow.insert(newEdge);
    }
  }
  return 1;
}
string PromelaCodeGenerator::generateCode(Flow& automaton, int id, EdgeAnnotationMap edgeAnnotationMap, 
					  bool useTransitionIds, boost::unordered_map<string, int>& transitionIdMap) {
  stringstream ss;
  ss << "/* Process "<<id<<" */" << endl;
  ss << "active proctype Proc"<<id<<"()" << endl;
  ss << "{" << endl;
  ss << "  int state = "<<automaton.getStartLabel().getId()<<";" << endl;
  ss << "  do" << endl;

  set<Label> visited; //TODO: maybe change to hashset
  list<Label> worklist;
  worklist.push_back(automaton.getStartLabel());
  visited.insert(automaton.getStartLabel());
  while (!worklist.empty()) {
    Label label = worklist.front();
    worklist.pop_front();
    ss << "  :: state == "<<label.getId()<<" ->" << endl;
    ss << "    atomic {" << endl;
    ss << "      if" << endl;
    Flow outEdges = automaton.outEdges(label);
    for (Flow::iterator i=outEdges.begin(); i!= outEdges.end(); ++i) {
      ss << "      :: "<<communicationDetails((*i).getAnnotation(), id, edgeAnnotationMap, useTransitionIds, transitionIdMap) << endl;
      ss << "        state = "<<(*i).target().getId()<<";" << endl;
      if (visited.find((*i).target()) == visited.end()) {
	worklist.push_back((*i).target());
        visited.insert((*i).target());
      }
    }
    ss << "      fi" << endl;
    ss << "    }" << endl;
  }

  ss << "  od" << endl;
  ss << "}" << endl;
  return ss.str();
}
Пример #4
0
int CFAnalysis::reduceBlockBeginNodes(Flow& flow) {
  LabelSet labs=flow.nodeLabels();
  int cnt=0;
  for(LabelSet::iterator i=labs.begin();i!=labs.end();++i) {
    //cout<<"Checking label: "<<(*i)<<" node: "<<getNode(*i)<<" code:"<<getNode(*i)->unparseToString()<<endl;
    if(isSgBasicBlock(getNode(*i))) {
#if 1
      cnt+=reduceNode(flow,*i);
#else
      cnt++;
      Flow inFlow=flow.inEdges(*i);
      Flow outFlow=flow.outEdges(*i);

      // multiple out-edges not supported yet
      assert(outFlow.size()<=1); 

      /* description of essential operations:
       *   inedges: (n_i,b)
       *   outedge: (b,n2) 
       *   remove(n_i,b)
       *   remove(b,n2)
       *   insert(n1,n2)
       */
      for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
        Edge e1=*initer;
        Edge e2=*outFlow.begin();
        Edge newEdge=Edge(e1.source,e1.types(),e2.target);
        flow.erase(e1);
        flow.erase(e2);
        flow.insert(newEdge);
      }
#endif
    }
  }
  return cnt;
}
Пример #5
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove forward (we are not removing the cycle)
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    set<Edge> toErase;
    set<Edge> toInsert;
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        EdgeTypeSet unionEdgeTypeSet;
        EdgeTypeSet edgeTypeSet1=(*initer).types();
        unionEdgeTypeSet.insert(edgeTypeSet1.begin(),edgeTypeSet1.end());
        EdgeTypeSet edgeTypeSet2=(*outiter).types();
        // only copy an edge annotation in the outgoing edge if it is
        // not a true-annotation or a false-annotation
        for(EdgeTypeSet::iterator i=edgeTypeSet2.begin();i!=edgeTypeSet2.end();++i) {
          if(*i!=EDGE_TRUE && *i!=EDGE_FALSE) {
            unionEdgeTypeSet.insert(*i);
          }
        }
        if(unionEdgeTypeSet.find(EDGE_TRUE)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_FALSE)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_TRUE);
          unionEdgeTypeSet.erase(EDGE_FALSE);
        }
        if(unionEdgeTypeSet.find(EDGE_FORWARD)!=unionEdgeTypeSet.end()
           && unionEdgeTypeSet.find(EDGE_BACKWARD)!=unionEdgeTypeSet.end()) {
          unionEdgeTypeSet.erase(EDGE_FORWARD);
          // keep backward edge annotation
        }
        
        Edge newEdge=Edge(e1.source(),unionEdgeTypeSet,e2.target());
        toErase.insert(e1);
        toErase.insert(e2);
        if(e1.source()!=e2.target()) {
          toInsert.insert(newEdge);
        }
      }
    }
    for(set<Edge>::iterator i=toErase.begin();i!=toErase.end();++i) {
      flow.erase(*i);
    }
    for(set<Edge>::iterator i=toInsert.begin();i!=toInsert.end();++i) {
      flow.insert(*i);
    }
    return 1;
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}
Пример #6
0
int CFAnalysis::reduceNode(Flow& flow, Label lab) {
  Flow inFlow=flow.inEdges(lab);
  Flow outFlow=flow.outEdges(lab);
  EdgeTypeSet unionEdgeTypeSets;
  for(Flow::iterator i=inFlow.begin();i!=inFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  for(Flow::iterator i=outFlow.begin();i!=outFlow.end();++i) {
    EdgeTypeSet edgeTypeSet=(*i).types();
    unionEdgeTypeSets.insert(edgeTypeSet.begin(),edgeTypeSet.end());
  }
  // edge type cleanup
  // if true and false edge exist, remove both (merging true and false branches to a single branch)
  // if forward and backward exist, remove backward (we are removing a cycle)
  if(unionEdgeTypeSets.find(EDGE_TRUE)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_FALSE)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_TRUE);
    unionEdgeTypeSets.erase(EDGE_FALSE);
  }
  if(unionEdgeTypeSets.find(EDGE_FORWARD)!=unionEdgeTypeSets.end()
     && unionEdgeTypeSets.find(EDGE_BACKWARD)!=unionEdgeTypeSets.end()) {
    unionEdgeTypeSets.erase(EDGE_FORWARD);
    unionEdgeTypeSets.erase(EDGE_BACKWARD);
  }
  
  /* description of essential operations:
   *   inedges: (n_i,b)
   *   outedge: (b,n2) 
   *   remove(n_i,b)
   *   remove(b,n2)
   *   insert(n1,n2)
   */
  if(inFlow.size()==0 && outFlow.size()==0) {
    return 0;
  } else if(inFlow.size()>0 && outFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
        Edge e1=*initer;
        Edge e2=*outiter;
        // preserve edge annotations of ingoing and outgoing edges
        Edge newEdge=Edge(e1.source,unionEdgeTypeSets,e2.target);
        flow.erase(e1);
        flow.erase(e2);
        flow.insert(newEdge);
      }
      return 1;
    }
  } else if(inFlow.size()>0) {
    for(Flow::iterator initer=inFlow.begin();initer!=inFlow.end();++initer) {
      Edge e1=*initer;
      flow.erase(e1);
    }
    return 1;
  } else if(outFlow.size()>0) {
    for(Flow::iterator outiter=outFlow.begin();outiter!=outFlow.end();++outiter) {
      Edge e2=*outiter;
      flow.erase(e2);
    }
    return 1;
  }
  return 0;
}