]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More than double the speed of the resolveP2Values() routine in vdbeaux.c by
authordrh <drh@noemail.net>
Tue, 6 Aug 2013 07:45:08 +0000 (07:45 +0000)
committerdrh <drh@noemail.net>
Tue, 6 Aug 2013 07:45:08 +0000 (07:45 +0000)
moving from an extended if-else on every opcode to a switch.  Opcodes are
reordered in mkopcodesh.awk to put the switched opcodes close together,
for additional performance and to reduce code footprint.

FossilOrigin-Name: 924f7e4d7a8fa2fe9100836663f3733b6e1a9084

manifest
manifest.uuid
mkopcodeh.awk
src/vdbeaux.c

index 5e6cb063f9fe6531cb5edbb492066fa01c32644a..df242bb579969ee853384eced1b96b34e4317db6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Performance\soptimization:\sAvoid\scalling\sconvertCompoundSelecctToSubquery()\non\squeries\sthat\sdo\snot\suse\sthe\sUNION,\sEXCEPT,\sor\sINTERSECT\soperators.
-D 2013-08-05T22:05:02.528
+C More\sthan\sdouble\sthe\sspeed\sof\sthe\sresolveP2Values()\sroutine\sin\svdbeaux.c\sby\nmoving\sfrom\san\sextended\sif-else\son\severy\sopcode\sto\sa\sswitch.\s\sOpcodes\sare\nreordered\sin\smkopcodesh.awk\sto\sput\sthe\sswitched\sopcodes\sclose\stogether,\nfor\sadditional\sperformance\sand\sto\sreduce\scode\sfootprint.
+D 2013-08-06T07:45:08.160
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -144,7 +144,7 @@ F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
 F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
 F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
 F mkopcodec.awk f6fccee29e68493bfd90a2e0466ede5fa94dd2fc
-F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
+F mkopcodeh.awk e7334b45c023b5ee2efc6e8f479560c2026fa34a
 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
@@ -281,7 +281,7 @@ F src/vdbe.c 4914ae1d00045a5310aea9e0f7c9a8edd3d9f856
 F src/vdbe.h 4f554b5627f26710c4c36d919110a3fc611ca5c4
 F src/vdbeInt.h e9b7c6b165a31a4715c5aa97223d20d265515231
 F src/vdbeapi.c 4d13580bd058b39623e8fcfc233b7df4b8191e8b
-F src/vdbeaux.c d5cdd5bd5c063cc912df20b0bcadf78b6b351cb2
+F src/vdbeaux.c a6ea36a9dc714e1128a0173249a0532ddcab0489
 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
 F src/vdbemem.c 833005f1cbbf447289f1973dba2a0c2228c7b8ab
 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
@@ -1105,7 +1105,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 240f7252c66ad3ff5ae0ef06455c1ff9bd78bbb4
-R 2fa5b161c92663b5ccc93db65bbe97fe
+P c589b2fed7beabc2337d701094c22635914d9c23
+R 63c66722ef11a129368dbe6ccc84108b
 U drh
-Z 4bd26a74b5ae2ab01f7864a9d28488af
+Z db760ef775aca796d7a23f90b9b7ee9e
index b872e4ded8fd065776050ea241f21f7e70cdd13c..43da133fc81f366087bfbfd4dc7c7831f20c611a 100644 (file)
@@ -1 +1 @@
-c589b2fed7beabc2337d701094c22635914d9c23
\ No newline at end of file
+924f7e4d7a8fa2fe9100836663f3733b6e1a9084
\ No newline at end of file
index f6b90c114dde30b6f5f18c5c7007100396d3bfe2..9685c3a0e860337960ff932ec97da4e0ec44fd21 100644 (file)
@@ -35,7 +35,7 @@
 
 # Remember the TK_ values from the parse.h file
 /^#define TK_/ {
-  tk[$2] = 0+$3
+  tk[$2] = 0+$3    # tk[x] holds the numeric value for TK symbol X
 }
 
 # Scan for "case OP_aaaa:" lines in the vdbe.c file
@@ -43,7 +43,7 @@
   name = $2
   sub(/:/,"",name)
   sub("\r","",name)
-  op[name] = -1
+  op[name] = -1       # op[x] holds the numeric value for OP symbol x
   jump[name] = 0
   out2_prerelease[name] = 0
   in1[name] = 0
     if($i=="same" && $(i+1)=="as"){
       sym = $(i+2)
       sub(/,/,"",sym)
-      op[name] = tk[sym]
-      used[op[name]] = 1
-      sameas[op[name]] = sym
+      val = tk[sym]
+      op[name] = val
+      used[val] = 1
+      sameas[val] = sym
+      def[val] = name
     }
     x = $i
     sub(",","",x)
