Re-order some flag bits to avoid potential branches
authorKarl Williamson <public@khwilliamson.com>
Tue, 26 Nov 2013 03:12:33 +0000 (20:12 -0700)
committerKarl Williamson <public@khwilliamson.com>
Tue, 31 Dec 2013 15:27:21 +0000 (08:27 -0700)
The ANYOF_INVERT flag is used in every single pattern match of
[bracketed character classes].  With backtracking, this can be a huge
number.  All the other flags' uses pale by comparison.  I noticed that
by making it the lowest bit, we don't have to use CBOOL, as the only
possibilities are 0 and 1.  cBOOL hopefully will be optimized away, but
not always.  This commit reorders some of the flag bits to make this one
the lowest, and adds a compile check to make sure it isn't inadvertently
changed.

regcomp.h
regexec.c

index 9b0d7da..21a418c 100644 (file)
--- a/regcomp.h
+++ b/regcomp.h
@@ -327,15 +327,16 @@ struct regnode_ssc {
  * used in synthetic start class (SSC) nodes, so could be shared should new
  * flags be needed for SSCs. */
 
-#define ANYOF_LOCALE            0x01       /* /l modifier */
+#define ANYOF_LOCALE            0x02       /* /l modifier */
 
 /* The fold is calculated and stored in the bitmap where possible at compile
  * time.  However under locale, the actual folding varies depending on
  * what the locale is at the time of execution, so it has to be deferred until
  * then */
-#define ANYOF_LOC_FOLD           0x02
+#define ANYOF_LOC_FOLD           0x04
 
-#define ANYOF_INVERT            0x04
+/* regexec.c is expecting this to be in the low bit */
+#define ANYOF_INVERT            0x01
 
 /* For the SSC node only, which cannot be inverted, so is shared with that bit.
  * This means "Does this SSC match an empty string?"  This is used only during
index af434cf..e6c6bcc 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -7549,8 +7549,14 @@ S_reginclass(pTHX_ regexp * const prog, const regnode * const n, const U8* const
         }
     }
 
+#if ANYOF_INVERT != 1
+    /* Depending on compiler optimization cBOOL takes time, so if don't have to
+     * use it, don't */
+#   error ANYOF_INVERT needs to be set to 1, or guarded with cBOOL below,
+#endif
+
     /* The xor complements the return if to invert: 1^1 = 0, 1^0 = 1 */
-    return cBOOL(flags & ANYOF_INVERT) ^ match;
+    return (flags & ANYOF_INVERT) ^ match;
 }
 
 STATIC U8 *