File indexing completed on 2024-04-28 09:36:46
0001 /* 0002 This file is part of KCachegrind. 0003 0004 SPDX-FileCopyrightText: 2002-2016 Josef Weidendorfer <Josef.Weidendorfer@gmx.de> 0005 0006 SPDX-License-Identifier: GPL-2.0-only 0007 */ 0008 0009 #ifndef EVENTTYPE_H 0010 #define EVENTTYPE_H 0011 0012 #include <QString> 0013 0014 #include "subcost.h" 0015 #include "costitem.h" 0016 0017 class EventTypeSet; 0018 0019 /** 0020 * A cost type, e.g. "L1 Read Miss", short "l1rm". 0021 * 0022 * We distinguish "real" cost types, where the values come 0023 * from the trace file, and "virtual" cost types, which 0024 * are calculated from the real ones. 0025 * 0026 * For a virtual cost type, set a formula to calculate it: 0027 * e.g. for "Read Misses" : "l1rm + l2rm". 0028 * To allow for parsing, you must specify a EventTypeSet 0029 * with according cost types (e.g. "l1rm" and "l2rm" for above formula). 0030 * 0031 * The cost type with empty name is the "const" cost type. 0032 */ 0033 class EventType 0034 { 0035 public: 0036 0037 /** 0038 * @param name is a short (non-localized) identifier for the cost type, 0039 * e.g. "l1rm". 0040 * @param longName is a long localized string, e.g. "L1 Read Miss" 0041 * @param formula uses short names to reference other types 0042 */ 0043 explicit EventType(const QString& name, 0044 const QString& longName = QString(), 0045 const QString& formula = QString()); 0046 0047 void setName(const QString& n) { _name = n; } 0048 void setLongName(const QString& n) { _longName = n; } 0049 void setEventTypeSet(EventTypeSet* m); 0050 // enforces event to be derived, even with empty formula 0051 void setFormula(const QString&); 0052 // default arg is for specifying a real type, but index unknown 0053 void setRealIndex(int r = ProfileCostArray::MaxRealIndex); 0054 0055 const QString& name() { return _name; } 0056 const QString& longName() { return _longName; } 0057 const QString& formula() { return _formula; } 0058 EventTypeSet* set() { return _set; } 0059 int realIndex() { return _realIndex; } 0060 bool isReal() { return _isReal; } 0061 0062 /* 0063 * returns true if all cost type names can be resolved in formula 0064 */ 0065 bool parseFormula(); 0066 QString parsedFormula(); 0067 QString parsedRealFormula(); 0068 0069 SubCost subCost(ProfileCostArray*); 0070 0071 /* 0072 * For virtual costs, returns a histogram for use with 0073 * partitionPixmap(). 0074 * Returns maximal real index. 0075 */ 0076 int histCost(ProfileCostArray* c, double total, double* hist); 0077 0078 // application wide known types, referenced by short name 0079 // next 2 functions return a new event type instance 0080 static EventType* cloneKnownRealType(const QString&); 0081 static EventType* cloneKnownDerivedType(const QString&); 0082 static bool hasKnownRealType(const QString&); 0083 static bool hasKnownDerivedType(const QString&); 0084 static void add(EventType*, bool overwriteExisting = true); 0085 static bool remove(const QString&); 0086 static int knownTypeCount(); 0087 static EventType* knownType(int); 0088 0089 private: 0090 0091 QString _name, _longName, _formula, _parsedFormula; 0092 EventTypeSet* _set; 0093 bool _parsed, _inParsing, _isReal; 0094 // index MaxRealIndex is for constant addition 0095 int _coefficient[MaxRealIndexValue]; 0096 int _realIndex; 0097 0098 static QList<EventType*>* _knownTypes; 0099 }; 0100 0101 0102 /** 0103 * A class for managing a set of event types. 0104 * 0105 * Each event type has an index: 0106 * - Real events are in range [0 .. ProfileCostArray:MaxRealIndex[ 0107 * - Derived events are in range [MaxRealIndex, ...] 0108 */ 0109 class EventTypeSet 0110 { 0111 public: 0112 EventTypeSet(); 0113 ~EventTypeSet(); 0114 0115 /** 0116 * Defines a mapping from indexes into a list of costs to real event types 0117 * @param types the types 0118 */ 0119 EventTypeMapping* createMapping(const QString& types); 0120 0121 // "knows" about some real types 0122 int addReal(const QString&); 0123 int add(EventType*); 0124 bool remove(EventType*); 0125 int realCount() { return _realCount; } 0126 int derivedCount() { return _derivedCount; } 0127 int minDerivedIndex() { return ProfileCostArray::MaxRealIndex; } 0128 EventType* type(int); 0129 EventType* realType(int); 0130 EventType* derivedType(int); 0131 EventType* type(const QString&); 0132 EventType* typeForLong(const QString&); 0133 int realIndex(const QString&); 0134 int index(const QString&); 0135 0136 /** 0137 * Adds all known derived event types that can be parsed 0138 */ 0139 int addKnownDerivedTypes(); 0140 0141 private: 0142 // we support only a fixed number of real and derived types 0143 EventType* _real[MaxRealIndexValue]; 0144 EventType* _derived[MaxRealIndexValue]; 0145 int _realCount, _derivedCount; 0146 }; 0147 0148 /** 0149 * A index list into a EventTypeSet 0150 * 0151 * This ordered list maps from indexes into real cost types 0152 * of a set. 0153 * 0154 * You can define a set of event types by requesting submaps by name. 0155 * Every new event type name will get a new real type index. 0156 * EventTypeSet s; 0157 * m1 = s.createMapping("Event1 Cost1 Cost2"); // returns mapping [0,1,2] 0158 * m2 = s.createMapping("Event2 Cost3 Event1"); // returns mapping [3,4,0] 0159 * Real types of s will be: 0160 * (0:Event1, 1:Cost1, 2:Cost2, 3:Event2, 4:Cost3) 0161 */ 0162 class EventTypeMapping 0163 { 0164 public: 0165 explicit EventTypeMapping(EventTypeSet*); 0166 0167 bool append(const QString&, bool create=true); 0168 bool append(int); 0169 void clear(); 0170 0171 EventTypeSet* set() { return _set; } 0172 0173 /** 0174 * Get number of used indexes 0175 */ 0176 int count() { return _count; } 0177 0178 /** 0179 * Is this mapping the identity( i.e. realIndex(i)=i ) ? 0180 * This often allows for optimizations. 0181 */ 0182 bool isIdentity() { return _isIdentity; } 0183 int realIndex(int i) 0184 { return (i<0 || i>=_count) ? ProfileCostArray::InvalidIndex : _realIndex[i]; } 0185 0186 /** 0187 * Get maximal real index for the first @p count mapping indexes. 0188 * @param count the count 0189 */ 0190 int maxRealIndex(int count); 0191 0192 /** 0193 * Allows an iteration over the sorted list of all real indexes not used in 0194 * this mapping, up to topIndex (use ProfileCostArray::MaxRealIndex for all). 0195 * Usage: for(i = firstUnused(); i < topIndex; i = nextUnused(i)) { LOOP } 0196 */ 0197 int firstUnused() { return _firstUnused; } 0198 int nextUnused(int i) { 0199 if (i<0 || i>=ProfileCostArray::MaxRealIndex) return ProfileCostArray::InvalidIndex; 0200 return _nextUnused[i]; } 0201 0202 private: 0203 EventTypeSet* _set; 0204 int _count, _firstUnused; 0205 bool _isIdentity; 0206 int _realIndex[MaxRealIndexValue]; 0207 int _nextUnused[MaxRealIndexValue]; 0208 }; 0209 0210 0211 #endif // EVENTTYPE_H