HPCToolkit
CCT-TreeIterator.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 //************************* System Include Files ****************************
61 
62 #include <iostream>
63 using std::ostream;
64 using std::endl;
65 
66 #include <stdint.h>
67 
68 //*************************** User Include Files ****************************
69 
70 #include "CCT-Tree.hpp"
71 
73 
74 //*************************** Forward Declarations **************************
75 
76 //***************************************************************************
77 
78 namespace Prof {
79 
80 namespace CCT {
81 
82 
83 //***************************************************************************
84 // ANodeFilter support
85 //***************************************************************************
86 
87 bool
88 HasANodeTy(const ANode& node, long type)
89 {
90  return (type == ANode::TyANY || node.type() == ANode::IntToANodeType(type));
91 }
92 
93 
100  ANode::TyProc),
102  ANode::TyLoop),
104  ANode::TyStmt),
106  ANode::TyCall),
108  ANode::TyANY)
109 };
110 
111 
112 //***************************************************************************
113 // ANodeChildIterator
114 //***************************************************************************
115 
116 
117 //***************************************************************************
118 // ANodeIterator
119 //***************************************************************************
120 
121 
122 //***************************************************************************
123 // ANodeSortedIterator
124 //***************************************************************************
125 
126 static int
127 cmp(uint64_t x, uint64_t y)
128 {
129  // compare without the possible overflow caused by (x - y)
130  if (x == y) {
131  return 0;
132  }
133  else if (x < y) {
134  return -1;
135  }
136  else {
137  return 1;
138  }
139 }
140 
141 
142 static int
143 cmpByDynInfoSpecial(const ADynNode* x_dyn, const ADynNode* y_dyn)
144 {
145  // INVARIANT: x and y are non-NULL
146 
147  // 1. lm-id for physical or logical frames
148  int cmp_lmId = x_dyn->lmId() - y_dyn->lmId();
149  if (cmp_lmId != 0) {
150  return cmp_lmId;
151  }
152 
153  // 2. physical ip
154  int cmp_ip_real = cmp(x_dyn->lmIP_real(), y_dyn->lmIP_real());
155  if (cmp_ip_real != 0) {
156  return cmp_ip_real;
157  }
158 
159  // 3. logical ip (if available)
160  int cmp_ip = cmp(x_dyn->lmIP(), y_dyn->lmIP());
161  return cmp_ip;
162 }
163 
164 
168  const ANodeFilter* filterFunc,
169  bool leavesOnly)
170 {
171  ANodeIterator it(node, filterFunc, leavesOnly);
172  for (ANode* cur = NULL; (cur = it.current()); it++) {
173  scopes.Add((unsigned long) cur);
174  }
175  ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn);
176 }
177 
178 
179 void
181 {
182  os << "ANodeSortedIterator: " << endl;
183  while (current()) {
184  os << current()->toStringMe() << endl;
185  (*this)++;
186  }
187  reset();
188 }
189 
190 
191 int
192 ANodeSortedIterator::cmpByName(const void* a, const void* b)
193 {
194  ANode* x = (*(ANode**)a);
195  ANode* y = (*(ANode**)b);
196  return x->name().compare(y->name()); // strcmp(x, y)
197 }
198 
199 
200 int
201 ANodeSortedIterator::cmpByLine(const void* a, const void* b)
202 {
203  ANode* x = (*(ANode**)a);
204  ANode* y = (*(ANode**)b);
205  return ANodeLineComp(x, y);
206 }
207 
208 
209 int
210 ANodeSortedIterator::cmpByStructureInfo(const void* a, const void* b)
211 {
212  ANode* x = (*(ANode**)a);
213  ANode* y = (*(ANode**)b);
214 
215  if (x && y) {
216  // 0. test for equality
217  if (x == y) {
218  return 0;
219  }
220 
221  // INVARIANT: x != y, so never return 0
222 
223  // 1. distinguish by structure ids
224  uint x_id = x->structureId();
225  uint y_id = y->structureId();
226  int cmp_sid = cmp(x_id, y_id);
227  if (cmp_sid != 0) {
228  return cmp_sid;
229  }
230 
231  // 2. distinguish by types
232  int cmp_ty = (int)x->type() - (int)y->type();
233  if (cmp_ty != 0) {
234  return cmp_ty;
235  }
236 
237  // 3. distinguish by dynamic info (unnormalized CCTs)
238  // (for determinism, ensure x and y are both ADynNodes)
239  ADynNode* x_dyn = dynamic_cast<ADynNode*>(x);
240  ADynNode* y_dyn = dynamic_cast<ADynNode*>(y);
241  if (x_dyn && y_dyn) {
242  int cmp_dyn = cmpByDynInfoSpecial(x_dyn, y_dyn);
243  if (cmp_dyn != 0) {
244  return cmp_dyn;
245  }
246  }
247 
248 
249  // 5. distinguish by id
250  int cmp_id = (int)x->id() - (int)y->id();
251  if (cmp_id != 0) {
252  return cmp_id;
253  }
254 
255  // 4. distinguish by tree context
256  ANode* x_parent = x->parent();
257  ANode* y_parent = y->parent();
258  if (x_parent != y_parent) {
259  int cmp_ctxt = cmpByStructureInfo(&x_parent, &y_parent);
260  if (cmp_ctxt != 0) {
261  return cmp_ctxt;
262  }
263  }
264  // *. Could compare childCount() and other aspects of children.
265  DIAG_Die("Prof::CCT::ANodeSortedIterator::cmpByStructureInfo: cannot compare:"
266  << "\n\tx: " << x->toStringMe(Prof::CCT::Tree::OFlg_Debug)
267  << "\n\ty: " << y->toStringMe(Prof::CCT::Tree::OFlg_Debug));
268  return 0;
269  }
270  else if (x) {
271  return 1; // x > y=NULL (only used for recursive case)
272  }
273  else if (y) {
274  return -1; // x=NULL < y (only used for recursive case)
275  }
276  else {
278  }
279 }
280 
281 
282 int
283 ANodeSortedIterator::cmpByDynInfo(const void* a, const void* b)
284 {
285  ANode* x = (*(ANode**)a);
286  ANode* y = (*(ANode**)b);
287 
288  // 0. test for equality
289  if (x == y) {
290  return 0;
291  }
292 
293  // INVARIANT: x != y, so never return 0
294 
295  ADynNode* x_dyn = dynamic_cast<ADynNode*>(x);
296  ADynNode* y_dyn = dynamic_cast<ADynNode*>(y);
297 
298  // 1. distinguish by dynamic info
299  if (x_dyn && y_dyn) {
300  return cmpByDynInfoSpecial(x_dyn, y_dyn);
301  }
302 
303  // 2. distinguish by structure ids
304  uint x_id = x->structureId();
305  uint y_id = y->structureId();
306  if (x_id != Prof::Struct::ANode::Id_NULL
307  && y_id != Prof::Struct::ANode::Id_NULL) {
308  int cmp_sid = cmp(x_id, y_id);
309  if (cmp_sid != 0) {
310  return cmp_sid;
311  }
312  }
313 
314  // 3. distinguish by type
315  int cmp_ty = (int)x->type() - (int)y->type();
316  if (cmp_ty != 0) {
317  return cmp_ty;
318  }
319 
320 
321 #if 1
322  // 4. distinguish by id
323  int cmp_id = (int)x->id() - (int)y->id();
324  if (cmp_id != 0) {
325  return cmp_id;
326  }
327 #endif
328 
329  // *. Could compare childCount() and other aspects of children.
330  DIAG_Die("Prof::CCT::ANodeSortedIterator::cmpByDynInfo: cannot compare:"
331  << "\n\tx: " << x->toStringMe(Prof::CCT::Tree::OFlg_Debug)
332  << "\n\ty: " << y->toStringMe(Prof::CCT::Tree::OFlg_Debug));
333 }
334 
335 
336 //***************************************************************************
337 // ANodeSortedChildIterator
338 //***************************************************************************
339 
343  const ANodeFilter* f)
344 {
345  ANodeChildIterator it(node, f);
346  for (ANode* cur = NULL; (cur = it.current()); it++) {
347  scopes.Add((unsigned long) cur);
348  }
349  ptrSetIt = new WordSetSortedIterator(&scopes, compare_fn);
350 }
351 
352 
353 void
355 {
356  os << "ANodeSortedChildIterator: " << endl;
357  while (current()) {
358  os << current()->toStringMe() << endl;
359  (*this)++;
360  }
361  reset();
362 }
363 
364 //***************************************************************************
365 
366 } // namespace CCT
367 
368 } // namespace Prof
ANode * parent() const
Definition: CCT-Tree.hpp:434
uint structureId() const
Definition: CCT-Tree.hpp:409
virtual std::string toStringMe(uint oFlags=0) const
Definition: CCT-Tree.cpp:1134
static ANodeTy IntToANodeType(long i)
Definition: CCT-Tree.cpp:334
ANodeSortedChildIterator(const ANode *root, ANodeSortedIterator::cmp_fptr_t compare_fn, const ANodeFilter *filterFunc=NULL)
static const uint Id_NULL
ANodeSortedIterator(const ANode *node, cmp_fptr_t compare_fn, const ANodeFilter *filterFunc=NULL, bool leavesOnly=true)
static int cmpByLine(const void *x, const void *y)
cct_node_t * node
Definition: cct.c:128
int(* cmp_fptr_t)(const void *x, const void *y)
static int cmp(uint64_t x, uint64_t y)
virtual VMA lmIP() const
Definition: CCT-Tree.hpp:845
void dumpAndReset(std::ostream &os=std::cerr)
static int cmpByStructureInfo(const void *x, const void *y)
WordSetSortedIterator * ptrSetIt
unsigned int uint
Definition: uint.h:124
virtual const std::string & name() const
Definition: CCT-Tree.hpp:394
static int cmpByDynInfo(const void *x, const void *y)
void dumpAndReset(std::ostream &os=std::cerr)
int ANodeLineComp(ANode *x, ANode *y)
Definition: CCT-Tree.cpp:1527
LoadMap::LMId_t lmId() const
Definition: CCT-Tree.hpp:823
void Add(unsigned long entry)
Definition: WordSet.cpp:107
const char * DIAG_UnexpectedInput
static int cmpByDynInfoSpecial(const ADynNode *x_dyn, const ADynNode *y_dyn)
#define NULL
Definition: ElfHelper.cpp:85
uint id() const
Definition: CCT-Tree.hpp:383
VMA lmIP_real() const
Definition: CCT-Tree.hpp:854
static int cmpByName(const void *x, const void *y)
bool HasANodeTy(const ANode &node, long type)
#define DIAG_Die(...)
Definition: diagnostics.h:267
const ANodeFilter ANodeTyFilter[ANode::TyNUMBER]
static const std::string & ANodeTyToName(ANodeTy tp)
Definition: CCT-Tree.cpp:327
ANodeTy type() const
Definition: CCT-Tree.hpp:374