From: drh Date: Fri, 13 Nov 2009 19:43:43 +0000 (+0000) Subject: Simplify the OPFLG processing logic in the VDBE for a speed boost in the X-Git-Tag: fts3-refactor~1^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=93952eb8c51fb50249d150a7f457106231b702b6;p=thirdparty%2Fsqlite.git Simplify the OPFLG processing logic in the VDBE for a speed boost in the VDBE processing loop and a reduction in code size. FossilOrigin-Name: 3352b3eba545c3128efb7665ec91d4df3b16011d --- diff --git a/manifest b/manifest index 0790916e4a..a85470290c 100644 --- 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----- diff --git a/manifest.uuid b/manifest.uuid index 387904bf6c..133a7c45f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdc45ba77fb77771c8ff46b8d6c2dd29e6d3b019 \ No newline at end of file +3352b3eba545c3128efb7665ec91d4df3b16011d \ No newline at end of file diff --git a/mkopcodeh.awk b/mkopcodeh.awk index 572331b38f..f6b90c114d 100644 --- a/mkopcodeh.awk +++ b/mkopcodeh.awk @@ -49,6 +49,7 @@ in1[name] = 0 in2[name] = 0 in3[name] = 0 + out2[name] = 0 out3[name] = 0 for(i=3; iopcode]; - 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;