home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 7 / FreshFishVol7.bin / bbs / gnu / gcc-2.3.3-src.lha / GNU / src / amiga / gcc-2.3.3 / PROJECTS < prev    next >
Text File  |  1994-02-06  |  18KB  |  449 lines

  1. 0. Improved efficiency.
  2.  
  3. * Parse and output array initializers an element at a time, freeing
  4. storage after each, instead of parsing the whole initializer first and
  5. then outputting.  This would reduce memory usage for large
  6. initializers.
  7.  
  8. * See if the techniques describe in Oct 1991 SIGPLAN Notices
  9. (Frazer and Hanson) are applicable to GCC.
  10.  
  11. 1. Better optimization.
  12.  
  13. * Constants in unused inline functions
  14.  
  15. It would be nice to delay output of string constants so that string
  16. constants mentioned in unused inline functions are never generated.
  17. Perhaps this would also take care of string constants in dead code.
  18.  
  19. The difficulty is in finding a clean way for the RTL which refers
  20. to the constant (currently, only by an assembler symbol name)
  21. to point to the constant and cause it to be output.
  22.  
  23. * More cse
  24.  
  25. The techniques for doing full global cse are described in the red
  26. dragon book, or (a different version) in Frederick Chow's thesis from
  27. Stanford.  It is likely to be slow and use a lot of memory, but it
  28. might be worth offering as an additional option.
  29.  
  30. It is probably possible to extend cse to a few very frequent cases
  31. without so much expense.
  32.  
  33. For example, it is not very hard to handle cse through if-then
  34. statements with no else clauses.  Here's how to do it.  On reaching a
  35. label, notice that the label's use-count is 1 and that the last
  36. preceding jump jumps conditionally to this label.  Now you know it
  37. is a simple if-then statement.  Remove from the hash table
  38. all the expressions that were entered since that jump insn
  39. and you can continue with cse.
  40.  
  41. It is probably not hard to handle cse from the end of a loop
  42. around to the beginning, and a few loops would be greatly sped
  43. up by this.
  44.  
  45. * Optimize a sequence of if statements whose conditions are exclusive.
  46.  
  47. It is possible to optimize 
  48.  
  49.     if (x == 1) ...;
  50.     if (x == 2) ...;
  51.     if (x == 3) ...;
  52.  
  53. into
  54.  
  55.     if (x == 1) ...;
  56.     else if (x == 2) ...;
  57.     else if (x == 3) ...;
  58.  
  59. provided that x is not altered by the contents of the if statements.
  60.  
  61. It's not certain whether this is worth doing.  Perhaps programmers
  62. nearly always write the else's themselves, leaving few opportunities
  63. to improve anything.
  64.  
  65. * Un-cse.
  66.  
  67. Perhaps we should have an un-cse step right after cse, which tries to
  68. replace a reg with its value if the value can be substituted for the
  69. reg everywhere, if that looks like an improvement.  Which is if the
  70. reg is used only a few times.  Use rtx_cost to determine if the
  71. change is really an improvement.
  72.  
  73. * Clean up how cse works.
  74.  
  75. The scheme is that each value has just one hash entry.  The
  76. first_same_value and next_same_value chains are no longer needed.
  77.  
  78. For arithmetic, each hash table elt has the following slots:
  79.  
  80. * Operation.  This is an rtx code.
  81. * Mode.
  82. * Operands 0, 1 and 2.  These point to other hash table elements.
  83.  
  84. So, if we want to enter (PLUS:SI (REG:SI 30) (CONST_INT 104)), we
  85. first enter (CONST_INT 104) and find the entry that (REG:SI 30) now
  86. points to.  Then we put these elts into operands 0 and 1 of a new elt.
  87. We put PLUS and SI into the new elt.
  88.  
  89. Registers and mem refs would never be entered into the table as such.
  90. However, the values they contain would be entered.  There would be a
  91. table indexed by regno which points at the hash entry for the value in
  92. that reg.
  93.  
  94. The hash entry index now plays the role of a qty number.
  95. We still need qty_first_reg, reg_next_eqv, etc. to record which regs
  96. share a particular qty.
  97.  
  98. When a reg is used whose contents are unknown, we need to create a
  99. hash table entry whose contents say "unknown", as a place holder for
  100. whatever the reg contains.  If that reg is added to something, then
  101. the hash entry for the sum will refer to the "unknown" entry.  Use
  102. UNKNOWN for the rtx code in this entry.  This replaces make_new_qty.
  103.  
  104. For a constant, a unique hash entry would be made based on the
  105. value of the constant.
  106.  
  107. What about MEM?  Each time a memory address is referenced, we need a
  108. qty (a hash table elt) to represent what is in it.  (Just as for a
  109. register.)  If this isn't known, create one, just as for a reg whose
  110. contents are unknown.
  111.  
  112. We need a way to find all mem refs that still contain a certain value.
  113. Do this with a chain of hash elts (for memory addresses) that point to
  114. locations that hold the value.  The hash elt for the value itself should
  115. point to the start of the chain.  It would be good for the hash elt
  116. for an address to point to the hash elt for the contents of that address
  117. (but this ptr can be null if the contents have never been entered).
  118.  
  119. With this data structure, nothing need ever be invalidated except
  120. the lists of which regs or mems hold a particular value.  It is easy
  121. to see if there is a reg or mem that is equiv to a particular value.
  122. If the value is constant, it is always explicitly constant.
  123.  
  124. * Support more general tail-recursion among different functions.
  125.  
  126. This might be possible under certain circumstances, such as when
  127. the argument lists of the functions have the same lengths.
  128. Perhaps it could be done with a special declaration.
  129.  
  130. You would need to verify in the calling function that it does not
  131. use the addresses of any local variables and does not use setjmp.
  132.  
  133. * Put short statics vars at low addresses and use short addressing mode?
  134.  
  135. Useful on the 68000/68020 and perhaps on the 32000 series,
  136. provided one has a linker that works with the feature.
  137. This is said to make a 15% speedup on the 68000.
  138.  
  139. * Keep global variables in registers.
  140.  
  141. Here is a scheme for doing this.  A global variable, or a local variable
  142. whose address is taken, can be kept in a register for an entire function
  143. if it does not use non-constant memory addresses and (for globals only)
  144. does not call other functions.  If the entire function does not meet
  145. this criterion, a loop may.
  146.  
  147. The VAR_DECL for such a variable would have to have two RTL expressions:
  148. the true home in memory, and the pseudo-register used temporarily. 
  149. It is necessary to emit insns to copy the memory location into the
  150. pseudo-register at the beginning of the function or loop, and perhaps
  151. back out at the end.  These insns should have REG_EQUIV notes so that,
  152. if the pseudo-register does not get a hard register, it is spilled into
  153. the memory location which exists in any case.
  154.  
  155. The easiest way to set up these insns is to modify the routine
  156. put_var_into_stack so that it does not apply to the entire function
  157. (sparing any loops which contain nothing dangerous) and to call it at
  158. the end of the function regardless of where in the function the
  159. address of a local variable is taken.  It would be called
  160. unconditionally at the end of the function for all relevant global
  161. variables.
  162.  
  163. For debugger output, the thing to do is to invent a new binding level
  164. around the appropriate loop and define the variable name as a register
  165. variable with that scope.
  166.  
  167. * Live-range splitting.
  168.  
  169. Currently a variable is allocated a hard register either for the full
  170. extent of its use or not at all.  Sometimes it would be good to
  171. allocate a variable a hard register for just part of a function; for
  172. example, through a particular loop where the variable is mostly used,
  173. or outside of a particular loop where the variable is not used.  (The
  174. latter is nice because it might let the variable be in a register most
  175. of the time even though the loop needs all the registers.)
  176.  
  177. It might not be very hard to do this in global.c when a variable
  178. fails to get a hard register for its entire life span.
  179.  
  180. The first step is to find a loop in which the variable is live, but
  181. which is not the whole life span or nearly so.  It's probably best to
  182. use a loop in which the variable is heavily used.
  183.  
  184. Then create a new pseudo-register to represent the variable in that loop.
  185. Substitute this for the old pseudo-register there, and insert move insns
  186. to copy between the two at the loop entry and all exits.  (When several
  187. such moves are inserted at the same place, some new feature should be
  188. added to say that none of those registers conflict merely because of
  189. overlap between the new moves.  And the reload pass should reorder them
  190. so that a store precedes a load, for any given hard register.)
  191.  
  192. After doing this for all the reasonable candidates, run global-alloc
  193. over again.  With luck, one of th