namespace CCT { //*************************************************************************** // ANodeFilter support //*************************************************************************** bool HasANodeTy(const ANode& node, long type) { return (type == ANode::TyANY || node.type() == ANode::IntToANodeType(type)); } const ANodeFilter ANodeTyFilter[ANode::TyNUMBER] = { ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyRoot).c_str(), ANode::TyRoot), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyProcFrm).c_str(), ANode::TyProcFrm), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyProc).c_str(), ANode::TyProc), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyLoop).c_str(), ANode::TyLoop), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyStmt).c_str(), ANode::TyStmt), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyCall).c_str(), ANode::TyCall), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyANY).c_str(), ANode::TyANY) }; //*************************************************************************** // ANodeChildIterator //*************************************************************************** //*************************************************************************** // ANodeIterator //*************************************************************************** //*************************************************************************** // ANodeSortedIterator //*************************************************************************** static int cmp(uint64_t x, uint64_t y) { // compare without the possible overflow caused by (x - y) if (x == y) { return 0; } else if (x < y) { return -1; } else { return 1; } } static int cmpByDynInfoSpecial(const ADynNode* x_dyn, const ADynNode* y_dyn) { // INVARIANT: x and y are non-NULL // 1. lm-id for physical or logical frames int cmp_lmId = x_dyn->lmId() - y_dyn->lmId(); if (cmp_lmId != 0) { return cmp_lmId; } // 2. physical ip int cmp_ip_real = cmp(x_dyn->lmIP_real(), y_dyn->lmIP_real()); if (cmp_ip_real != 0) { return cmp_ip_real; } // 3. logical ip (if available) int cmp_ip = cmp(x_dyn->lmIP(), y_dyn->lmIP()); return cmp_ip; } ANodeSortedIterator:: ANodeSortedIterator(const ANode* node, ANodeSortedIterator::cmp_fptr_t compare_fn, const ANodeFilter* filterFunc, bool leavesOnly) { ANodeIterator it(node, filterFunc, leavesOnly); for (ANode* cur = NULL; (cur = it.current()); it++) { scopes.Add((unsigned long) cur); } ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn); } void ANodeSortedIterator::dumpAndReset(ostream& os) { os << "ANodeSortedIterator: " << endl; while (current()) { os << current()->toStringMe() << endl; (*this)++; } reset(); } 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) } int ANodeSortedIterator::cmpByLine(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); return ANodeLineComp(x, y); } 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); } } 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)); } //*************************************************************************** // ANodeSortedChildIterator //*************************************************************************** ANodeSortedChildIterator:: ANodeSortedChildIterator(const ANode* node, ANodeSortedIterator::cmp_fptr_t compare_fn, const ANodeFilter* f) { ANodeChildIterator it(node, f); for (ANode* cur = NULL; (cur = it.current()); it++) { scopes.Add((unsigned long) cur); } ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn); } void ANodeSortedChildIterator::dumpAndReset(ostream& os) { os << "ANodeSortedChildIterator: " << endl; while (current()) { os << current()->toStringMe() << endl; (*this)++; } reset(); } //*************************************************************************** } // namespace CCT
namespace Struct { //*************************************************************************** // ANodeFilter support //*************************************************************************** bool HasANodeTy(const ANode& node, long type) { return (type == ANode::TyANY || node.type() == ANode::IntToANodeTy(type)); } const ANodeFilter ANodeTyFilter[ANode::TyNUMBER] = { ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyRoot).c_str(), ANode::TyRoot), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyGroup).c_str(), ANode::TyGroup), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyLM).c_str(), ANode::TyLM), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyFile).c_str(), ANode::TyFile), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyProc).c_str(), ANode::TyProc), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyAlien).c_str(), ANode::TyAlien), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyLoop).c_str(), ANode::TyLoop), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyStmt).c_str(), ANode::TyStmt), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyRef).c_str(), ANode::TyRef), ANodeFilter(HasANodeTy, ANode::ANodeTyToName(ANode::TyANY).c_str(), ANode::TyANY) }; //*************************************************************************** // ANodeChildIterator //*************************************************************************** //*************************************************************************** // ANodeIterator //*************************************************************************** //*************************************************************************** // ANodeSortedIterator //*************************************************************************** ANodeSortedIterator:: ANodeSortedIterator(const ANode* node, ANodeSortedIterator::cmp_fptr_t compare_fn, const ANodeFilter* filterFunc, bool leavesOnly) { ANodeIterator it(node, filterFunc, leavesOnly); for (ANode* cur = NULL; (cur = it.current()); it++) { scopes.Add((unsigned long) cur); } ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn); } void ANodeSortedIterator::dumpAndReset(ostream& os) { os << "ANodeSortedIterator: " << endl; while (current()) { os << current()->toString() << endl; (*this)++; } reset(); } 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) } int ANodeSortedIterator::cmpByLine(const void* a, const void* b) { // WARNING: this assumes it will only see ACodeNodes! ACodeNode* x = (*(ACodeNode**)a); ACodeNode* y = (*(ACodeNode**)b); return ACodeNode::compare(x, y); } int ANodeSortedIterator::cmpById(const void* a, const void* b) { ANode* x = (*(ANode**)a); ANode* y = (*(ANode**)b); return (x->id() - y->id()); } int ANodeSortedIterator::cmpByMetric_mId = -1; 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; } //*************************************************************************** // ANodeSortedChildIterator //*************************************************************************** ANodeSortedChildIterator:: ANodeSortedChildIterator(const ANode* node, ANodeSortedIterator::cmp_fptr_t compare_fn, const ANodeFilter* f) { ANodeChildIterator it(node, f); for (ANode* cur = NULL; (cur = it.current()); it++) { scopes.Add((unsigned long) cur); } ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn); } void ANodeSortedChildIterator::dumpAndReset(ostream& os) { os << "ANodeSortedChildIterator: " << endl; while (current()) { os << current()->toString() << endl; (*this)++; } reset(); } //*************************************************************************** } // namespace Struct