Commit a4e85f89e8 for qemu.org

commit a4e85f89e8c765ea5d425651741ac1e6d510b70d
Author: Bin Guo <guobin@linux.alibaba.com>
Date:   Tue Mar 31 14:07:31 2026 +0800

    memory: Optimize flatview_simplify() to eliminate redundant memmove calls

    The original flatview_simplify() implementation uses memmove() to shift
    array elements after each merge operation, resulting in O(n²) time
    complexity in the worst case. This is inefficient for VMs with large
    memory topologies containing hundreds of MemoryRegions.

    Replace the memmove-based approach with a two-pointer in-place compression
    algorithm that achieves O(n) time complexity. The new algorithm uses a
    write pointer i and a read pointer j, where i ≤ j is always maintained.
    This invariant ensures we never overwrite unprocessed data, making memmove
    unnecessary.

    Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
    Link: https://lore.kernel.org/r/20260331060731.82641-1-guobin@linux.alibaba.com
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

diff --git a/system/memory.c b/system/memory.c
index 56f3225b21..0ff066c348 100644
--- a/system/memory.c
+++ b/system/memory.c
@@ -336,24 +336,25 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
 /* Attempt to simplify a view by merging adjacent ranges */
 static void flatview_simplify(FlatView *view)
 {
-    unsigned i, j, k;
+    unsigned i, j;
+
+    if (view->nr <= 1) {
+        return;
+    }

     i = 0;
-    while (i < view->nr) {
-        j = i + 1;
-        while (j < view->nr
-               && can_merge(&view->ranges[j-1], &view->ranges[j])) {
+    for (j = 1; j < view->nr; j++) {
+        if (can_merge(&view->ranges[i], &view->ranges[j])) {
             int128_addto(&view->ranges[i].addr.size, view->ranges[j].addr.size);
-            ++j;
-        }
-        ++i;
-        for (k = i; k < j; k++) {
-            memory_region_unref(view->ranges[k].mr);
+            memory_region_unref(view->ranges[j].mr);
+        } else {
+            i++;
+            if (i != j) {
+                view->ranges[i] = view->ranges[j];
+            }
         }
-        memmove(&view->ranges[i], &view->ranges[j],
-                (view->nr - j) * sizeof(view->ranges[j]));
-        view->nr -= j - i;
     }
+    view->nr = i + 1;
 }

 static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)