From: drh Date: Thu, 17 Jan 2008 17:15:56 +0000 (+0000) Subject: Reuse registers better in the inner loop of a SELECT statement. (CVS 4719) X-Git-Tag: version-3.6.10~1458 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d847eaad91c50668d292b86d1ae1da271d14bf02;p=thirdparty%2Fsqlite.git Reuse registers better in the inner loop of a SELECT statement. (CVS 4719) FossilOrigin-Name: 5ba4e5adf638c6812a2813961ea30a11a670409c --- diff --git a/manifest b/manifest index a599ffc1a0..a47b52cc73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Registerification\sof\sthe\sVDBE\sis\scomplete.\s\sThe\soperand\sstack\shas\sbeen\nremoved\sfrom\sthe\scode.\s\sAll\sinstructions\soperate\sout\sof\sregisters\sonly.\s(CVS\s4718) -D 2008-01-17T16:22:14 +C Reuse\sregisters\sbetter\sin\sthe\sinner\sloop\sof\sa\sSELECT\sstatement.\s(CVS\s4719) +D 2008-01-17T17:15:56 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -92,7 +92,7 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 F src/delete.c 739ccbab8fa7478762bded5c9cc67f16a4d09dbe F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 217ba4f47ffc17b10c79b091d896535e28aaa033 +F src/expr.c f13ad688f64d93efe6c4f86c46e9d172d9166217 F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 @@ -131,7 +131,7 @@ F src/pragma.c 155315ee3e6a861a0060ba4d184dfffd08ebbc03 F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd -F src/select.c fb2d6653954478c0a7f4ca64b5c4a6f024212296 +F src/select.c d9a394a2566849f9f7b03e2da3fd3ed4a91611eb F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 0691a3d52dc37cf6ac2f74838e5ff8ae1055ac9b F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f @@ -606,7 +606,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 5581160f43c60825d03de58e67aa66904d9d8964 -R 9b66d11764748ee0bf0a1a49c0663779 +P 706b41b70bd1e2030e6fa44358c38a26c5cf0985 +R 87052e903d0b7d48d785076f690c7979 U drh -Z a08c417a1e9cffb9cc564c4f53d0978f +Z 0235b0e407d857e973632bb3bd532b62 diff --git a/manifest.uuid b/manifest.uuid index c19098bb27..4701dc7a9d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -706b41b70bd1e2030e6fa44358c38a26c5cf0985 \ No newline at end of file +5ba4e5adf638c6812a2813961ea30a11a670409c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6693db4614..cfae6450d1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.347 2008/01/17 16:22:15 drh Exp $ +** $Id: expr.c,v 1.348 2008/01/17 17:15:56 drh Exp $ */ #include "sqliteInt.h" #include @@ -2162,7 +2162,7 @@ static int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ r1 = sqlite3GetTempRange(pParse, nExpr); sqlite3ExprCodeExprList(pParse, pList, r1); }else{ - nExpr = 0; + nExpr = r1 = 0; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is diff --git a/src/select.c b/src/select.c index 4c6b1f2b80..55334a08aa 100644 --- a/src/select.c +++ b/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.404 2008/01/17 16:22:15 drh Exp $ +** $Id: select.c,v 1.405 2008/01/17 17:15:56 drh Exp $ */ #include "sqliteInt.h" @@ -516,11 +516,13 @@ static int selectInnerLoop( char *aff /* affinity string if eDest is SRT_Union */ ){ Vdbe *v = pParse->pVdbe; - int i, n; + int i; int hasDistinct; /* True if the DISTINCT keyword is present */ - int iMem; /* Start of memory holding result set */ - int eDest = pDest->eDest; - int iParm = pDest->iParm; + int regResult; /* Start of memory holding result set */ + int eDest = pDest->eDest; /* How to dispose of results */ + int iParm = pDest->iParm; /* First argument to disposal method */ + int nResultCol; /* Number of result columns */ + int nToFree; /* Number of result columns to release */ if( v==0 ) return 0; assert( pEList!=0 ); @@ -536,29 +538,30 @@ static int selectInnerLoop( /* Pull the requested columns. */ if( nColumn>0 ){ - n = nColumn; + nResultCol = nColumn; }else{ - n = pEList->nExpr; + nResultCol = pEList->nExpr; } if( pDest->iMem>0 ){ - iMem = pDest->iMem; + regResult = pDest->iMem; + nToFree = 0; }else{ - pDest->iMem = iMem = pParse->nMem+1; - pParse->nMem += n; + pDest->iMem = regResult = sqlite3GetTempRange(pParse, nResultCol); + nToFree = nResultCol; } if( nColumn>0 ){ for(i=0; ia[i].pExpr, iMem+i); + for(i=0; ia[i].pExpr, regResult+i); } } - nColumn = n; + nColumn = nResultCol; /* If the DISTINCT keyword was present on the SELECT statement ** and this row has been seen before, then do not make this row @@ -567,7 +570,7 @@ static int selectInnerLoop( if( hasDistinct ){ assert( pEList!=0 ); assert( pEList->nExpr==nColumn ); - codeDistinct(pParse, distinct, iContinue, nColumn, iMem); + codeDistinct(pParse, distinct, iContinue, nColumn, regResult); if( pOrderBy==0 ){ codeOffset(v, p, iContinue); } @@ -585,7 +588,7 @@ static int selectInnerLoop( case SRT_Union: { int r1; r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); if( aff ){ sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC); } @@ -601,7 +604,7 @@ static int selectInnerLoop( case SRT_Except: { int addr, r1; r1 = sqlite3GetTempReg(pParse); - addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, nColumn, r1); + addr = sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC); sqlite3VdbeAddOp3(v, OP_NotFound, iParm, addr+3, r1); sqlite3VdbeAddOp1(v, OP_Delete, iParm); @@ -615,7 +618,7 @@ static int selectInnerLoop( case SRT_Table: case SRT_EphemTab: { int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); if( pOrderBy ){ pushOntoSorter(pParse, pOrderBy, p, r1); }else{ @@ -638,17 +641,17 @@ static int selectInnerLoop( int addr2; assert( nColumn==1 ); - addr2 = sqlite3VdbeAddOp2(v, OP_IsNull, iMem, 0); + addr2 = sqlite3VdbeAddOp1(v, OP_IsNull, regResult); p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); if( pOrderBy ){ /* At first glance you would think we could optimize out the ** ORDER BY in this case since the order of entries in the set ** does not matter. But there might be a LIMIT clause, in which ** case the order does matter */ - pushOntoSorter(pParse, pOrderBy, p, iMem); + pushOntoSorter(pParse, pOrderBy, p, regResult); }else{ int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, iMem, 1, r1, &p->affinity, 1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, 1, r1, &p->affinity, 1); sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1); sqlite3ReleaseTempReg(pParse, r1); } @@ -671,9 +674,9 @@ static int selectInnerLoop( case SRT_Mem: { assert( nColumn==1 ); if( pOrderBy ){ - pushOntoSorter(pParse, pOrderBy, p, iMem); + pushOntoSorter(pParse, pOrderBy, p, regResult); }else{ - sqlite3VdbeAddOp2(v, OP_Move, iMem, iParm); + sqlite3VdbeAddOp2(v, OP_Move, regResult, iParm); /* The LIMIT clause will jump out of the loop for us */ } break; @@ -688,13 +691,14 @@ static int selectInnerLoop( case SRT_Callback: { if( pOrderBy ){ int r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, nColumn, r1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); pushOntoSorter(pParse, pOrderBy, p, r1); sqlite3ReleaseTempReg(pParse, r1); }else if( eDest==SRT_Subroutine ){ + nToFree = 0; /* Preserve registers. Subroutine will need them. */ sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm); }else{ - sqlite3VdbeAddOp2(v, OP_ResultRow, iMem, nColumn); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); } break; } @@ -718,6 +722,7 @@ static int selectInnerLoop( sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1); sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak); } + sqlite3ReleaseTempRange(pParse, regResult, nToFree); return 0; }