bool IsReachable(ControlFlowNode *head, ControlFlowNode *tail) { if (head == tail) { return true; } NodeSet visited; visited.insert(tail); stack<ControlFlowNode*> toProcess; toProcess.push(tail); while (!toProcess.empty()) { ControlFlowNode *node = toProcess.top(); toProcess.pop(); for (ControlFlowNode *pred : node->Predecessors()) { if (pred == head) { return true; } if (!visited.contains(pred)) { visited.insert(pred); toProcess.push(pred); } } } return false; }
// ----------------------------------------------------------------------------- Graph *SpanningTree::create_spanning_tree(Graph* g, Node* root) { if(root == NULL) throw std::runtime_error("create_spanning_tree NULL exception"); Graph *t = new Graph(FLAG_DAG); NodeSet visited; NodeStack node_stack; node_stack.push(root); while(!node_stack.empty()) { Node* n = node_stack.top(); node_stack.pop(); visited.insert(n); Node* tree_node1 = t->add_node_ptr(n->_value); EdgePtrIterator* eit = n->get_edges(); Edge* e; while((e = eit->next()) != NULL) { Node* inner_node = e->traverse(n); if(inner_node != NULL && visited.count(inner_node) == 0) { Node* tree_node2 = t->add_node_ptr(inner_node->_value); t->add_edge(tree_node1, tree_node2, e->weight, e->label); node_stack.push(inner_node); visited.insert(inner_node); } } delete eit; } return t; }
NodeSet* getLeftNeighbours(NodeSet &scanline,Node *v) { NodeSet *leftv = new NodeSet; NodeSet::iterator i=scanline.find(v); while(i--!=scanline.begin()) { Node *u=*(i); if(u->r->overlapX(v->r)<=0) { leftv->insert(u); return leftv; } if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) { leftv->insert(u); } } return leftv; }
NodeSet* getRightNeighbours(NodeSet &scanline,Node *v) { NodeSet *rightv = new NodeSet; NodeSet::iterator i=scanline.find(v); for(++i;i!=scanline.end(); ++i) { Node *u=*(i); if(u->r->overlapX(v->r)<=0) { rightv->insert(u); return rightv; } if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) { rightv->insert(u); } } return rightv; }
// Returns the set of all nodes between tail and head, assuming // head and tail form a single entry and exit point. // Possible is there just for debugging. There should be no nodes outside possible NodeSet CollectNodesBetween(ControlFlowNode *head, ControlFlowNode *tail, NodeSet possible) { NodeSet collection; stack<ControlFlowNode*> toProcess; toProcess.push(tail); while (!toProcess.empty()) { ControlFlowNode *node = toProcess.top(); toProcess.pop(); collection.insert(node); if (node != head) { for (ControlFlowNode *pred : node->Predecessors()) { if (!collection.contains(pred)) // Haven't already visited it { assert(possible.contains(pred));// We could just filter these, but let's assert for now to catch bad callers. toProcess.push(pred); } } } } return collection; }
void LazyConstraintCallback::separateConnectedComponents( Graph const & g , GraphVariables const & vars , Graph::Node const & root , NodeSetVector const & nonZeroNodesComponents , int & nCuts ) { IloExpr rhs( getEnv() ); for ( const NodeSet& S : nonZeroNodesComponents ) { // only consider the non-zero components that don't contain the root auto it = S.find( root ); if ( it == S.end() || it->componentIndex() != root.componentIndex() ) { // determine dS NodeSet dS; for ( Graph::Node i : S ) { for ( Graph::Edge e : g.incEdges( i ) ) { Graph::Node j = g.oppositeNode( i, e ); if ( S.find( j ) == S.end() ) { dS.insert( j ); } } } constructRHS( vars, dS, S, rhs ); for ( Graph::Node i : S ) { assert( isValid( g, i, dS, S ) ); add( vars.xVars[vars.nodeToIndex[i]] <= rhs, IloCplex::UseCutPurge ).end(); ++nCuts; } } } rhs.end(); }
void State::functionGreaterEqual(const string& a_name, int a_value) { NodeSet* parentSet = getVariableNodes(a_name); if (parentSet == NULL) { error("State::functionGreaterEqual - variable " + a_name + " doesn't exist" , false); return; } NodeSet removedRoots; for (NodeSetConstIter iter = parentSet->begin(); iter != parentSet->end(); iter++) { if ((*iter) == NULL) { error("State::functionGreaterEqual - iterator for variable " + a_name + " is NULL", false); continue; } if ((*iter)->getMaxValue() < a_value) { debug("State::functionGreaterEqual - Adding " + a_name + "'s root to removedRoots set"); removedRoots.insert((*iter)->getRoot()); continue; } if ((*iter)->getMinValue() < a_value) { (*iter)->setMinValue(a_value); } } debug("State::functionGreaterEqual - removing trees"); removeTrees(removedRoots); }
bool Callback::isValid( Graph const & g , Graph::Node const & i , NodeSet const & dS , NodeSet const & S) const { if ( S.find( i ) == S.end() ) { // i must be in S return false; } if ( dS.find( i ) != dS.end() ) { // i must not be in dS return false; } // determine dS again NodeSet ddS; for ( Graph::Node i : S ) { for ( Graph::Edge e : g.incEdges( i) ) { Graph::Node j = g.oppositeNode( i, e ); if ( S.find( j ) == S.end() ) { ddS.insert( j ); } } } return dS == ddS; }
Item::Ptr UTransform::TransformResult::next(DynamicContext *context) { context->testInterrupt(); AutoVariableStoreReset reset(context, &scope_); if(toDo_) { toDo_ = false; NodeSet copiedNodes = NodeSet(nodecompare(context)); VectorOfCopyBinding::const_iterator end = transform_->getBindings()->end(); for(VectorOfCopyBinding::const_iterator it = transform_->getBindings()->begin(); it != end; ++it) { if((*it)->qname_ == 0) continue; Sequence values = (*it)->expr_->createResult(context)->toSequence(context); // Keep a record of the nodes that have been copied Result valIt = values; Item::Ptr val; while((val = valIt->next(context)).notNull()) { copiedNodes.insert((Node*)val.get()); } scope_.setVar((*it)->uri_, (*it)->name_, values); } // Get the pending update list PendingUpdateList pul = transform_->getModifyExpr()->createUpdateList(context); // Check that the targets of the pending updates are copied nodes for(PendingUpdateList::const_iterator i = pul.begin(); i != pul.end(); ++i) { Node::Ptr target = i->getTarget(); while(copiedNodes.find(target) == copiedNodes.end()) { target = target->dmParent(context); if(target.isNull()) { XQThrow3(StaticErrorException,X("UTransform::staticTyping"), X("The target node of an update expression in the transform expression is not a node from the copy clauses [err:XUDY0014]"), &(*i)); } } } // Apply the updates AutoDelete<UpdateFactory> ufactory(context->createUpdateFactory()); ufactory->applyUpdates(pul, context, transform_->getRevalidationMode()); // Execute the return expression result_ = transform_->getReturnExpr()->createResult(context); } Item::Ptr result = result_->next(context); if(result.isNull()) { result_ = 0; return 0; } return result; }
void ActionChoiceWindow::ActionNode::getAllNodes(ActionNode* treeRoot, NodeSet& nodes) { nodes.insert(treeRoot); const NodeSet children = treeRoot->getChildren(); for (NodeSet::const_iterator iter = children.begin(); iter != children.end(); iter++) getAllNodes(*iter, nodes); }
static void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM, NodeSet &Nodes) { NodeVect Work; Work.push_back(Root); Nodes.insert(Root); while (!Work.empty()) { NodeVect::iterator First = Work.begin(); GepNode *N = *First; Work.erase(First); NodeChildrenMap::iterator CF = NCM.find(N); if (CF != NCM.end()) { Work.insert(Work.end(), CF->second.begin(), CF->second.end()); Nodes.insert(CF->second.begin(), CF->second.end()); } } }
NodeSet Liveness::getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs) { NodeSet Uses; // If the original register is already covered by all the intervening // defs, no more uses can be reached. if (DefRRs.hasCoverOf(RefRR)) return Uses; // Add all directly reached uses. // If the def is dead, it does not provide a value for any use. bool IsDead = DefA.Addr->getFlags() & NodeAttrs::Dead; NodeId U = !IsDead ? DefA.Addr->getReachedUse() : 0; while (U != 0) { auto UA = DFG.addr<UseNode*>(U); if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) { RegisterRef UR = UA.Addr->getRegRef(DFG); if (PRI.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR)) Uses.insert(U); } U = UA.Addr->getSibling(); } // Traverse all reached defs. This time dead defs cannot be ignored. for (NodeId D = DefA.Addr->getReachedDef(), NextD; D != 0; D = NextD) { auto DA = DFG.addr<DefNode*>(D); NextD = DA.Addr->getSibling(); RegisterRef DR = DA.Addr->getRegRef(DFG); // If this def is already covered, it cannot reach anything new. // Similarly, skip it if it is not aliased to the interesting register. if (DefRRs.hasCoverOf(DR) || !PRI.alias(RefRR, DR)) continue; NodeSet T; if (DFG.IsPreservingDef(DA)) { // If it is a preserving def, do not update the set of intervening defs. T = getAllReachedUses(RefRR, DA, DefRRs); } else { RegisterAggr NewDefRRs = DefRRs; NewDefRRs.insert(DR); T = getAllReachedUses(RefRR, DA, NewDefRRs); } Uses.insert(T.begin(), T.end()); } return Uses; }
std::pair<NodeSet,bool> Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs, unsigned Nest, unsigned MaxNest) { if (Nest > MaxNest) return { NodeSet(), false }; // Collect all defined registers. Do not consider phis to be defining // anything, only collect "real" definitions. RegisterAggr DefRRs(PRI); for (NodeId D : Defs) { const auto DA = DFG.addr<const DefNode*>(D); if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef)) DefRRs.insert(DA.Addr->getRegRef(DFG)); } NodeList RDs = getAllReachingDefs(RefRR, RefA, false, true, DefRRs); if (RDs.empty()) return { Defs, true }; // Make a copy of the preexisting definitions and add the newly found ones. NodeSet TmpDefs = Defs; for (NodeAddr<NodeBase*> R : RDs) TmpDefs.insert(R.Id); NodeSet Result = Defs; for (NodeAddr<DefNode*> DA : RDs) { Result.insert(DA.Id); if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef)) continue; NodeAddr<PhiNode*> PA = DA.Addr->getOwner(DFG); if (Visited.count(PA.Id)) continue; Visited.insert(PA.Id); // Go over all phi uses and get the reaching defs for each use. for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) { const auto &T = getAllReachingDefsRecImpl(RefRR, U, Visited, TmpDefs, Nest+1, MaxNest); if (!T.second) return { T.first, false }; Result.insert(T.first.begin(), T.first.end()); } } return { Result, true }; }
NodeSet Liveness::getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA, const RegisterSet &DefRRs) { NodeSet Uses; // If the original register is already covered by all the intervening // defs, no more uses can be reached. if (RAI.covers(DefRRs, RefRR, DFG)) return Uses; // Add all directly reached uses. NodeId U = DefA.Addr->getReachedUse(); while (U != 0) { auto UA = DFG.addr<UseNode*>(U); if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) { auto UR = UA.Addr->getRegRef(); if (RAI.alias(RefRR, UR, DFG) && !RAI.covers(DefRRs, UR, DFG)) Uses.insert(U); } U = UA.Addr->getSibling(); } // Traverse all reached defs. for (NodeId D = DefA.Addr->getReachedDef(), NextD; D != 0; D = NextD) { auto DA = DFG.addr<DefNode*>(D); NextD = DA.Addr->getSibling(); auto DR = DA.Addr->getRegRef(); // If this def is already covered, it cannot reach anything new. // Similarly, skip it if it is not aliased to the interesting register. if (RAI.covers(DefRRs, DR, DFG) || !RAI.alias(RefRR, DR, DFG)) continue; NodeSet T; if (DFG.IsPreservingDef(DA)) { // If it is a preserving def, do not update the set of intervening defs. T = getAllReachedUses(RefRR, DA, DefRRs); } else { RegisterSet NewDefRRs = DefRRs; NewDefRRs.insert(DR); T = getAllReachedUses(RefRR, DA, NewDefRRs); } Uses.insert(T.begin(), T.end()); } return Uses; }
uint64_t CVC4::theory::bv::utils::numNodes(TNode node, NodeSet& seen) { if (seen.find(node) != seen.end()) return 0; uint64_t size = 1; for (unsigned i = 0; i < node.getNumChildren(); ++i) { size += numNodes(node[i], seen); } seen.insert(node); return size; }
void CVC4::theory::bv::utils::collectVariables(TNode node, NodeSet& vars) { if (vars.find(node) != vars.end()) return; if (Theory::isLeafOf(node, THEORY_BV) && node.getKind() != kind::CONST_BITVECTOR) { vars.insert(node); return; } for (unsigned i = 0; i < node.getNumChildren(); ++i) { collectVariables(node[i], vars); } }
/** * Prepares constraints in order to apply VPSC vertically to remove ALL overlap. */ int generateYConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs) { events=new Event*[2*n]; int ctr=0,i,m; for(i=0;i<n;i++) { vars[i]->desiredPosition=rs[i]->getCentreY(); Node *v = new Node(vars[i],rs[i],rs[i]->getCentreY()); events[ctr++]=new Event(Open,v,rs[i]->getMinX()); events[ctr++]=new Event(Close,v,rs[i]->getMaxX()); } qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events ); NodeSet scanline; vector<Constraint*> constraints; for(i=0;i<2*n;i++) { Event *e=events[i]; Node *v=e->v; if(e->type==Open) { scanline.insert(v); NodeSet::iterator i=scanline.find(v); if(i--!=scanline.begin()) { Node *u=*i; v->firstAbove=u; u->firstBelow=v; } i=scanline.find(v); if(++i!=scanline.end()) { Node *u=*i; v->firstBelow=u; u->firstAbove=v; } } else { // Close event Node *l=v->firstAbove, *r=v->firstBelow; if(l!=NULL) { double sep = (v->r->height()+l->r->height())/2.0; constraints.push_back(new Constraint(l->v,v->v,sep)); l->firstBelow=v->firstBelow; } if(r!=NULL) { double sep = (v->r->height()+r->r->height())/2.0; constraints.push_back(new Constraint(v->v,r->v,sep)); r->firstAbove=v->firstAbove; } scanline.erase(v); delete v; } delete e; } delete [] events; cs=new Constraint*[m=constraints.size()]; for(i=0;i<m;i++) cs[i]=constraints[i]; return m; }
NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) { // Collect all defined registers. Do not consider phis to be defining // anything, only collect "real" definitions. RegisterSet DefRRs; for (const auto D : Defs) { const auto DA = DFG.addr<const DefNode*>(D); if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef)) DefRRs.insert(DA.Addr->getRegRef()); } auto RDs = getAllReachingDefs(RefRR, RefA, true, DefRRs); if (RDs.empty()) return Defs; // Make a copy of the preexisting definitions and add the newly found ones. NodeSet TmpDefs = Defs; for (auto R : RDs) TmpDefs.insert(R.Id); NodeSet Result = Defs; for (NodeAddr<DefNode*> DA : RDs) { Result.insert(DA.Id); if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef)) continue; NodeAddr<PhiNode*> PA = DA.Addr->getOwner(DFG); if (Visited.count(PA.Id)) continue; Visited.insert(PA.Id); // Go over all phi uses and get the reaching defs for each use. for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) { const auto &T = getAllReachingDefsRec(RefRR, U, Visited, TmpDefs); Result.insert(T.begin(), T.end()); } } return Result; }
void TheoryEngineModelBuilder::checkTerms(TNode n, TheoryModel* tm, NodeSet& cache) { if (cache.find(n) != cache.end()) { return; } if (isAssignable(n)) { tm->d_equalityEngine.addTerm(n); } for(TNode::iterator child_it = n.begin(); child_it != n.end(); ++child_it) { checkTerms(*child_it, tm, cache); } cache.insert(n); }
void SomeFunction(DominatorMap &dominators, NodeSet &newDominators, ControlFlowNode *n, _Func func) { newDominators.insert(n); if (!func(n).empty()) { NodeSet result; bool first = true; for (ControlFlowNode *pred : func(n)) { if (first) { result = dominators[pred]; first = false; } else { NodeSet resultTemp; NodeSet &temp = dominators[pred]; set_intersection(result.begin(), result.end(), temp.begin(), temp.end(), inserter(resultTemp, resultTemp.begin()), std::less<ControlFlowNode*>() ); swap(resultTemp, result); } } for (ControlFlowNode *node : result) { newDominators.insert(node); } } // Now look at all the predecessors p of n. // Add in the intersection of all those dominators for them. }
// ---------------------------------------------------------------------- bool LocalizationNeighborhood:: is_sound( void ) const throw() { NodeSet temp = ref_nodes(); temp.insert( sounds_.begin(), sounds_.end() ); // if there is no info about ref-nodes of the anchors, ignore this // check return true anyway if ( anchor_cnt() > 0 && temp.size() == 0 ) return true; //TODO: Dimension anpassen !!!! return (int)temp.size() >= 3; }
void GraphicsContext::removeCamera(osg::Camera* camera) { Cameras::iterator itr = std::find(_cameras.begin(), _cameras.end(), camera); if (itr != _cameras.end()) { // find a set of nodes attached the camera that we are removing that isn't // shared by any other cameras on this GraphicsContext typedef std::set<Node*> NodeSet; NodeSet nodes; for(unsigned int i=0; i<camera->getNumChildren(); ++i) { nodes.insert(camera->getChild(i)); } for(Cameras::iterator citr = _cameras.begin(); citr != _cameras.end(); ++citr) { if (citr != itr) { osg::Camera* otherCamera = *citr; for(unsigned int i=0; i<otherCamera->getNumChildren(); ++i) { NodeSet::iterator nitr = nodes.find(otherCamera->getChild(i)); if (nitr != nodes.end()) nodes.erase(nitr); } } } // now release the GLobjects associated with these non shared nodes for(NodeSet::iterator nitr = nodes.begin(); nitr != nodes.end(); ++nitr) { const_cast<osg::Node*>(*nitr)->releaseGLObjects(_state.get()); } // release the context of the any RenderingCache that the Camera has. if (camera->getRenderingCache()) { camera->getRenderingCache()->releaseGLObjects(_state.get()); } _cameras.erase(itr); } }
// ---------------------------------------------------------------------- const localization::NodeSet LocalizationNeighborhood:: ref_nodes( void ) const throw() { NodeSet temp; for ( ConstNeighborhoodIterator it = begin_neighborhood(); it != end_neighborhood(); ++it ) if ( it->second->is_anchor() && it->second->is_valid() ) temp.insert( it->second->ref_nodes().begin(), it->second->ref_nodes().end() ); return temp; }
// Filter out predecessors that are a single jump with no predecessors // We need them in the tree because they might represent breaks in ifs, but // they mess up the dominator tree and cause loops to not be identified. NodeSet NoJmpPreds(ControlFlowNode *node) { NodeSet filtered; for (ControlFlowNode *pred : node->Predecessors()) { if (pred->Type == CFGNodeType::RawCode) { RawCodeNode *rawCodeNode = static_cast<RawCodeNode*>(pred); if (rawCodeNode->start->get_opcode() == Opcode::JMP) { if (rawCodeNode->Predecessors().empty()) { continue; // Don't insert it... } } } filtered.insert(pred); } return filtered; }
void State::divideTrees(const State& a_other, NodePairSet& a_commonRoots, NodeSet& a_myUniqueRoots, NodeSet& a_otherUniqueRoots) { NodeSet otherRootSet = a_other.getRootSet(); // Copy the entire set a_commonRoots.clear(); a_myUniqueRoots.clear(); a_otherUniqueRoots.clear(); for (NodeSetIter iter = m_rootSet.begin(); iter != m_rootSet.end(); iter++) { bool isUnique = true; string rootName; if (!((*iter)->getUniqueName(rootName))) { error("State::divideTrees - Multiple roots (in this state) with the same name " + rootName + " exist! " + string(*this), true); } for (NodeSetIter otherIter = otherRootSet.begin(); otherIter != otherRootSet.end(); otherIter++) { string otherRootName; if (!((*otherIter)->getUniqueName(otherRootName))) { error("State::divideTrees - Multiple roots (in joined state) with the same name " + otherRootName + " exist! " + string(a_other), true); } if (rootName == otherRootName) { a_commonRoots.insert(make_pair((*iter), (*otherIter))); otherRootSet.erase(otherIter); isUnique = false; break; } } if (isUnique) { a_myUniqueRoots.insert(*iter); } } a_otherUniqueRoots = otherRootSet; }
void part_1() { // topological sort with an ordered set NodeSet roots; Graph children, parents; get_graphs("input.txt", children, parents, roots); stringstream res; while (!roots.empty()) { char n = *roots.begin(); roots.erase(roots.begin()); res << n; for (char m : children[n]) { parents[m].erase(n); if (parents[m].empty()) { roots.insert(m); } } children.erase(n); } cout << res.str() << endl; }
/* * DeleteCFG() * Remove one CFG. */ void DeleteCFG(GraphNode *Root) { NodeVec VisitStack; NodeSet Visited; VisitStack.push_back(Root); while(VisitStack.size()) { GraphNode *Parent = VisitStack.back(); VisitStack.pop_back(); if (Visited.count(Parent)) continue; Visited.insert(Parent); NodeVec &Child = Parent->getSuccessor(); for (int i = 0, e = Child.size(); i < e; i++) VisitStack.push_back(Child[i]); } for (NodeSet::iterator I = Visited.begin(), E = Visited.end(); I != E; I++) delete *I; }
ActionChoiceWindow::NodeSet ActionChoiceWindow::ActionNode::getAllNodesNotBelow( ActionNode* treeRoot, ActionChoiceWindow::ActionNode* targetNode) { NodeSet allNodes; getAllNodes(treeRoot, allNodes); NodeSet nodes; for (NodeSet::iterator iter = allNodes.begin(); iter != allNodes.end(); iter++) { bool leaveOut = false; if ((*iter)->getParent() == treeRoot || *iter == targetNode || (*iter)->getButton() == NULL) { leaveOut = true; continue; } ActionNode* node = *iter; while(node->getParent() != NULL) { node = node->getParent(); if (node == targetNode) { leaveOut = true; continue; } } if (!leaveOut) nodes.insert(*iter); } return nodes; }
void HexagonCommonGEP::common() { // The essence of this commoning is finding gep nodes that are equal. // To do this we need to compare all pairs of nodes. To save time, // first, partition the set of all nodes into sets of potentially equal // nodes, and then compare pairs from within each partition. using NodeSetMap = std::map<unsigned, NodeSet>; NodeSetMap MaybeEq; for (NodeVect::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) { GepNode *N = *I; unsigned H = node_hash(N); MaybeEq[H].insert(N); } // Compute the equivalence relation for the gep nodes. Use two caches, // one for equality and the other for non-equality. NodeSymRel EqRel; // Equality relation (as set of equivalence classes). NodePairSet Eq, Ne; // Caches. for (NodeSetMap::iterator I = MaybeEq.begin(), E = MaybeEq.end(); I != E; ++I) { NodeSet &S = I->second; for (NodeSet::iterator NI = S.begin(), NE = S.end(); NI != NE; ++NI) { GepNode *N = *NI; // If node already has a class, then the class must have been created // in a prior iteration of this loop. Since equality is transitive, // nothing more will be added to that class, so skip it. if (node_class(N, EqRel)) continue; // Create a new class candidate now. NodeSet C; for (NodeSet::iterator NJ = std::next(NI); NJ != NE; ++NJ) if (node_eq(N, *NJ, Eq, Ne)) C.insert(*NJ); // If Tmp is empty, N would be the only element in it. Don't bother // creating a class for it then. if (!C.empty()) { C.insert(N); // Finalize the set before adding it to the relation. std::pair<NodeSymRel::iterator, bool> Ins = EqRel.insert(C); (void)Ins; assert(Ins.second && "Cannot add a class"); } } } LLVM_DEBUG({ dbgs() << "Gep node equality:\n"; for (NodePairSet::iterator I = Eq.begin(), E = Eq.end(); I != E; ++I) dbgs() << "{ " << I->first << ", " << I->second << " }\n"; dbgs() << "Gep equivalence classes:\n"; for (NodeSymRel::iterator I = EqRel.begin(), E = EqRel.end(); I != E; ++I) { dbgs() << '{'; const NodeSet &S = *I; for (NodeSet::const_iterator J = S.begin(), F = S.end(); J != F; ++J) { if (J != S.begin()) dbgs() << ','; dbgs() << ' ' << *J; } dbgs() << " }\n"; } });
void generateConstraints(vector<Node*>& nodes, vector<Edge*>& edges,vector<SimpleConstraint*>& cs,Dim dim) { unsigned nevents=2*nodes.size()+2*edges.size(); events=new Event*[nevents]; unsigned ctr=0; if(dim==HORIZONTAL) { //cout << "Scanning top to bottom..." << endl; for(unsigned i=0;i<nodes.size();i++) { Node *v=nodes[i]; v->scanpos=v->x; events[ctr++]=new Event(Open,v,v->ymin+0.01); events[ctr++]=new Event(Close,v,v->ymax-0.01); } for(unsigned i=0;i<edges.size();i++) { Edge *e=edges[i]; events[ctr++]=new Event(Open,e,e->ymin-1); events[ctr++]=new Event(Close,e,e->ymax+1); } } else { //cout << "Scanning left to right..." << endl; for(unsigned i=0;i<nodes.size();i++) { Node *v=nodes[i]; v->scanpos=v->y; events[ctr++]=new Event(Open,v,v->xmin+0.01); events[ctr++]=new Event(Close,v,v->xmax-0.01); } for(unsigned i=0;i<edges.size();i++) { Edge *e=edges[i]; events[ctr++]=new Event(Open,e,e->xmin-1); events[ctr++]=new Event(Close,e,e->xmax+1); } } qsort((Event*)events, (size_t)nevents, sizeof(Event*), compare_events ); NodeSet openNodes; vector<Edge*> openEdges; for(unsigned i=0;i<nevents;i++) { Event *e=events[i]; Node *v=e->v; if(v!=NULL) { v->open = true; //printf("NEvent@%f,nid=%d,(%f,%f),w=%f,h=%f,openn=%d,opene=%d\n",e->pos,v->id,v->x,v->y,v->width,v->height,(int)openNodes.size(),(int)openEdges.size()); Node *l=NULL, *r=NULL; if(!openNodes.empty()) { // it points to the first node to the right of v NodeSet::iterator it=openNodes.lower_bound(v); // step left to find the first node to the left of v if(it--!=openNodes.begin()) { l=*it; //printf("l=%d\n",l->id); } it=openNodes.upper_bound(v); if(it!=openNodes.end()) { r=*it; } } vector<Node*> L; sortNeighbours(v,l,r,e->pos,openEdges,L,nodes,dim); //printf("L=["); for(unsigned i=0;i<L.size();i++) { //printf("%d ",L[i]->id); } //printf("]\n"); // Case A: create constraints between adjacent edges skipping edges joined // to l,v or r. Node* lastNode=NULL; for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) { if((*i)->dummy) { // node is on an edge Edge *edge=(*i)->edge; if(!edge->isEnd(v->id) &&((l!=NULL&&!edge->isEnd(l->id))||l==NULL) &&((r!=NULL&&!edge->isEnd(r->id))||r==NULL)) { if(lastNode!=NULL) { //printf(" Rule A: Constraint: v%d +g <= v%d\n",lastNode->id,(*i)->id); cs.push_back(createConstraint(lastNode,*i,dim)); } lastNode=*i; } } else { // is an actual node lastNode=NULL; } } // Case B: create constraints for all the edges connected to the right of // their own end, also in the scan line vector<Node*> skipList; lastNode=NULL; for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { if((*i)->edge->isEnd(lastNode->id)) { skipList.push_back(*i); } else { for(vector<Node*>::iterator j=skipList.begin(); j!=skipList.end();j++) { //printf(" Rule B: Constraint: v%d +g <= v%d\n",(*j)->id,(*i)->id); cs.push_back(createConstraint(*j,*i,dim)); } skipList.clear(); } } } else { // is an actual node skipList.clear(); skipList.push_back(*i); lastNode=*i; } } skipList.clear(); // Case C: reverse of B lastNode=NULL; for(vector<Node*>::reverse_iterator i=L.rbegin();i!=L.rend();i++) { if((*i)->dummy) { // node is on an edge if(lastNode!=NULL) { if((*i)->edge->isEnd(lastNode->id)) { skipList.push_back(*i); } else { for(vector<Node*>::iterator j=skipList.begin(); j!=skipList.end();j++) { //printf(" Rule C: Constraint: v%d +g <= v%d\n",(*i)->id,(*j)->id); cs.push_back(createConstraint(*i,*j,dim)); } skipList.clear(); } } } else { // is an actual node skipList.clear(); skipList.push_back(*i); lastNode=*i; } } if(e->type==Close) { if(l!=NULL) cs.push_back(createConstraint(l,v,dim)); if(r!=NULL) cs.push_back(createConstraint(v,r,dim)); } } if(e->type==Open) { if(v!=NULL) { openNodes.insert(v); } else { //printf("EdgeOpen@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode); e->e->openInd=openEdges.size(); openEdges.push_back(e->e); } } else { // Close if(v!=NULL) { openNodes.erase(v); v->open=false; } else { //printf("EdgeClose@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode); unsigned i=e->e->openInd; openEdges[i]=openEdges[openEdges.size()-1]; openEdges[i]->openInd=i; openEdges.resize(openEdges.size()-1); } } delete e; } delete [] events; }