@@ -90,31 +92,55 @@ END {
   order[n_op++] = "OP_Noop";
   op["OP_Explain"] = -1;
   order[n_op++] = "OP_Explain";
+
+  # Assign small values to opcodes that are processed by resolveP2Values()
+  # to make code generation for the switch() statement smaller and faster.
   for(i=0; i<n_op; i++){
     name = order[i];
-    if( op[name]<0 ){
+    if( op[name]>=0 ) continue;
+    if( name=="OP_Function"      \
+     || name=="OP_AggStep"       \
+     || name=="OP_Transaction"   \
+     || name=="OP_AutoCommit"    \
+     || name=="OP_Savepoint"     \
+     || name=="OP_Checkpoint"    \
+     || name=="OP_Vacuum"        \
+     || name=="OP_JournalMode"   \
+     || name=="OP_VUpdate"       \
+     || name=="OP_VFilter"       \
+     || name=="OP_Next"          \
+     || name=="OP_SorterNext"    \
+     || name=="OP_Prev"          \
+    ){
       cnt++
       while( used[cnt] ) cnt++
       op[name] = cnt
+      used[cnt] = 1
+      def[cnt] = name
     }
-    used[op[name]] = 1;
-    if( op[name]>max ) max = op[name]
-    printf "#define %-25s %15d", name, op[name]
-    if( sameas[op[name]] ) {
-      printf "   /* same as %-12s*/", sameas[op[name]]
-    } 
-    printf "\n"
+  }
 
+  # Generate the numeric values for opcodes
+  for(i=0; i<n_op; i++){
+    name = order[i];
+    if( op[name]<0 ){
+      cnt++
+      while( used[cnt] ) cnt++
+      op[name] = cnt
+      used[cnt] = 1
+      def[cnt] = name
+    }
   }
-  seenUnused = 0;
-  for(i=1; i<max; i++){
+  max = cnt
+  for(i=1; i<=max; i++){
     if( !used[i] ){
-      if( !seenUnused ){
-        printf "\n/* The following opcode values are never used */\n"
-        seenUnused = 1
-      }
-      printf "#define %-25s %15d\n", sprintf( "OP_NotUsed_%-3d", i ), i
+      def[i] = "OP_NotUsed_" i 
     }
+    printf "#define %-25s %15d", def[i], i
+    if( sameas[i] ){
+      printf "   /* same as %-12s*/", sameas[i]
+    } 
+    printf "\n"
   }
 
   # Generate the bitvectors:
@@ -123,12 +149,9 @@ END {
   #  bit 1:     pushes a result onto stack
   #  bit 2:     output to p1.  release p1 before opcode runs
   #
-  for(i=0; i<=max; i++) bv[i] = 0;
-  for(i=0; i<n_op; i++){
-    name = order[i];
-    x = op[name]
+  for(i=0; i<=max; i++){
+    name = def[i]
     a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
-    # a7 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
     if( jump[name] ) a0 = 1;
     if( out2_prerelease[name] ) a1 = 2;
     if( in1[name] ) a2 = 4;
@@ -136,8 +159,7 @@ END {
     if( in3[name] ) a4 = 16;
     if( out2[name] ) a5 = 32;
     if( out3[name] ) a6 = 64;
-    # bv[x] = a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15;
-    bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
+    bv[i] = a0+a1+a2+a3+a4+a5+a6+a7;
   }
   print "\n"
   print "/* Properties such as \"out2\" or \"jump\" that are specified in"
index 2e2ba5d00d52b935047dec1c57a1f1deec59d22f..576483e141ae6e8aabb2f71184644e725e14c867 100644 (file)
@@ -407,40 +407,60 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
   for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
     u8 opcode = pOp->opcode;
 
-    pOp->opflags = sqlite3OpcodeProperty[opcode];
-    if( opcode==OP_Function || opcode==OP_AggStep ){
-      if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
-    }else if( opcode==OP_Transaction ){
-      if( pOp->p2!=0 ) p->readOnly = 0;
-      p->bIsReader = 1;
-    }else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
-      p->bIsReader = 1;
-    }else if( opcode==OP_Vacuum
-           || opcode==OP_JournalMode
+    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
+    ** cases from this switch! */
+    switch( opcode ){
+      case OP_Function:
+      case OP_AggStep: {
+        if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
+        break;
+      }
+      case OP_Transaction: {
+        if( pOp->p2!=0 ) p->readOnly = 0;
+        /* fall thru */
+      }
+      case OP_AutoCommit:
+      case OP_Savepoint: {
+        p->bIsReader = 1;
+        break;
+      }
 #ifndef SQLITE_OMIT_WAL
-           || opcode==OP_Checkpoint
+      case OP_Checkpoint:
 #endif
-    ){
-      p->readOnly = 0;
-      p->bIsReader = 1;
+      case OP_Vacuum:
+      case OP_JournalMode: {
+        p->readOnly = 0;
+        p->bIsReader = 1;
+        break;
+      }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-    }else if( opcode==OP_VUpdate ){
-      if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
-    }else if( opcode==OP_VFilter ){
-      int n;
-      assert( p->nOp - i >= 3 );
-      assert( pOp[-1].opcode==OP_Integer );
-      n = pOp[-1].p1;
-      if( n>nMaxArgs ) nMaxArgs = n;
+      case OP_VUpdate: {
+        if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+        break;
+      }
+      case OP_VFilter: {
+        int n;
+        assert( p->nOp - i >= 3 );
+        assert( pOp[-1].opcode==OP_Integer );
+        n = pOp[-1].p1;
+        if( n>nMaxArgs ) nMaxArgs = n;
+        break;
+      }
 #endif
-    }else if( opcode==OP_Next || opcode==OP_SorterNext ){
-      pOp->p4.xAdvance = sqlite3BtreeNext;
-      pOp->p4type = P4_ADVANCE;
-    }else if( opcode==OP_Prev ){
-      pOp->p4.xAdvance = sqlite3BtreePrevious;
-      pOp->p4type = P4_ADVANCE;
+      case OP_Next:
+      case OP_SorterNext: {
+        pOp->p4.xAdvance = sqlite3BtreeNext;
+        pOp->p4type = P4_ADVANCE;
+        break;
+      }
+      case OP_Prev: {
+        pOp->p4.xAdvance = sqlite3BtreePrevious;
+        pOp->p4type = P4_ADVANCE;
+        break;
+      }
     }
 
+    pOp->opflags = sqlite3OpcodeProperty[opcode];
     if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
       assert( -1-pOp->p2<p->nLabel );
       pOp->p2 = aLabel[-1-pOp->p2];