mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-19 09:18:10 +02:00
This was something that came up in the slop MR. Not sure it's actually a
good idea or not but kind of curious what people think, given we have a
sound tool (Coccinelle) to do the transform. Saves a redundant branch
but means extra noninlined function calls.. likely no actual perf impact
but saves some code.
Via Coccinelle patches:
@@
expression ptr;
@@
-if (ptr) {
-free(ptr);
-}
+free(ptr);
@@
expression ptr;
@@
-if (ptr) {
-FREE(ptr);
-}
+FREE(ptr);
@@
expression ptr;
@@
-if (ptr) {
-ralloc_free(ptr);
-}
+ralloc_free(ptr);
@@
expression ptr;
@@
-if (ptr != NULL) {
-free(ptr);
-}
-
+free(ptr);
@@
expression ptr;
@@
-if (ptr != NULL) {
-FREE(ptr);
-}
-
+FREE(ptr);
@@
expression ptr;
@@
-if (ptr != NULL) {
-ralloc_free(ptr);
-}
-
+ralloc_free(ptr);
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> [v3d]
Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> [venus]
Reviewed-by: Frank Binns <frank.binns@imgtec.com> [powervr]
Reviewed-by: Janne Grunau <j@jannau.net> [asahi]
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> [radv]
Reviewed-by: Job Noorman <jnoorman@igalia.com> [ir3]
Acked-by: Marek Olšák <maraeo@gmail.com>
Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Acked-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Acked-by: Job Noorman <jnoorman@igalia.com>
Acked-by: Yonggang Luo <luoyonggang@gmail.com>
Acked-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37892>
213 lines
6.5 KiB
C
213 lines
6.5 KiB
C
/*
|
|
* Copyright © 2025 Valve Corporation
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the next
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
* Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "ralloc.h"
|
|
#include "u_range_remap.h"
|
|
|
|
/* Binary search for the range that contains n */
|
|
static struct range_entry *
|
|
get_range_entry(unsigned n, const struct range_remap *r_remap)
|
|
{
|
|
if (!r_remap->sorted_array)
|
|
return NULL;
|
|
|
|
unsigned low = 0;
|
|
unsigned high = r_remap->sorted_array_length - 1;
|
|
unsigned mid = (low + high) / 2;
|
|
|
|
struct range_entry *mid_entry = &r_remap->sorted_array[mid];
|
|
|
|
while (low <= high) {
|
|
if (n < mid_entry->start) {
|
|
if (low == high || mid == low) {
|
|
/* No entry found for n */
|
|
return NULL;
|
|
}
|
|
|
|
high = mid - 1;
|
|
mid = (low + high) / 2;
|
|
|
|
/* Move backward to new_mid */
|
|
mid_entry = &r_remap->sorted_array[mid];
|
|
} else if (n > mid_entry->end) {
|
|
if (low == high || mid == high) {
|
|
/* No entry found for n */
|
|
return NULL;
|
|
}
|
|
|
|
low = mid + 1;
|
|
mid = (low + high) / 2;
|
|
|
|
/* Move forward to new_mid */
|
|
mid_entry = &r_remap->sorted_array[mid];
|
|
} else {
|
|
/* n is within the current range */
|
|
return mid_entry;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* Insert a new range entry or if ptr is non-null update an existing entries
|
|
* pointer value if start and end match exactly. If the range overlaps an
|
|
* existing entry we return NULL or if start and end match an entry exactly
|
|
* but ptr is null we return the existing entry.
|
|
*/
|
|
struct range_entry *
|
|
util_range_insert_remap(unsigned start, unsigned end,
|
|
struct range_remap *r_remap, void *ptr)
|
|
{
|
|
struct list_head *r_list = &r_remap->r_list;
|
|
struct list_range_entry *lre = NULL;
|
|
if (list_is_empty(r_list)) {
|
|
lre = rzalloc(r_remap->list_mem_ctx, struct list_range_entry);
|
|
list_addtail(&lre->node, r_list);
|
|
goto insert_end;
|
|
}
|
|
|
|
/* Shortcut for consecutive location inserts */
|
|
struct list_range_entry *last_entry =
|
|
list_last_entry(r_list, struct list_range_entry, node);
|
|
if (last_entry->entry.end < start) {
|
|
lre = rzalloc(r_remap->list_mem_ctx, struct list_range_entry);
|
|
list_addtail(&lre->node, r_list);
|
|
goto insert_end;
|
|
}
|
|
|
|
unsigned low = 0;
|
|
unsigned high = list_length(r_list) - 1;
|
|
unsigned mid = (low + high) / 2;
|
|
|
|
struct list_range_entry *mid_entry =
|
|
list_first_entry(r_list, struct list_range_entry, node);
|
|
unsigned i = 0;
|
|
while (i < mid) {
|
|
mid_entry =
|
|
list_entry(mid_entry->node.next, struct list_range_entry, node);
|
|
i++;
|
|
}
|
|
|
|
while (low <= high) {
|
|
if (end < mid_entry->entry.start) {
|
|
if (low == high || mid == low) {
|
|
lre = rzalloc(r_remap->list_mem_ctx, struct list_range_entry);
|
|
list_addtail(&lre->node, &mid_entry->node); /* insert before mid */
|
|
goto insert_end;
|
|
}
|
|
|
|
high = mid - 1;
|
|
unsigned new_mid = (low + high) / 2;
|
|
while (mid > new_mid) {
|
|
mid_entry =
|
|
list_entry(mid_entry->node.prev, struct list_range_entry, node);
|
|
mid--;
|
|
}
|
|
} else if (start > mid_entry->entry.end) {
|
|
if (low == high || mid == high) {
|
|
lre = rzalloc(r_remap->list_mem_ctx, struct list_range_entry);
|
|
list_add(&lre->node, &mid_entry->node); /* insert after mid */
|
|
goto insert_end;
|
|
}
|
|
|
|
low = mid + 1;
|
|
unsigned new_mid = (low + high) / 2;
|
|
while (mid < new_mid) {
|
|
mid_entry =
|
|
list_entry(mid_entry->node.next, struct list_range_entry, node);
|
|
mid++;
|
|
}
|
|
} else if (mid_entry->entry.start == start && mid_entry->entry.end == end) {
|
|
if (!ptr)
|
|
return &mid_entry->entry;
|
|
|
|
lre = mid_entry;
|
|
goto insert_end;
|
|
} else {
|
|
/* Attempting to insert an entry that overlaps an existing range */
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
insert_end:
|
|
lre->entry.start = start;
|
|
lre->entry.end = end;
|
|
lre->entry.ptr = ptr;
|
|
|
|
return &lre->entry;
|
|
}
|
|
|
|
void
|
|
util_range_switch_to_sorted_array(struct range_remap *r_remap)
|
|
{
|
|
r_remap->sorted_array_length = list_length(&r_remap->r_list);
|
|
|
|
if (r_remap->sorted_array) {
|
|
ralloc_free(r_remap->sorted_array);
|
|
r_remap->sorted_array = NULL;
|
|
}
|
|
|
|
if (r_remap->sorted_array_length == 0)
|
|
return;
|
|
|
|
r_remap->sorted_array = rzalloc_array(r_remap, struct range_entry,
|
|
r_remap->sorted_array_length);
|
|
|
|
unsigned i = 0;
|
|
list_for_each_entry(struct list_range_entry, e, &r_remap->r_list, node) {
|
|
r_remap->sorted_array[i].start = e->entry.start;
|
|
r_remap->sorted_array[i].end = e->entry.end;
|
|
r_remap->sorted_array[i].ptr = e->entry.ptr;
|
|
i++;
|
|
}
|
|
|
|
/* Free linked list and reset head */
|
|
list_inithead(&r_remap->r_list);
|
|
ralloc_free(r_remap->list_mem_ctx);
|
|
r_remap->list_mem_ctx = ralloc_context(r_remap);
|
|
}
|
|
|
|
/* Return the range entry that maps to n or NULL if no match found. */
|
|
struct range_entry *
|
|
util_range_remap(unsigned n, const struct range_remap *r_remap)
|
|
{
|
|
return get_range_entry(n, r_remap);
|
|
}
|
|
|
|
struct range_remap *
|
|
util_create_range_remap()
|
|
{
|
|
struct range_remap *r = rzalloc(NULL, struct range_remap);
|
|
list_inithead(&r->r_list);
|
|
r->list_mem_ctx = ralloc_context(r);
|
|
return r;
|
|
}
|
|
|
|
/* Free previous list and create a new empty list */
|
|
struct range_remap *
|
|
util_reset_range_remap(struct range_remap *r_remap)
|
|
{
|
|
ralloc_free(r_remap);
|
|
|
|
return util_create_range_remap();
|
|
}
|