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