Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Simplify the OPFLG processing logic in the VDBE for a speed boost in the

VDBE processing loop and a reduction in code size.
  • Loading branch information...
commit cb5eca324eef6ea3c31753916abac0fd42907530 1 parent 62510e8
Unknown authored November 13, 2009

Showing 2 changed files with 57 additions and 94 deletions. Show diff stats Hide diff stats

  1. 11  mkopcodeh.awk
  2. 140  src/vdbe.c
11  mkopcodeh.awk
@@ -49,6 +49,7 @@
49 49
   in1[name] = 0
50 50
   in2[name] = 0
51 51
   in3[name] = 0
  52
+  out2[name] = 0
52 53
   out3[name] = 0
53 54
   for(i=3; i<NF; i++){
54 55
     if($i=="same" && $(i+1)=="as"){
@@ -70,6 +71,8 @@
70 71
       in2[name] = 1
71 72
     }else if(x=="in3"){
72 73
       in3[name] = 1
  74
+    }else if(x=="out2"){
  75
+      out2[name] = 1
73 76
     }else if(x=="out3"){
74 77
       out3[name] = 1
75 78
     }
@@ -125,13 +128,14 @@ END {
125 128
     name = order[i];
126 129
     x = op[name]
127 130
     a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
128  
-    # a8 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
  131
+    # a7 = a9 = a10 = a11 = a12 = a13 = a14 = a15 = 0
129 132
     if( jump[name] ) a0 = 1;
130 133
     if( out2_prerelease[name] ) a1 = 2;
131 134
     if( in1[name] ) a2 = 4;
132 135
     if( in2[name] ) a3 = 8;
133 136
     if( in3[name] ) a4 = 16;
134  
-    if( out3[name] ) a5 = 32;
  137
+    if( out2[name] ) a5 = 32;
  138
+    if( out3[name] ) a6 = 64;
135 139
     # bv[x] = a0+a1+a2+a3+a4+a5+a6+a7+a8+a9+a10+a11+a12+a13+a14+a15;
136 140
     bv[x] = a0+a1+a2+a3+a4+a5+a6+a7;
137 141
   }
@@ -145,7 +149,8 @@ END {
145 149
   print "#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */"
146 150
   print "#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */"
147 151
   print "#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */"
148  
-  print "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
  152
+  print "#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */"
  153
+  print "#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */"
149 154
   print "#define OPFLG_INITIALIZER {\\"
150 155
   for(i=0; i<=max; i++){
151 156
     if( i%8==0 ) printf("/* %3d */",i)
140  src/vdbe.c
@@ -677,60 +677,41 @@ int sqlite3VdbeExec(
677 677
     ** is initialized to a NULL.
678 678
     */
679 679
     opProperty = opcodeProperty[pOp->opcode];
680  
-    if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
681  
-      assert( pOp->p2>0 );
682  
-      assert( pOp->p2<=p->nMem );
683  
-      pOut = &p->aMem[pOp->p2];
684  
-      sqlite3VdbeMemReleaseExternal(pOut);
685  
-      pOut->flags = MEM_Null;
686  
-      pOut->n = 0;
687  
-    }else
688  
- 
689  
-    /* Do common setup for opcodes marked with one of the following
690  
-    ** combinations of properties.
691  
-    **
692  
-    **           in1
693  
-    **           in1 in2
694  
-    **           in1 in2 out3
695  
-    **           in1 in3
696  
-    **
697  
-    ** Variables pIn1, pIn2, and pIn3 are made to point to appropriate
698  
-    ** registers for inputs.  Variable pOut points to the output register.
699  
-    */
700  
-    if( (opProperty & OPFLG_IN1)!=0 ){
701  
-      assert( pOp->p1>0 );
702  
-      assert( pOp->p1<=p->nMem );
703  
-      pIn1 = &p->aMem[pOp->p1];
704  
-      REGISTER_TRACE(pOp->p1, pIn1);
705  
-      if( (opProperty & OPFLG_IN2)!=0 ){
  680
+    if( opProperty & (OPFLG_OUT2_PRERELEASE | OPFLG_IN1 | OPFLG_IN2
  681
+                      | OPFLG_IN3 | OPFLG_OUT2 | OPFLG_OUT3)
  682
+    ){
  683
+      if( (opProperty & OPFLG_OUT2_PRERELEASE)!=0 ){
706 684
         assert( pOp->p2>0 );
707 685
         assert( pOp->p2<=p->nMem );
708  
-        pIn2 = &p->aMem[pOp->p2];
709  
-        REGISTER_TRACE(pOp->p2, pIn2);
710  
-        /* As currently implemented, in2 implies out3.  There is no reason
711  
-        ** why this has to be, it just worked out that way. */
712  
-        assert( (opProperty & OPFLG_OUT3)!=0 );
713  
-        assert( pOp->p3>0 );
714  
-        assert( pOp->p3<=p->nMem );
715  
-        pOut = &p->aMem[pOp->p3];
716  
-      }else if( (opProperty & OPFLG_IN3)!=0 ){
717  
-        assert( pOp->p3>0 );
718  
-        assert( pOp->p3<=p->nMem );
719  
-        pIn3 = &p->aMem[pOp->p3];
720  
-        REGISTER_TRACE(pOp->p3, pIn3);
  686
+        pOut = &p->aMem[pOp->p2];
  687
+        sqlite3VdbeMemReleaseExternal(pOut);
  688
+        pOut->flags = MEM_Null;
  689
+        pOut->n = 0;
  690
+      }else{
  691
+        if( (opProperty & OPFLG_IN1)!=0 ){
  692
+          assert( pOp->p1>0 );
  693
+          assert( pOp->p1<=p->nMem );
  694
+          pIn1 = &p->aMem[pOp->p1];
  695
+          REGISTER_TRACE(pOp->p1, pIn1);
  696
+        }
  697
+        if( (opProperty & (OPFLG_IN2|OPFLG_OUT2))!=0 ){
  698
+          assert( pOp->p2>0 );
  699
+          assert( pOp->p2<=p->nMem );
  700
+          assert( (opProperty & OPFLG_OUT2)==0 || (opProperty & OPFLG_IN3)==0 );
  701
+          pIn2 = pOut = &p->aMem[pOp->p2];
  702
+        }
  703
+        if( (opProperty & (OPFLG_IN3|OPFLG_OUT3))!=0 ){
  704
+          assert( pOp->p3>0 );
  705
+          assert( pOp->p3<=p->nMem );
  706
+          pIn3 = pOut = &p->aMem[pOp->p3];
  707
+        }
  708
+#ifdef SQLITE_DEBUG
  709
+        if( opProperty & OPFLG_IN2 ){ REGISTER_TRACE(pOp->p2, pIn2); }
  710
+        if( opProperty & OPFLG_IN3 ){ REGISTER_TRACE(pOp->p3, pIn3); }
  711
+#endif
721 712
       }
722  
-    }else if( (opProperty & OPFLG_IN2)!=0 ){
723  
-      assert( pOp->p2>0 );
724  
-      assert( pOp->p2<=p->nMem );
725  
-      pIn2 = &p->aMem[pOp->p2];
726  
-      REGISTER_TRACE(pOp->p2, pIn2);
727  
-    }else if( (opProperty & OPFLG_IN3)!=0 ){
728  
-      assert( pOp->p3>0 );
729  
-      assert( pOp->p3<=p->nMem );
730  
-      pIn3 = &p->aMem[pOp->p3];
731  
-      REGISTER_TRACE(pOp->p3, pIn3);
732 713
     }
733  
-
  714
+  
734 715
     switch( pOp->opcode ){
735 716
 
736 717
 /*****************************************************************************
@@ -786,10 +767,7 @@ case OP_Goto: {             /* jump */
786 767
 ** Write the current address onto register P1
787 768
 ** and then jump to address P2.
788 769
 */
789  
-case OP_Gosub: {            /* jump */
790  
-  assert( pOp->p1>0 );
791  
-  assert( pOp->p1<=p->nMem );
792  
-  pIn1 = &p->aMem[pOp->p1];
  770
+case OP_Gosub: {            /* jump, in1 */
793 771
   assert( (pIn1->flags & MEM_Dyn)==0 );
794 772
   pIn1->flags = MEM_Int;
795 773
   pIn1->u.i = pc;
@@ -1075,10 +1053,7 @@ case OP_Move: {
1075 1053
 ** This instruction makes a deep copy of the value.  A duplicate
1076 1054
 ** is made of any string or blob constant.  See also OP_SCopy.
1077 1055
 */
1078  
-case OP_Copy: {             /* in1 */
1079  
-  assert( pOp->p2>0 );
1080  
-  assert( pOp->p2<=p->nMem );
1081  
-  pOut = &p->aMem[pOp->p2];
  1056
+case OP_Copy: {             /* in1, out2 */
1082 1057
   assert( pOut!=pIn1 );
1083 1058
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
1084 1059
   Deephemeralize(pOut);
@@ -1098,11 +1073,7 @@ case OP_Copy: {             /* in1 */
1098 1073
 ** during the lifetime of the copy.  Use OP_Copy to make a complete
1099 1074
 ** copy.
1100 1075
 */
1101  
-case OP_SCopy: {            /* in1 */
1102  
-  REGISTER_TRACE(pOp->p1, pIn1);
1103  
-  assert( pOp->p2>0 );
1104  
-  assert( pOp->p2<=p->nMem );
1105  
-  pOut = &p->aMem[pOp->p2];
  1076
+case OP_SCopy: {            /* in1, out2 */
1106 1077
   assert( pOut!=pIn1 );
1107 1078
   sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
1108 1079
   REGISTER_TRACE(pOp->p2, pOut);
@@ -1945,8 +1916,7 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
1945 1916
 ** boolean complement in register P2.  If the value in register P1 is 
1946 1917
 ** NULL, then a NULL is stored in P2.
1947 1918
 */
1948  
-case OP_Not: {                /* same as TK_NOT, in1 */
1949  
-  pOut = &p->aMem[pOp->p2];
  1919
+case OP_Not: {                /* same as TK_NOT, in1, out2 */
1950 1920
   if( pIn1->flags & MEM_Null ){
1951 1921
     sqlite3VdbeMemSetNull(pOut);
1952 1922
   }else{
@@ -1961,8 +1931,7 @@ case OP_Not: {                /* same as TK_NOT, in1 */
1961 1931
 ** ones-complement of the P1 value into register P2.  If P1 holds
1962 1932
 ** a NULL then store a NULL in P2.
1963 1933
 */
1964  
-case OP_BitNot: {             /* same as TK_BITNOT, in1 */
1965  
-  pOut = &p->aMem[pOp->p2];
  1934
+case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
1966 1935
   if( pIn1->flags & MEM_Null ){
1967 1936
     sqlite3VdbeMemSetNull(pOut);
1968 1937
   }else{
@@ -4333,8 +4302,8 @@ case OP_IdxRowid: {              /* out2-prerelease */
4333 4302
 ** If P5 is non-zero then the key value is increased by an epsilon prior 
4334 4303
 ** to the comparison.  This makes the opcode work like IdxLE.
4335 4304
 */
4336  
-case OP_IdxLT:          /* jump, in3 */
4337  
-case OP_IdxGE: {        /* jump, in3 */
  4305
+case OP_IdxLT:          /* jump */
  4306
+case OP_IdxGE: {        /* jump */
4338 4307
   VdbeCursor *pC;
4339 4308
   int res;
4340 4309
   UnpackedRecord r;
@@ -4696,19 +4665,13 @@ case OP_IntegrityCk: {
4696 4665
 **
4697 4666
 ** An assertion fails if P2 is not an integer.
4698 4667
 */
4699  
-case OP_RowSetAdd: {       /* in2 */
4700  
-  Mem *pIdx;
4701  
-  Mem *pVal;
4702  
-  assert( pOp->p1>0 && pOp->p1<=p->nMem );
4703  
-  pIdx = &p->aMem[pOp->p1];
4704  
-  assert( pOp->p2>0 && pOp->p2<=p->nMem );
4705  
-  pVal = &p->aMem[pOp->p2];
4706  
-  assert( (pVal->flags & MEM_Int)!=0 );
4707  
-  if( (pIdx->flags & MEM_RowSet)==0 ){
4708  
-    sqlite3VdbeMemSetRowSet(pIdx);
4709  
-    if( (pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
4710  
-  }
4711  
-  sqlite3RowSetInsert(pIdx->u.pRowSet, pVal->u.i);
  4668
+case OP_RowSetAdd: {       /* in1, in2 */
  4669
+  assert( (pIn2->flags & MEM_Int)!=0 );
  4670
+  if( (pIn1->flags & MEM_RowSet)==0 ){
  4671
+    sqlite3VdbeMemSetRowSet(pIn1);
  4672
+    if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem;
  4673
+  }
  4674
+  sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i);
4712 4675
   break;
4713 4676
 }
4714 4677
 
@@ -4718,22 +4681,17 @@ case OP_RowSetAdd: {       /* in2 */
4718 4681
 ** register P3.  Or, if boolean index P1 is initially empty, leave P3
4719 4682
 ** unchanged and jump to instruction P2.
4720 4683
 */
4721  
-case OP_RowSetRead: {       /* jump, out3 */
4722  
-  Mem *pIdx;
  4684
+case OP_RowSetRead: {       /* jump, in1, out3 */
4723 4685
   i64 val;
4724  
-  assert( pOp->p1>0 && pOp->p1<=p->nMem );
4725 4686
   CHECK_FOR_INTERRUPT;
4726  
-  pIdx = &p->aMem[pOp->p1];
4727  
-  pOut = &p->aMem[pOp->p3];
4728  
-  if( (pIdx->flags & MEM_RowSet)==0 
4729  
-   || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0
  4687
+  if( (pIn1->flags & MEM_RowSet)==0 
  4688
+   || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
4730 4689
   ){
4731 4690
     /* The boolean index is empty */
4732  
-    sqlite3VdbeMemSetNull(pIdx);
  4691
+    sqlite3VdbeMemSetNull(pIn1);
4733 4692
     pc = pOp->p2 - 1;
4734 4693
   }else{
4735 4694
     /* A value was pulled from the index */
4736  
-    assert( pOp->p3>0 && pOp->p3<=p->nMem );
4737 4695
     sqlite3VdbeMemSetInt64(pOut, val);
4738 4696
   }
4739 4697
   break;

0 notes on commit cb5eca3

Please sign in to comment.
Something went wrong with that request. Please try again.