[Pcre-svn] [1052] code/trunk/pcre_jit_compile.c: Optimizing …

Startseite
Nachricht löschen
Autor: Subversion repository
Datum:  
To: pcre-svn
Betreff: [Pcre-svn] [1052] code/trunk/pcre_jit_compile.c: Optimizing clists in JIT.
Revision: 1052
          http://vcs.pcre.org/viewvc?view=rev&revision=1052
Author:   zherczeg
Date:     2012-10-03 12:36:18 +0100 (Wed, 03 Oct 2012)


Log Message:
-----------
Optimizing clists in JIT.

Modified Paths:
--------------
    code/trunk/pcre_jit_compile.c


Modified: code/trunk/pcre_jit_compile.c
===================================================================
--- code/trunk/pcre_jit_compile.c    2012-10-02 08:18:24 UTC (rev 1051)
+++ code/trunk/pcre_jit_compile.c    2012-10-03 11:36:18 UTC (rev 1052)
@@ -1692,7 +1692,7 @@
 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
 #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B


-static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
+static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
{
return (value & (value - 1)) == 0;
}
@@ -1998,7 +1998,7 @@
return (0 << 8) | 0x20;

/* Since c != oc, they must have at least 1 bit difference. */
-if (!ispowerof2(bit))
+if (!is_powerof2(bit))
return 0;

 #ifdef COMPILE_PCRE8
@@ -2765,7 +2765,7 @@
 else
   {
   bit = first_char ^ oc;
-  if (ispowerof2(bit))
+  if (is_powerof2(bit))
     {
     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
@@ -2983,7 +2983,7 @@
 else
   {
   bit = req_char ^ oc;
-  if (ispowerof2(bit))
+  if (is_powerof2(bit))
     {
     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
@@ -3213,7 +3213,7 @@
       }
     return TRUE;
     }
-  if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
+  if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
     {
     if (readch)
       read_char(common);
@@ -4019,18 +4019,53 @@
       case PT_CLIST:
       other_cases = PRIV(ucd_caseless_sets) + cc[1];


-      /* At least two characters are required. */
-      SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR);
+      /* At least three characters are required.
+         Otherwise this case would be handled by the normal code path. */
+      SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
+      SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);


-      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
-      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+      /* Optimizing character pairs, if their difference is power of 2. */
+      if (is_powerof2(other_cases[1] ^ other_cases[0]))
+        {
+        if (charoffset == 0)
+          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+        else
+          {
+          OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
+          OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+          }
+        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
+        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+        other_cases += 2;
+        }
+      else if (is_powerof2(other_cases[2] ^ other_cases[1]))
+        {
+        if (charoffset == 0)
+          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
+        else
+          {
+          OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
+          OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
+          }
+        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
+        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);


-      do
+        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
+        COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
+
+        other_cases += 3;
+        }
+      else
         {
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
+        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
+        }
+
+      while (*other_cases != NOTACHAR)
+        {
+        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
         COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
         }
-      while (*other_cases != NOTACHAR);
       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
       break;
       }
@@ -4458,7 +4493,7 @@
     }
   oc = char_othercase(common, c);
   bit = c ^ oc;
-  if (ispowerof2(bit))
+  if (is_powerof2(bit))
     {
     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
     add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
@@ -4519,7 +4554,7 @@
     {
     oc = char_othercase(common, c);
     bit = c ^ oc;
-    if (ispowerof2(bit))
+    if (is_powerof2(bit))
       {
       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
       add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));