HPCToolkit
DCPIMetricDesc.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 // DCPIMetricDesc.C
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::endl;
64 using std::hex;
65 using std::dec;
66 
67 #include <string>
68 using std::string;
69 
70 #include <cstring>
71 
72 //*************************** User Include Files ****************************
73 
74 #include "DCPIMetricDesc.hpp"
75 
77 
78 //*************************** Forward Declarations ***************************
79 
80 int
81 SetDCPIMetricDescBit(const char* token, DCPIMetricDesc& m);
82 
83 
84 //****************************************************************************
85 // DCPITranslationTable
86 //****************************************************************************
87 
89 public:
90  struct Entry {
91  const char* tok;
93  };
94 
95 public:
98 
99  static Entry* FindEntry(const char* token);
100  static unsigned int GetSize() { return size; }
101 
102 private:
103  // Should not be used
106 
107 private:
108  static Entry table[];
109  static unsigned int size;
110  static bool sorted;
111 };
112 
113 //****************************************************************************
114 
115 #define TYPEPM(m) DCPI_MTYPE_PM | (m)
116 #define TYPERM(m) DCPI_MTYPE_RM | (m)
117 
118 // 'pfx', 'n1', 'n2', 'n3' should all be strings
119 #define DCPI_PM_CNTR(pfx, n1, n2, n3, bit1, bit2, bit3) \
120  { pfx n1, TYPEPM((bit1)) }, \
121  { pfx n2, TYPEPM((bit2)) }, \
122  { pfx n3, TYPEPM((bit3)) }
123  /* the macro concatenation operator ## must produce a token */
124 
125 // 'name' should be a string
126 #define DCPI_PM_ATTR(name, truebits, falsebits) \
127  { name, TYPEPM((truebits)) }, \
128  { "!" name, TYPEPM((falsebits)) }
129  /* the macro concatenation operator ## must produce a token */
130 
131 // 'name' should be a string
132 #define DCPI_PM_TRAP(name, truebits, falsebits) \
133  { name, TYPEPM((truebits)) }, \
134  { "!" name, TYPEPM((falsebits)) }
135  /* the macro concatenation operator ## must produce a token */
136 
137 
138 #define TABLE_SZ \
139  sizeof(DCPITranslationTable::table) / sizeof(DCPITranslationTable::Entry)
140 
141 
143  // ProfileMe counters
144  DCPI_PM_CNTR("m0", "count", "inflight", "retires", DCPI_PM_CNTR_count, DCPI_PM_CNTR_inflight, DCPI_PM_CNTR_retires),
145  DCPI_PM_CNTR("m1", "count", "inflight", "retdelay", DCPI_PM_CNTR_count, DCPI_PM_CNTR_inflight, DCPI_PM_CNTR_retdelay),
146  DCPI_PM_CNTR("m2", "count", "retires", "bcmisses", DCPI_PM_CNTR_count, DCPI_PM_CNTR_retires, DCPI_PM_CNTR_bcmisses),
147  DCPI_PM_CNTR("m3", "count", "inflight", "replays", DCPI_PM_CNTR_count, DCPI_PM_CNTR_inflight, DCPI_PM_CNTR_replays),
148 
149  // ProfileMe instruction attributes
161 
162  // ProfileMe instruction traps
163  { "trap", TYPEPM(DCPI_PM_TRAP_trap) },
180 
181  // Non-ProfileMe event types
182  { "cycles", TYPERM(DCPI_RM_cycles) },
183  { "retires", TYPERM(DCPI_RM_retires) },
184  { "replaytrap", TYPERM(DCPI_RM_replaytrap) },
185  { "bmiss", TYPERM(DCPI_RM_bmiss) }
186 
187 };
188 
189 unsigned int DCPITranslationTable::size = TABLE_SZ;
190 
191 bool DCPITranslationTable::sorted = false;
192 
193 #undef TYPEPM
194 #undef TYPERM
195 #undef DCPI_PM_CNTR
196 #undef DCPI_PM_ATTR
197 #undef DCPI_PM_TRAP
198 #undef TABLE_SZ
199 
200 //****************************************************************************
201 
204 {
205  // FIXME: we should search a quick-sorted table with binary search.
206  // check 'sorted'
207  Entry* found = NULL;
208  for (unsigned int i = 0; i < GetSize(); ++i) {
209  if (strcmp(token, table[i].tok) == 0) {
210  found = &table[i];
211  }
212  }
213  return found;
214 }
215 
216 
217 //****************************************************************************
218 // DCPIMetricDesc
219 //****************************************************************************
220 
222 {
223  Ctor(str);
224 }
225 
226 
227 DCPIMetricDesc::DCPIMetricDesc(const std::string& str)
228 {
229  Ctor(str.c_str());
230 }
231 
232 
233 void DCPIMetricDesc::Ctor(const char* str)
234 {
236  bits = m.bits;
237 }
238 
239 
240 // String2DCPIMetricDesc: See header for accepted syntax. If an error
241 // occurs, the DCPIMetricDesc::IsValid() will return false.
243 String2DCPIMetricDesc(const char* str)
244 {
245  DCPIMetricDesc m; // initialized to invalid state
246 
247  // 0. Test for NULL or empty string
248  if (!str || strlen(str) == 0) {
249  return m;
250  }
251 
252  // 1. Special recursive case (should only happen once)
253  // str ::= ProfileMe_sample_set:ProfileMe_counter
254  // Note: cannot use strtok because of recursion.
255  char* sep = const_cast<char*>(strchr(str, ':')); // separator
256  if (sep != NULL) {
257  *sep = '\0'; // temporarily modify to get first part
258  string sampleset = str;
259  *sep = ':';
260  string counter = sep+1;
261  DCPIMetricDesc m1 = String2DCPIMetricDesc(sampleset.c_str());
262  DCPIMetricDesc m2 = String2DCPIMetricDesc(counter.c_str());
263 
264  if (m1.IsValid() && m2.IsValid()) {
265  m.Set(m1);
266  m.Set(m2);
267  }
268  return m;
269  }
270 
271  // 2. Typical case:
272  // str ::= ProfileMe_sample_set | ProfileMe_counter | Regular_counter
273  //
274  // ProfileMe_sample_set may contain multiple tokens (divided by '^');
275  // otherwise we can only distinguish which type we have by
276  // string matching. Fortunately, this can be a very simple
277  // implementation because attribute and counter names are unique.
278 
279  DCPIMetricDesc m1;
280  char* tok = strtok(const_cast<char*>(str), "^");
281  while (tok != NULL) {
282  int ret = SetDCPIMetricDescBit(tok, m1);
283  if (ret != 0) { return m; }
284 
285  tok = strtok((char*)NULL, "^");
286  }
287  m.Set(m1);
288 
289  return m;
290 }
291 
292 
293 // SetDCPIMetricDescBit: Given a DCPI bit value (possibly preceeded by
294 // ! for negation) or counter name token string, set the appropriate
295 // bit in 'm'. Returns non-zero on error.
296 int
297 SetDCPIMetricDescBit(const char* token, DCPIMetricDesc& m)
298 {
299  // 0. Test for NULL or empty string
300  if (!token || strlen(token) == 0) {
301  return 1;
302  }
303 
304  // 1. Set the appropriate bit by string comparisons
306  if (!e) { return 1; }
307  m.Set(e->bits);
308 
309  return 0;
310 }
311 
312 //****************************************************************************
313 
314 
#define DCPI_PM_TRAP_OPCDECtrap
#define DCPI_PM_TRAP_itbmiss
#define DCPI_PM_TRAP_notrap
#define DCPI_PM_ATTR_retired_F
#define DCPI_PM_ATTR_early_kill_T
#define DCPI_PM_ATTR(name, truebits, falsebits)
#define DCPI_PM_TRAP(name, truebits, falsebits)
#define DCPI_PM_TRAP_interrupt
#define DCPI_PM_ATTR_late_kill_F
#define TABLE_SZ
#define DCPI_PM_TRAP_N_mchktrap
#define DCPI_RM_retires
#define TYPEPM(m)
#define DCPI_RM_bmiss
void Ctor(const char *str)
#define DCPI_PM_TRAP_dtbmiss
#define DCPI_PM_TRAP_N_dtb2miss4
#define DCPI_PM_ATTR_early_kill_F
int SetDCPIMetricDescBit(const char *token, DCPIMetricDesc &m)
#define DCPI_PM_TRAP_trap
#define DCPI_PM_CNTR_count
#define DCPI_PM_CNTR_retires
#define DCPI_PM_ATTR_nyp_F
#define DCPI_PM_TRAP_N_MT_FPCRtrap
#define TYPERM(m)
#define DCPI_PM_TRAP_arithtrap
#define DCPI_PM_ATTR_map_stall_F
#define DCPI_PM_ATTR_capped_T
#define DCPI_PM_TRAP_N_dfaulttrap
#define DCPI_PM_TRAP_N_fpdisabledtrap
#define DCPI_PM_TRAP_N_arithtrap
#define DCPI_PM_ATTR_valid_F
#define DCPI_PM_ATTR_nyp_T
#define DCPI_PM_TRAP_N_unaligntrap
#define DCPI_PM_TRAP_N_dtbmiss
#define DCPI_PM_TRAP_mchktrap
static unsigned int GetSize()
#define DCPI_PM_TRAP_MT_FPCRtrap
#define DCPI_PM_TRAP_iacvtrap
static unsigned int size
void Set(const bitvec_t bv)
static Entry * FindEntry(const char *token)
DCPIMetricDesc::bitvec_t bits
#define DCPI_PM_CNTR_replays
DCPITranslationTable & operator=(const DCPITranslationTable &p)
DCPITranslationTable(const DCPITranslationTable &p)
#define DCPI_RM_cycles
#define DCPI_PM_CNTR_bcmisses
#define DCPI_PM_ATTR_taken_T
#define DCPI_PM_ATTR_late_kill_T
#define DCPI_PM_TRAP_N_mispredict
#define DCPI_PM_ATTR_map_stall_T
#define DCPI_PM_TRAP_N_itbmiss
#define DCPI_PM_TRAP_N_iacvtrap
bool found
Definition: cct.c:129
#define DCPI_PM_ATTR_ldstorder_F
#define DCPI_PM_TRAP_replays
#define DCPI_PM_TRAP_N_interrupt
bool IsValid() const
DCPIMetricDesc(bitvec_t bv=0)
#define DCPI_PM_ATTR_ldstorder_T
#define DCPI_PM_TRAP_dfaulttrap
#define DCPI_PM_CNTR(pfx, n1, n2, n3, bit1, bit2, bit3)
#define DCPI_PM_TRAP_dtb2miss3
#define DCPI_RM_replaytrap
#define NULL
Definition: ElfHelper.cpp:85
DCPIMetricDesc String2DCPIMetricDesc(const char *str)
#define DCPI_PM_TRAP_dtb2miss4
#define DCPI_PM_TRAP_fpdisabledtrap
#define DCPI_PM_ATTR_valid_T
#define DCPI_PM_ATTR_twnzrd_F
#define DCPI_PM_TRAP_unaligntrap
#define DCPI_PM_TRAP_N_dtb2miss3
#define DCPI_PM_TRAP_N_replays
#define DCPI_PM_ATTR_cbrmispredict_F
#define DCPI_PM_ATTR_cbrmispredict_T
#define DCPI_PM_TRAP_mispredict
#define DCPI_PM_ATTR_twnzrd_T
#define DCPI_PM_ATTR_retired_T
#define DCPI_PM_CNTR_inflight
#define DCPI_PM_ATTR_capped_F
#define DCPI_PM_TRAP_N_OPCDECtrap
#define DCPI_PM_TRAP_N_notrap
#define DCPI_PM_CNTR_retdelay
#define DCPI_PM_ATTR_taken_F