OLD | NEW |
| (Empty) |
1 #!/usr/bin/tcl | |
2 # | |
3 # This script makes modifications to the vdbe.c source file which reduce | |
4 # the amount of stack space required by the sqlite3VdbeExec() routine. | |
5 # | |
6 # The modifications performed by this script are optional. The vdbe.c | |
7 # source file will compile correctly with and without the modifications | |
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 | |
10 # the C compiler to generate code for sqlite3VdbeExec() that uses less | |
11 # stack space. | |
12 # | |
13 # Script usage: | |
14 # | |
15 # mv vdbe.c vdbe.c.template | |
16 # tclsh vdbe-compress.tcl $CFLAGS <vdbe.c.template >vdbe.c | |
17 # | |
18 # Modifications made: | |
19 # | |
20 # All modifications are within the sqlite3VdbeExec() function. The | |
21 # modifications seek to reduce the amount of stack space allocated by | |
22 # this routine by moving local variable declarations out of individual | |
23 # opcode implementations and into a single large union. The union contains | |
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 | |
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 | |
28 # required for any single opcode. | |
29 # | |
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 | |
32 # implementation. Local variables must not have initializers, though they | |
33 # may be commented. | |
34 # | |
35 # The union definition is inserted in place of a special marker comment | |
36 # in the preamble to the sqlite3VdbeExec() implementation. | |
37 # | |
38 ############################################################################# | |
39 # | |
40 set beforeUnion {} ;# C code before union | |
41 set unionDef {} ;# C code of the union | |
42 set afterUnion {} ;# C code after the union | |
43 set sCtr 0 ;# Context counter | |
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 | |
55 # Read program text up to the spot where the union should be | |
56 # inserted. | |
57 # | |
58 while {![eof stdin]} { | |
59 set line [gets stdin] | |
60 if {[regexp {INSERT STACK UNION HERE} $line]} break | |
61 append beforeUnion $line\n | |
62 } | |
63 | |
64 # Process the remaining text. Build up the union definition as we go. | |
65 # | |
66 set vlist {} | |
67 set seenDecl 0 | |
68 set namechars {abcdefghijklmnopqrstuvwxyz} | |
69 set nnc [string length $namechars] | |
70 while {![eof stdin]} { | |
71 set line [gets stdin] | |
72 if {[regexp "^case (OP_\\w+): \173" $line all operator]} { | |
73 append afterUnion $line\n | |
74 set vlist {} | |
75 while {![eof stdin]} { | |
76 set line [gets stdin] | |
77 if {[regexp {^ +(const )?\w+ \**(\w+)(\[.*\])?;} $line \ | |
78 all constKeyword vname notused1]} { | |
79 if {!$seenDecl} { | |
80 set sname {} | |
81 append sname [string index $namechars [expr {$sCtr/$nnc}]] | |
82 append sname [string index $namechars [expr {$sCtr%$nnc}]] | |
83 incr sCtr | |
84 append unionDef " struct ${operator}_stack_vars \173\n" | |
85 append afterUnion \ | |
86 "#if 0 /* local variables moved into u.$sname */\n" | |
87 set seenDecl 1 | |
88 } | |
89 append unionDef " $line\n" | |
90 append afterUnion $line\n | |
91 lappend vlist $vname | |
92 } elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} { | |
93 append unionDef "$line\n" | |
94 append afterUnion $line\n | |
95 } else { | |
96 break | |
97 } | |
98 } | |
99 if {$seenDecl} { | |
100 append unionDef " \175 $sname;\n" | |
101 append afterUnion "#endif /* local variables moved into u.$sname */\n" | |
102 } | |
103 set seenDecl 0 | |
104 } | |
105 if {[regexp "^\175" $line]} { | |
106 append afterUnion $line\n | |
107 set vlist {} | |
108 } elseif {[llength $vlist]>0} { | |
109 append line " " | |
110 foreach v $vlist { | |
111 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 | |
118 } | |
119 append afterUnion [string trimright $line]\n | |
120 } elseif {$line=="" && [eof stdin]} { | |
121 # no-op | |
122 } else { | |
123 append afterUnion $line\n | |
124 } | |
125 } | |
126 | |
127 # Output the resulting text. | |
128 # | |
129 puts -nonewline $beforeUnion | |
130 puts " /********************************************************************" | |
131 puts " ** Automatically generated code" | |
132 puts " **" | |
133 puts " ** The following union is automatically generated by the" | |
134 puts " ** vdbe-compress.tcl script. The purpose of this union is to" | |
135 puts " ** reduce the amount of stack space required by this function." | |
136 puts " ** See comments in the vdbe-compress.tcl script for details." | |
137 puts " */" | |
138 puts " union vdbeExecUnion \173" | |
139 puts -nonewline $unionDef | |
140 puts " \175 u;" | |
141 puts " /* End automatically generated code" | |
142 puts " ********************************************************************/" | |
143 puts -nonewline $afterUnion | |
OLD | NEW |