This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [cfe-dev] C++11: new builtin to allow constexpr to be applied to performance-critical functions
- From: Chandler Carruth <chandlerc at google dot com>
- To: Richard Smith <richard at metafoo dot co dot uk>
- Cc: GCC Mailing List <gcc at gcc dot gnu dot org>, clang-dev Developers <cfe-dev at cs dot uiuc dot edu>
- Date: Fri, 19 Oct 2012 22:53:18 -0700
- Subject: Re: [cfe-dev] C++11: new builtin to allow constexpr to be applied to performance-critical functions
- References: <CAOfiQqmO1Hmfddqb+OMkANTofN0XVtLLCj=V-qAvQCzzpb+YVw@mail.gmail.com>
On Fri, Oct 19, 2012 at 10:04 PM, Richard Smith <richard@metafoo.co.uk> wrote:
>
> [Crossposted to both GCC and Clang dev lists]
>
> Hi,
>
> One issue facing library authors wanting to use C++11's constexpr feature is that the same implementation must be provided for both the case of function invocation substitution and for execution at runtime. Due to the constraints on constexpr function definitions, this can force an implementation of a library function to be inefficient. To counteract this, I'd like to propose the addition of a builtin:
>
> bool __builtin_constexpr_p()
>
> This builtin would only be supported within constexpr function definitions. If the containing function is undergoing function invocation substitution, it returns true. Otherwise, it returns false. Hence we can implement library functions with a pattern like:
>
> constexpr int constexpr_strncmp(const char *p, const char *q, size_t n) {
> return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : constexpr_strncmp(p+1, q+1, n-1);
> }
> __attribute__((always_inline)) constexpr int my_strncmp(const char *p, const char *q, size_t n) {
> return __builtin_constexpr_p() ? constexpr_strncmp(p, q, n) : strncmp(p, q, n);
> }
>
> Does this seem reasonable?
Yes, especially the primary functionality. However, I have some
concerns about the interface. Let me hypothesize a different
interface:
This stays the same...
> constexpr int constexpr_strncmp(const char *p, const char *q, size_t n) {
> return !n ? 0 : *p != *q ? *p - *q : !*p ? 0 : constexpr_strncmp(p+1, q+1, n-1);
> }
But here we do something different on the actual declaration:
>
> [[constexpr_alias(constexpr_strncmp)]]
> int strncmp(const char *p, const char *q, size_t n);
When parsing the *declaration* of this function, we lookup the
function name passed to constexpr_alias. We must find a constexpr
function with an identical signature. Then, at function invocation
substitution of strncmp, we instead substitute the body of
constexpr_strncmp.
This seems more direct (no redirection in the code), and it also
provides a specific advantage of allowing this to be easily added to
an existing declaration in a declaration-only header file without
impacting or changing the name of the runtime executed body or
definition.
-Chandler
PS: Sorry for the dup Clang folks, the GCC list doesn't like my mail client.