[PATCH 3/4] shallow.c: bit manipulation tweaks
- From
Rasmus Villemoes <rv@rasmusvillemoes.dk>
- Date
- Dec 2, 2016, 20:31 UTC
- Message-ID
- <1480710664-26290-3-git-send-email-rv@rasmusvillemoes.dk>
- In-Reply-To
- <1480710664-26290-1-git-send-email-rv@rasmusvillemoes.dk>
First of all, 1 << 31 is technically undefined behaviour, so let's just use an unsigned literal.
If i is 'signed int' and gcc doesn't know that i is positive, gcc generates code to compute the C99-mandated values of "i / 32" and "i % 32", which is a lot more complicated than simple a simple shifts/mask.
The only caller of paint_down actually passes an "unsigned int" value, but the prototype of paint_down causes (completely well-defined) conversion to signed int, and gcc has no way of knowing that the converted value is non-negative. Just make the id parameter unsigned.
In update_refstatus, the change in generated code is much smaller, presumably because gcc is smart enough to see that i starts as 0 and is only incremented, so it is allowed (per the UD of signed overflow) to assume that i is always non-negative. But let's just help less smart compilers generate good code anyway.
Signed-off-by: Rasmus Villemoes <rv@rasmusvillemoes.dk> --- shallow.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/shallow.c b/shallow.c index 8b1c35d..5aec5a5 100644 --- a/shallow.c +++ b/shallow.c @@ -464,7 +464,7 @@ static uint32_t *paint_alloc(struct paint_info *info) * all walked commits. */ static void paint_down(struct paint_info *info, const unsigned char *sha1, - int id) + unsigned int id) { unsigned int i, nr; struct commit_list *head = NULL; @@ -476,7 +476,7 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1, if (!c) return; memset(bitmap, 0, bitmap_size); - bitmap[id / 32] |= (1 << (id % 32)); + bitmap[id / 32] |= (1U << (id % 32)); commit_list_insert(c, &head); while (head) { struct commit_list *p; @@ -650,11 +650,11 @@ static int add_ref(const char *refname, const struct object_id *oid, static void update_refstatus(int *ref_status, int nr, uint32_t *bitmap) { - int i; + unsigned int i; if (!ref_status) return; for (i = 0; i < nr; i++) - if (bitmap[i / 32] & (1 << (i % 32))) + if (bitmap[i / 32] & (1U << (i % 32))) ref_status[i]++; }
-- 2.1.4