/ Changes On Branch factor-constant-funcs
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch factor-constant-funcs Excluding Merge-Ins

This is equivalent to a diff from d3ac32a6 to 2ab997e4

2017-01-04
04:18
Factor constant functions out of the inner loop since they are more expensive than the extra OP_Copy needed to move the result into place. (check-in: 80ad317f user: drh tags: trunk)
04:10
Clean up the implementation of constant function factorization. (Closed-Leaf check-in: 2ab997e4 user: drh tags: factor-constant-funcs)
01:07
Attempt to factor out constant functions from the interior of table scans, since functions can often be expensive to compute. (check-in: 62e9270a user: drh tags: factor-constant-funcs)
00:26
Changes to the printf implementation for better performance. (Closed-Leaf check-in: acdb8f6f user: drh tags: printf-optimization)
2017-01-03
21:57
Use compiler intrinsic functions for signed integer math when overflow detection is needed. (check-in: d3ac32a6 user: drh tags: trunk)
21:50
Back out the use of __sync_fetch_and_sub() as it does not appear to work. (Closed-Leaf check-in: 4c2efd42 user: drh tags: gnu-safe-math)
14:45
Add the experimental affinity() SQL function when SQLITE_DEBUG is defined. (check-in: bed0eaa5 user: drh tags: trunk)

Changes to src/expr.c.

  3608   3608         const char *zId;       /* The function name */
  3609   3609         u32 constMask = 0;     /* Mask of function arguments that are constant */
  3610   3610         int i;                 /* Loop counter */
  3611   3611         sqlite3 *db = pParse->db;  /* The database connection */
  3612   3612         u8 enc = ENC(db);      /* The text encoding used by this database */
  3613   3613         CollSeq *pColl = 0;    /* A collating sequence */
  3614   3614   
         3615  +      if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
         3616  +        /* SQL function can be expensive. So try to move constant functions
         3617  +        ** out of the inner loop, even if that means an extra OP_Copy. */
         3618  +        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
         3619  +      }
  3615   3620         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
  3616   3621         if( ExprHasProperty(pExpr, EP_TokenOnly) ){
  3617   3622           pFarg = 0;
  3618   3623         }else{
  3619   3624           pFarg = pExpr->x.pList;
  3620   3625         }
  3621   3626         nFarg = pFarg ? pFarg->nExpr : 0;
