vdbe-compress.tcl 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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 <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. # Read program text up to the spot where the union should be
  45. # inserted.
  46. #
  47. while {![eof stdin]} {
  48. set line [gets stdin]
  49. if {[regexp {INSERT STACK UNION HERE} $line]} break
  50. append beforeUnion $line\n
  51. }
  52. # Process the remaining text. Build up the union definition as we go.
  53. #
  54. set vlist {}
  55. set seenDecl 0
  56. set namechars {abcdefghijklmnopqrstuvwxyz}
  57. set nnc [string length $namechars]
  58. while {![eof stdin]} {
  59. set line [gets stdin]
  60. if {[regexp "^case (OP_\\w+): \173" $line all operator]} {
  61. append afterUnion $line\n
  62. set vlist {}
  63. while {![eof stdin]} {
  64. set line [gets stdin]
  65. if {[regexp {^ +(const )?\w+ \**(\w+)(\[.*\])?;} $line \
  66. all constKeyword vname notused1]} {
  67. if {!$seenDecl} {
  68. set sname {}
  69. append sname [string index $namechars [expr {$sCtr/$nnc}]]
  70. append sname [string index $namechars [expr {$sCtr%$nnc}]]
  71. incr sCtr
  72. append unionDef " struct ${operator}_stack_vars \173\n"
  73. append afterUnion \
  74. "#if 0 /* local variables moved into u.$sname */\n"
  75. set seenDecl 1
  76. }
  77. append unionDef " $line\n"
  78. append afterUnion $line\n
  79. lappend vlist $vname
  80. } elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} {
  81. append unionDef "$line\n"
  82. append afterUnion $line\n
  83. } else {
  84. break
  85. }
  86. }
  87. if {$seenDecl} {
  88. append unionDef " \175 $sname;\n"
  89. append afterUnion "#endif /* local variables moved into u.$sname */\n"
  90. }
  91. set seenDecl 0
  92. }
  93. if {[regexp "^\175" $line]} {
  94. append afterUnion $line\n
  95. set vlist {}
  96. } elseif {[llength $vlist]>0} {
  97. append line " "
  98. foreach v $vlist {
  99. regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
  100. regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
  101. }
  102. append afterUnion [string trimright $line]\n
  103. } elseif {$line=="" && [eof stdin]} {
  104. # no-op
  105. } else {
  106. append afterUnion $line\n
  107. }
  108. }
  109. # Output the resulting text.
  110. #
  111. puts -nonewline $beforeUnion
  112. puts " /********************************************************************"
  113. puts " ** Automatically generated code"
  114. puts " **"
  115. puts " ** The following union is automatically generated by the"
  116. puts " ** vdbe-compress.tcl script. The purpose of this union is to"
  117. puts " ** reduce the amount of stack space required by this function."
  118. puts " ** See comments in the vdbe-compress.tcl script for details."
  119. puts " */"
  120. puts " union vdbeExecUnion \173"
  121. puts -nonewline $unionDef
  122. puts " \175 u;"
  123. puts " /* End automatically generated code"
  124. puts " ********************************************************************/"
  125. puts -nonewline $afterUnion