]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Simplify the OPFLG processing logic in the VDBE for a speed boost in the
authordrh <drh@noemail.net>
Fri, 13 Nov 2009 19:43:43 +0000 (19:43 +0000)
committerdrh <drh@noemail.net>
Fri, 13 Nov 2009 19:43:43 +0000 (19:43 +0000)
VDBE processing loop and a reduction in code size.

FossilOrigin-Name: 3352b3eba545c3128efb7665ec91d4df3b16011d

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

index 0790916e4a74fad06120f0e6a797d53157be1e1b..a85470290cb4796f8c5448d05caeee7726be36bd 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Force\s8-byte\smemory\salignment\son\smemory\sallocated\sfor\sVDBE\scursors.
-D 2009-11-13T17:05:54
+C Simplify\sthe\sOPFLG\sprocessing\slogic\sin\sthe\sVDBE\sfor\sa\sspeed\sboost\sin\sthe\nVDBE\sprocessing\sloop\sand\sa\sreduction\sin\scode\ssize.
+D 2009-11-13T19:43:44
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in 53f3dfa49f28ab5b80cb083fb7c9051e596bcfa1
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -94,7 +94,7 @@ F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
 F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
 F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
 F mkopcodec.awk 3fb9bf077053c968451f4dd03d11661ac373f9d1
-F mkopcodeh.awk 104fa333e4a7a689fac074437cbd51a31a803bd4
+F mkopcodeh.awk 29b84656502eee5f444c3147f331ee686956ab0e
 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83
 F publish.sh c74b6c2b6b63435aa1b4b43b1396dfebfae84095
 F publish_osx.sh 2ad2ee7d50632dff99949edc9c162dbb052f7534
@@ -210,7 +210,7 @@ F src/update.c 8efeb09822886e33c265dd96d29a3d865ea6dcf2
 F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052
 F src/util.c ad4f03079ba0fe83590d1cc9197e8e4844e38592
 F src/vacuum.c 03309a08d549f9389cc3a3589afd4fadbdaf0679
-F src/vdbe.c 3067cfcc86e61e1662f7322aa153f52857b61f8b
+F src/vdbe.c bc7fe6c752a86adb63ddfdefe41c2912f0dbb207
 F src/vdbe.h 65cd747e36ad444cb1a17e529030942c45a61fe3
 F src/vdbeInt.h 59c65e7b810836b9e946acee45c7b3c02b967d1b
 F src/vdbeapi.c 17680ab7a75ec938c5ba039a6c87489d01faf2cb
@@ -771,14 +771,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P f0599d28fabe9e67a7150a91c266cb7655a2002e
-R b787bcf50272d59401284264a4dcbb30
+P bdc45ba77fb77771c8ff46b8d6c2dd29e6d3b019
+R 5ea278d36772610aa788376c8fbcebe2
 U drh
-Z 255150de2174a2682813e546e8d990c7
+Z 259be306ad269f147c546ad8a52bafc1
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFK/ZH1oxKgR168RlERAuF9AJ9hHIIG7PFtXPqnbvCge9luG/0VIACfc7kV
-v+sk467/hW51kXF6lY7carY=
-=mwCb
+iD8DBQFK/bbzoxKgR168RlERAnLoAKCIVxGvqT+6vMWYcfnTE0ON/9WBLwCfXEdv
+WTqwwhvX+GL8mTOt3BiR/h8=
+=9zc9
 -----END PGP SIGNATURE-----
index 387904bf6c240d733cef87e38edffe79d8b3c532..133a7c45f2206282eb43a033573275d9cab0eaf4 100644 (file)
@@ -1 +1 @@
-bdc45ba77fb77771c8ff46b8d6c2dd29e6d3b019
\ No newline at end of file
+3352b3eba545c3128efb7665ec91d4df3b16011d
\ No newline at end of file
index 572331b38f55e6f381443d90d4add0f045f0e576..f6b90c114dde30b6f5f18c5c7007100396d3bfe2 100644 (file)
@@ -49,6 +49,7 @@
   in1[name] = 0
   in2[name] = 0
   in3[name] = 0
