int ANodeSortedIterator::cmpByName(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); return x->name().compare(y->name()); // strcmp(x, y) }
bool ANode::merge(ANode* node_dst, ANode* node_src) { // Do we really want this? //if (!IsMergable(node_dst, node_src)) { // return false; //} // Perform the merge // 1. Move all children of 'node_src' into 'node_dst' for (ANodeChildIterator it(node_src); it.Current(); /* */) { ANode* x = it.current(); it++; // advance iterator so we can unlink 'x' x->unlink(); x->link(node_dst); } // 2. If merging ACodeNodes, update line ranges ACodeNode* dst0 = dynamic_cast<ACodeNode*>(node_dst); ACodeNode* src0 = dynamic_cast<ACodeNode*>(node_src); DIAG_Assert(Logic::equiv(dst0, src0), "Invariant broken!"); if (dst0 && src0) { SrcFile::ln begLn = std::min(dst0->begLine(), src0->begLine()); SrcFile::ln endLn = std::max(dst0->endLine(), src0->endLine()); dst0->setLineRange(begLn, endLn); dst0->vmaSet().merge(src0->vmaSet()); // merge VMAs } // 3. Unlink 'node_src' from the tree and delete it node_src->unlink(); delete node_src; return true; }
int ANodeSortedIterator::cmpById(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); return (x->id() - y->id()); }
int IsAncestorOf(ANode *parent, ANode *son, int difference) { ANode *iter = son; while (iter && difference > 0 && iter != parent) { iter = iter->Parent(); difference--; } if (iter && iter == parent) return 1; return 0; }
int ANodeSortedIterator::cmpByDynInfo(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); // 0. test for equality if (x == y) { return 0; } // INVARIANT: x != y, so never return 0 ADynNode* x_dyn = dynamic_cast<ADynNode*>(x); ADynNode* y_dyn = dynamic_cast<ADynNode*>(y); // 1. distinguish by dynamic info if (x_dyn && y_dyn) { return cmpByDynInfoSpecial(x_dyn, y_dyn); } // 2. distinguish by structure ids uint x_id = x->structureId(); uint y_id = y->structureId(); if (x_id != Prof::Struct::ANode::Id_NULL && y_id != Prof::Struct::ANode::Id_NULL) { int cmp_sid = cmp(x_id, y_id); if (cmp_sid != 0) { return cmp_sid; } } // 3. distinguish by type int cmp_ty = (int)x->type() - (int)y->type(); if (cmp_ty != 0) { return cmp_ty; } #if 1 // 4. distinguish by id int cmp_id = (int)x->id() - (int)y->id(); if (cmp_id != 0) { return cmp_id; } #endif // *. Could compare childCount() and other aspects of children. DIAG_Die("Prof::CCT::ANodeSortedIterator::cmpByDynInfo: cannot compare:" << "\n\tx: " << x->toStringMe(Prof::CCT::Tree::OFlg_Debug) << "\n\ty: " << y->toStringMe(Prof::CCT::Tree::OFlg_Debug)); }
ANode* Tree::findNode(uint nodeId) const { if (!m_nodeidMap) { m_nodeidMap = new NodeIdToANodeMap; for (ANodeIterator it(m_root); it.Current(); ++it) { ANode* n = it.current(); m_nodeidMap->insert(std::make_pair(n->id(), n)); } } NodeIdToANodeMap::iterator it = m_nodeidMap->find(nodeId); return (it != m_nodeidMap->end()) ? it->second : NULL; }
int ANode::distance(ANode* anc, ANode* desc) { int distance = 0; for (ANode* x = desc; x != NULL; x = x->parent()) { if (x == anc) { return distance; } ++distance; } // If we arrive here, there was no path between 'anc' and 'desc' return -1; }
void ANode::pruneByMetrics() { for (ANodeChildIterator it(this); it.Current(); /* */) { ANode* x = it.current(); it++; // advance iterator -- it is pointing at 'x' if (x->hasMetrics()) { x->pruneByMetrics(); } else { x->unlink(); // unlink 'x' from tree delete x; } } }
ostream& Root::writeXML(ostream& os, uint oFlags, const char* pfx) const { if (oFlags & Tree::OFlg_Compressed) { pfx = ""; } // N.B.: Assume that my children are LM's bool doPost = ANode::writeXML_pre(os, oFlags, pfx); for (ANodeSortedChildIterator it(this, ANodeSortedIterator::cmpByName); it.current(); it++) { ANode* scope = it.current(); scope->writeXML(os, oFlags, pfx); } if (doPost) { ANode::writeXML_post(os, oFlags, pfx); } return os; }
void ACodeNode::relocate() { ACodeNode* prev = dynamic_cast<ACodeNode*>(prevSibling()); ACodeNode* next = dynamic_cast<ACodeNode*>(nextSibling()); // NOTE: Technically should check for ln_NULL if ((!prev || (prev->begLine() <= m_begLn)) && (!next || (m_begLn <= next->begLine()))) { return; } // INVARIANT: The parent scope contains at least two children DIAG_Assert(parent()->childCount() >= 2, ""); ANode* prnt = parent(); unlink(); //if (prnt->firstChild() == NULL) { // link(prnt); //} if (m_begLn == ln_NULL) { // insert as first child linkBefore(prnt->firstChild()); } else { // insert after sibling with sibling->begLine() <= begLine() // or iff that does not exist insert as first in sibling list ACodeNode* sibling = NULL; for (sibling = dynamic_cast<ACodeNode*>(prnt->lastChild()); sibling; sibling = dynamic_cast<ACodeNode*>(sibling->prevSibling())) { if (sibling->begLine() <= m_begLn) { break; } } if (sibling != NULL) { linkAfter(sibling); } else { linkBefore(prnt->FirstChild()); } } }
void ANode::aggregateMetrics(uint mBegId, uint mEndId) { if ( !(mBegId < mEndId) ) { return; // short circuit } const ANode* root = this; ANodeIterator it(root, NULL/*filter*/, false/*leavesOnly*/, IteratorStack::PostOrder); for (ANode* n = NULL; (n = it.current()); ++it) { ANode* n_parent = n->parent(); if (n != root) { for (uint mId = mBegId; mId < mEndId; ++mId) { double mVal = n->demandMetric(mId, mEndId/*size*/); n_parent->demandMetric(mId, mEndId/*size*/) += mVal; } } } }
void AStarFindPath::reset() { ANode* pNodeItem = m_pMapNodes; for (int y = 0; y < m_iRow; ++y) { for (int x = 0; x < m_iCol; ++x) { pNodeItem->reset(); pNodeItem->m_iPosX = x; pNodeItem->m_iPosY = y; ++pNodeItem; } } m_iStartX = m_iStartY = -1; m_iEndX = m_iEndY = -1; m_eAstarError = EAStarError::Error_Ok; m_pOpendHeap->reset(); m_arrClosedList.clear(); }
ostream& LM::writeXML(ostream& os, uint oFlags, const char* pre) const { string indent = " "; if (oFlags & Tree::OFlg_Compressed) { pre = ""; indent = ""; } // N.B.: Assume my children are Files bool doPost = ANode::writeXML_pre(os, oFlags, pre); string prefix = pre + indent; for (ANodeSortedChildIterator it(this, ANodeSortedIterator::cmpByName); it.current(); it++) { ANode* scope = it.current(); scope->writeXML(os, oFlags, prefix.c_str()); } if (doPost) { ANode::writeXML_post(os, oFlags, pre); } return os; }
ANode* ANode::leastCommonAncestor(ANode* n1, ANode* n2) { // Collect all ancestors of n1 and n2. The root will be at the front // of the ancestor list. ANodeList anc1, anc2; for (ANode* a = n1->parent(); (a); a = a->parent()) { anc1.push_front(a); } for (ANode* a = n2->parent(); (a); a = a->parent()) { anc2.push_front(a); } // Find the most deeply nested common ancestor ANode* lca = NULL; while ( (!anc1.empty() && !anc2.empty()) && (anc1.front() == anc2.front())) { lca = anc1.front(); anc1.pop_front(); anc2.pop_front(); } return lca; }
bool ANode::mergePaths(ANode* lca, ANode* node_dst, ANode* node_src) { bool merged = false; // Should we verify that lca is really the lca? // Collect nodes along the paths 'lca' --> 'node_dst', 'node_src'. // Exclude 'lca'. Shallowest nodes are at beginning of list. ANodeList path_dst, path_src; for (ANode* x = node_dst; x != lca; x = x->parent()) { path_dst.push_front(x); } for (ANode* x = node_src; x != lca; x = x->parent()) { path_src.push_front(x); } DIAG_Assert(path_dst.size() > 0 && path_src.size() > 0, ""); // Merge nodes in 'path_src' into 'path_dst', shallowest to deepest, // exiting as soon as a merge fails ANodeList::iterator it_dst = path_dst.begin(); ANodeList::iterator it_src = path_src.begin(); for ( ; (it_dst != path_dst.end() && it_src != path_src.end()); ++it_src, ++it_dst) { ANode* x_src = *it_src; ANode* x_dst = *it_dst; if (isMergable(x_dst, x_src)) { merged |= merge(x_dst, x_src); } else { break; // done } } return merged; }
bool ANode::arePathsOverlapping(ANode* lca, ANode* desc1, ANode* desc2) { // Ensure that d1 is on the longest path ANode* d1 = desc1, *d2 = desc2; int dist1 = distance(lca, d1); int dist2 = distance(lca, d2); if (dist2 > dist1) { ANode* t = d1; d1 = d2; d2 = t; } // Iterate over the longest path (d1 -> lca) searching for d2. Stop // when x is NULL or lca. for (ANode* x = d1; (x && x != lca); x = x->parent()) { if (x == d2) { return true; } } // If we arrive here, we did not encounter d2. Divergent. return false; }
int ANodeSortedIterator::cmpByMetric_fn(const void* a, const void *b) { ANode* x = *(ANode**) a; ANode* y = *(ANode**) b; double vx = x->hasMetric(cmpByMetric_mId) ? x->metric(cmpByMetric_mId) : 0.0; double vy = y->hasMetric(cmpByMetric_mId) ? y->metric(cmpByMetric_mId) : 0.0; double difference = vy - vx; if (difference < 0) return -1; else if (difference > 0) return 1; return 0; }
int ANodeSortedIterator::cmpByStructureInfo(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); if (x && y) { // 0. test for equality if (x == y) { return 0; } // INVARIANT: x != y, so never return 0 // 1. distinguish by structure ids uint x_id = x->structureId(); uint y_id = y->structureId(); int cmp_sid = cmp(x_id, y_id); if (cmp_sid != 0) { return cmp_sid; } // 2. distinguish by types int cmp_ty = (int)x->type() - (int)y->type(); if (cmp_ty != 0) { return cmp_ty; } // 3. distinguish by dynamic info (unnormalized CCTs) // (for determinism, ensure x and y are both ADynNodes) ADynNode* x_dyn = dynamic_cast<ADynNode*>(x); ADynNode* y_dyn = dynamic_cast<ADynNode*>(y); if (x_dyn && y_dyn) { int cmp_dyn = cmpByDynInfoSpecial(x_dyn, y_dyn); if (cmp_dyn != 0) { return cmp_dyn; } } // 5. distinguish by id int cmp_id = (int)x->id() - (int)y->id(); if (cmp_id != 0) { return cmp_id; } // 4. distinguish by tree context ANode* x_parent = x->parent(); ANode* y_parent = y->parent(); if (x_parent != y_parent) { int cmp_ctxt = cmpByStructureInfo(&x_parent, &y_parent); if (cmp_ctxt != 0) { return cmp_ctxt; } } // *. Could compare childCount() and other aspects of children. DIAG_Die("Prof::CCT::ANodeSortedIterator::cmpByStructureInfo: cannot compare:" << "\n\tx: " << x->toStringMe(Prof::CCT::Tree::OFlg_Debug) << "\n\ty: " << y->toStringMe(Prof::CCT::Tree::OFlg_Debug)); return 0; } else if (x) { return 1; // x > y=NULL (only used for recursive case) } else if (y) { return -1; // x=NULL < y (only used for recursive case) } else { DIAG_Die(DIAG_UnexpectedInput); } }
/** * TODO: Check graph's data structures being consistent with node and edge functionality */ bool uTestGraphOwn() { { AGraph graph( true); ANode *dummy = graph.newNode(); graph.deleteNode( dummy); ANode *pred = graph.newNode(); ANode *succ = graph.newNode(); AEdge *edge = graph.newEdge( pred, succ); /** Check node insertion */ ANode *new_node = edge->insertNode(); AEdge *edge2 = new_node->firstSucc(); assert( areEqP( new_node->firstPred(), pred->firstSucc())); assert( areEqP( new_node->firstSucc(), succ->firstPred())); assert( areEqP( edge->pred(), pred)); assert( areEqP( pred->firstSucc(), edge)); assert( areEqP( edge->succ(), new_node)); assert( areEqP( new_node->firstPred(), edge)); assert( areEqP( edge2->pred(), new_node)); assert( areEqP( edge2->succ(), succ)); assert( areEqP( succ->firstPred(), edge2)); } /** Test iterators */ { AGraph graph( true); ANode *node1 = graph.newNode(); ANode *node2 = graph.newNode(); ANode *node3 = graph.newNode(); AEdge *edge1 = graph.newEdge( node1, node2); AEdge *edge2 = graph.newEdge( node2, node3); for ( Node::Succ succ_iter = node2->succsBegin(), succ_iter_end = node2->succsEnd(); succ_iter != succ_iter_end; succ_iter++ ) { assert( areEqP( *succ_iter, edge2)); } for ( Node::Pred pred_iter = node2->predsBegin(), pred_iter_end = node2->predsEnd(); pred_iter != pred_iter_end; pred_iter++ ) { assert( areEqP( *pred_iter, edge1)); } Node::EdgeIter edge_iter = node2->edgesBegin(); Node::EdgeIter edge_iter_end = node2->edgesEnd(); assert( edge_iter != edge_iter_end); assert( areEqP( *edge_iter, edge1) || areEqP( *edge_iter, edge2)); if ( areEqP( *edge_iter, edge1)) { assert( areEqP( edge_iter.node(), edge1->pred())); assert( areEqP( edge_iter.node(), node1)); } else { assert( areEqP( edge_iter.node(), edge2->succ())); assert( areEqP( edge_iter.node(), node3)); } edge_iter++; assert( edge_iter != edge_iter_end); assert( areEqP( *edge_iter, edge1) || areEqP( *edge_iter, edge2)); if ( areEqP( *edge_iter, edge1)) { assert( areEqP( edge_iter.node(), edge1->pred())); assert( areEqP( edge_iter.node(), node1)); } else { assert( areEqP( edge_iter.node(), edge2->succ())); assert( areEqP( edge_iter.node(), node3)); } edge_iter++; assert( edge_iter == edge_iter_end); } return true; }
bool HasANodeTy(const ANode& node, long type) { return (type == ANode::TyANY || node.type() == ANode::IntToANodeType(type)); }
/** * Check marker functionality */ bool uTestMarkers() { AGraph graph( true); ANode *dummy = graph.newNode(); graph.deleteNode( dummy); ANode *pred = graph.newNode(); ANode *succ = graph.newNode(); AEdge *edge = graph.newEdge( pred, succ); Marker m = graph.newMarker(); Marker m2 = graph.newMarker(); Marker m_array[ MAX_GRAPH_MARKERS]; assert( !pred->isMarked( m)); assert( !succ->isMarked( m)); assert( !edge->isMarked( m)); assert( !pred->isMarked( m2)); pred->mark( m); succ->mark( m); edge->mark( m); edge->mark( m2); assert( pred->isMarked( m)); assert( succ->isMarked( m)); assert( edge->isMarked( m)); assert( edge->isMarked( m2)); edge->unmark( m); /** Check that different markers have different behaviour */ assert( edge->isMarked( m2)); assert( !edge->isMarked( m)); graph.freeMarker( m); graph.freeMarker( m2); for ( MarkerIndex i = 0; i < MAX_GRAPH_MARKERS; i++) { m_array [ i] = graph.newMarker(); } for ( MarkerIndex i = 0; i < MAX_GRAPH_MARKERS; i++) { graph.freeMarker( m_array[ i]); } m = graph.newMarker(); graph.freeMarker( m); ANode *n; for ( n = graph.firstNode(); isNotNullP( n);) { ANode *tmp = n; n = n->nextNode(); graph.deleteNode( tmp); } return true; }