develooper Front page | perl.perl5.changes | Postings from March 2019

[perl.git] branch blead updated. v5.29.9-12-gb877c1ff73

From:
Karl Williamson
Date:
March 21, 2019 17:17
Subject:
[perl.git] branch blead updated. v5.29.9-12-gb877c1ff73
Message ID:
E1h71K9-0002Jk-Mq@git.dc.perl.space
In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/b877c1ff7374e89bad1d494c2a847af552d40782?hp=ef65a74af186beb93566cf827c5f543f4aa14645>

- Log -----------------------------------------------------------------
commit b877c1ff7374e89bad1d494c2a847af552d40782
Author: Karl Williamson <khw@cpan.org>
Date:   Thu Mar 21 10:14:37 2019 -0600

    handy.h: Change some macros to use new inRANGE
    
    It turns out that on ASCII platforms, several of the character classes
    are expressible as a single range, and using the new inRANGE macro saves
    some instructions each time versus the array lookup still done for these
    on EBCDIC platforms.  Here is a sample benchmark
    
    Key:
        Ir   Instruction read
        Dr   Data read
        Dw   Data write
        COND conditional branches
        IND  indirect branches
    
    The numbers represent raw counts per loop iteration.
    
    isDIGIT_A('5')
    
           blead  hack Ratio %
           ----- ----- -------
        Ir 358.0 355.0   100.8
        Dr 123.0 121.0   101.7
        Dw  57.0  57.0   100.0
      COND  51.0  50.0   102.0
       IND   7.0   7.0   100.0
    
    The differences are small, but these macros are executed ubiquitously

commit 305fe86ebe53ebaec4b94533f37a83774647e346
Author: Karl Williamson <khw@cpan.org>
Date:   Wed Mar 20 15:31:03 2019 -0600

    Generalize macro and move to handy.h
    
    The macro verified that its input was in the range '1' to '9' by using a
    subtraction and a single conditional.  This commit generalizes this
    non-obvious method of avoiding a conditional, and moves it to handy.h so
    it can be used in other places.

-----------------------------------------------------------------------

Summary of changes:
 handy.h | 26 ++++++++++++++++++++------
 sv.c    | 18 ++++++------------
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/handy.h b/handy.h
index 57ad62dc61..3ce0b1bca7 100644
--- a/handy.h
+++ b/handy.h
@@ -1094,6 +1094,12 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
 #define FITS_IN_8_BITS(c) (1)
 #endif
 
+/* Returns true if c is in the range l..u
+ * Written with the cast so it only needs one conditional test
+ */
+#define inRANGE(c, l, u) (__ASSERT_((u) >= (l))                          \
+    ((WIDEST_UTYPE) (((c) - (l)) | 0) <= ((WIDEST_UTYPE) ((u) - (l)))))
+
 #ifdef EBCDIC
 #   ifndef _ALL_SOURCE
         /* The native libc isascii() et.al. functions return the wrong results
@@ -1248,17 +1254,25 @@ END_EXTERN_C
         && ((PL_charclass[(U8) (c)] & _CC_mask_A(classnum))     \
                                    == _CC_mask_A(classnum)))
 
-#   define isALPHA_A(c)  _generic_isCC_A(c, _CC_ALPHA)
+#   ifdef EBCDIC
+#     define isALPHA_A(c)  _generic_isCC_A(c, _CC_ALPHA)
+#     define isGRAPH_A(c)  _generic_isCC_A(c, _CC_GRAPH)
+#     define isLOWER_A(c)  _generic_isCC_A(c, _CC_LOWER)
+#     define isPRINT_A(c)  _generic_isCC_A(c, _CC_PRINT)
+#     define isUPPER_A(c)  _generic_isCC_A(c, _CC_UPPER)
+#   else
+#     define isALPHA_A(c)  inRANGE((~('A' ^ 'a') & (c)), 'A', 'Z')
+#     define isGRAPH_A(c)  inRANGE((c), ' ' + 1, 0x7e)
+#     define isLOWER_A(c)  inRANGE(c, 'a', 'z')
+#     define isPRINT_A(c)  inRANGE(c, ' ', 0x7e)
+#     define isUPPER_A(c)  inRANGE(c, 'A', 'Z')
+#   endif
 #   define isALPHANUMERIC_A(c) _generic_isCC_A(c, _CC_ALPHANUMERIC)
 #   define isBLANK_A(c)  _generic_isCC_A(c, _CC_BLANK)
 #   define isCNTRL_A(c)  _generic_isCC_A(c, _CC_CNTRL)
-#   define isDIGIT_A(c)  _generic_isCC(c, _CC_DIGIT) /* No non-ASCII digits */
-#   define isGRAPH_A(c)  _generic_isCC_A(c, _CC_GRAPH)
-#   define isLOWER_A(c)  _generic_isCC_A(c, _CC_LOWER)
-#   define isPRINT_A(c)  _generic_isCC_A(c, _CC_PRINT)
+#   define isDIGIT_A(c)  inRANGE(c, '0', '9')
 #   define isPUNCT_A(c)  _generic_isCC_A(c, _CC_PUNCT)
 #   define isSPACE_A(c)  _generic_isCC_A(c, _CC_SPACE)
