Manages the data related to specific set of opcodes, e.g. tier1 (with prefix "opcode") or tier2 (with prefix "uops").
| 180 | |
| 181 | |
| 182 | class OpcodeStats: |
| 183 | """ |
| 184 | Manages the data related to specific set of opcodes, e.g. tier1 (with prefix |
| 185 | "opcode") or tier2 (with prefix "uops"). |
| 186 | """ |
| 187 | |
| 188 | def __init__(self, data: dict[str, Any], defines, specialized_instructions): |
| 189 | self._data = data |
| 190 | self._defines = defines |
| 191 | self._specialized_instructions = specialized_instructions |
| 192 | |
| 193 | def get_opcode_names(self) -> KeysView[str]: |
| 194 | return self._data.keys() |
| 195 | |
| 196 | def get_pair_counts(self) -> dict[tuple[str, str], int]: |
| 197 | pair_counts = {} |
| 198 | for name_i, opcode_stat in self._data.items(): |
| 199 | for key, value in opcode_stat.items(): |
| 200 | if value and key.startswith("pair_count"): |
| 201 | name_j, _, _ = key[len("pair_count") + 1 :].partition("]") |
| 202 | pair_counts[(name_i, name_j)] = value |
| 203 | return pair_counts |
| 204 | |
| 205 | def get_total_execution_count(self) -> int: |
| 206 | return sum(x.get("execution_count", 0) for x in self._data.values()) |
| 207 | |
| 208 | def get_execution_counts(self) -> dict[str, tuple[int, int]]: |
| 209 | counts = {} |
| 210 | for name, opcode_stat in self._data.items(): |
| 211 | if "execution_count" in opcode_stat: |
| 212 | count = opcode_stat["execution_count"] |
| 213 | miss = 0 |
| 214 | if "specializable" not in opcode_stat: |
| 215 | miss = opcode_stat.get("specialization.miss", 0) |
| 216 | counts[name] = (count, miss) |
| 217 | return counts |
| 218 | |
| 219 | @functools.cache |
| 220 | def _get_pred_succ( |
| 221 | self, |
| 222 | ) -> tuple[dict[str, collections.Counter], dict[str, collections.Counter]]: |
| 223 | pair_counts = self.get_pair_counts() |
| 224 | |
| 225 | predecessors: dict[str, collections.Counter] = collections.defaultdict( |
| 226 | collections.Counter |
| 227 | ) |
| 228 | successors: dict[str, collections.Counter] = collections.defaultdict( |
| 229 | collections.Counter |
| 230 | ) |
| 231 | for (first, second), count in pair_counts.items(): |
| 232 | if count: |
| 233 | predecessors[second][first] = count |
| 234 | successors[first][second] = count |
| 235 | |
| 236 | return predecessors, successors |
| 237 | |
| 238 | def get_predecessors(self, opcode: str) -> collections.Counter[str]: |
| 239 | return self._get_pred_succ()[0][opcode] |
no outgoing calls
no test coverage detected
searching dependent graphs…