................................................................................
  3988   3993     sqlite3ReleaseTempReg(pParse, regFree1);
  3989   3994     sqlite3ReleaseTempReg(pParse, regFree2);
  3990   3995     return inReg;
  3991   3996   }
  3992   3997   
  3993   3998   /*
  3994   3999   ** Factor out the code of the given expression to initialization time.
         4000  +**
         4001  +** If regDest>=0 then the result is always stored in that register and the
         4002  +** result is not reusable.  If regDest<0 then this routine is free to 
         4003  +** store the value whereever it wants.  The register where the expression 
         4004  +** is stored is returned.  When regDest<0, two identical expressions will
         4005  +** code to the same register.
  3995   4006   */
  3996         -void sqlite3ExprCodeAtInit(
         4007  +int sqlite3ExprCodeAtInit(
  3997   4008     Parse *pParse,    /* Parsing context */
  3998   4009     Expr *pExpr,      /* The expression to code when the VDBE initializes */
  3999         -  int regDest,      /* Store the value in this register */
  4000         -  u8 reusable       /* True if this expression is reusable */
         4010  +  int regDest       /* Store the value in this register */
  4001   4011   ){
  4002   4012     ExprList *p;
  4003   4013     assert( ConstFactorOk(pParse) );
  4004   4014     p = pParse->pConstExpr;
         4015  +  if( regDest<0 && p ){
         4016  +    struct ExprList_item *pItem;
         4017  +    int i;
         4018  +    for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
         4019  +      if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
         4020  +        return pItem->u.iConstExprReg;
         4021  +      }
         4022  +    }
         4023  +  }
  4005   4024     pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
  4006   4025     p = sqlite3ExprListAppend(pParse, p, pExpr);
  4007   4026     if( p ){
  4008   4027        struct ExprList_item *pItem = &p->a[p->nExpr-1];
         4028  +     pItem->reusable = regDest<0;
         4029  +     if( regDest<0 ) regDest = ++pParse->nMem;
  4009   4030        pItem->u.iConstExprReg = regDest;
  4010         -     pItem->reusable = reusable;
  4011   4031     }
  4012   4032     pParse->pConstExpr = p;
         4033  +  return regDest;
  4013   4034   }
  4014   4035   
  4015   4036   /*
  4016   4037   ** Generate code to evaluate an expression and store the results
  4017   4038   ** into a register.  Return the register number where the results
  4018   4039   ** are stored.
  4019   4040   **
................................................................................
  4028   4049   int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
  4029   4050     int r2;
  4030   4051     pExpr = sqlite3ExprSkipCollate(pExpr);
  4031   4052     if( ConstFactorOk(pParse)
  4032   4053      && pExpr->op!=TK_REGISTER
  4033   4054      && sqlite3ExprIsConstantNotJoin(pExpr)
  4034   4055     ){
  4035         -    ExprList *p = pParse->pConstExpr;
  4036         -    int i;
  4037   4056       *pReg  = 0;
  4038         -    if( p ){
  4039         -      struct ExprList_item *pItem;
  4040         -      for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
  4041         -        if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
  4042         -          return pItem->u.iConstExprReg;
  4043         -        }
  4044         -      }
  4045         -    }
  4046         -    r2 = ++pParse->nMem;
  4047         -    sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
         4057  +    r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
  4048   4058     }else{
  4049   4059       int r1 = sqlite3GetTempReg(pParse);
  4050   4060       r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
  4051   4061       if( r2==r1 ){
  4052   4062         *pReg = r1;
  4053   4063       }else{
  4054   4064         sqlite3ReleaseTempReg(pParse, r1);
................................................................................
  4094   4104   ** Generate code that will evaluate expression pExpr and store the
  4095   4105   ** results in register target.  The results are guaranteed to appear
  4096   4106   ** in register target.  If the expression is constant, then this routine
  4097   4107   ** might choose to code the expression at initialization time.
  4098   4108   */
  4099   4109   void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
  4100   4110     if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
  4101         -    sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
         4111  +    sqlite3ExprCodeAtInit(pParse, pExpr, target);
  4102   4112     }else{
  4103   4113       sqlite3ExprCode(pParse, pExpr, target);
  4104   4114     }
  4105   4115   }
  4106   4116   
  4107   4117   /*
  4108   4118   ** Generate code that evaluates the given expression and puts the result
................................................................................
  4166   4176         if( flags & SQLITE_ECEL_OMITREF ){
  4167   4177           i--;
  4168   4178           n--;
  4169   4179         }else{
  4170   4180           sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
  4171   4181         }
  4172   4182       }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
  4173         -      sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
         4183  +      sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
  4174   4184       }else{
  4175   4185         int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
  4176   4186         if( inReg!=target+i ){
  4177   4187           VdbeOp *pOp;
  4178   4188           if( copyOp==OP_Copy
  4179   4189            && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
  4180   4190            && pOp->p1+pOp->p3+1==inReg

Changes to src/sqliteInt.h.

  3712   3712   void sqlite3ExprCachePop(Parse*);
  3713   3713   void sqlite3ExprCacheRemove(Parse*, int, int);
  3714   3714   void sqlite3ExprCacheClear(Parse*);
  3715   3715   void sqlite3ExprCacheAffinityChange(Parse*, int, int);
  3716   3716   void sqlite3ExprCode(Parse*, Expr*, int);
  3717   3717   void sqlite3ExprCodeCopy(Parse*, Expr*, int);
  3718   3718   void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
  3719         -void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
         3719  +int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
  3720   3720   int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
  3721   3721   int sqlite3ExprCodeTarget(Parse*, Expr*, int);
  3722   3722   void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
  3723   3723   int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
  3724   3724   #define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
  3725   3725   #define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
  3726   3726   #define SQLITE_ECEL_REF      0x04  /* Use ExprList.u.x.iOrderByCol */