-#   define isUPPER_A(c)  _generic_isCC_A(c, _CC_UPPER)
 #   define isWORDCHAR_A(c) _generic_isCC_A(c, _CC_WORDCHAR)
 #   define isXDIGIT_A(c)  _generic_isCC(c, _CC_XDIGIT) /* No non-ASCII xdigits
                                                         */
diff --git a/sv.c b/sv.c
index e9a46827d3..b6d9123971 100644
--- a/sv.c
+++ b/sv.c
@@ -11071,12 +11071,6 @@ S_sprintf_arg_num_val(pTHX_ va_list *const args, int i, SV *sv, bool *neg)
     return (STRLEN)iv;
 }
 
-
-/* Returns true if c is in the range '1'..'9'
- * Written with the cast so it only needs one conditional test
- */
-#define IS_1_TO_9(c) ((U8)(c - '1') <= 8)
-
 /* Read in and return a number. Updates *pattern to point to the char
  * following the number. Expects the first char to 1..9.
  * Croaks if the number exceeds 1/4 of the maximum value of STRLEN.
@@ -11093,7 +11087,7 @@ S_expect_number(pTHX_ const char **const pattern)
 
     PERL_ARGS_ASSERT_EXPECT_NUMBER;
 
-    assert(IS_1_TO_9(**pattern));
+    assert(inRANGE(**pattern, '1', '9'));
 
     var = *(*pattern)++ - '0';
     while (isDIGIT(**pattern)) {
@@ -12042,7 +12036,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
     [%bcdefginopsuxDFOUX] format (mandatory)
 */
 
-	if (IS_1_TO_9(*q)) {
+	if (inRANGE(*q, '1', '9')) {
             width = expect_number(&q);
 	    if (*q == '$') {
                 if (args)
@@ -12110,7 +12104,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 	if (*q == '*') {
             STRLEN ix; /* explicit width/vector separator index */
 	    q++;
-	    if (IS_1_TO_9(*q)) {
+            if (inRANGE(*q, '1', '9')) {
                 ix = expect_number(&q);
 		if (*q++ == '$') {
                     if (args)
@@ -12182,7 +12176,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 		fill = TRUE;
                 q++;
             }
-            if (IS_1_TO_9(*q))
+            if (inRANGE(*q, '1', '9'))
                 width = expect_number(&q);
 	}
 
@@ -12195,7 +12189,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 	    if (*q == '*') {
                 STRLEN ix; /* explicit precision index */
 		q++;
-                if (IS_1_TO_9(*q)) {
+                if (inRANGE(*q, '1', '9')) {
                     ix = expect_number(&q);
                     if (*q++ == '$') {
                         if (args)
@@ -12234,7 +12228,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                  */
                 while (*q == '0')
                     q++;
-                precis = IS_1_TO_9(*q) ? expect_number(&q) : 0;
+                precis = inRANGE(*q, '1', '9') ? expect_number(&q) : 0;
 		has_precis = TRUE;
 	    }
 	}

-- 
Perl5 Master Repository



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About