OLD | NEW |
1 #!/usr/bin/tcl | 1 #!/usr/bin/tcl |
2 # | 2 # |
3 # This script makes modifications to the vdbe.c source file which reduce | 3 # This script makes modifications to the vdbe.c source file which reduce |
4 # the amount of stack space required by the sqlite3VdbeExec() routine. | 4 # the amount of stack space required by the sqlite3VdbeExec() routine. |
5 # | 5 # |
6 # The modifications performed by this script are optional. The vdbe.c | 6 # The modifications performed by this script are optional. The vdbe.c |
7 # source file will compile correctly with and without the modifications | 7 # source file will compile correctly with and without the modifications |
8 # performed by this script. And all routines within vdbe.c will compute | 8 # performed by this script. And all routines within vdbe.c will compute |
9 # the same result. The modifications made by this script merely help | 9 # the same result. The modifications made by this script merely help |
10 # the C compiler to generate code for sqlite3VdbeExec() that uses less | 10 # the C compiler to generate code for sqlite3VdbeExec() that uses less |
11 # stack space. | 11 # stack space. |
12 # | 12 # |
13 # Script usage: | 13 # Script usage: |
14 # | 14 # |
15 # mv vdbe.c vdbe.c.template | 15 # mv vdbe.c vdbe.c.template |
16 # tclsh vdbe-compress.tcl <vdbe.c.template >vdbe.c | 16 # tclsh vdbe-compress.tcl $CFLAGS <vdbe.c.template >vdbe.c |
17 # | 17 # |
18 # Modifications made: | 18 # Modifications made: |
19 # | 19 # |
20 # All modifications are within the sqlite3VdbeExec() function. The | 20 # All modifications are within the sqlite3VdbeExec() function. The |
21 # modifications seek to reduce the amount of stack space allocated by | 21 # modifications seek to reduce the amount of stack space allocated by |
22 # this routine by moving local variable declarations out of individual | 22 # this routine by moving local variable declarations out of individual |
23 # opcode implementations and into a single large union. The union contains | 23 # opcode implementations and into a single large union. The union contains |
24 # a separate structure for each opcode and that structure contains the | 24 # a separate structure for each opcode and that structure contains the |
25 # local variables used by that opcode. In this way, the total amount | 25 # local variables used by that opcode. In this way, the total amount |
26 # of stack space required by sqlite3VdbeExec() is reduced from the | 26 # of stack space required by sqlite3VdbeExec() is reduced from the |
27 # sum of all local variables to the maximum of the local variable space | 27 # sum of all local variables to the maximum of the local variable space |
28 # required for any single opcode. | 28 # required for any single opcode. |
29 # | 29 # |
30 # In order to be recognized by this script, local variables must appear | 30 # In order to be recognized by this script, local variables must appear |
31 # on the first line after the open curly-brace that begins a new opcode | 31 # on the first line after the open curly-brace that begins a new opcode |
32 # implementation. Local variables must not have initializers, though they | 32 # implementation. Local variables must not have initializers, though they |
33 # may be commented. | 33 # may be commented. |
34 # | 34 # |
35 # The union definition is inserted in place of a special marker comment | 35 # The union definition is inserted in place of a special marker comment |
36 # in the preamble to the sqlite3VdbeExec() implementation. | 36 # in the preamble to the sqlite3VdbeExec() implementation. |
37 # | 37 # |
38 ############################################################################# | 38 ############################################################################# |
39 # | 39 # |
40 set beforeUnion {} ;# C code before union | 40 set beforeUnion {} ;# C code before union |
41 set unionDef {} ;# C code of the union | 41 set unionDef {} ;# C code of the union |
42 set afterUnion {} ;# C code after the union | 42 set afterUnion {} ;# C code after the union |
43 set sCtr 0 ;# Context counter | 43 set sCtr 0 ;# Context counter |
44 | 44 |
| 45 # If the SQLITE_SMALL_STACK compile-time option is missing, then |
| 46 # this transformation becomes a no-op. |
| 47 # |
| 48 if {![regexp {SQLITE_SMALL_STACK} $argv]} { |
| 49 while {![eof stdin]} { |
| 50 puts [gets stdin] |
| 51 } |
| 52 exit |
| 53 } |
| 54 |
45 # Read program text up to the spot where the union should be | 55 # Read program text up to the spot where the union should be |
46 # inserted. | 56 # inserted. |
47 # | 57 # |
48 while {![eof stdin]} { | 58 while {![eof stdin]} { |
49 set line [gets stdin] | 59 set line [gets stdin] |
50 if {[regexp {INSERT STACK UNION HERE} $line]} break | 60 if {[regexp {INSERT STACK UNION HERE} $line]} break |
51 append beforeUnion $line\n | 61 append beforeUnion $line\n |
52 } | 62 } |
53 | 63 |
54 # Process the remaining text. Build up the union definition as we go. | 64 # Process the remaining text. Build up the union definition as we go. |
(...skipping 17 matching lines...) Expand all Loading... |
72 append sname [string index $namechars [expr {$sCtr%$nnc}]] | 82 append sname [string index $namechars [expr {$sCtr%$nnc}]] |
73 incr sCtr | 83 incr sCtr |
74 append unionDef " struct ${operator}_stack_vars \173\n" | 84 append unionDef " struct ${operator}_stack_vars \173\n" |
75 append afterUnion \ | 85 append afterUnion \ |
76 "#if 0 /* local variables moved into u.$sname */\n" | 86 "#if 0 /* local variables moved into u.$sname */\n" |
77 set seenDecl 1 | 87 set seenDecl 1 |
78 } | 88 } |
79 append unionDef " $line\n" | 89 append unionDef " $line\n" |
80 append afterUnion $line\n | 90 append afterUnion $line\n |
81 lappend vlist $vname | 91 lappend vlist $vname |
| 92 } elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} { |
| 93 append unionDef "$line\n" |
| 94 append afterUnion $line\n |
82 } else { | 95 } else { |
83 break | 96 break |
84 } | 97 } |
85 } | 98 } |
86 if {$seenDecl} { | 99 if {$seenDecl} { |
87 append unionDef " \175 $sname;\n" | 100 append unionDef " \175 $sname;\n" |
88 append afterUnion "#endif /* local variables moved into u.$sname */\n" | 101 append afterUnion "#endif /* local variables moved into u.$sname */\n" |
89 } | 102 } |
90 set seenDecl 0 | 103 set seenDecl 0 |
91 } | 104 } |
92 if {[regexp "^\175" $line]} { | 105 if {[regexp "^\175" $line]} { |
93 append afterUnion $line\n | 106 append afterUnion $line\n |
94 set vlist {} | 107 set vlist {} |
95 } elseif {[llength $vlist]>0} { | 108 } elseif {[llength $vlist]>0} { |
96 append line " " | 109 append line " " |
97 foreach v $vlist { | 110 foreach v $vlist { |
98 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line | 111 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line |
99 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line | 112 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line |
| 113 |
| 114 # The expressions above fail to catch instance of variable "abc" in |
| 115 # expressions like (32>abc). The following expression makes those |
| 116 # substitutions. |
| 117 regsub -all "(\[^-\])>${v}(\\W)" $line "\\1>u.$sname.$v\\2" line |
100 } | 118 } |
101 append afterUnion [string trimright $line]\n | 119 append afterUnion [string trimright $line]\n |
102 } elseif {$line=="" && [eof stdin]} { | 120 } elseif {$line=="" && [eof stdin]} { |
103 # no-op | 121 # no-op |
104 } else { | 122 } else { |
105 append afterUnion $line\n | 123 append afterUnion $line\n |
106 } | 124 } |
107 } | 125 } |
108 | 126 |
109 # Output the resulting text. | 127 # Output the resulting text. |
110 # | 128 # |
111 puts -nonewline $beforeUnion | 129 puts -nonewline $beforeUnion |
112 puts " /********************************************************************" | 130 puts " /********************************************************************" |
113 puts " ** Automatically generated code" | 131 puts " ** Automatically generated code" |
114 puts " **" | 132 puts " **" |
115 puts " ** The following union is automatically generated by the" | 133 puts " ** The following union is automatically generated by the" |
116 puts " ** vdbe-compress.tcl script. The purpose of this union is to" | 134 puts " ** vdbe-compress.tcl script. The purpose of this union is to" |
117 puts " ** reduce the amount of stack space required by this function." | 135 puts " ** reduce the amount of stack space required by this function." |
118 puts " ** See comments in the vdbe-compress.tcl script for details." | 136 puts " ** See comments in the vdbe-compress.tcl script for details." |
119 puts " */" | 137 puts " */" |
120 puts " union vdbeExecUnion \173" | 138 puts " union vdbeExecUnion \173" |
121 puts -nonewline $unionDef | 139 puts -nonewline $unionDef |
122 puts " \175 u;" | 140 puts " \175 u;" |
123 puts " /* End automatically generated code" | 141 puts " /* End automatically generated code" |
124 puts " ********************************************************************/" | 142 puts " ********************************************************************/" |
125 puts -nonewline $afterUnion | 143 puts -nonewline $afterUnion |
OLD | NEW |