This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: bzero optimization rarely does
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: roger at eyesopen dot com
- Cc: gcc-patches at gcc dot gnu dot org, gcc at gcc dot gnu dot org, hp at bitrange dot com, pkoning at equallogic dot com, rth at redhat dot com
- Date: Fri, 12 Jul 2002 22:13:46 -0400 (EDT)
- Subject: Re: bzero optimization rarely does
- References: <Pine.LNX.4.33.0207121629180.23423-100000@www.eyesopen.com>
> From: Roger Sayle <roger@eyesopen.com>
>
> I'm just unsure of how to portably test how memset and memcpy are
> expanded, without restricting the currently available
> functionality. [Perhaps thats a reasonable thing to do?]. Can you
> think of a test that will still work when and if the ns32k backend
> decides to "#define CLEAR_RATIO 0"?
> Roger
In my prior email I gave you examples to follow, namely you take the
builtin testing mechanism of string-opt-17.c and the per-chip value
setting of gcc.dg/20020312-2.c.
I went ahead and wrote it. This testcase requires each cpu to define
MAX appropriately, I'd expect someone testing on each platform to set
their cpu values after I check it in.
I tested on sparc-sun-solaris2.7. (I don't know if the i386 value is
right, I just guessed to show an example of another cpu so I'll take
that out if necessary.)
Ok to install as execute/memset-3.c? (With or without the i386 bit?)
--Kaveh
PS: Everyone feel free to suggest cpu MAX values before I check it in
and I'll enter them ahead of time.
/* Copyright (C) 2002 Free Software Foundation.
Ensure that builtin memset/bzero operations for constant length
(and for memset an assigned value of zero) don't cause problems.
Written by Kaveh Ghazi, 2002-07-12. */
extern void abort (void);
typedef __SIZE_TYPE__ size_t;
extern int memcmp(const void *, const void *, size_t);
extern void *memset (void *, int, size_t);
extern void bzero (void *, size_t);
char buffer[1024];
const char zeros[sizeof(buffer)]; /* Defaults to zeros. */
#ifdef __OPTIMIZE_SIZE__
# define MAX 2
#elif defined (__sparc__)
# define MAX 14
#elif defined (__i386__)
# define MAX 63
#else
# define MAX sizeof(buffer) /* Define MAX appropriately for your cpu. */
#endif
/* Reset BUF to a known state. */
#define RESET(BUF) \
do { \
size_t i; \
for (i=0; i < sizeof(BUF); i++) \
((unsigned char *)(BUF))[i] = 0xff; \
} while (0)
/* Test memset and bzero. */
#define DOTEST(LEN) \
do { \
if ((LEN) > (MAX)) return 0; \
RESET(buffer); \
memset (buffer, 0, (LEN)); \
if (memcmp (buffer, zeros, (LEN))) \
abort(); \
RESET(buffer); \
bzero (buffer, (LEN)); \
if (memcmp (buffer, zeros, (LEN))) \
abort(); \
} while (0)
/* In case the platform doesn't have memset or bzero at -O0. */
#ifndef __OPTIMIZE__
# define memset __builtin_memset
# define bzero __builtin_bzero
#endif
int
main (void)
{
DOTEST(0);
DOTEST(1);
DOTEST(2);
DOTEST(3);
DOTEST(4);
DOTEST(5);
DOTEST(6);
DOTEST(7);
DOTEST(8);
DOTEST(9);
DOTEST(10);
DOTEST(11);
DOTEST(12);
DOTEST(13);
DOTEST(14);
DOTEST(15);
DOTEST(16);
DOTEST(17);
DOTEST(18);
DOTEST(19);
DOTEST(20);
DOTEST(31);
DOTEST(32);
DOTEST(33);
DOTEST(63);
DOTEST(64);
DOTEST(65);
DOTEST(127);
DOTEST(128);
DOTEST(129);
DOTEST(255);
DOTEST(256);
DOTEST(257);
DOTEST(511);
DOTEST(512);
DOTEST(513);
DOTEST(sizeof(buffer)-1);
DOTEST(sizeof(buffer));
return 0;
}
#ifdef __OPTIMIZE__
/* When optimizing, most of the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. */
static void *
memset (void *dst, int c, size_t len)
{
abort ();
}
static void
bzero (void *dst, size_t len)
{
abort ();
}
#endif