[size] Replace memset by memclr when 2nd parameter is zero

Bug #638014 reported by Yao Qi
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Confirmed
Undecided
Unassigned

Bug Description

When 2nd parameter of memcpy is zero, GCC can replace it by memclr. Code size can be reduced.

/* Test case mem.c*/
#include <string.h>
void foo1(int* array, int length)
{
  memset (array, 0, length);
}
void foo2(int* array, int length)
{
  memclr (array, length);
}

$arm-none-linux-gnueabi-gcc -Os -mthumb -mcpu=cortex-a9 -S mem.c

foo1:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        mov r2, r1
        movs r1, #0
        b memset
foo2:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        b memclr

Tags: size task
Revision history for this message
Michael Hope (michaelh1) wrote :

The test is a bit contrived, but it's still probably worthwhile to make the load #0 common.

I can't find any function called memclr - do you mean bzero?

Revision history for this message
Yao Qi (yao-codesourcery) wrote :

Michael,
This case is extracted from CINT2000/256.bzip2/spec.c,
int spec_reset(int fd) {
    memset(spec_fd[fd].buf, 0, spec_fd[fd].len);
    spec_fd[fd].pos = spec_fd[fd].len = 0;
    return 0;
}

Yeah, we can use bzero, or __aeabi_memclr, which is ARM/EABI specific.

Michael Hope (michaelh1)
tags: added: size task
Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :

I think the compiler is only free to do this kind of optimization with standard library functions. memclr and bzero are not in the standard, and so cannot be relied upon. Indeed, the bzero man page says it is deprecated and users should use memset.

However, __aeabi_memclr is probably fair game - it's documented in the ARM EABI, and that makes it standard in our world. Obviously, this would have to be not only ARM specific, but EABI-specific.

Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :

OK, I think I know how to tackle this one: we need to add a new pattern 'define_expand "setmemsi" ' to the arm machine description, and have it emit a call to __aeabi_memclr in the case that the operand is zero.

There's a catch though: __aeabi_memclr is defined in the ABI, but it isn't defined in GCC.

Back to square one ... we could transform memset to bzero for our own purposes, but it's not a standard function so they won't accept it upstream.

Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :

Ok, so __aeabi_memclr is defined in glibc. I was just looking for it in the wrong place.

Paul Brook also suggests that 'setmemsi' is not the best way to fix this. Instead we should teach gcc about it as a new ARM-specific builtin.

Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :

I did write a patch to substitute in __aeabi_memset and _aeabi_memclr calls in builtin.c:expand_builtin_memset_args, but it was unsuccessful.

Firstly, expand_builtin_memset_args is not the only place memset calls come from. Other places include expr.c:block_clear_fn.

Secondly, __aeabi_memset has it's arguments in a non-standard order, so it's not enough to just change the function name - there needs to be some kind of target hook to configure the order.

Thirdly, there is at least one place that assumes it knows what the arguments to memset mean (dse.c:scan_insn), so they'd need to be adjusted.

Fourthly, there doesn't seem to be any central place that defines what the memset call should be. The name seems to be hardcoded in a few places. Actually, libfuncs.h does define one, but nothing seems to use it (although a few places do override it).

Viktor (vchong)
Changed in gcc-linaro:
status: New → Confirmed
Revision history for this message
Kugan Vivekanandarajah (kugan-vivekanandarajah) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.