From a68eac4c9ba5b8753880ad2d3626f3a9ee992ece Mon Sep 17 00:00:00 2001 From: Emmanuel Blot Date: Wed, 28 Aug 2024 11:01:59 +0200 Subject: [PATCH] [rom_ctrl,util] Make collision check faster in scramble_image.py Update the collision check implementation using a dict to traverse the chunks only once. Signed-off-by: Emmanuel Blot --- hw/ip/rom_ctrl/util/mem.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/hw/ip/rom_ctrl/util/mem.py b/hw/ip/rom_ctrl/util/mem.py index 1f96eeb93ea489..b76864e62a2b26 100644 --- a/hw/ip/rom_ctrl/util/mem.py +++ b/hw/ip/rom_ctrl/util/mem.py @@ -6,6 +6,7 @@ import re import subprocess import tempfile +from itertools import combinations from typing import Any, BinaryIO, Dict, IO, List, Optional, TextIO, Tuple from elftools.elf.elffile import ELFFile # type: ignore @@ -331,16 +332,15 @@ def collisions(self) -> List[Tuple[int, int]]: such addresses where addr0 < addr1 and in ascending order of addr0. ''' - ret = [] - for idx0, chunk0 in enumerate(self.chunks): - for off0, word0 in enumerate(chunk0.words): - for diff_idx, chunk1 in enumerate(self.chunks[idx0:]): - first_off1 = 0 if diff_idx else off0 + 1 - for diff_off, word1 in enumerate(chunk1.words[first_off1:]): - off1 = first_off1 + diff_off - - if word0 == word1: - addr0 = chunk0.base_addr + off0 - addr1 = chunk1.base_addr + off1 - ret.append((addr0, addr1)) - return ret + data = {} # type: Dict[int, List[int]] + for chunk in self.chunks: + addr = chunk.base_addr + for off, word in enumerate(chunk.words): + if word not in data: + data[word] = [] + data[word].append(addr + off) + ret = [] # type: List[Tuple[int, int]] + for addrs in data.values(): + if len(addrs) > 1: + ret.extend(combinations(addrs, 2)) + return list(sorted(ret))