Bill Stoddard wrote:
> While trying to create a simple testcase demonstrating a bug in the xlc
> compiler, I did a little experiment.  Here is a code snip from core.c:
> 

I'm just wondering if there is any kind of measureable performance 
benefit in keeping these as a macro vs putting them in a  function 
(possibly inline if the compiler can support it).
> <snip>
>   /* Code from core.c */
>   if (mode == AP_MODE_INIT) {
>      return APR_SUCCESS;
>   }
>   if (!ctx)
>   {
>      ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
>      ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
> 
>      e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
>      APR_BRIGADE_INSERT_TAIL(ctx->b, e);
>      net->in_ctx = ctx;
>   }
>   else if (APR_BRIGADE_EMPTY(ctx->b)) {
>      return APR_EOF;
>   }
>   avoid_xlc_bug(f->c->base_server);
>   BRIGADE_NORMALIZE(ctx->b);
> </snip>
> 
> And here is that same code with the macros unrolled. The xlc optimizer
> chokes on this. avoid_xlc_bug() just returns 1 and does nothing else (and
> makes the optimzer happy again). This is just nasty.
> 
> /* Code from core.c with macros unrolled. */
> if (mode == AP_MODE_INIT) {
> #line 3330
>    return 0;
> }
> if (!ctx)
> {
>    ctx = apr_pcalloc(f->c->pool, sizeof(*ctx));
>    ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc);
> #line 3339
>    e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc);
>    do { apr_bucket *ap__b = (e); do { ((((ap__b))))->link.next = ((struct
> apr_bucket
> *)((char *)(((&(ctx->b)->list))) - ((l
> ong) (((char *) (&(((struct apr_bucket*)0)->link))) - ((char *) 0)))));
> ((((ap__b))))->link.prev = (((struct apr_bucket *)((char
>  *)(((&(ctx->b)->list))) - ((long) (((char *) (&(((struct
> apr_bucket*)0)->link))) - ((char
> *) 0))))))->link.prev; ((((struct apr
> _bucket *)((char *)(((&(ctx->b)->list))) - ((long) (((char *) (&(((struct
> apr_bucket*)0)->link))) - ((char *) 0))))))->link.prev
> )->link.next = (((ap__b))); (((struct apr_bucket *)((char
> *)(((&(ctx->b)->list))) -
> ((long) (((char *) (&(((struct apr_bucket*)0
> )->link))) - ((char *) 0))))))->link.prev = (((ap__b))); } while (0); }
> while (0);
>         net->in_ctx = ctx;
>     }
>     else if ((((&(ctx->b)->list))->next == (struct apr_bucket *)((char
> *)((&(ctx->b)->list)) - ((long) (((char *) (&(((struct ap
> r_bucket*)0)->link))) - ((char *) 0)))))) {
>         return ((20000 + 500) + 14);
>     }
> 
>     avoid_xlc_bug(f->c->base_server);
> #line 3350
>     do { apr_bucket *e = (&(ctx->b)->list)->next; do { if (e->length == 0)
> { apr_bucket
> *d; d = ((e))->link.next; do { do { ((((
> (e))))->link.prev)->link.next = ((((e))))->link.next;
> (((((e))))->link.next)->link.prev =
> ((((e))))->link.prev; } while (0); do
> { (e)->type->destroy((e)->data); (e)->free(e); } while (0); } while (0); e =
> d; } e =
> ((e))->link.next; } while (!(((&(ctx->b)->
> list))->next == (struct apr_bucket *)((char *)((&(ctx->b)->list)) - ((long)
> (((char *)
> (&(((struct apr_bucket*)0)->link))) - ((c
> har *) 0))))) && (e != (struct apr_bucket *)((char *)(&(ctx->b)->list) -
> ((long) (((char
> *) (&(((struct apr_bucket*)0)->link)))
> - ((char *) 0)))))); } while (0);
> #line 3358
>     if ((((&(ctx->b)->list))->next == (struct apr_bucket *)((char
> *)((&(ctx->b)->list)) -
> ((long) (((char *) (&(((struct apr_buc
> ket*)0)->link))) - ((char *) 0)))))) {
>         return ((20000 + 500) + 14);
>     }
> #line 3365
> 


Reply via email to