From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <libc-alpha-return-59233-listarch-libc-alpha=sources.redhat.com@sourceware.org>
Received: (qmail 10633 invoked by alias); 25 May 2015 01:43:37 -0000
Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm
Precedence: bulk
List-Id: <libc-alpha.sourceware.org>
List-Subscribe: <mailto:libc-alpha-subscribe@sourceware.org>
List-Archive: <http://sourceware.org/ml/libc-alpha/>
List-Post: <mailto:libc-alpha@sourceware.org>
List-Help: <mailto:libc-alpha-help@sourceware.org>, <http://sourceware.org/ml/#faqs>
Sender: libc-alpha-owner@sourceware.org
Received: (qmail 10623 invoked by uid 89); 25 May 2015 01:43:36 -0000
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=-0.6 required=5.0 tests=AWL,BAYES_50,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2
X-HELO: port70.net
Date: Mon, 25 May 2015 04:41:00 -0000
From: Szabolcs Nagy <nsz@port70.net>
To: Ond??ej B?lka <neleai@seznam.cz>
Cc: libc-alpha@sourceware.org
Subject: Re: [RFC] ifunc suck, use ufunc.
Message-ID: <20150525014323.GC26188@port70.net>
References: <20150524213858.GA18221@domone>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20150524213858.GA18221@domone>
User-Agent: Mutt/1.5.23 (2014-03-12)
X-SW-Source: 2015-05/txt/msg00589.txt.bz2

* Ond??ej B?lka <neleai@seznam.cz> [2015-05-24 23:38:58 +0200]:
> A main benefit would be interlibrary constant folding. Why waste cycles
> on reinitializing constant, just save it to ufunc structure. Resolver 
> then could precompute tables to improve speed.
> 
> As interposing these you would need to interpose resolver.
> 
> An gcc support is not needed but we could get something with alternate
> calling convention as passing resolver struct is common and could be
> preserved for loops with tail calls.
> 
> A future direction could be replace plt and linker with ufunc, it would
> require adding function string pointer to structure and calling first
> generic resolver to select specific resolver.
> 
> Comments?
> 

this makes memset non-async-signal-safe. (qoi issue)

it is not thread-safe either and would need an acquire
load barrier on every invocation of memset to fix that
or the use of thread local storage. (conformance issue)

(in the example only resolve->fn is modified and idempotently,
this would work in practice but as soon as ->data is accessed
too the memory ordering guarantees are required.. which can
be made efficient on some archs but only in asm)

in the example memset is called through the wrong type
of function pointer: the resolver and resolvee are
incompatible so this is invalid c, only works in asm.

it is not clear to me how many such ufunc structs will be
in a program for a specific function and how their redundant
initialization is avoided.
(one for every call site? every tu? every dso?)

> An simplified example is here (for arch that pass four arguments in registers):
> 
> struct memset_ufunc
> {
>   void *(*fn)(void *, int, size_t, struct memset_ufunc *);
>   char  __attribute__((aligned (32))) data[32];
> };
> # define memset(s, c, n) \
>    (__extension__({ \
>     static struct memset_ufunc __resolve = {.fn = memset_resolver}; \
>     __resolve.fn (s, c, n, &__resolve); \
>     }))
> 
> void *
> memset_resolver (void *s, int c, size_t n, struct memset_ufunc *resolve)
> {
>   resolve->fn = dlsym (RTLD_DEFAULT, "memset");
>   return resolve->fn (s, c, n, resolve);
> }
> 
> void foo (char *c);
> int main ()
> {
>   char u[32];
>   memset (u, 1, 32);
> }