HPCToolkit
Struct-Tree.hpp
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 #ifndef prof_Prof_Struct_Tree_hpp
61 #define prof_Prof_Struct_Tree_hpp
62 
63 //************************* System Include Files ****************************
64 
65 #include <iostream>
66 
67 #include <string>
68 #include <list>
69 #include <set>
70 #include <map>
71 
72 #include <typeinfo>
73 
74 //*************************** User Include Files ****************************
75 
76 #include <include/uint.h>
77 
78 #include "Metric-IData.hpp"
79 
81 
83 #include <lib/support/FileUtil.hpp>
84 #include <lib/support/Logic.hpp>
87 #include <lib/support/SrcFile.hpp>
88 using SrcFile::ln_NULL;
89 #include <lib/support/Unique.hpp>
90 
91 //*************************** Forward Declarations **************************
92 
93 namespace Prof {
94 namespace Struct {
95 
96  class ANode;
97 
98  // Some possibly useful containers
99  typedef std::list<ANode*> ANodeList;
100  typedef std::set<ANode*> ANodeSet;
101 
102 } // namespace Struct
103 } // namespace Prof
104 
105 
106 //*************************** Forward Declarations **************************
107 
108 namespace Prof {
109 namespace Struct {
110 
111 // FIXME: move these into their respective classes...
112 class Group;
113 class GroupMap : public std::map<std::string, Group*> { };
114 
115 class LM;
116 class LMMap : public std::map<std::string, LM*> { };
117 
118 // ProcMap: This is is a multimap because procedure names are
119 // sometimes "generic", i.e. not qualified by types in the case of
120 // templates, resulting in duplicate names
121 class Proc;
122 class ProcMap : public std::multimap<std::string, Proc*> { };
123 
124 class File;
125 class FileMap : public std::map<std::string, File*> { };
126 
127 class Stmt;
128 class StmtMap : public std::map<SrcFile::ln, Stmt*> { };
129 
130 } // namespace Struct
131 } // namespace Prof
132 
133 
134 //***************************************************************************
135 // Tree
136 //***************************************************************************
137 
138 namespace Prof {
139 namespace Struct {
140 
141 class Root;
142 
143 class Tree : public Unique {
144 public:
145 
146  enum {
147  // Output flags
148  OFlg_Compressed = (1 << 1), // Write in compressed format
149  OFlg_LeafMetricsOnly = (1 << 2), // Write metrics only at leaves
150  OFlg_Debug = (1 << 3) // Debug: show xtra source line info
151  };
152 
153  static const std::string UnknownLMNm;
154  static const std::string UnknownFileNm;
155  static const std::string UnknownProcNm;
156  static const std::string UnknownGlobalVariable;
157 
158  static const SrcFile::ln UnknownLine;
159 
160  static const std::string PartialUnwindProcNm;
161 
162 public:
163  // -------------------------------------------------------
164  // Create/Destroy
165  // -------------------------------------------------------
166  Tree(const char* name, Root* root = NULL);
167 
168  Tree(const std::string& name, Root* root = NULL)
169  { Tree(name.c_str(), root); }
170 
171  virtual ~Tree();
172 
173 
174  // -------------------------------------------------------
175  // Tree data
176  // -------------------------------------------------------
177  Root*
178  root() const
179  { return m_root; }
180 
181  void
182  root(Root* x)
183  { m_root = x; }
184 
185  bool
186  empty() const
187  { return (m_root == NULL); }
188 
189  std::string
190  name() const;
191 
192 
193  // -------------------------------------------------------
194  // Write contents
195  // -------------------------------------------------------
196  std::ostream&
197  writeXML(std::ostream& os = std::cerr, uint oFlags = 0) const;
198 
199  // Dump contents for inspection (use flags from ANode)
200  std::ostream&
201  dump(std::ostream& os = std::cerr, uint oFlags = 0) const;
202 
203  void
204  ddump() const;
205 
206 private:
208 };
209 
210 
211 // TODO: integrate with Tree::writeXML()
212 void
213 writeXML(std::ostream& os, const Prof::Struct::Tree& strctTree,
214  bool prettyPrint = true);
215 
216 
217 } // namespace Struct
218 } // namespace Prof
219 
220 
221 //***************************************************************************
222 
223 
224 namespace Prof {
225 namespace Struct {
226 
227 //***************************************************************************
228 // ANode, ACodeNode.
229 //***************************************************************************
230 
231 // FIXME: It would make more sense for Group and LM to
232 // simply be ANodes and not ACodeNodes, but the assumption that
233 // *only* a Root is not a ACodeNode is deeply embedded and would
234 // take a while to untangle.
235 
236 class ANode; // Base class for all nodes
237 class ACodeNode; // Base class for everyone but Root
238 
239 class Root;
240 class Group;
241 class LM;
242 class File;
243 class Proc;
244 class Alien;
245 class Loop;
246 class Stmt;
247 class Ref;
248 
249 // ---------------------------------------------------------
250 // ANode: The base node for a program scope tree
251 // ---------------------------------------------------------
253  public Metric::IData {
254 public:
255  enum ANodeTy {
256  TyRoot = 0,
267  TyNUMBER
268  };
269 
270  static const std::string&
271  ANodeTyToName(ANodeTy tp);
272 
273  static const std::string&
274  ANodeTyToXMLelement(ANodeTy tp);
275 
276  static ANodeTy
277  IntToANodeTy(long i);
278 
279 private:
280  static const std::string ScopeNames[TyNUMBER];
281 
282 public:
283  // --------------------------------------------------------
284  // Create/Destroy
285  // --------------------------------------------------------
286  ANode(ANodeTy ty, ANode* parent = NULL)
287  : NonUniformDegreeTreeNode(parent),
288  Metric::IData(),
289  m_type(ty),
290  m_visible(true)
291  {
292  m_id = s_nextUniqueId++;
293  m_origId = 0;
294  }
295 
296  virtual ~ANode()
297  {
298  DIAG_DevMsgIf(0, "~ANode::ANode: " << toString_id()
299  << " " << std::hex << this << std::dec);
300  }
301 
302  // clone: return a shallow copy, unlinked from the tree
303  virtual ANode*
305  { return new ANode(*this); }
306 
307 
308 protected:
309  ANode(const ANode& x)
310  { *this = x; }
311 
312  // deep copy of internals (but without children)
313  ANode&
314  operator=(const ANode& x)
315  {
316  if (this != &x) {
319  m_type = x.m_type;
320  m_id = x.m_id;
321  m_visible = x.m_visible;
322  m_origId = x.m_origId;
323  }
324  return *this;
325  }
326 
327 
328 public:
329 
330  // --------------------------------------------------------
331  // General data
332  // --------------------------------------------------------
333  ANodeTy
334  type() const
335  { return m_type; }
336 
337  // id: a unique id; 0 is reserved for a NULL value
338  uint
339  id() const
340  { return m_id; }
341 
342  static const uint Id_NULL = 0;
343 
344  // maxId: the maximum id of all structure nodes
345  static uint
347  { return s_nextUniqueId - 1; }
348 
349  // name:
350  // nameQual: qualified name [built dynamically]
351  virtual const std::string&
352  name() const
353  { return ANodeTyToName(type()); }
354 
355  virtual std::string
356  nameQual() const
357  { return name(); }
358 
359  void
361  { m_visible = false; }
362 
363  bool
364  isVisible() const
365  { return m_visible == true; }
366 
367  // --------------------------------------------------------
368  // Tree navigation
369  // --------------------------------------------------------
370  ANode*
371  parent() const
372  { return static_cast<ANode*>(NonUniformDegreeTreeNode::Parent()); }
373 
374  ANode*
375  firstChild() const
376  { return static_cast<ANode*>(NonUniformDegreeTreeNode::FirstChild()); }
377 
378  ANode*
379  lastChild() const
380  { return static_cast<ANode*>(NonUniformDegreeTreeNode::LastChild()); }
381 
382  ANode*
383  nextSibling() const
384  {
385  // siblings are linked in a circular list
386  if ((parent()->lastChild() != this)) {
387  return static_cast<ANode*>(NonUniformDegreeTreeNode::NextSibling());
388  }
389  return NULL;
390  }
391 
392  ANode*
393  prevSibling() const
394  {
395  // siblings are linked in a circular list
396  if ((parent()->firstChild() != this)) {
397  return static_cast<ANode*>(NonUniformDegreeTreeNode::PrevSibling());
398  }
399  return NULL;
400  }
401 
402 
403  // --------------------------------------------------------
404  // ancestor: find first ANode in path from this to root with given type
405  // (Note: We assume that a node *can* be an ancestor of itself.)
406  // --------------------------------------------------------
407  ANode*
408  ancestor(ANodeTy type) const;
409 
410  ANode*
411  ancestor(ANodeTy ty1, ANodeTy ty2) const;
412 
413  ANode*
414  ancestor(ANodeTy ty1, ANodeTy ty2, ANodeTy ty3) const;
415 
416  Root*
417  ancestorRoot() const;
418 
419  Group*
420  ancestorGroup() const;
421 
422  LM*
423  ancestorLM() const;
424 
425  File*
426  ancestorFile() const;
427 
428  Proc*
429  ancestorProc() const;
430 
431  Alien*
432  ancestorAlien() const;
433 
434  Loop*
435  ancestorLoop() const;
436 
437  Stmt*
438  ancestorStmt() const;
439 
440  ACodeNode*
441  ancestorProcCtxt() const; // return ancestor(TyAlien|TyProc)
442 
443  ACodeNode*
444  ACodeNodeParent() const;
445 
446 
447  // --------------------------------------------------------
448  // Metrics (cf. CCT::ANode)
449  // --------------------------------------------------------
450 
451  // aggregates metrics from children. [mBegId, mEndId) forms an
452  // inclusive interval for batch processing. In particular, 'raw'
453  // metrics are independent of all other raw metrics.
454  void
455  aggregateMetrics(uint mBegId, uint mEndId);
456 
457  void
459  { aggregateMetrics(mBegId, mBegId + 1); }
460 
461 
462  // pruneByMetrics: recursively prunes all (children) of the current
463  // node for which hasMetrics() is false.
464  void
465  pruneByMetrics();
466 
467 public:
468 
469  // --------------------------------------------------------
470  // Paths and Merging
471  // --------------------------------------------------------
472 
473  // leastCommonAncestor: Given two ANode nodes, return the least
474  // common ancestor (deepest nested common ancestor) or NULL.
475  static ANode*
476  leastCommonAncestor(ANode* n1, ANode* n2);
477 
478 
479  // distance: Given two ANode nodes, a node and some ancestor,
480  // return the distance of the path between the two. The distance
481  // between a node and its direct ancestor is 1. If there is no path
482  // between the two nodes, returns a negative number; if the two
483  // nodes are equal, returns 0.
484  static int
485  distance(ANode* ancestor, ANode* descendent);
486 
487  // arePathsOverlapping: Given two nodes and their least common
488  // ancestor, lca, returns whether the paths from the nodes to lca
489  // overlap.
490  //
491  // Let d1 and d2 be two nodes descended from their least common
492  // ancestor, lca. Furthermore, let the path p1 from d1 to lca be as
493  // long or longer than the path p2 from d2 to lca. (Thus, d1 is
494  // nested as deep or more deeply than d2.) If the paths p1 and p2 are
495  // overlapping then d2 will be somewhere on the path between d1 and
496  // lca.
497  //
498  // Examples:
499  // 1. Overlapping: lca --- d2 --- ... --- d1
500  //
501  // 2. Divergent: lca --- d1
502  // \--- d2
503  //
504  // 3. Divergent: lca ---...--- d1
505  // \---...--- d2
506  static bool
507  arePathsOverlapping(ANode* lca, ANode* desc1, ANode* desc2);
508 
509  // mergePaths: Given divergent paths (as defined above), merges the
510  // path 'lca' -> 'node_src' into the path 'lca' --> 'node_dst'. If a
511  // merge takes place returns true.
512  static bool
513  mergePaths(ANode* lca, ANode* node_dst, ANode* node_src);
514 
515  // merge: Given two nodes, 'node_src' and 'node_dst', merges the
516  // former into the latter, if possible. If the merge takes place,
517  // deletes 'node_src' and returns true; otherwise returns false.
518  static bool
519  merge(ANode* node_dst, ANode* node_src);
520 
521  // isMergable: Returns whether 'node_src' is capable of being merged
522  // into 'node_dst'
523  static bool
524  isMergable(ANode* node_dst, ANode* node_src);
525 
526 
527  // --------------------------------------------------------
528  // XML output
529  // --------------------------------------------------------
530 
531  std::string
532  toStringXML(uint oFlags = 0, const char* pre = "") const;
533 
534  virtual std::string
535  toXML(uint oFlags = 0) const;
536 
537  virtual std::ostream&
538  writeXML(std::ostream& os = std::cout, uint oFlags = 0,
539  const char* pre = "") const;
540 
541  void
542  ddumpXML() const;
543 
544  // --------------------------------------------------------
545  // Other output
546  // --------------------------------------------------------
547 
548  void
549  CSV_DumpSelf(const Root &root, std::ostream& os = std::cout) const;
550 
551  virtual void
552  CSV_dump(const Root &root, std::ostream& os = std::cout,
553  const char* file_name = NULL,
554  const char* proc_name = NULL,
555  int lLevel = 0) const;
556 
557  // --------------------------------------------------------
558  // debugging
559  // --------------------------------------------------------
560 
561  virtual std::string
562  toString(uint oFlags = 0, const char* pre = "") const;
563 
564  std::string
565  toString_id(uint oFlags = 0) const;
566 
567  std::string
568  toStringMe(uint oFlags = 0, const char* pre = "") const;
569 
570  // dump
571  std::ostream&
572  dump(std::ostream& os = std::cerr, uint oFlags = 0,
573  const char* pre = "") const;
574 
575  void ddump() const;
576 
577  virtual std::ostream&
578  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
579  const char* pre = "") const;
580 
581 protected:
582  bool
583  writeXML_pre(std::ostream& os = std::cout, uint oFlags = 0,
584  const char* prefix = "") const;
585 
586  void
587  writeXML_post(std::ostream& os = std::cout, uint oFlags = 0,
588  const char* prefix = "") const;
589 private:
590  void
591  ctorCheck() const;
592 
593  void
594  dtorCheck() const;
595 
597 
598 protected:
599  ANodeTy m_type; // obsolete with typeid(), but hard to replace
601  bool m_visible;
602 
603 public:
604  // original node id from .hpcstruct file (for debug)
606 };
607 
608 
609 // --------------------------------------------------------------------------
610 // ACodeNode is a base class for all scopes other than TyRoot and TyLM.
611 // Describes some kind of code, i.e. Files, Procedures, Loops...
612 // --------------------------------------------------------------------------
613 class ACodeNode : public ANode {
614 protected:
615  ACodeNode(ANodeTy ty, ANode* parent = NULL,
616  SrcFile::ln begLn = ln_NULL,
617  SrcFile::ln endLn = ln_NULL,
618  VMA begVMA = 0, VMA endVMA = 0)
619  : ANode(ty, parent), m_begLn(ln_NULL), m_endLn(ln_NULL)
620  {
621  m_lineno_frozen = false;
622  setLineRange(begLn, endLn);
623  if (!VMAInterval::empty(begVMA, endVMA)) {
624  m_vmaSet.insert(begVMA, endVMA);
625  }
626  m_scope_filenm = "";
627  m_scope_lineno = 0;
628  }
629 
630 
632  : ANode(x.m_type)
633  { *this = x; }
634 
635 
636  ACodeNode&
638  {
639  // shallow copy
640  if (this != &x) {
641  ANode::operator=(x);
642  m_begLn = x.m_begLn;
643  m_endLn = x.m_endLn;
644  // m_vmaSet
645  }
646  return *this;
647  }
648 
649 public:
650  // --------------------------------------------------------
651  // Create/Destroy
652  // --------------------------------------------------------
653 
654  virtual ~ACodeNode()
655  { }
656 
657  virtual ANode*
659  { return new ACodeNode(*this); }
660 
661 
662  // --------------------------------------------------------
663  //
664  // --------------------------------------------------------
665 
666  // Line range in source code
668  begLine() const
669  { return m_begLn; }
670 
671  void
673  { m_begLn = x; }
674 
676  endLine() const
677  { return m_endLn; }
678 
679  void
681  { m_endLn = x; }
682 
683  void
684  setLineRange(SrcFile::ln begLn, SrcFile::ln endLn, int propagate = 1);
685 
686  void
687  expandLineRange(SrcFile::ln begLn, SrcFile::ln endLn, int propagate = 1);
688 
689  void
690  linkAndSetLineRange(ACodeNode* parent);
691 
692  void
694  {
695  DIAG_Assert(Logic::equiv(begLn == ln_NULL, endLn == ln_NULL),
696  "ACodeNode::checkLineRange: b=" << begLn << " e=" << endLn);
697  DIAG_Assert(begLn <= endLn,
698  "ACodeNode::checkLineRange: b=" << begLn << " e=" << endLn);
699  DIAG_Assert(Logic::equiv(m_begLn == ln_NULL, m_endLn == ln_NULL),
700  "ACodeNode::checkLineRange: b=" << m_begLn << " e=" << m_endLn);
701  }
702 
703  void
705  { m_lineno_frozen = true; }
706 
707  void
709  { m_lineno_frozen = false; }
710 
711 
712  // -------------------------------------------------------
713  // A set of *unrelocated* VMAs associated with this scope
714  // -------------------------------------------------------
715 
716  const VMAIntervalSet&
717  vmaSet() const
718  { return m_vmaSet; }
719 
722  { return m_vmaSet; }
723 
724 
725  // -------------------------------------------------------
726  // containsLine: returns true if this scope contains line number
727  // 'ln'. A non-zero beg_epsilon and end_epsilon allows fuzzy
728  // matches by expanding the interval of the scope.
729  //
730  // containsInterval: returns true if this scope fully contains the
731  // interval specified by [begLn...endLn]. A non-zero beg_epsilon
732  // and end_epsilon allows fuzzy matches by expanding the interval of
733  // the scope.
734  //
735  // Note: We assume that it makes no sense to compare against ln_NULL.
736  // -------------------------------------------------------
737  bool
739  { return (m_begLn != ln_NULL && (m_begLn <= ln && ln <= m_endLn)); }
740 
741  bool
742  containsLine(SrcFile::ln ln, int beg_epsilon, int end_epsilon) const;
743 
744  bool
746  { return (containsLine(begLn) && containsLine(endLn)); }
747 
748  bool
750  int beg_epsilon, int end_epsilon) const
751  { return (containsLine(begLn, beg_epsilon, end_epsilon)
752  && containsLine(endLn, beg_epsilon, end_epsilon)); }
753 
754  ACodeNode*
755  ACodeNodeWithLine(SrcFile::ln ln) const;
756 
757 
758  // compare: Return negative if x < y; 0 if x == y; positive
759  // otherwise. If x == y, break ties using VMAIntervalSet and then
760  // by name attributes.
761  static int
762  compare(const ACodeNode* x, const ACodeNode* y);
763 
764  ACodeNode*
765  nextSiblingNonOverlapping() const;
766 
767 
768  // --------------------------------------------------------
769  //
770  // --------------------------------------------------------
771 
772  virtual std::string
773  nameQual() const
774  { return codeName(); }
775 
776  // returns a string representing the code name in the form:
777  // loadmodName
778  // [loadmodName]fileName
779  // [loadmodName]<fileName>procName
780  // [loadmodName]<fileName>begLn-endLn
781 
782  virtual std::string
783  codeName() const;
784 
785  std::string
786  lineRange() const;
787 
788 
789  // --------------------------------------------------------
790  // XML output
791  // --------------------------------------------------------
792 
793  virtual std::string
794  toXML(uint oFlags = 0) const;
795 
796  virtual std::string
797  XMLLineRange(uint oFlags) const;
798 
799  virtual std::string
800  XMLVMAIntervals(uint oFlags) const;
801 
802  virtual void
803  CSV_dump(const Root &root, std::ostream& os = std::cout,
804  const char* file_name = NULL, const char* proc_name = NULL,
805  int lLevel = 0) const;
806 
807  // --------------------------------------------------------
808  // debugging
809  // --------------------------------------------------------
810 
811  virtual std::ostream&
812  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
813  const char* pre = "") const;
814 
815 protected:
816  // NOTE: currently designed for PROCs
817  void
818  relocate();
819 
820  void
822  {
823  if (parent() && type() == ANode::TyProc) {
824  // typeid(*this) == typeid(ANode::Proc)
825  relocate();
826  }
827  }
828 
829  std::string codeName_LM_F() const;
830 
831 protected:
835 
836  // --------------------------------------------------------
837  // Inline support -- Save the location (file name, line num) of an
838  // alien scope (loop) node to help find the same scope in a later
839  // InlineNode sequence inside the location manager.
840  // --------------------------------------------------------
841 private:
842  std::string m_scope_filenm;
845 
846 public:
847  void setScopeLocation(std::string &file, SrcFile::ln line) {
848  m_scope_filenm = file;
849  m_scope_lineno = line;
850  }
851  std::string & getScopeFileName() { return m_scope_filenm; }
852  SrcFile::ln getScopeLineNum() { return m_scope_lineno; }
853 };
854 
855 
856 
857 //***************************************************************************
858 // Root, Group, LM, File, Proc, Loop,
859 // Stmt, Variable
860 //***************************************************************************
861 
862 // --------------------------------------------------------------------------
863 // Root is root of the scope tree
864 // --------------------------------------------------------------------------
865 class Root: public ANode {
866 protected:
867  Root(const Root& x)
868  : ANode(x.m_type)
869  {
870  *this = x;
871  }
872 
873  Root&
874  operator=(const Root& x);
875 
876 public:
877  Root(const char* nm)
878  : ANode(TyRoot, NULL)
879  {
880  Ctor(nm);
881  }
882 
883  Root(const std::string& nm)
884  : ANode(TyRoot, NULL)
885  {
886  Ctor(nm.c_str());
887  }
888 
889  virtual ~Root()
890  {
891  delete groupMap;
892  delete lmMap_realpath;
893  delete lmMap_basename;
894  }
895 
896  virtual const std::string&
897  name() const
898  { return m_name; }
899 
900  void
901  name(const char* x)
902  { m_name = (x) ? x : ""; }
903 
904  void
905  name(const std::string& x)
906  { m_name = x; }
907 
908  // --------------------------------------------------------
909  //
910  // --------------------------------------------------------
911 
912  // findLM: First, try to find by nm_real = realpath(nm). If that is
913  // unsuccesful, try to find by nm_base = basename(nm_real) if
914  // nm_base == nm_real.
915  LM*
916  findLM(const char* nm) const;
917 
918  LM*
919  findLM(const std::string& nm) const
920  { return findLM(nm.c_str()); }
921 
922  Group*
923  findGroup(const char* nm) const
924  {
925  GroupMap::iterator it = groupMap->find(nm);
926  Group* x = (it != groupMap->end()) ? it->second : NULL;
927  return x;
928  }
929 
930  Group*
931  findGroup(const std::string& nm) const
932  { return findGroup(nm.c_str()); }
933 
934  virtual ANode*
936  { return new Root(*this); }
937 
938 
939  // --------------------------------------------------------
940  // XML output
941  // --------------------------------------------------------
942 
943  virtual std::string
944  toXML(uint oFlags = 0) const;
945 
946  virtual std::ostream&
947  writeXML(std::ostream& os = std::cout, uint oFlags = 0,
948  const char* pre = "") const;
949 
950  void
951  CSV_TreeDump(std::ostream& os = std::cout) const;
952 
953  // --------------------------------------------------------
954  // debugging
955  // --------------------------------------------------------
956 
957  virtual std::ostream&
958  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
959  const char* pre = "") const;
960 
961 protected:
962 private:
963  void
964  Ctor(const char* nm);
965 
966  void
967  insertGroupMap(Group* grp);
968 
969  void
970  insertLMMap(LM* lm);
971 
972  friend class Group;
973  friend class LM;
974 
975 private:
976  std::string m_name; // the program name
977 
979 
980  LMMap* lmMap_realpath; // mapped by 'realpath'
982 
983 #if 0
984  static RealPathMgr& s_realpathMgr;
985 #endif
986 };
987 
988 
989 
990 // --------------------------------------------------------------------------
991 // Variable
992 // --------------------------------------------------------------------------
993 
994 class Variable: public ACodeNode {
995 public:
996  Variable(std::string nm, ANode* parent,
997  VMA begVMA = 0, VMA endVMA = 0)
998  :ACodeNode(TyVariable, parent, ln_NULL,ln_NULL, begVMA, endVMA)
999  {
1000  m_name = nm;
1001  }
1002 
1003 private:
1004  std::string m_name; // the variable name
1005 };
1006 
1007 
1008 // --------------------------------------------------------------------------
1009 // Groups are children of Root's, Group's, LMs's,
1010 // File's, Proc's, Loop's
1011 // children: Group's, LM's, File's, Proc's,
1012 // Loop's, Stmts,
1013 // They may be used to describe several different types of scopes
1014 // (including user-defined ones)
1015 // --------------------------------------------------------------------------
1016 class Group: public ACodeNode {
1017 public:
1018  Group(const char* nm, ANode* parent,
1019  int begLn = ln_NULL, int endLn = ln_NULL)
1020  : ACodeNode(TyGroup, parent, begLn, endLn, 0, 0)
1021  {
1022  Ctor(nm, parent);
1023  }
1024 
1025  Group(const std::string& nm, ANode* parent,
1026  int begLn = ln_NULL, int endLn = ln_NULL)
1027  : ACodeNode(TyGroup, parent, begLn, endLn, 0, 0)
1028  {
1029  Ctor(nm.c_str(), parent);
1030  }
1031 
1032  virtual ~Group()
1033  { }
1034 
1035  static Group*
1036  demand(Root* pgm, const std::string& nm, ANode* parent);
1037 
1038  virtual const std::string&
1039  name() const
1040  { return m_name; } // same as grpName
1041 
1042  virtual std::string
1043  codeName() const;
1044 
1045  virtual ANode*
1047  { return new Group(*this); }
1048 
1049  virtual std::string
1050  toXML(uint oFlags = 0) const;
1051 
1052  // --------------------------------------------------------
1053  // debugging
1054  // --------------------------------------------------------
1055 
1056  virtual std::ostream&
1057  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1058  const char* pre = "") const;
1059 
1060 private:
1061  void
1062  Ctor(const char* nm, ANode* parent);
1063 
1064 private:
1065  std::string m_name;
1066 };
1067 
1068 
1069 // --------------------------------------------------------------------------
1070 // LMs are children of Root's or Group's
1071 // children: Group's, File's
1072 // --------------------------------------------------------------------------
1073 class LM: public ACodeNode {
1074 protected:
1075  LM&
1076  operator=(const LM& x);
1077 
1078 public:
1079 
1080  // --------------------------------------------------------
1081  // Create/Destroy
1082  // --------------------------------------------------------
1083  LM(const char* nm, ANode* parent)
1084  : ACodeNode(TyLM, parent, ln_NULL, ln_NULL, 0, 0)
1085  {
1086  Ctor(nm, parent);
1087  }
1088 
1089  LM(const std::string& nm, ANode* parent)
1090  : ACodeNode(TyLM, parent, ln_NULL, ln_NULL, 0, 0)
1091  {
1092  Ctor(nm.c_str(), parent);
1093  }
1094 
1095  virtual ~LM()
1096  {
1097  delete m_fileMap;
1098  delete m_procMap;
1099  delete m_stmtMap;
1100  }
1101 
1102  virtual ANode*
1104  { return new LM(*this); }
1105 
1106  static LM*
1107  demand(Root* pgm, const std::string& lm_fnm);
1108 
1109 
1110  // --------------------------------------------------------
1111  //
1112  // --------------------------------------------------------
1113 
1114  virtual const std::string&
1115  name() const
1116  { return m_name; }
1117 
1118  virtual std::string
1119  codeName() const
1120  { return name(); }
1121 
1122  const char *
1123  pretty_name() const
1124  { return m_pretty_name.c_str(); }
1125 
1126  void
1127  pretty_name(const char *nm)
1128  { m_pretty_name = nm; }
1129 
1130  std::string
1131  baseName() const
1132  { return FileUtil::basename(m_name); }
1133 
1134 
1135  // --------------------------------------------------------
1136  // search for enclosing nodes
1137  // --------------------------------------------------------
1138 
1139  // findFile: find using RealPathMgr
1140  File*
1141  findFile(const char* nm) const;
1142 
1143  File*
1144  findFile(const std::string& nm) const
1145  { return findFile(nm.c_str()); }
1146 
1147 
1148  // --------------------------------------------------------
1149  // search by VMA
1150  // --------------------------------------------------------
1151 
1152  // findByVMA: find scope by *unrelocated* VMA
1153  // findProc: VMA interval -> Struct::Proc*
1154  // findStmt: VMA interval -> Struct::Stmt*
1155  //
1156  // N.B. these maps are maintained when new Struct::Proc or
1157  // Struct::Stmt are created
1158  ACodeNode*
1159  findByVMA(VMA vma) const;
1160 
1161  void
1163  {
1164  delete m_procMap;
1165  m_procMap = NULL;
1166  delete m_stmtMap;
1167  m_stmtMap = NULL;
1168  findProc(0);
1169  findStmt(0);
1170  }
1171 
1172 
1173  Proc*
1174  findProc(VMA vma) const;
1175 
1176  bool
1177  insertProcIf(Proc* proc) const
1178  {
1179  if (m_procMap) {
1180  insertInMap(m_procMap, proc);
1181  return true;
1182  }
1183  return false;
1184  }
1185 
1186 
1187  Stmt*
1188  findStmt(VMA vma) const;
1189 
1190  bool
1191  insertStmtIf(Stmt* stmt) const
1192  {
1193  if (m_stmtMap) {
1194  insertInMap(m_stmtMap, stmt);
1195  return true;
1196  }
1197  return false;
1198  }
1199 
1200  bool
1201  eraseStmtIf(Stmt* stmt) const
1202  {
1203  if (m_stmtMap) {
1204  eraseFromMap(m_stmtMap, stmt);
1205  return true;
1206  }
1207  return false;
1208  }
1209 
1210 
1211  // --------------------------------------------------------
1212  // Output
1213  // --------------------------------------------------------
1214 
1215  virtual std::string
1216  toXML(uint oFlags = 0) const;
1217 
1218  virtual std::ostream&
1219  writeXML(std::ostream& os = std::cout, uint oFlags = 0,
1220  const char* pre = "") const;
1221 
1222 
1223  virtual std::ostream&
1224  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1225  const char* pre = "") const;
1226 
1227  void
1228  dumpmaps() const;
1229 
1230  bool
1231  verifyStmtMap() const;
1232 
1233 public:
1236 
1237 protected:
1238  void
1239  Ctor(const char* nm, ANode* parent);
1240 
1241  void
1242  insertFileMap(File* file);
1243 
1244 
1245  template<typename T>
1246  void
1247  buildMap(VMAIntervalMap<T>*& mp, ANode::ANodeTy ty) const;
1248 
1249  template<typename T>
1250  void
1252  {
1253  const VMAIntervalSet& vmaset = x->vmaSet();
1254  for (VMAIntervalSet::const_iterator it = vmaset.begin();
1255  it != vmaset.end(); ++it) {
1256  const VMAInterval& vmaint = *it;
1257  DIAG_MsgIf(0, vmaint.toString());
1258  mp->insert(std::make_pair(vmaint, x));
1259  }
1260  }
1261 
1262 
1263  template<typename T>
1264  void
1266  {
1267  const VMAIntervalSet& vmaset = x->vmaSet();
1268  for (VMAIntervalSet::const_iterator it = vmaset.begin();
1269  it != vmaset.end(); ++it) {
1270  const VMAInterval& vmaint = *it;
1271  mp->erase(vmaint);
1272  }
1273  }
1274 
1275 
1276  template<typename T>
1277  static bool
1278  verifyMap(VMAIntervalMap<T>* mp, const char* map_nm);
1279 
1280 
1281  friend class File;
1282 
1283 private:
1284  std::string m_name; // the load module name
1285 
1286  // for pseudo module, this will be set
1287  // keep this in addition to m_name to avoid disturbing other
1288  // things that depend upon a full path
1289  std::string m_pretty_name;
1290 
1291  // maps to support fast lookups; building them does not logically
1292  // change the object
1293  FileMap* m_fileMap; // mapped by RealPathMgr
1294  mutable VMAToProcMap* m_procMap;
1295  mutable VMAToStmtRangeMap* m_stmtMap;
1296 
1297 #if 0
1298  static RealPathMgr& s_realpathMgr;
1299 #endif
1300 };
1301 
1302 
1303 // --------------------------------------------------------------------------
1304 // Files are children of Root's, Group's and LM's.
1305 // children: Group's, Proc's, Loop's, or Stmt's.
1306 // Files may refer to an unreadable file
1307 // --------------------------------------------------------------------------
1308 class File: public ACodeNode {
1309 protected:
1310  File(const File& x)
1311  : ACodeNode(x.m_type)
1312  { *this = x; }
1313 
1314  File&
1315  operator=(const File& x);
1316 
1317 public:
1318 
1319  // --------------------------------------------------------
1320  // Create/Destroy
1321  // --------------------------------------------------------
1322  File(const char* filenm, ANode *parent,
1323  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1324  : ACodeNode(TyFile, parent, begLn, endLn, 0, 0)
1325  {
1326  Ctor(filenm, parent);
1327  }
1328 
1329  File(const std::string& filenm, ANode *parent,
1330  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1331  : ACodeNode(TyFile, parent, begLn, endLn, 0, 0)
1332  {
1333  Ctor(filenm.c_str(), parent);
1334  }
1335 
1336  virtual ~File()
1337  {
1338  delete m_procMap;
1339  }
1340 
1341  virtual ANode*
1343  { return new File(*this); }
1344 
1345  static File*
1346  demand(LM* lm, const std::string& filenm);
1347 
1348 
1349  // --------------------------------------------------------
1350  //
1351  // --------------------------------------------------------
1352 
1353  virtual const std::string&
1354  name() const
1355  { return m_name; }
1356 
1357  virtual std::string
1358  codeName() const;
1359 
1360 
1361  void
1362  name(const char* fname)
1363  { m_name = fname; }
1364 
1365  void
1366  name(const std::string& fname)
1367  { m_name = fname; }
1368 
1369  std::string
1370  baseName() const
1371  { return FileUtil::basename(m_name); }
1372 
1373 
1374  // --------------------------------------------------------
1375  // search for enclosing nodes
1376  // --------------------------------------------------------
1377 
1378  // FindProc: Attempt to find the procedure within the multimap. If
1379  // 'lnm' is provided, require that link names match.
1380  Proc*
1381  findProc(const char* name, const char* linkname = NULL) const;
1382 
1383  Proc*
1384  findProc(const std::string& name, const std::string& linkname = "") const
1385  { return findProc(name.c_str(), linkname.c_str()); }
1386 
1387 
1388  // --------------------------------------------------------
1389  // Output
1390  // --------------------------------------------------------
1391 
1392  virtual std::string
1393  toXML(uint oFlags = 0) const;
1394 
1395  virtual void
1396  CSV_dump(const Root &root, std::ostream& os = std::cout,
1397  const char* file_name = NULL, const char* proc_name = NULL,
1398  int lLevel = 0) const;
1399 
1400  virtual std::ostream&
1401  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1402  const char* pre = "") const;
1403 
1404 private:
1405  void
1406  Ctor(const char* filenm, ANode* parent);
1407 
1408  void
1409  insertProcMap(Proc* proc);
1410 
1411  friend class Proc;
1412 
1413 private:
1414  std::string m_name; // the file name including the path
1416 
1417 #if 0
1418  static RealPathMgr& s_realpathMgr;
1419 #endif
1420 };
1421 
1422 
1423 // --------------------------------------------------------------------------
1424 // Procs are children of Group's or File's
1425 // children: Group's, Loop's, Stmt's
1426 //
1427 // (begLn == 0) <==> (endLn == 0)
1428 // (begLn != 0) <==> (endLn != 0)
1429 // --------------------------------------------------------------------------
1430 class Proc: public ACodeNode {
1431 protected:
1432  Proc(const Proc& x)
1433  : ACodeNode(x.m_type)
1434  { *this = x; }
1435 
1436  Proc&
1437  operator=(const Proc& x);
1438 
1439 public:
1440 
1441  // --------------------------------------------------------
1442  // Create/Destroy
1443  // --------------------------------------------------------
1444  Proc(const char* name, ACodeNode* parent, const char* linkname, bool hasSym,
1445  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1446  : ACodeNode(TyProc, parent, begLn, endLn, 0, 0)
1447  {
1448  Ctor(name, parent, linkname, hasSym);
1449  }
1450 
1451  Proc(const std::string& name, ACodeNode* parent, const std::string& linkname,
1452  bool hasSym, SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1453  : ACodeNode(TyProc, parent, begLn, endLn, 0, 0)
1454  {
1455  Ctor(name.c_str(), parent, linkname.c_str(), hasSym);
1456  }
1457 
1458  virtual ~Proc()
1459  {
1460  delete m_stmtMap;
1461  }
1462 
1463  virtual ANode*
1465  { return new Proc(*this); }
1466 
1467  // demand: if didCreate is non-NULL, it will be set to true if a new
1468  // Proc was created and false otherwise.
1469  // Note: currently sets hasSymbolic() to false on creation
1470  static Proc*
1471  demand(File* file, const std::string& name, const std::string& linkname,
1472  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL,
1473  bool* didCreate = NULL);
1474 
1475  static Proc*
1476  demand(File* file, const std::string& name)
1477  { return demand(file, name, "", ln_NULL, ln_NULL, NULL); }
1478 
1479 
1480  // --------------------------------------------------------
1481  //
1482  // --------------------------------------------------------
1483 
1484  virtual const std::string&
1485  name() const
1486  { return m_name; }
1487 
1488  virtual std::string
1489  codeName() const;
1490 
1491 
1492  void
1493  name(const char* x)
1494  { m_name = (x) ? x : ""; }
1495 
1496  void
1497  name(const std::string& x)
1498  { m_name = x; }
1499 
1500  const std::string&
1501  linkName() const
1502  { return m_linkname; }
1503 
1504  bool
1505  hasSymbolic() const
1506  { return m_hasSym; }
1507 
1508  void
1509  hasSymbolic(bool x)
1510  { m_hasSym = x; }
1511 
1512 
1513  // --------------------------------------------------------
1514  // search for enclosing nodes
1515  // --------------------------------------------------------
1516 
1517  // FIXME: confusion between native and alien statements
1518  Stmt*
1520  {
1521  StmtMap::iterator it = m_stmtMap->find(begLn);
1522  Stmt* x = (it != m_stmtMap->end()) ? it->second : NULL;
1523  return x;
1524  }
1525 
1526 
1527  // --------------------------------------------------------
1528  // Output
1529  // --------------------------------------------------------
1530 
1531  virtual std::string
1532  toXML(uint oFlags = 0) const;
1533 
1534  virtual void
1535  CSV_dump(const Root &root, std::ostream& os = std::cout,
1536  const char* file_name = NULL, const char* proc_name = NULL,
1537  int lLevel = 0) const;
1538 
1539  virtual std::ostream&
1540  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1541  const char* pre = "") const;
1542 
1543 private:
1544  void
1545  Ctor(const char* n, ACodeNode* parent, const char* ln, bool hasSym);
1546 
1547  void
1548  insertStmtMap(Stmt* stmt);
1549 
1550  friend class Stmt;
1551 
1552 private:
1553  std::string m_name;
1554  std::string m_linkname;
1555  bool m_hasSym;
1557 };
1558 
1559 
1560 // --------------------------------------------------------------------------
1561 // Alien: represents an alien context (e.g. inlined procedure, macro).
1562 //
1563 // Aliens are children of Group's, Alien's, Proc's
1564 // or Loop's
1565 // children: Group's, Alien's, Loop's, Stmt's
1566 //
1567 // (begLn == 0) <==> (endLn == 0)
1568 // (begLn != 0) <==> (endLn != 0)
1569 // --------------------------------------------------------------------------
1570 class Alien: public ACodeNode {
1571 protected:
1572  Alien(const Alien& x)
1573  : ACodeNode(x.m_type)
1574  { *this = x; }
1575 
1576  Alien&
1577  operator=(const Alien& x);
1578 
1579 public:
1580 
1581  // --------------------------------------------------------
1582  // Create/Destroy
1583  // --------------------------------------------------------
1584  Alien(ACodeNode* parent, const char* filenm, const char* procnm,
1585  const char* displaynm,
1586  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1587  : ACodeNode(TyAlien, parent, begLn, endLn, 0, 0)
1588  {
1589  Ctor(parent, filenm, procnm, displaynm);
1590  }
1591 
1592  Alien(ACodeNode* parent,
1593  const std::string& filenm, const std::string& procnm,
1594  const std::string& displaynm,
1595  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1596  : ACodeNode(TyAlien, parent, begLn, endLn, 0, 0)
1597  {
1598  Ctor(parent, filenm.c_str(), procnm.c_str(), displaynm.c_str());
1599  }
1600 
1601  virtual ~Alien()
1602  { }
1603 
1604  virtual ANode*
1606  { return new Alien(*this); }
1607 
1608 
1609  // --------------------------------------------------------
1610  //
1611  // --------------------------------------------------------
1612 
1613  const std::string&
1614  fileName() const
1615  { return m_filenm; }
1616 
1617  void
1618  fileName(const std::string& fnm)
1619  { m_filenm = fnm; }
1620 
1621  virtual const std::string&
1622  name() const
1623  { return m_name; }
1624 
1625  void
1626  name(const char* n)
1627  { m_name = n; }
1628 
1629  void
1630  name(const std::string& n)
1631  { m_name = n; }
1632 
1633  void
1635  { m_proc = proc; }
1636 
1637  const std::string&
1638  displayName() const
1639  { return m_displaynm; }
1640 
1641  virtual std::string
1642  codeName() const;
1643 
1644 
1645  // --------------------------------------------------------
1646  // Output
1647  // --------------------------------------------------------
1648 
1649  virtual std::string
1650  toXML(uint oFlags = 0) const;
1651 
1652  virtual void
1653  CSV_dump(const Root &root, std::ostream& os = std::cout,
1654  const char* file_name = NULL, const char* proc_name = NULL,
1655  int lLevel = 0) const;
1656 
1657  virtual std::ostream&
1658  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1659  const char* pre = "") const;
1660 
1661 private:
1662  void
1663  Ctor(ACodeNode* parent, const char* filenm, const char* procnm,
1664  const char* displaynm);
1665 
1666 private:
1667  std::string m_filenm;
1668  std::string m_name;
1669  std::string m_displaynm;
1670 
1672 
1673 #if 0
1674  static RealPathMgr& s_realpathMgr;
1675 #endif
1676 };
1677 
1678 
1679 // --------------------------------------------------------------------------
1680 // Loops are children of Group's, File's, Proc's,
1681 // or Loop's.
1682 // children: Group's, Loop's, or Stmt's
1683 // --------------------------------------------------------------------------
1684 class Loop: public ACodeNode {
1685 public:
1686 
1687  // --------------------------------------------------------
1688  // Create/Destroy
1689  // --------------------------------------------------------
1690  Loop(ACodeNode* parent, std::string &filenm,
1691  SrcFile::ln begLn = ln_NULL, SrcFile::ln endLn = ln_NULL)
1692  : ACodeNode(TyLoop, parent, begLn, endLn, 0, 0)
1693  {
1694  ANodeTy t = (parent) ? parent->type() : TyANY;
1695  setFile(filenm);
1696  DIAG_Assert((parent == NULL) || (t == TyGroup) || (t == TyFile) ||
1697  (t == TyProc) || (t == TyAlien) || (t == TyLoop), "");
1698  }
1699 
1700  void setFile(std::string filenm);
1701 
1702  virtual ~Loop()
1703  { }
1704 
1705  virtual ANode*
1707  { return new Loop(*this); }
1708 
1709 
1710  // --------------------------------------------------------
1711  //
1712  // --------------------------------------------------------
1713 
1714  virtual std::string
1715  codeName() const;
1716 
1717 
1718  // --------------------------------------------------------
1719  // Output
1720  // --------------------------------------------------------
1721 
1722  virtual std::string
1723  toXML(uint oFlags = 0) const;
1724 
1725  virtual std::ostream&
1726  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1727  const char* pre = "") const;
1728 
1729  const std::string&
1730  fileName() const
1731  { return m_filenm; }
1732 
1733  void
1734  fileName(const std::string& fnm)
1735  { m_filenm = fnm; }
1736 
1737 private:
1738  std::string m_filenm;
1739 };
1740 
1741 
1742 // --------------------------------------------------------------------------
1743 // Stmts are children of Group's, File's,
1744 // Proc's, or Loop's.
1745 // children: none
1746 // --------------------------------------------------------------------------
1747 class Stmt: public ACodeNode {
1748 public:
1749 
1750  // --------------------------------------------------------
1751  // Create/Destroy
1752  // --------------------------------------------------------
1753  Stmt(ACodeNode* parent, SrcFile::ln begLn, SrcFile::ln endLn,
1754  VMA begVMA = 0, VMA endVMA = 0)
1755  : ACodeNode(TyStmt, parent, begLn, endLn, begVMA, endVMA),
1756  m_sortId((int)begLn)
1757  {
1758  ANodeTy t = (parent) ? parent->type() : TyANY;
1759  DIAG_Assert((parent == NULL) || (t == TyGroup) || (t == TyFile)
1760  || (t == TyProc) || (t == TyAlien) || (t == TyLoop), "");
1761 
1762  LM* lmStrct = NULL;
1763  Proc* pStrct = ancestorProc();
1764  if (pStrct) {
1765  pStrct->insertStmtMap(this);
1766  lmStrct = pStrct->ancestorLM();
1767  }
1768  if (lmStrct && begVMA) {
1769  lmStrct->insertStmtIf(this);
1770  }
1771 
1772  //DIAG_DevMsg(3, "Stmt::Stmt: " << toStringMe());
1773  }
1774 
1775  virtual ~Stmt()
1776  { }
1777 
1778  virtual ANode*
1780  { return new Stmt(*this); }
1781 
1782 
1783  // --------------------------------------------------------
1784  //
1785  // --------------------------------------------------------
1786 
1787  virtual std::string codeName() const;
1788 
1789  // a handle for sorting within the enclosing procedure context
1790  int
1792  { return m_sortId; }
1793 
1794  void
1795  sortId(int x)
1796  { m_sortId = x; }
1797 
1798 
1799  // --------------------------------------------------------
1800  // Output
1801  // --------------------------------------------------------
1802 
1803  virtual std::string
1804  toXML(uint oFlags = 0) const;
1805 
1806  virtual std::ostream&
1807  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1808  const char* pre = "") const;
1809 
1810 private:
1812 };
1813 
1814 
1815 // ----------------------------------------------------------------------
1816 // Refs are chldren of LineScopes
1817 // They are used to describe a reference in source code.
1818 // Refs are build only iff we have preprocessing information.
1819 // ----------------------------------------------------------------------
1820 class Ref: public ACodeNode {
1821 public:
1822  Ref(ACodeNode* parent, int _begPos, int _endPos, const char* refName);
1823  // parent->type() == TyStmt
1824 
1825  uint
1826  BegPos() const
1827  { return begPos; };
1828 
1829  uint
1830  EndPos() const
1831  { return endPos; };
1832 
1833  virtual const std::string&
1834  name() const
1835  { return m_name; }
1836 
1837  virtual std::string
1838  codeName() const;
1839 
1840  virtual ANode*
1842  { return new Ref(*this); }
1843 
1844  virtual std::string
1845  toXML(uint oFlags = 0) const;
1846 
1847  // --------------------------------------------------------
1848  // debugging
1849  // --------------------------------------------------------
1850 
1851  virtual std::ostream&
1852  dumpme(std::ostream& os = std::cerr, uint oFlags = 0,
1853  const char* pre = "") const;
1854 
1855 private:
1856  void RelocateRef();
1859  std::string m_name;
1860 };
1861 
1862 
1863 } // namespace Struct
1864 } // namespace Prof
1865 
1866 
1867 /************************************************************************/
1868 // Iterators
1869 /************************************************************************/
1870 
1871 #include "Struct-TreeIterator.hpp"
1872 
1873 
1874 #endif /* prof_Prof_Struct_Tree_hpp */
virtual ANode * clone()
virtual ANode * clone()
VMAToProcMap * m_procMap
SrcFile::ln getScopeLineNum()
Proc * findProc(const std::string &name, const std::string &linkname="") const
void root(Root *x)
void insertInMap(VMAIntervalMap< T > *mp, T x) const
static uint s_nextUniqueId
static const std::string PartialUnwindProcNm
void aggregateMetrics(uint mBegId)
ANode * parent() const
unsigned int ln
Definition: SrcFile.hpp:66
void name(const char *x)
static const std::string UnknownFileNm
void name(const std::string &fname)
void fileName(const std::string &fnm)
bfd_vma VMA
Definition: ISATypes.hpp:79
std::string m_filenm
ANode & operator=(const ANode &x)
virtual ANode * clone()
My_t::const_iterator const_iterator
void checkLineRange(SrcFile::ln begLn, SrcFile::ln endLn)
std::string m_name
NonUniformDegreeTreeNode * NextSibling() const
static const std::string UnknownGlobalVariable
File * findFile(const std::string &nm) const
Group(const std::string &nm, ANode *parent, int begLn=ln_NULL, int endLn=ln_NULL)
ACodeNode & operator=(const ACodeNode &x)
virtual ANode * clone()
bool containsInterval(SrcFile::ln begLn, SrcFile::ln endLn) const
void writeXML(std::ostream &os, const Prof::Struct::Tree &strctTree, bool prettyPrint)
void name(const char *n)
File(const char *filenm, ANode *parent, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
Proc(const Proc &x)
NonUniformDegreeTreeNode * FirstChild() const
void computeVMAMaps() const
virtual const std::string & name() const
VMAToStmtRangeMap * m_stmtMap
bool equiv(bool p, bool q)
Definition: Logic.hpp:93
LM(const char *nm, ANode *parent)
virtual const std::string & name() const
bool containsInterval(SrcFile::ln begLn, SrcFile::ln endLn, int beg_epsilon, int end_epsilon) const
Group(const char *nm, ANode *parent, int begLn=ln_NULL, int endLn=ln_NULL)
std::set< ANode * > ANodeSet
std::string m_name
virtual ANode * clone()
bool eraseStmtIf(Stmt *stmt) const
virtual const std::string & name() const
bool hasSymbolic() const
static const std::string UnknownProcNm
void name(const std::string &n)
ANode * nextSibling() const
NonUniformDegreeTreeNode * LastChild() const
int compare(SrcFile::ln x, SrcFile::ln y)
Definition: SrcFile.hpp:80
void fileName(const std::string &fnm)
static uint maxId()
Alien(ACodeNode *parent, const char *filenm, const char *procnm, const char *displaynm, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
const std::string & linkName() const
Root * root() const
void name(const char *x)
std::string m_name
NonUniformDegreeTreeNode * PrevSibling() const
void name(const std::string &x)
#define DIAG_MsgIf(ifexpr,...)
Definition: diagnostics.h:236
virtual const std::string & name() const
static char * prefix
Definition: common.c:164
void(* T)(int code, va_list_box *box, int put(int c, void *cl), void *cl, unsigned char flags[256], int width, int precision)
Definition: fmt.h:62
void name(const std::string &x)
Root(const Root &x)
virtual std::string nameQual() const
LM(const std::string &nm, ANode *parent)
const char * pretty_name() const
LM * findLM(const std::string &nm) const
unsigned int uint
Definition: uint.h:124
bool insertStmtIf(Stmt *stmt) const
static Proc * demand(File *file, const std::string &name)
virtual ANode * clone()
bool empty() const
SrcFile::ln begLine() const
VMAIntervalSet m_vmaSet
Prof::Struct::Proc * m_proc
Alien(ACodeNode *parent, const std::string &filenm, const std::string &procnm, const std::string &displaynm, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
VMAIntervalMap< Stmt * > VMAToStmtRangeMap
VMAIntervalMap< Proc * > VMAToProcMap
Group * findGroup(const char *nm) const
void pretty_name(const char *nm)
static const std::string UnknownLMNm
bool empty() const
virtual std::string nameQual() const
virtual ANode * clone()
virtual const std::string & name() const
Root(const char *nm)
ACodeNode(const ACodeNode &x)
virtual const std::string & name() const
std::string & getScopeFileName()
bool isVisible() const
ANode(ANodeTy ty, ANode *parent=NULL)
uint BegPos() const
uint EndPos() const
void eraseFromMap(VMAIntervalMap< T > *mp, T x) const
ANode * firstChild() const
virtual std::string codeName() const
const VMAIntervalSet & vmaSet() const
Loop(ACodeNode *parent, std::string &filenm, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
std::string m_pretty_name
Stmt * findStmt(SrcFile::ln begLn)
ANode * lastChild() const
ANode(const ANode &x)
ANode * prevSibling() const
std::string baseName() const
RealPathMgr & s_realpathMgr
Group * findGroup(const std::string &nm) const
void endLine(SrcFile::ln x)
File(const File &x)
Proc(const std::string &name, ACodeNode *parent, const std::string &linkname, bool hasSym, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
const std::string & displayName() const
std::string baseName() const
File(const std::string &filenm, ANode *parent, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)
bool insertProcIf(Proc *proc) const
std::list< ANode * > ANodeList
Definition: Struct-Tree.hpp:96
void hasSymbolic(bool x)
const std::string & fileName() const
std::string m_displaynm
void name(const char *fname)
SrcFile::ln endLine() const
Root(const std::string &nm)
#define NULL
Definition: ElfHelper.cpp:85
Tree(const std::string &name, Root *root=NULL)
virtual const std::string & name() const
virtual ANode * clone()
Stmt(ACodeNode *parent, SrcFile::ln begLn, SrcFile::ln endLn, VMA begVMA=0, VMA endVMA=0)
void insertStmtMap(Stmt *stmt)
const std::string & fileName() const
virtual ANode * clone()
std::string toString() const
Definition: VMAInterval.cpp:93
void begLine(SrcFile::ln x)
LM * ancestorLM() const
string basename(const char *fName)
Definition: FileUtil.cpp:90
std::string m_linkname
NonUniformDegreeTreeNode * Parent() const
IData & operator=(const IData &x)
bool containsLine(SrcFile::ln ln) const
VMAIntervalSet & vmaSet()
virtual ANode * clone()
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
Variable(std::string nm, ANode *parent, VMA begVMA=0, VMA endVMA=0)
virtual const std::string & name() const
void proc(Prof::Struct::Proc *proc)
Alien(const Alien &x)
static const SrcFile::ln UnknownLine
void setScopeLocation(std::string &file, SrcFile::ln line)
ACodeNode(ANodeTy ty, ANode *parent=NULL, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL, VMA begVMA=0, VMA endVMA=0)
virtual ANode * clone()
ANodeTy type() const
const ln ln_NULL
Definition: SrcFile.hpp:67
Proc(const char *name, ACodeNode *parent, const char *linkname, bool hasSym, SrcFile::ln begLn=ln_NULL, SrcFile::ln endLn=ln_NULL)