This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: bzero optimization rarely does


 > 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]