aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2020-02-07 19:44:13 +0000
committerdrh <drh@noemail.net>2020-02-07 19:44:13 +0000
commitdc4f6fc099b3fd2476f95286503985f1a22370bc (patch)
tree4270e12b34467a53fe7bffd2462bd572db57201c /src
parentb48c0d59faf3bfd3e1fc0c3bed5557816c36cb7e (diff)
downloadsqlite-dc4f6fc099b3fd2476f95286503985f1a22370bc.tar.gz
sqlite-dc4f6fc099b3fd2476f95286503985f1a22370bc.zip
During byte-code generation, strive to avoid jumps that merely jump to the
following instruction. FossilOrigin-Name: bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31
Diffstat (limited to 'src')
-rw-r--r--src/delete.c4
-rw-r--r--src/fkey.c2
-rw-r--r--src/select.c2
-rw-r--r--src/update.c4
-rw-r--r--src/vdbe.h1
-rw-r--r--src/vdbeaux.c28
6 files changed, 37 insertions, 4 deletions
diff --git a/src/delete.c b/src/delete.c
index 0a83f1b64..60efc9d56 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -533,7 +533,9 @@ void sqlite3DeleteFrom(
iTabCur, aToOpen, &iDataCur, &iIdxCur);
assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
- if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
+ if( eOnePass==ONEPASS_MULTI ){
+ sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce);
+ }
}
/* Set up a loop over the rowids/primary-keys that were found in the
diff --git a/src/fkey.c b/src/fkey.c
index 9698d343c..7bc20fed0 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -658,7 +658,7 @@ static void fkScanChildren(
/* Clean up the WHERE clause constructed above. */
sqlite3ExprDelete(db, pWhere);
if( iFkIfZero ){
- sqlite3VdbeJumpHere(v, iFkIfZero);
+ sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero);
}
}
diff --git a/src/select.c b/src/select.c
index 595b6eb6b..6f8d45c4e 100644
--- a/src/select.c
+++ b/src/select.c
@@ -5493,7 +5493,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){
pAggInfo->directMode = 0;
if( addrHitTest ){
- sqlite3VdbeJumpHere(v, addrHitTest);
+ sqlite3VdbeJumpHereOrPopInst(v, addrHitTest);
}
}
diff --git a/src/update.c b/src/update.c
index 61b1740b4..d54a6cb9f 100644
--- a/src/update.c
+++ b/src/update.c
@@ -616,7 +616,9 @@ void sqlite3Update(
}
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur,
aToOpen, 0, 0);
- if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
+ if( addrOnce ){
+ sqlite3VdbeJumpHereOrPopInst(v, addrOnce);
+ }
}
/* Top of the update loop */
diff --git a/src/vdbe.h b/src/vdbe.h
index bfde25873..482331eff 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -230,6 +230,7 @@ void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
+void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
#ifdef SQLITE_DEBUG
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 52959a43e..2a4741573 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -1065,6 +1065,34 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){
sqlite3VdbeChangeP2(p, addr, p->nOp);
}
+/*
+** Change the P2 operand of the jump instruction at addr so that
+** the jump lands on the next opcode. Or if the jump instruction was
+** the previous opcode (and is thus a no-op) then simply back up
+** the next instruction counter by one slot so that the jump is
+** overwritten by the next inserted opcode.
+**
+** This routine is an optimization of sqlite3VdbeJumpHere() that
+** strives to omit useless byte-code like this:
+**
+** 7 Once 0 8 0
+** 8 ...
+*/
+void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
+ if( addr==p->nOp-1 ){
+ assert( p->aOp[addr].opcode==OP_Once
+ || p->aOp[addr].opcode==OP_If
+ || p->aOp[addr].opcode==OP_FkIfZero );
+ assert( p->aOp[addr].p4type==0 );
+#ifdef SQLITE_VDBE_COVERAGE
+ sqlite3VdbeGetOp(v,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */
+#endif
+ p->nOp--;
+ }else{
+ sqlite3VdbeChangeP2(p, addr, p->nOp);
+ }
+}
+
/*
** If the input FuncDef structure is ephemeral, then free it. If