+  out2[name] = 0
   out3[name] = 0
   for(i=3; i<NF; i++){
     if($i=="same" && $(i+1)=="as"){
@@ -70,6 +71,8 @@
       in2[name] = 1
     }else if(x=="in3"){
       in3[name] = 1
+    }else if(x=="out2"){
+      out2[name] = 1
     }else if(x=="out3"){
       out3[name] = 1
     }
@@ -125,13 +128,14 @@ END {
     name = order[i];
     x = op[name]
     a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
-    # a8 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 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;
     if( in2[name] ) a3 = 8;
     if( in3[name] ) a4 = 16;
-    if( out3[name] ) a5 = 32;
+    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;
   }
@@ -145,7 +149,8 @@ END {
   print "#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */"
   print "#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */"
   print "#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */"
-  print "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
+  print "#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */"
+  print "#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */"
   print "#define OPFLG_INITIALIZER {\\"
   for(i=0; i<=max; i++){
     if( i%8==0 ) printf("/* %3d */",i)
index 19548f6357d0a3cb2c48391ea89bcc3a7583bb58..85fc902a795153e1f06617bf375befe06bfafd9d 100644 (file)
@@ -677,60 +677,41 @@ int sqlite3VdbeExec(
     ** is initialized to a NULL.
     */
     opProperty = opcodeProperty[pOp->opcode];
-    if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
-      assert( pOp->p2>0 );
-      assert( pOp->p2<=p->nMem );
-      pOut = &p->aMem[pOp->p2];
-      sqlite3VdbeMemReleaseExternal(pOut);
-      pOut->flags = MEM_Null;
-      pOut->n = 0;
-    }else
-    /* Do common setup for opcodes marked with one of the following
-    ** combinations of properties.
-    **
-    **           in1
-    **           in1 in2
-    **           in1 in2 out3
-    **           in1 in3
-    **
-    ** Variables pIn1, pIn2, and pIn3 are made to point to appropriate
-    ** registers for inputs.  Variable pOut points to the output register.
-    */
-    if( (opProperty & OPFLG_IN1)!=0 ){
-      assert( pOp->p1>0 );
-      assert( pOp->p1<=p->nMem );
-      pIn1 = &p->aMem[pOp->p1];
-      REGISTER_TRACE(pOp->p1, pIn1);
-      if( (opProperty & OPFLG_IN2)!=0 ){
+    if( opProperty & (OPFLG_OUT2_PRERELEASE | OPFLG_IN1 | OPFLG_IN2
+                      | OPFLG_IN3 | OPFLG_OUT2 | OPFLG_OUT3)
+    ){
+      if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
         assert( pOp->p2>0 );
         assert( pOp->p2<=p->nMem );
-        pIn2 = &p->aMem[pOp->p2];
-        REGISTER_TRACE(pOp->p2, pIn2);
-        /* As currently implemented, in2 implies out3.  There is no reason
-        ** why this has to be, it just worked out that way. */
-        assert( (opProperty & OPFLG_OUT3)!=0 );
-        assert( pOp->p3>0 );
-        assert( pOp->p3<=p->nMem );
-        pOut = &p->aMem[pOp->p3];
-      }else if( (opProperty & OPFLG_IN3)!=0 ){
-        assert( pOp->p3>0 );
-        assert( pOp->p3<=p->nMem );
-        pIn3 = &p->aMem[pOp->p3];
-        REGISTER_TRACE(pOp->p3, pIn3);
+        pOut = &p->aMem[pOp->p2];
+        sqlite3VdbeMemReleaseExternal(pOut);
+        pOut->flags = MEM_Null;
+        pOut->n = 0;
+      }else{
+        if( (opProperty & OPFLG_IN1)!=0 ){
+          assert( pOp->p1>0 );
+          assert( pOp->p1<=p->nMem );
+          pIn1 = &p->aMem[pOp->p1];
+          REGISTER_TRACE(pOp->p1, pIn1);
+        }
+        if( (opProperty & (OPFLG_IN2|OPFLG_OUT2))!=0 ){
+          assert( pOp->p2>0 );
+          assert( pOp->p2<=p->nMem );
+          assert( (opProperty & OPFLG_OUT2)==0 || (opProperty & OPFLG_IN3)==0 );
+          pIn2 = pOut = &p->aMem[pOp->p2];
+        }
+        if( (opProperty & (OPFLG_IN3|OPFLG_OUT3))!=0 ){
+          assert( pOp->p3>0 );
+          assert( pOp->p3<=p->nMem );
+          pIn3 = pOut = &p->aMem[pOp->p3];
+        }
+#ifdef SQLITE_DEBUG
+        if( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); }
+        if( opProperty & OPFLG_IN3 ){ REGISTER_TRACE(pOp->p3, pIn3); }
+#endif
       }
-    }else if( (opProperty & OPFLG_IN2)!=0 ){
-      assert( pOp->p2>0 );
-      assert( pOp->p2<=p->nMem );
-      pIn2 = &p->aMem[pOp->p2];
-      REGISTER_TRACE(pOp->p2, pIn2);
-    }else if( (opProperty & OPFLG_IN3)!=0 ){
-      assert( pOp->p3>0 );
-      assert( pOp->p3<=p->nMem );
-      pIn3 = &p->aMem[pOp->p3];
-      REGISTER_TRACE(pOp->p3, pIn3);
     }
-
+  
     switch( pOp->opcode ){
 
 /*****************************************************************************
@@ -786,10 +767,7 @@ case OP_Goto: {             /* jump */
 ** Write the current address onto register P1
 ** and then jump to address P2.
 */
-case OP_Gosub: {            /* jump */
-  assert( pOp->p1>0 );
-  assert( pOp->p1<=p->nMem );
-  pIn1 = &p->aMem[pOp->p1];
+case OP_Gosub: {            /* jump, in1 */
   assert( (pIn1->flags & MEM_Dyn)==0 );
   pIn1->flags = MEM_Int;
   pIn1->u.i = pc;
@@ -1075,10 +1053,7 @@ case OP_Move: {
 ** This instruction makes a deep copy of the value.  A duplicate
 ** is made of any string or blob constant.  See also OP_SCopy.
 */
-case OP_Copy: {             /* in1 */
-  assert( pOp->p2>0 );
-  assert( pOp->p2<=p->nMem );
-  pOut = &p->aMem[pOp->p2];
+case OP_Copy: {             /* in1, out2 */
   assert( pOut!=pIn1 );
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
   Deephemeralize(pOut);
@@ -1098,11 +1073,7 @@ case OP_Copy: {             /* in1 */
 ** during the lifetime of the copy.  Use OP_Copy to make a complete
 ** copy.
 */
-case OP_SCopy: {            /* in1 */
-  REGISTER_TRACE(pOp->p1, pIn1);
-  assert( pOp->p2>0 );
-  assert( pOp->p2<=p->nMem );
-  pOut = &p->aMem[pOp->p2];
+case OP_SCopy: {            /* in1, out2 */
   assert( pOut!=pIn1 );
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
   REGISTER_TRACE(pOp->p2, pOut);
@@ -1945,8 +1916,7 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
 ** boolean complement in register P2.  If the value in register P1 is 
 ** NULL, then a NULL is stored in P2.
 */
-case OP_Not: {                /* same as TK_NOT, in1 */
-  pOut = &p->aMem[pOp->p2];
+case OP_Not: {                /* same as TK_NOT, in1, out2 */
   if( pIn1->flags & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
   }else{
@@ -1961,8 +1931,7 @@ case OP_Not: {                /* same as TK_NOT, in1 */
 ** ones-complement of the P1 value into register P2.  If P1 holds
 ** a NULL then store a NULL in P2.
 */
-case OP_BitNot: {             /* same as TK_BITNOT, in1 */
-  pOut = &p->aMem[pOp->p2];
+case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
   if( pIn1->flags & MEM_Null ){
     sqlite3VdbeMemSetNull(pOut);
   }else{
@@ -4333,8 +4302,8 @@ case OP_IdxRowid: {              /* out2-prerelease */
 ** If P5 is non-zero then the key value is increased by an epsilon prior 
 ** to the comparison.  This makes the opcode work like IdxLE.
 */
-case OP_IdxLT:          /* jump, in3 */
-case OP_IdxGE: {        /* jump, in3 */
+case OP_IdxLT:          /* jump */
+case OP_IdxGE: {        /* jump */
   VdbeCursor *pC;
   int res;
   UnpackedRecord r;
@@ -4696,19 +4665,13 @@ case OP_IntegrityCk: {
 **
 ** An assertion fails if P2 is not an integer.
 */
-case OP_RowSetAdd: {       /* in2 */
-  Mem *pIdx;
-  Mem *pVal;
-  assert( pOp->p1>0 && pOp->p1<=p->nMem );
-  pIdx = &p->aMem[pOp->p1];
-  assert( pOp->p2>0 && pOp->p2<=p->nMem );
-  pVal = &p->aMem[pOp->p2];
-  assert( (pVal->flags & MEM_Int)!=0 );
-  if( (pIdx->flags & MEM_RowSet)==0 ){
-    sqlite3VdbeMemSetRowSet(pIdx);
-    if( (pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
-  }
-  sqlite3RowSetInsert(pIdx->u.pRowSet, pVal->u.i);
+case OP_RowSetAdd: {       /* in1, in2 */
+  assert( (pIn2->flags & MEM_Int)!=0 );
+  if( (pIn1->flags & MEM_RowSet)==0 ){
+    sqlite3VdbeMemSetRowSet(pIn1);
+    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
+  }
+  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
   break;
 }
 
@@ -4718,22 +4681,17 @@ case OP_RowSetAdd: {       /* in2 */
 ** register P3.  Or, if boolean index P1 is initially empty, leave P3
 ** unchanged and jump to instruction P2.
 */
-case OP_RowSetRead: {       /* jump, out3 */
-  Mem *pIdx;
+case OP_RowSetRead: {       /* jump, in1, out3 */
   i64 val;
-  assert( pOp->p1>0 && pOp->p1<=p->nMem );
   CHECK_FOR_INTERRUPT;
-  pIdx = &p->aMem[pOp->p1];
-  pOut = &p->aMem[pOp->p3];
-  if( (pIdx->flags & MEM_RowSet)==0 
-   || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0
+  if( (pIn1->flags & MEM_RowSet)==0 
+   || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
   ){
     /* The boolean index is empty */
-    sqlite3VdbeMemSetNull(pIdx);
+    sqlite3VdbeMemSetNull(pIn1);
     pc = pOp->p2 - 1;
   }else{
     /* A value was pulled from the index */
-    assert( pOp->p3>0 && pOp->p3<=p->nMem );
     sqlite3VdbeMemSetInt64(pOut, val);
   }
   break;