From: drh Date: Thu, 21 Nov 2013 14:33:48 +0000 (+0000) Subject: Add the ability to factor constant functions out of inner loops. But do X-Git-Tag: version-3.8.2~65 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b1fba2868b7e1c1932fe7985658ca409e8bbd6da;p=thirdparty%2Fsqlite.git Add the ability to factor constant functions out of inner loops. But do not factor out non-constant functions, like random(). FossilOrigin-Name: 1b0f779e19a5c0d51eddd2d88db50034d77d132c --- diff --git a/manifest b/manifest index 6c4d9ef46a..f32b14861b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\simprovement\sto\sOP_Function\sand\san\simprovement\sto\sOP_Move. -D 2013-11-21T04:18:31.892 +C Add\sthe\sability\sto\sfactor\sconstant\sfunctions\sout\sof\sinner\sloops.\s\sBut\sdo\nnot\sfactor\sout\snon-constant\sfunctions,\slike\srandom(). +D 2013-11-21T14:33:48.381 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,10 +175,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c d81090a3f3bb0845fa6c6795d221ec23ef107737 +F src/expr.c c3a87def4d55a2bf734de266e74388be8617f98e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 -F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 +F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -217,14 +217,14 @@ F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 -F src/resolve.c 6fcceeb653a0020b14491975d567c989e794d408 +F src/resolve.c 1568ba369113851743ec7123d859a358e63664bb F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 03b91c6bceccd7718473f3d790abcb8d5c2b1bf1 +F src/sqliteInt.h 300dbe249ea28b094bdf304d6d96d414fef0bb26 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b890eefd57fbd189f7df611e82eb1fb4b197e1c3 -R f453cb4528248c0309ea050c9ba4ca77 +P 70b056fb6f60cdfbe24e4b77a1770eef064a73c6 +R 4b398323e41fc9e4c6f9c8eb17716c1f U drh -Z 2b2e2a3a32727285c9b4dfbebd948b02 +Z 4f758cd7144fa1f23ddbc35887f66833 diff --git a/manifest.uuid b/manifest.uuid index 4fff4fd7d3..c8206cdd9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70b056fb6f60cdfbe24e4b77a1770eef064a73c6 \ No newline at end of file +1b0f779e19a5c0d51eddd2d88db50034d77d132c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ce541ed8ab..f0a4190401 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1191,9 +1191,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ switch( pExpr->op ){ /* Consider functions to be constant if all their arguments are constant - ** and pWalker->u.i==2 */ + ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST + ** flag. */ case TK_FUNCTION: - if( pWalker->u.i==2 ) return WRC_Continue; + if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){ + return WRC_Continue; + } /* Fall through */ case TK_ID: case TK_COLUMN: @@ -2697,9 +2700,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); - testcase( (pDef->funcFlags&~SQLITE_FUNC_ENCMASK) - ==SQLITE_FUNC_LENGTH ); - pFarg->a[0].pExpr->op2 = pDef->funcFlags&~SQLITE_FUNC_ENCMASK; + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); + pFarg->a[0].pExpr->op2 = + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); } } diff --git a/src/func.c b/src/func.c index c9962f6d91..46c606ac06 100644 --- a/src/func.c +++ b/src/func.c @@ -1664,8 +1664,8 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION(random, 0, 0, 0, randomFunc ), - FUNCTION(randomblob, 1, 0, 0, randomBlob ), + VFUNCTION(random, 0, 0, 0, randomFunc ), + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), @@ -1675,9 +1675,9 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ FUNCTION(quote, 1, 0, 0, quoteFunc ), - FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), - FUNCTION(changes, 0, 0, 0, changes ), - FUNCTION(total_changes, 0, 0, 0, total_changes ), + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), + VFUNCTION(changes, 0, 0, 0, changes ), + VFUNCTION(total_changes, 0, 0, 0, total_changes ), FUNCTION(replace, 3, 0, 0, replaceFunc ), FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), #ifdef SQLITE_SOUNDEX diff --git a/src/resolve.c b/src/resolve.c index b5ba80ec75..999c628c06 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -725,6 +725,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->op = TK_NULL; return WRC_Prune; } + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); } #endif if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f52c6c1d14..84c69972a1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1143,6 +1143,7 @@ struct FuncDestructor { #define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ +#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1155,6 +1156,9 @@ struct FuncDestructor { ** as the user-data (sqlite3_user_data()) for the function. If ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. ** +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. +** ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) ** Used to create an aggregate function definition implemented by ** the C functions xStep and xFinal. The first four parameters @@ -1170,16 +1174,20 @@ struct FuncDestructor { ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, 0, #zName, 0, 0} #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_UTF8|flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} @@ -1839,6 +1847,7 @@ struct Expr { #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_Constant 0x080000 /* Node is a constant */ /* ** These macros can be used to test, set, or clear bits in the