From: Andy Lester Date: Wed, 28 Dec 2005 15:34:08 +0000 (-0600) Subject: Support for __builtin_expect and __builtin_choose_expr X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=635aebb78abd81c28ceb76ef8d65d262f3647e23;p=p5sagit%2Fp5-mst-13.2.git Support for __builtin_expect and __builtin_choose_expr Message-ID: <20051228213408.GB26033@petdance.com> p4raw-id: //depot/perl@27370 --- diff --git a/Configure b/Configure index 12b8fb0..be4a11b 100755 --- a/Configure +++ b/Configure @@ -26,7 +26,7 @@ # $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $ # -# Generated on Fri Mar 3 08:34:32 CET 2006 [metaconfig 3.0 PL70] +# Generated on Fri Mar 3 17:34:44 CET 2006 [metaconfig 3.0 PL70] # (with additional metaconfig patches by perlbug@perl.org) cat >c1$$ <&4 + $cat >try.c <<'EOCP' +#include +#include +#include + +#define SYRINX(x) __builtin_choose_expr( x, (1056*2), (103*50) ) + +int main(void) { + assert( SYRINX(1) == 2112 ); + assert( SYRINX(1) != 5150 ); + assert( SYRINX(0) == 5150 ); + assert( SYRINX(0) != 2112 ); + puts( "All good!" ); + exit(0); +} + +EOCP + set try + if eval $compile; then + echo "Your C compiler supports __builtin_choose_expr." + val="$define" + else + echo "Your C compiler doesn't seem to understand __builtin_choose_expr." + val="$undef" + fi +;; +*) val="$d_builtin_choose_expr" ;; +esac + +set d_builtin_choose_expr +eval $setvar +$rm -f try.* try core core.try.* + +: Look for GCC-style __builtin_expect +case "$d_builtin_expect" in +'') + echo " " + echo "Checking whether your compiler can handle __builtin_expect ..." >&4 + $cat >builtin.c <<'EOCP' +int main(void) { + int n = 50; + if ( __builtin_expect(n, 0) ) n = 1; +} +EOCP + set try + if eval $compile; then + echo "Your C compiler supports __builtin_choose_expr." + val="$define" + else + echo "Your C compiler doesn't seem to understand __builtin_choose_expr." + val="$undef" + fi + ;; +*) val="$d_builtin_expect" ;; +esac + +set d_builtin_expect +eval $setvar +$rm -f try.* try core core.try.* + : see if bzero exists set bzero d_bzero eval $inlibc @@ -21172,6 +21239,8 @@ d_bcopy='$d_bcopy' d_bsd='$d_bsd' d_bsdgetpgrp='$d_bsdgetpgrp' d_bsdsetpgrp='$d_bsdsetpgrp' +d_builtin_choose_expr='$d_builtin_choose_expr' +d_builtin_expect='$d_builtin_expect' d_bzero='$d_bzero' d_casti32='$d_casti32' d_castneg='$d_castneg' diff --git a/Porting/Glossary b/Porting/Glossary index bcd3a97..7d3ff3f 100644 --- a/Porting/Glossary +++ b/Porting/Glossary @@ -34,7 +34,7 @@ afsroot (afs.U): This variable is by default set to '/afs'. In the unlikely case this is not the correct root, it is possible to override this with a hint value or command line option. This will be used in subsequent - tests for AFSness in the Perl configure and test process. + tests for AFSness in the Perl configure and test process. alignbytes (alignbytes.U): This variable holds the number of bytes required to align a @@ -42,7 +42,7 @@ alignbytes (alignbytes.U): 2, 4 and 8. The default is eight, for safety. ansi2knr (ansi2knr.U): - This variable is set if the user needs to run ansi2knr. + This variable is set if the user needs to run ansi2knr. Currently, this is not supported, so we just abort. aphostname (d_gethname.U): @@ -464,6 +464,20 @@ d_bsdsetpgrp (d_setpgrp.U): setpgrp needs two arguments whereas USG one needs none. See also d_setpgid for a POSIX interface. +d_builtin_choose_expr (d_builtin.U): + This conditionally defines HAS_BUILTIN_CHOOSE_EXPR, which + indicates that the compiler supports __builtin_choose_expr(x,y,z). + This built-in function is analogous to the "x?y:z" operator in C, + except that the expression returned has its type unaltered by + promotion rules. Also, the built-in function does not evaluate + the expression that was not chosen. + +d_builtin_expect (d_builtin.U): + This conditionally defines HAS_BUILTIN_EXPECT, which indicates + that the compiler supports __builtin_expect(exp,c). You may use + __builtin_expect to provide the compiler with branch prediction + information. + d_bzero (d_bzero.U): This variable conditionally defines the HAS_BZERO symbol if the bzero() routine is available to set memory to 0. @@ -822,11 +836,11 @@ d_Gconvert (d_gconvert.U): long doubles, the macro uses the first of the following functions that pass Configure's tests: qgcvt, sprintf (if Configure knows how to make sprintf format long doubles--see - sPRIgldbl), gconvert, gcvt, and sprintf (casting to double). - The gconvert_preference and gconvert_ld_preference variables + sPRIgldbl), gconvert, gcvt, and sprintf (casting to double). + The gconvert_preference and gconvert_ld_preference variables can be used to alter Configure's preferences, for doubles and - long doubles, respectively. If present, they contain a - space-separated list of one or more of the above function + long doubles, respectively. If present, they contain a + space-separated list of one or more of the above function names in the order they should be tried. d_Gconvert may be set to override Configure with a platform- @@ -910,7 +924,7 @@ d_gethostent_r (d_gethostent_r.U): d_gethostprotos (d_gethostprotos.U): This variable conditionally defines the HAS_GETHOST_PROTOS symbol, which indicates to the C program that supplies - prototypes for the various gethost*() functions. + prototypes for the various gethost*() functions. See also netdbtype.U for probing for various netdb types. d_getitimer (d_getitimer.U): @@ -969,7 +983,7 @@ d_getnetent_r (d_getnetent_r.U): d_getnetprotos (d_getnetprotos.U): This variable conditionally defines the HAS_GETNET_PROTOS symbol, which indicates to the C program that supplies - prototypes for the various getnet*() functions. + prototypes for the various getnet*() functions. See also netdbtype.U for probing for various netdb types. d_getpagsz (d_getpagsz.U): @@ -977,14 +991,14 @@ d_getpagsz (d_getpagsz.U): is available to get the system page size. d_getpbyname (d_getprotby.U): - This variable conditionally defines the HAS_GETPROTOBYNAME - symbol, which indicates to the C program that the + This variable conditionally defines the HAS_GETPROTOBYNAME + symbol, which indicates to the C program that the getprotobyname() routine is available to look up protocols by their name. d_getpbynumber (d_getprotby.U): - This variable conditionally defines the HAS_GETPROTOBYNUMBER - symbol, which indicates to the C program that the + This variable conditionally defines the HAS_GETPROTOBYNUMBER + symbol, which indicates to the C program that the getprotobynumber() routine is available to look up protocols by their number. @@ -1033,7 +1047,7 @@ d_getprotoent_r (d_getprotoent_r.U): d_getprotoprotos (d_getprotoprotos.U): This variable conditionally defines the HAS_GETPROTO_PROTOS symbol, which indicates to the C program that supplies - prototypes for the various getproto*() functions. + prototypes for the various getproto*() functions. See also netdbtype.U for probing for various netdb types. d_getprpwnam (d_getprpwnam.U): @@ -1061,14 +1075,14 @@ d_getpwuid_r (d_getpwuid_r.U): routine is available. d_getsbyname (d_getsrvby.U): - This variable conditionally defines the HAS_GETSERVBYNAME - symbol, which indicates to the C program that the + This variable conditionally defines the HAS_GETSERVBYNAME + symbol, which indicates to the C program that the getservbyname() routine is available to look up services by their name. d_getsbyport (d_getsrvby.U): - This variable conditionally defines the HAS_GETSERVBYPORT - symbol, which indicates to the C program that the + This variable conditionally defines the HAS_GETSERVBYPORT + symbol, which indicates to the C program that the getservbyport() routine is available to look up services by their port. @@ -1094,7 +1108,7 @@ d_getservent_r (d_getservent_r.U): d_getservprotos (d_getservprotos.U): This variable conditionally defines the HAS_GETSERV_PROTOS symbol, which indicates to the C program that supplies - prototypes for the various getserv*() functions. + prototypes for the various getserv*() functions. See also netdbtype.U for probing for various netdb types. d_getspnam (d_getspnam.U): @@ -1202,11 +1216,11 @@ d_lockf (d_lockf.U): available to do file locking. d_longdbl (d_longdbl.U): - This variable conditionally defines HAS_LONG_DOUBLE if + This variable conditionally defines HAS_LONG_DOUBLE if the long double type is supported. d_longlong (d_longlong.U): - This variable conditionally defines HAS_LONG_LONG if + This variable conditionally defines HAS_LONG_LONG if the long long type is supported. d_lseekproto (d_lseekproto.U): @@ -1863,7 +1877,7 @@ d_shmat (d_shmat.U): indicates to the C program that the shmat() routine is available. d_shmatprototype (d_shmat.U): - This variable conditionally defines the HAS_SHMAT_PROTOTYPE + This variable conditionally defines the HAS_SHMAT_PROTOTYPE symbol, which indicates that sys/shm.h has a prototype for shmat. @@ -2425,7 +2439,7 @@ expr (Loc.U): extensions (Extensions.U): This variable holds a list of all extension files (both XS and non-xs linked into the package. It is propagated to Config.pm - and is typically used to test whether a particular extesion + and is typically used to test whether a particular extesion is available. extras (Extras.U): @@ -2460,7 +2474,7 @@ fpossize (fpossize.U): This variable contains the size of a fpostype in bytes. fpostype (fpostype.U): - This variable defines Fpos_t to be something like fpos_t, long, + This variable defines Fpos_t to be something like fpos_t, long, uint, or whatever type is used to declare file positions in libc. freetype (mallocsrc.U): @@ -2676,7 +2690,7 @@ groupcat (nis.U): command, in which case this variable is unset. groupstype (groupstype.U): - This variable defines Groups_t to be something like gid_t, int, + This variable defines Groups_t to be something like gid_t, int, ushort, or whatever type is used for the second argument to getgroups() and setgroups(). Usually, this is the same as gidtype (gid_t), but sometimes it isn't. @@ -3120,7 +3134,7 @@ inc_version_list (inc_version_list.U): inc_version_list_init (inc_version_list.U): This variable holds the same list as inc_version_list, but - each item is enclosed in double quotes and separated by commas, + each item is enclosed in double quotes and separated by commas, suitable for use in the PERL_INC_VERSION_LIST initialization. incpath (usrinc.U): @@ -3143,13 +3157,13 @@ installbin (bin.U): be used in your makefiles for maximum portability. installhtml1dir (html1dir.U): - This variable is really the same as html1direxp, unless you are - using a different installprefix. For extra portability, you + This variable is really the same as html1direxp, unless you are + using a different installprefix. For extra portability, you should only use this variable within your makefiles. installhtml3dir (html3dir.U): - This variable is really the same as html3direxp, unless you are - using a different installprefix. For extra portability, you + This variable is really the same as html3direxp, unless you are + using a different installprefix. For extra portability, you should only use this variable within your makefiles. installman1dir (man1dir.U): @@ -3165,7 +3179,7 @@ installman3dir (man3dir.U): portability, you should only use this variable within your makefiles. installprefix (installprefix.U): - This variable holds the name of the directory below which + This variable holds the name of the directory below which "make install" will install the package. For most users, this is the same as prefix. However, it is useful for installing the software into a different (usually temporary) @@ -3322,7 +3336,7 @@ issymlink (issymlink.U): ivdformat (perlxvf.U): This variable contains the format string used for printing - a Perl IV as a signed decimal integer. + a Perl IV as a signed decimal integer. ivsize (perlxv.U): This variable is the size of an IV in bytes. @@ -3331,7 +3345,7 @@ ivtype (perlxv.U): This variable contains the C type used for Perl's IV. known_extensions (Extensions.U): - This variable holds a list of all XS extensions included in + This variable holds a list of all XS extensions included in the package. ksh (Loc.U): @@ -3434,7 +3448,7 @@ ln (Loc.U): the value is reset to a plain "ln" and is not useful. lns (lns.U): - This variable holds the name of the command to make + This variable holds the name of the command to make symbolic links (if they are supported). It can be used in the Makefile. It is either 'ln -s' or 'ln' @@ -3484,12 +3498,12 @@ ls (Loc.U): the value is reset to a plain "ls" and is not useful. lseeksize (lseektype.U): - This variable defines lseektype to be something like off_t, long, + This variable defines lseektype to be something like off_t, long, or whatever type is used to declare lseek offset's type in the kernel (which also appears to be lseek's return type). lseektype (lseektype.U): - This variable defines lseektype to be something like off_t, long, + This variable defines lseektype to be something like off_t, long, or whatever type is used to declare lseek offset's type in the kernel (which also appears to be lseek's return type). @@ -3593,8 +3607,8 @@ mmaptype (d_mmap.U): It can be 'void *' or 'caddr_t'. modetype (modetype.U): - This variable defines modetype to be something like mode_t, - int, unsigned short, or whatever type is used to declare file + This variable defines modetype to be something like mode_t, + int, unsigned short, or whatever type is used to declare file modes for system calls. more (Loc.U): @@ -3863,7 +3877,7 @@ phostname (myhostname.U): there already. pidtype (pidtype.U): - This variable defines PIDTYPE to be something like pid_t, int, + This variable defines PIDTYPE to be something like pid_t, int, ushort, or whatever type is used to declare process ids in the kernel. plibpth (libpth.U): @@ -3918,7 +3932,7 @@ quadkind (quadtype.U): 1 = int, 2 = long, 3 = long long, 4 = int64_t. quadtype (quadtype.U): - This variable defines Quad_t to be something like long, int, + This variable defines Quad_t to be something like long, int, long long, int64_t, or whatever type is used for 64-bit integers. randbits (randfunc.U): @@ -4022,7 +4036,7 @@ selectminbits (selectminbits.U): selecttype (selecttype.U): This variable holds the type used for the 2nd, 3rd, and 4th arguments to select. Usually, this is 'fd_set *', if HAS_FD_SET - is defined, and 'int *' otherwise. This is only useful if you + is defined, and 'int *' otherwise. This is only useful if you have select(), naturally. sendmail (Loc.U): @@ -4099,7 +4113,7 @@ shortsize (intsize.U): shrpenv (libperl.U): If the user builds a shared libperl.so, then we need to tell the - 'perl' executable where it will be able to find the installed libperl.so. + 'perl' executable where it will be able to find the installed libperl.so. One way to do this on some systems is to set the environment variable LD_RUN_PATH to the directory that will be the final location of the shared libperl.so. The makefile can use this with something like @@ -4128,8 +4142,8 @@ sig_name (sig_name.U): sig_name_init (sig_name.U): This variable holds the signal names, enclosed in double quotes and - separated by commas, suitable for use in the SIG_NAME definition - below. A "ZERO" is prepended to the list, and the list is + separated by commas, suitable for use in the SIG_NAME definition + below. A "ZERO" is prepended to the list, and the list is terminated with a plain 0. The leading SIG in signal names is removed. See sig_num. @@ -4142,8 +4156,8 @@ sig_num (sig_name.U): sig_num_init (sig_name.U): This variable holds the signal numbers, enclosed in double quotes and - separated by commas, suitable for use in the SIG_NUM definition - below. A "ZERO" is prepended to the list, and the list is + separated by commas, suitable for use in the SIG_NUM definition + below. A "ZERO" is prepended to the list, and the list is terminated with a plain 0. sig_size (sig_name.U): @@ -4291,8 +4305,8 @@ sizesize (sizesize.U): This variable contains the size of a sizetype in bytes. sizetype (sizetype.U): - This variable defines sizetype to be something like size_t, - unsigned long, or whatever type is used to declare length + This variable defines sizetype to be something like size_t, + unsigned long, or whatever type is used to declare length parameters for string functions. sleep (Loc.U): @@ -4410,8 +4424,8 @@ sSCNfldbl (longdblfio.U): format long doubles (format 'f') for input. ssizetype (ssizetype.U): - This variable defines ssizetype to be something like ssize_t, - long or int. It is used by functions that return a count + This variable defines ssizetype to be something like ssize_t, + long or int. It is used by functions that return a count of bytes or an error condition. It must be a signed type. We will pick a type such that sizeof(SSize_t) == sizeof(Size_t). @@ -4601,7 +4615,7 @@ uidsize (uidsize.U): This variable contains the size of a uidtype in bytes. uidtype (uidtype.U): - This variable defines Uid_t to be something like uid_t, int, + This variable defines Uid_t to be something like uid_t, int, ushort, or whatever type is used to declare user ids in the kernel. uname (Loc.U): @@ -4764,7 +4778,7 @@ uuname (Loc.U): uvoformat (perlxvf.U): This variable contains the format string used for printing - a Perl UV as an unsigned octal integer. + a Perl UV as an unsigned octal integer. uvsize (perlxv.U): This variable is the size of a UV in bytes. @@ -4774,7 +4788,7 @@ uvtype (perlxv.U): uvuformat (perlxvf.U): This variable contains the format string used for printing - a Perl UV as an unsigned decimal integer. + a Perl UV as an unsigned decimal integer. uvxformat (perlxvf.U): This variable contains the format string used for printing @@ -4786,11 +4800,11 @@ uvXUformat (perlxvf.U): vendorarch (vendorarch.U): This variable contains the value of the PERL_VENDORARCH symbol. - It may have a ~ on the front. + It may have a ~ on the front. The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own architecture-dependent modules and extensions in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorarchexp (vendorarch.U): @@ -4803,7 +4817,7 @@ vendorbin (vendorbin.U): The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place additional binaries in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorbinexp (vendorbin.U): @@ -4811,12 +4825,12 @@ vendorbinexp (vendorbin.U): may use it directly in Makefiles or shell scripts. vendorhtml1dir (vendorhtml1dir.U): - This variable contains the name of the directory for html + This variable contains the name of the directory for html pages. It may have a ~ on the front. The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own html pages in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorhtml1direxp (vendorhtml1dir.U): @@ -4824,12 +4838,12 @@ vendorhtml1direxp (vendorhtml1dir.U): may use it directly in Makefiles or shell scripts. vendorhtml3dir (vendorhtml3dir.U): - This variable contains the name of the directory for html + This variable contains the name of the directory for html library pages. It may have a ~ on the front. The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own html pages for modules and extensions in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorhtml3direxp (vendorhtml3dir.U): @@ -4842,7 +4856,7 @@ vendorlib (vendorlib.U): The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own modules in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorlib_stem (vendorlib.U): @@ -4855,12 +4869,12 @@ vendorlibexp (vendorlib.U): may use it directly in Makefiles or shell scripts. vendorman1dir (vendorman1dir.U): - This variable contains the name of the directory for man1 + This variable contains the name of the directory for man1 pages. It may have a ~ on the front. The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own man1 pages in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorman1direxp (vendorman1dir.U): @@ -4868,12 +4882,12 @@ vendorman1direxp (vendorman1dir.U): may use it directly in Makefiles or shell scripts. vendorman3dir (vendorman3dir.U): - This variable contains the name of the directory for man3 + This variable contains the name of the directory for man3 pages. It may have a ~ on the front. The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place their own man3 pages in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorman3direxp (vendorman3dir.U): @@ -4895,7 +4909,7 @@ vendorscript (vendorscript.U): The standard distribution will put nothing in this directory. Vendors who distribute perl may wish to place additional executable scripts in this directory with - MakeMaker Makefile.PL INSTALLDIRS=vendor + MakeMaker Makefile.PL INSTALLDIRS=vendor or equivalent. See INSTALL for details. vendorscriptexp (vendorscript.U): @@ -4911,12 +4925,12 @@ version (patchlevel.U): version_patchlevel_string (patchlevel.U): This is a string combining version, subversion and - perl_patchlevel (if perl_patchlevel is non-zero). - It is typically something like + perl_patchlevel (if perl_patchlevel is non-zero). + It is typically something like 'version 7 subversion 1' or 'version 7 subversion 1 patchlevel 11224' It is computed here to avoid duplication of code in myconfig.SH - and lib/Config.pm. + and lib/Config.pm. versiononly (versiononly.U): If set, this symbol indicates that only the version-specific diff --git a/config_h.SH b/config_h.SH index 232152e..bf87d0a 100644 --- a/config_h.SH +++ b/config_h.SH @@ -3860,6 +3860,16 @@ sed <$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un */ #$d_aintl HAS_AINTL /**/ +/* HAS_BUILTIN_CHOOSE_EXPR: + * Can we handle GCC builtin for compile-time ternary-like expressions + */ +/* HAS_BUILTIN_EXPECT: + * Can we handle GCC builtin for telling that certain values are more + * likely + */ +#$d_builtin_expect HAS_BUILTIN_EXPECT /**/ +#$d_builtin_choose_expr HAS_BUILTIN_CHOOSE_EXPR /**/ + /* HAS_CLEARENV: * This symbol, if defined, indicates that the clearenv () routine is * available for use. diff --git a/perl.h b/perl.h index 0c7b2d7..797a7c3 100644 --- a/perl.h +++ b/perl.h @@ -2962,13 +2962,16 @@ typedef pthread_key_t perl_key; # define NORETURN_FUNCTION_END /* NOTREACHED */ return 0 #endif -#ifdef HASBUILTIN_EXPECT +#ifdef HAS_BUILTIN_EXPECT # define EXPECT(expr,val) __builtin_expect(expr,val) #else # define EXPECT(expr,val) (expr) #endif #define LIKELY(cond) EXPECT(cond,1) #define UNLIKELY(cond) EXPECT(cond,0) +#ifdef HAS_BUILTIN_CHOOSE_EXPR +/* placeholder */ +#endif /* Some unistd.h's give a prototype for pause() even though HAS_PAUSE ends up undefined. This causes the #define