From: drh Date: Thu, 10 Jan 2008 03:46:36 +0000 (+0000) Subject: Continuing work toward registerizing the code generator. (CVS 4703) X-Git-Tag: version-3.6.10~1474 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=892d317990991f8896e1b07904b916647ba8de4c;p=thirdparty%2Fsqlite.git Continuing work toward registerizing the code generator. (CVS 4703) FossilOrigin-Name: 173698c963473ab1b9db88b23a2de82e4097b96d --- diff --git a/manifest b/manifest index 300261c566..afef6b1e09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smixing\squote\sexcapes\sin\san\sawk\sscript.\s\sTicket\s#2877.\s(CVS\s4702) -D 2008-01-10T00:08:43 +C Continuing\swork\stoward\sregisterizing\sthe\scode\sgenerator.\s(CVS\s4703) +D 2008-01-10T03:46:36 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -92,11 +92,11 @@ F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131 F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6 F src/delete.c 4f760fb7e9b0bb3cf05534bb9d43ea9e726b7e74 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b -F src/expr.c 27971029714d4b24081cf20b35e7c96d0e148311 +F src/expr.c 522ba17fa6253a98dc6451e600341277ea43d5c6 F src/func.c 996071cf0af9d967e58b69fce1909555059ebc7d F src/hash.c 45a7005aac044b6c86bd7e49c44bc15d30006d6c F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 -F src/insert.c 8630ee92dac91944c9f7b75847fa4ef74292b220 +F src/insert.c b8406b40cc1cac732932ef587cbc0da006bfd68b F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2 F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 @@ -131,12 +131,12 @@ F src/pragma.c bc6063d91d56a8b3cdad9e3478bba86700759cc4 F src/prepare.c c31a879d6795f4765fd0b113675c6debbc96b7fd F src/printf.c eb27822ba2eec669161409ca31279a24c26ac910 F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da -F src/select.c 7b88e17052dce3c89530cd6be014505b00d6ff4c +F src/select.c 095296a572c296c9ce718768c6c984d33b239e5a F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c 5391e889384d2062249f668110d64ed16f601c4b F src/sqlite.h.in 2a7e3776534bbe6ff2cdc058f3abebe91e7e429f F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb -F src/sqliteInt.h c2866ab4a8eb42e4daffe30d19afc82952ed67c1 +F src/sqliteInt.h 0606321d38df78adef2325e0b51cd3963731f290 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4 F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf @@ -605,7 +605,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 1134c5ea7116bb2f342ccf09548d075c308c427b -R 965fc5391bf9a2a36bfcbb9b6a1fc252 +P 05fbca91085cb1b271a05e62181596b4f6f1bb9e +R 44353c14eaa458d109462754e477c6c2 U drh -Z b84d4a6ab04978dba07488e081c74e60 +Z d88167e0b41893f49eaf4061856356de diff --git a/manifest.uuid b/manifest.uuid index 1374695cbb..486aad7ba6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05fbca91085cb1b271a05e62181596b4f6f1bb9e \ No newline at end of file +173698c963473ab1b9db88b23a2de82e4097b96d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 39004b15ce..c1cb722c5d 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.340 2008/01/09 23:04:12 drh Exp $ +** $Id: expr.c,v 1.341 2008/01/10 03:46:36 drh Exp $ */ #include "sqliteInt.h" #include @@ -1610,8 +1610,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp1(v, OP_SCopy, iMem); - iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); + iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); @@ -1647,8 +1646,7 @@ int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){ iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp1(v, OP_SCopy, iMem); - iAddr = sqlite3VdbeAddOp2(v, OP_If, 0, iMem); + iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb, @@ -1704,10 +1702,9 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ */ if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ int mem = ++pParse->nMem; - sqlite3VdbeAddOp1(v, OP_SCopy, mem); - testAddr = sqlite3VdbeAddOp0(v, OP_If); + sqlite3VdbeAddOp1(v, OP_If, mem); + testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); assert( testAddr>0 || pParse->db->mallocFailed ); - sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); } switch( pExpr->op ){ @@ -1783,8 +1780,8 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( testAddr>0 && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, testAddr-1, 3); + if( testAddr && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, testAddr-1, 2); testAddr = 0; } @@ -1830,7 +1827,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } if( testAddr ){ - sqlite3VdbeJumpHere(v, testAddr); + sqlite3VdbeJumpHere(v, testAddr-1); } return; @@ -2178,7 +2175,12 @@ int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ nId = pExpr->token.n; pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, enc, 0); assert( pDef!=0 ); - nExpr = sqlite3ExprCodeExprList(pParse, pList, 0); + if( pList ){ + nExpr = pList->nExpr; + sqlite3ExprCodeExprList(pParse, pList, 0); + }else{ + nExpr = 0; + } #ifndef SQLITE_OMIT_VIRTUALTABLE /* Possibly overload the function if the first argument is ** a virtual table column. @@ -2402,9 +2404,10 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ /* ** Generate code that pushes the value of every element of the given -** expression list onto the stack. +** expression list onto the stack if target==0 or into a sequence of +** registers beginning at target. ** -** Return the number of elements pushed onto the stack. +** Return the number of elements evaluated. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ @@ -2413,12 +2416,13 @@ int sqlite3ExprCodeExprList( ){ struct ExprList_item *pItem; int i, n, incr = 1; - if( pList==0 ) return 0; + assert( pList!=0 || pParse->db->mallocFailed ); + if( pList==0 ){ + return 0; + } + assert( target>=0 ); n = pList->nExpr; - if( target<0 ){ - target = pParse->nMem+1; - pParse->nMem += n; - }else if( target==0 ){ + if( target==0 ){ incr = 0; } for(pItem=pList->a, i=n; i>0; i--, pItem++){ @@ -2888,3 +2892,41 @@ int sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ } return nErr; } + +/* +** Allocate or deallocate temporary use registers during code generation. +*/ +int sqlite3GetTempReg(Parse *pParse){ + if( pParse->nTempReg ){ + return pParse->aTempReg[--pParse->nTempReg]; + }else{ + return ++pParse->nMem; + } +} +void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ + if( pParse->nTempRegaTempReg)/sizeof(pParse->aTempReg[0]) ){ + pParse->aTempReg[pParse->nTempReg++] = iReg; + } +} + +/* +** Allocate or deallocate a block of nReg consecutive registers +*/ +int sqlite3GetTempRange(Parse *pParse, int nReg){ + int i; + if( nReg<=pParse->nRangeReg ){ + i = pParse->iRangeReg; + pParse->iRangeReg += nReg; + pParse->nRangeReg -= nReg; + }else{ + i = pParse->nMem+1; + pParse->nMem += nReg; + } + return i; +} +void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ + if( nReg>pParse->nRangeReg ){ + pParse->nRangeReg = nReg; + pParse->iRangeReg = iReg; + } +} diff --git a/src/insert.c b/src/insert.c index b9931abab1..72585705d5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.220 2008/01/09 23:04:12 drh Exp $ +** $Id: insert.c,v 1.221 2008/01/10 03:46:36 drh Exp $ */ #include "sqliteInt.h" @@ -1107,9 +1107,7 @@ void sqlite3GenerateConstraintChecks( } if( isUpdate ){ - sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1); - sqlite3VdbeAddOp1(v, OP_SCopy, regRowid); - j2 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0); + j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1); } j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid); switch( onError ){ @@ -1127,8 +1125,7 @@ void sqlite3GenerateConstraintChecks( case OE_Replace: { sqlite3GenerateRowIndexDelete(v, pTab, baseCur, 0); if( isUpdate ){ - sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-hasTwoRowids); - sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0); + sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-hasTwoRowids); } seenReplace = 1; break; @@ -1142,8 +1139,7 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, j3); if( isUpdate ){ sqlite3VdbeJumpHere(v, j2); - sqlite3VdbeAddOp1(v, OP_SCopy, regRowid-1); - sqlite3VdbeAddOp2(v, OP_MoveGe, baseCur, 0); + sqlite3VdbeAddOp3(v, OP_MoveGe, baseCur, 0, regRowid-1); } } diff --git a/src/select.c b/src/select.c index 794b9af6f3..f7ab87c9ee 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.395 2008/01/09 23:04:12 drh Exp $ +** $Id: select.c,v 1.396 2008/01/10 03:46:36 drh Exp $ */ #include "sqliteInt.h" @@ -397,11 +397,16 @@ static void pushOntoSorter( Select *pSelect /* The whole SELECT statement */ ){ Vdbe *v = pParse->pVdbe; - sqlite3ExprCodeExprList(pParse, pOrderBy, 0); - sqlite3VdbeAddOp1(v, OP_Sequence, pOrderBy->iECursor); - sqlite3VdbeAddOp1(v, OP_Pull, pOrderBy->nExpr + 1); - sqlite3VdbeAddOp1(v, OP_MakeRecord, pOrderBy->nExpr + 2); - sqlite3VdbeAddOp1(v, OP_IdxInsert, pOrderBy->iECursor); + int nExpr = pOrderBy->nExpr; + int regBase = sqlite3GetTempRange(pParse, nExpr+2); + int regRecord = sqlite3GetTempReg(pParse); + sqlite3ExprCodeExprList(pParse, pOrderBy, regBase); + sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr); + sqlite3VdbeAddOp2(v, OP_Move, 0, regBase+nExpr+1); + sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nExpr + 2, regRecord); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nExpr+2); if( pSelect->iLimit>=0 ){ int addr1, addr2; addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, pSelect->iLimit+1); @@ -3002,8 +3007,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ ExprList *pList = pF->pExpr->pList; if( pList ){ nArg = pList->nExpr; - sqlite3ExprCodeExprList(pParse, pList, 0); - regAgg = sqlite3StackToReg(pParse, nArg); + regAgg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pList, regAgg); }else{ nArg = 0; regAgg = 0; @@ -3029,6 +3034,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ sqlite3VdbeAddOp4(v, OP_AggStep, 0, regAgg, pF->iMem, (void*)pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } @@ -3545,18 +3551,38 @@ int sqlite3Select( ** then loop over the sorting index in order to get the output ** in sorted order */ + int regBase; + int regRecord; + int nCol; + int nGroupBy; + groupBySort = 1; - sqlite3ExprCodeExprList(pParse, pGroupBy, 0); - sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx, 0); - j = pGroupBy->nExpr+1; + nGroupBy = pGroupBy->nExpr; + nCol = nGroupBy + 1; + j = nGroupBy+1; + for(i=0; i=j ){ + nCol++; + j++; + } + } + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase); + sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy); + j = nGroupBy+1; for(i=0; iiSorterColumnpTab, pCol->iColumn,pCol->iTable,0); - j++; + if( pCol->iSorterColumn>=j ){ + sqlite3ExprCodeGetColumn(v, pCol->pTab, pCol->iColumn, pCol->iTable, + j + regBase); + j++; + } } - sqlite3VdbeAddOp2(v, OP_MakeRecord, j, 0); - sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, 0); + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_RegMakeRec, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_IdxInsert, sAggInfo.sortingIdx, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); sqlite3WhereEnd(pWInfo); sqlite3VdbeAddOp2(v, OP_Sort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ef1aab0d9a..6f6842acde 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.645 2008/01/09 23:04:12 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.646 2008/01/10 03:46:36 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1399,6 +1399,10 @@ struct Parse { u8 checkSchema; /* Causes schema cookie check after an error */ u8 nested; /* Number of nested calls to the parser/code generator */ u8 parseError; /* True after a parsing error. Ticket #1794 */ + u8 nTempReg; /* Number of temporary registers in aTempReg[] */ + int aTempReg[8]; /* Holding area for temporary registers */ + int nRangeReg; /* Size of the temporary register block */ + int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ @@ -1692,6 +1696,10 @@ void sqlite3DequoteExpr(sqlite3*, Expr*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); +int sqlite3GetTempReg(Parse*); +void sqlite3ReleaseTempReg(Parse*,int); +int sqlite3GetTempRange(Parse*,int); +void sqlite3ReleaseTempRange(Parse*,int,int); Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*);