[wwwdocs patch] adding a table of contents to the projects file

Dan Nicolaescu dann@ics.uci.edu
Wed Mar 28 13:18:00 GMT 2001


Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> writes:

  > On Wed, 21 Mar 2001, Dan Nicolaescu wrote:
  > > I have added a table of contents to the projects/index.html file.
  > > When doing this I changed some <li>s to be <h[23]>, so that they
  > > appear in the TOC.
  > > It makes it much more readable now.
  > 
  > This is fine (as we discussed off-list), but I note a couple of markup
  > problems, see below...

I fixed all of them as far as I can tell. 

  > > I also added a new section for "Work in progress" and added pointers
  > > for some stuff that I saw on the mailing list that is going on.
  > > Please add some more to that list.
  > 
  > This is also a good idea, though I'd prefer to split this into two
  > patches.

The patch is simple enough as it is, but if you still prefer to have
this as a different patch, I could do that too, just say so. 

  > > ! <H1><A NAME="toc">Table of Contents</H1>
  > > ! <UL>
  > > ! <LI><A HREF="#tocref1">Fix bugs in the GNATS database</A>
  > 
  > Please use lower-case letters for markup, that is,

Fixed. 

  >   <h1><a name="...">...</h1>
  >   <ul>
  >   <li><a href="..:">...</a>
  > 
  > > + <h2><A NAME="tocref1">Fix bugs in the GNATS database</h2>
  > >   <p>You can investigate bugs in our <a href="../gnats.html">GNATS
  > >   database</a> and attempt to fix them or see whether they still are
  > >   present in current GCC.
  > 
  > This hasn't been introduced by your patch, but we should have </p> here.

Fixed this and all the similar ones that I could find. 


  > > ! <h3><A NAME="tocref18">Fully document the interface of front ends to GCC</h3>
  > > ! Fully document the interface of front ends to GCC (that is, the
  > >   <code>tree</code> interfaces, and the various functions, hooks, etc.,
  > >   that a front end must or may provide).  <code>gcc/c-tree.texi</code>
  > >   includes some of this information; <code>gcc/LANGUAGES</code> contains
  > >   incomplete information about changes that have been made to this
  > > ! interface.
  > 
  > This has been changed by your patch, and we do need <p>...</p> here; there
  > are a couple of occurrences of this problem.

Fixed. 

  > Would you mind making these change (and the change to use more expressive
  > labels you mentioned) and resubmit these patches?
  > 
  > I'll be offline starting tomorrow, but perhaps someone else (Zack?) can
  > install your changes then?

Here is the patch, I hope somebody can install it... 

Index: index.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/projects/index.html,v
retrieving revision 1.12
diff -c -3 -p -r1.12 index.html
*** index.html	2001/02/10 21:04:44	1.12
--- index.html	2001/03/28 21:15:51
***************
*** 4,33 ****
  <title>GCC Projects</title>
  </head>
  
! <body>
  <h1 align=center>GCC Projects</h1>
  
  <p>You can investigate bugs in our <a href="../gnats.html">GNATS
  database</a> and attempt to fix them or see whether they still are
  present in current GCC.
  
  <p>If you are new to GCC, start with our <a
  href="beginner.html">projects for beginners</a>.
- 
- <p>There is a separate page for <a
- href="bp/main.html">Bounds Checking with Bounded Pointers</a>.
  
  <p>There is a separate project list for the <a
  href="cpplib.html">C preprocessor</a>.
  
  <p>There is a separate projects list for the <a href="web.html">web
  pages</a>.</p>
  
  <p>We also have a page detailing <a href="optimize.html">optimizer
  inadequacies</a>, if you'd prefer to think about it in terms of problems
! instead of features.
  
! <h2>Changes to support C99 standard</h2>
  
  <p>The new version of the C standard (ISO/IEC 9899:1999) requires a
  number of library changes; these have to be provided by the C library,
--- 4,132 ----
  <title>GCC Projects</title>
  </head>
  
! <body><!-- table of contents start -->
! <h1><a name="toc">Table of Contents</h1>
! <ul>
! <li><a href="#fix_bugs_in_the_gnats_database">Fix bugs in the GNATS database</a>
! <li><a href="#projects_for_beginner_gcc_hackers">Projects for beginner GCC hackers</a>
! <li><a href="#projects_for_the_c_preprocessor">Projects for the C preprocessor</a>
! <li><a href="#projects_for_the_gcc_web_pages">Projects for the GCC web pages</a>
! <li><a href="#work_in_progress">Work in progress</a>
! <ul>
! <li><a href="#bounds_checking_with_bounded_pointers">Bounds Checking with Bounded Pointers</a>
! <li><a href="#new_register_allocator">New register allocator</a>
! <li><a href="#ssa_for_trees">SSA for trees</a>
! <li><a href="#value_range_propagation_pass">Value range propagation pass</a>
! </ul>
! <li><a href="#optimizer_inadequacies">Optimizer inadequacies</a>
! <li><a href="#changes_to_support_c99_standard">Changes to support C99 standard</a>
! <li><a href="#improve_the_haifa_scheduler">Improve the Haifa scheduler</a>
! <li><a href="#improvements_to_gcse_and_pre">Improvements to global cse and partial redundancy elimination:</a>
! <li><a href="#miscellaneous_ideas">Miscellaneous ideas:</a>
! <ul>
! <li><a href="#chill_should_use_gc">Chill should use garbage collection</a>
! <li><a href="#improve_wconversion">Improve <code>-Wconversion</code></a>
! <li><a href="#implement_various_builtin_functions_for_isoc99">Implement various builtin functions for ISO C99's 
! <code><tgmath.h></code></a>
! <li><a href="#fully_document_the_interface_of_front_ends_to_gcc">Fully document the interface of front ends to GCC</a>
! </ul>
! <li><a href="#better_builtin_string_functions">Better builtin string functions</a>
! <ul>
! <li><a href="#optimize_memset">Optimize <code>memset</code></a>
! <li><a href="#optimize_strcpy">Optimize <code>strcpy</code></a>
! <li><a href="#optimize_strncpy">Optimize <code>strncpy</code></a>
! <li><a href="#optimize_strncat">Optimize <code>strncat</code></a>
! <li><a href="#optimize_strcmp">Optimize <code>strcmp</code></a>
! <li><a href="#optimize_strncmp">Optimize <code>strncmp</code></a>
! <li><a href="#optimize_strcspn">Optimize <code>strcspn</code></a>
! <li><a href="#optimize_strspn">Optimize <code>strspn</code></a>
! <li><a href="#optimize_strpbrk">Optimize <code>strpbrk</code></a>
! </ul>
! <li><a href="#format_checking">Format (<code>printf</code>, <code>scanf</code> and
! <code>strftime</code>) checking:</a>
! <li><a href="#improve_the_installation_procedure">Improve the installation procedure</a>
! <li><a href="#the_old_projects_file">The old PROJECTS file</a>
! <ul>
! <li><a href="#putting_constants_in_special_sections">Putting constants in special sections.</a>
! <li><a href="#optimize_a_sequence_of_if_statements_whose_conditions_are">Optimize a sequence of if statements whose conditions are
! exclusive.</a>
! <li><a href="#un_cse">Un-cse.</a>
! <li><a href="#clean_up_how_cse_works">Clean up how cse works.</a>
! <li><a href="#support_more_general_tail_recursion_among_different_functions">Support more general tail-recursion among different functions.</a>
! <li><a href="#keep_global_variables_in_registers">Keep global variables in registers.</a>
! <li><a href="#live_range_splitting">Live-range splitting.</a>
! <li><a href="#detect_dead_stores_into_memory">Detect dead stores into memory?</a>
! <li><a href="#loop_optimization">Loop optimization.</a>
! <li><a href="#using_constraints_on_values">Using constraints on values.</a>
! <li><a href="#change_the_type_of_a_variable">Change the type of a variable.</a>
! <li><a href="#better_handling_for_very_sparse_switches">Better handling for very sparse switches.</a>
! <li><a href="#order_of_subexpressions">Order of subexpressions.</a>
! <li><a href="#more_code_motion">More code motion.</a>
! <li><a href="#trace_scheduling">Trace scheduling.</a>
! <li><a href="#distributive_law">Distributive law.</a>
! <li><a href="#restructuring_conditionals">Restructuring conditionals</a>
! <li><a href="#how_to_call_this">??? How to call this???</a>
! </ul>
! <li><a href="#simpler_porting">Simpler porting</a>
! <li><a href="#other_languages">Other languages</a>
! <li><a href="#more_extensions">More extensions</a>
! <li><a href="#generalize_the_machine_model">Generalize the machine model</a>
! <li><a href="#more_warnings">More warnings</a>
! <li><a href="#better_documentation_of_how_gcc_works_and_how_to_port_it">Better documentation of how GCC works and how to port it</a>
! <li><a href="#the_old_problems_file">The old PROBLEMS file</a>
! </ul>
! <!-- table of contents end -->
! 
! 
  <h1 align=center>GCC Projects</h1>
  
+ <h2><a name="fix_bugs_in_the_gnats_database">Fix bugs in the GNATS database</h2>
  <p>You can investigate bugs in our <a href="../gnats.html">GNATS
  database</a> and attempt to fix them or see whether they still are
  present in current GCC.
  
+ <h2><a name="projects_for_beginner_gcc_hackers">Projects for beginner GCC hackers</h2>
  <p>If you are new to GCC, start with our <a
  href="beginner.html">projects for beginners</a>.
  
+ <h2><a name="projects_for_the_c_preprocessor">Projects for the C preprocessor</h2>
  <p>There is a separate project list for the <a
  href="cpplib.html">C preprocessor</a>.
  
+ <h2><a name="projects_for_the_gcc_web_pages">Projects for the GCC web pages</h2>
  <p>There is a separate projects list for the <a href="web.html">web
  pages</a>.</p>
  
+ <h2><a name="work_in_progress">Work in progress</h2>
+ <p>Different projects that are in progress.</p>
+ 
+ <h3><a name="bounds_checking_with_bounded_pointers">Bounds Checking with Bounded Pointers</h3>
+ <p>There is a separate page for <a
+ href="bp/main.html">Bounds Checking with Bounded Pointers</a>.</p>
+ 
+ <h3><a name="new_register_allocator">New register allocator</h3>
+ <p>Daniel Berlin and Michael Matz are working on an implementation of
+ a graph-coloring register allocator. A branch is created in CVS with
+ the tag <code>new-regalloc-branch</code>. It is known to bootstrap
+ under x86-linux and ppc-linux.</p>
+ 
+ <h3><a name="ssa_for_trees">SSA for trees</h3>
+ <p>Diego Novillo is working on implementing SSA analysis for trees. 
+ A patch was posted at <a
+ href=" http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00565.html" ;></a>.</p>
+ 
+ <h3><a name="value_range_propagation_pass">Value range propagation pass</h3>
+ <p>John Wehle (john@feith.com) implemented a <a
+ href=" http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00968.html" ;>value
+ range propagation pass</a> which isn't yet in GCC.</p>
+ 
+ 
+ <h2><a name="optimizer_inadequacies">Optimizer inadequacies</h2>
  <p>We also have a page detailing <a href="optimize.html">optimizer
  inadequacies</a>, if you'd prefer to think about it in terms of problems
! instead of features.</p>
  
! <h2><a name="changes_to_support_c99_standard">Changes to support C99 standard</h2>
  
  <p>The new version of the C standard (ISO/IEC 9899:1999) requires a
  number of library changes; these have to be provided by the C library,
*************** proper, and some compiler support is nee
*** 36,44 ****
  features.  An <a href="../c99status.html">overview</a> of the C99
  implementation status is available.</p>
  
! <h2>Haifa scheduler</h2> (haifa-sched.c, loop.[ch], unroll.c, genattrtab.c):
! (contact <a href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before
! starting any serious haifa work)
  
  <ul>
    <li>Fix/add comments throughout the code.  Many of the comments are
--- 135,144 ----
  features.  An <a href="../c99status.html">overview</a> of the C99
  implementation status is available.</p>
  
! <h2><a name="improve_the_haifa_scheduler">Improve the Haifa scheduler</h2> (haifa-sched.c, loop.[ch],
! unroll.c, genattrtab.c): (contact <a
! href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before starting any
! serious haifa work)
  
  <ul>
    <li>Fix/add comments throughout the code.  Many of the comments are
*************** starting any serious haifa work)
*** 69,75 ****
    they may need to be tuned to generate good schedules with haifa.
  </ul>
  
! <h2>Improvements to global cse and partial redundancy elimination:</h2>
  
  <p>The current implementation of global cse uses partial redundancy
  elimination via lazy code motion (lcm).
--- 169,175 ----
    they may need to be tuned to generate good schedules with haifa.
  </ul>
  
! <h2><a name="improvements_to_gcse_and_pre">Improvements to global cse and partial redundancy elimination:</h2>
  
  <p>The current implementation of global cse uses partial redundancy
  elimination via lazy code motion (lcm).
*************** compiler.
*** 85,109 ****
  <p>Contact <a href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> if
  you're interested in working on lazy code motion.</p>
  
! <h2>Miscellaneous ideas:</h2>
  
  <p>The following are some miscellaneous ideas for GCC projects to work
  on.</p>
  
! <ul>
! 
! <li>Convert the Chill front end to use garbage collection instead of
! obstacks, so it can work again with current GCC.</li>
  
! <li>Improve <code>-Wconversion</code> so that it can be used for
  security auditing as well as for its original intended purpose of
  helping with converting old code to ISO C.  See a
  <a href=" http://www2.merton.ox.ac.uk/~security/security-audit-200012/0028.html" ;>message
  to the security-audit list</a> discussing this.  The design for such
  an improved option or collection of options should be discussed with
! the gcc and security-audit lists.</li>
  
! <li>Design and implement builtin functions that assist in implementing
  the ISO C99 <code><tgmath.h></code> macros.  These builtins
  could be along the general lines of the macros used in glibc 2.2 (for
  example, the implementation of <code><tgmath.h></code> might use
--- 185,211 ----
  <p>Contact <a href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> if
  you're interested in working on lazy code motion.</p>
  
! <h2><a name="miscellaneous_ideas">Miscellaneous ideas:</h2>
  
  <p>The following are some miscellaneous ideas for GCC projects to work
  on.</p>
  
! <h3><a name="chill_should_use_gc">Chill should use garbage collection</h3>
! <p>Convert the Chill front end to use garbage collection instead of
! obstacks, so it can work again with current GCC.</p>
  
! <h3><a name="improve_wconversion">Improve <code>-Wconversion</code></h3>
! <p>Improve <code>-Wconversion</code> so that it can be used for
  security auditing as well as for its original intended purpose of
  helping with converting old code to ISO C.  See a
  <a href=" http://www2.merton.ox.ac.uk/~security/security-audit-200012/0028.html" ;>message
  to the security-audit list</a> discussing this.  The design for such
  an improved option or collection of options should be discussed with
! the gcc and security-audit lists.</p>
  
! <h3><a name="implement_various_builtin_functions_for_isoc99">Implement various builtin functions for ISO C99's 
! <code><tgmath.h></code></h3> 
! <p>Design and implement builtin functions that assist in implementing
  the ISO C99 <code><tgmath.h></code> macros.  These builtins
  could be along the general lines of the macros used in glibc 2.2 (for
  example, the implementation of <code><tgmath.h></code> might use
*************** in glibc, are needed to handle the trigo
*** 116,133 ****
  specifies have real or imaginary result type for imaginary arguments,
  but which have complex result type for complex arguments.  The design
  for these builtins should be discussed with the gcc and libc-alpha
! lists.</li>
  
! <li>Fully document the interface of front ends to GCC (that is, the
  <code>tree</code> interfaces, and the various functions, hooks, etc.,
  that a front end must or may provide).  <code>gcc/c-tree.texi</code>
  includes some of this information; <code>gcc/LANGUAGES</code> contains
  incomplete information about changes that have been made to this
! interface.</li>
! 
! </ul>
  
! <h2>Better builtin string functions</h2>
  
  <p>GNU libc includes some macros to optimize calls to some string
  functions with constant arguments.  These macros tend to cause huge
--- 218,234 ----
  specifies have real or imaginary result type for imaginary arguments,
  but which have complex result type for complex arguments.  The design
  for these builtins should be discussed with the gcc and libc-alpha
! lists.</p>
  
! <h3><a name="fully_document_the_interface_of_front_ends_to_gcc">Fully document the interface of front ends to GCC</h3>
! <p>Fully document the interface of front ends to GCC (that is, the
  <code>tree</code> interfaces, and the various functions, hooks, etc.,
  that a front end must or may provide).  <code>gcc/c-tree.texi</code>
  includes some of this information; <code>gcc/LANGUAGES</code> contains
  incomplete information about changes that have been made to this
! interface.</p>
  
! <h2><a name="better_builtin_string_functions">Better builtin string functions</h2>
  
  <p>GNU libc includes some macros to optimize calls to some string
  functions with constant arguments.  These macros tend to cause huge
*************** architectures.</p>
*** 167,175 ****
  <p>Many of these optimizations should not be applied if
  <code>-Os</code> is specified.</p>
  
! <ul>
! 
! <li>GCC optimizes <code>memset</code> only when the value and length
  involved have no side effects, and the value is a constant zero.  On
  architectures allowing unaligned accesses, glibc also optimizes if the
  length is constant and does not exceed 16; the value to which memory
--- 268,275 ----
  <p>Many of these optimizations should not be applied if
  <code>-Os</code> is specified.</p>
  
! <h3><a name="optimize_memset">Optimize <code>memset</code></h3>
! <p>GCC optimizes <code>memset</code> only when the value and length
  involved have no side effects, and the value is a constant zero.  On
  architectures allowing unaligned accesses, glibc also optimizes if the
  length is constant and does not exceed 16; the value to which memory
*************** architecture does not support unaligned 
*** 183,200 ****
  able to optimize if the destination is known to be suitably aligned.
  For example, no alignment is needed for a set of one byte; a set of
  zero bytes should be eliminated in all cases; if two bytes are to be
! set, two byte alignment may suffice; and so on.</li>
  
! <li>GCC converts <code>strcpy</code> from a string constant into a
  <code>memcpy</code> with the known length of that string constant.  In
  turn, <code>emit_block_move</code> may expand that <code>memcpy</code>
  inline.  glibc includes optimizations to load the constant contents of
  the string directly rather than via a memory copy, when no more than 8
  bytes need copying.  <code>emit_block_move</code> could be taught to
  find the contents of the string constant and include the appropriate
! integers directly in the assembler output for the copy.</li>
  
! <li>Similarly, glibc optimizes <code>strncpy</code> from a string
  constant.  Where the maximum length to be copied is not more than the
  length of the string constant including the terminating null
  character, GCC could (but does not) optimize as a
--- 283,302 ----
  able to optimize if the destination is known to be suitably aligned.
  For example, no alignment is needed for a set of one byte; a set of
  zero bytes should be eliminated in all cases; if two bytes are to be
! set, two byte alignment may suffice; and so on.</p>
  
! <h3><a name="optimize_strcpy">Optimize <code>strcpy</code></h3>
! <p>GCC converts <code>strcpy</code> from a string constant into a
  <code>memcpy</code> with the known length of that string constant.  In
  turn, <code>emit_block_move</code> may expand that <code>memcpy</code>
  inline.  glibc includes optimizations to load the constant contents of
  the string directly rather than via a memory copy, when no more than 8
  bytes need copying.  <code>emit_block_move</code> could be taught to
  find the contents of the string constant and include the appropriate
! integers directly in the assembler output for the copy.</p>
  
! <h3><a name="optimize_strncpy">Optimize <code>strncpy</code></h3>
! <p>Similarly, glibc optimizes <code>strncpy</code> from a string
  constant.  Where the maximum length to be copied is not more than the
  length of the string constant including the terminating null
  character, GCC could (but does not) optimize as a
*************** greater, trailing null characters must b
*** 203,254 ****
  here glibc can use a micro-optimization not available to GCC, its
  <code>__mempcpy</code> function to copy and return the address after
  the data copied, to pass into <code>memset</code>.  This is only used
! when as inline assembler <code>__mempcpy</code> is available.</li>
  
! <li>glibc optimizes <code>strncat</code> with constant source and
  maximum length.  If the maximum length exceeds the length of the
  source string, it is optimized to <code>strcat</code>; GCC could do
  this (including when the maximum length equals the length of the
  source string).  Otherwise, on architectures where glibc has an
  inline assembler <code>strchr</code> and it is used, glibc converts
  the <code>strncat</code> to a <code>memcpy</code>, but fails to add
! the terminating null character.</li>
  
! <li>glibc has various complicated optimizations for
  <code>strcmp</code>.  The following in GCC would completely cover
  them: comparisons of constant strings should be done at compile time;
  comparisons where one string is constant and of length less than 4
  should be inlined to compare successive bytes to the known constant
  ones (further optimization to compare more than one byte at once is in
  general unsafe as it might access too much memory).  Certain of these
! cases could also be inlined for <code>memcmp</code>.</li>
  
! <li>glibc optimizes <code>strncmp</code>, where one string is constant
  and strictly shorter than the maximum number of characters to be
  compared, by replacing it with <code>strcmp</code> (which may then be
  further optimized).  This may not be safe for GCC except in the cases
  where it handles <code>strcmp</code> internally as above, since
  <code>strcmp</code> may require both strings to be null-terminated
! whereas <code>strncmp</code> doesn't.</li>
  
! <li>glibc optimizes <code>strcspn</code> where the string of excluded
  characters is constant and of length not greater than three.  GCC
  could readily optimize the specific case where the length is zero,
! converting it to <code>strlen</code>.</li>
  
! <li>Similarly, glibc optimizes <code>strspn</code> where not more than
  three characters are involved.  Where there are zero characters
  acceptable in the initial segment, GCC could optimize to the integer
! constant 0.</li>
  
! <li>glibc also has similar optimizations for <code>strpbrk</code>.
  The cases of finding the first occurrence of zero characters (return a
  null pointer) or one character (convert to <code>strchr</code>) could
! readily be optimized by GCC.</li>
  
- </ul>
  
! <h2>Format (<code>printf</code>, <code>scanf</code> and
  <code>strftime</code>) checking:</h2>
  
  <p>Contact <a href=" mailto:jsm28@cam.ac.uk" ;>jsm28@cam.ac.uk</a> before
--- 305,361 ----
  here glibc can use a micro-optimization not available to GCC, its
  <code>__mempcpy</code> function to copy and return the address after
  the data copied, to pass into <code>memset</code>.  This is only used
! when as inline assembler <code>__mempcpy</code> is available.</p>
  
! <h3><a name="optimize_strncat">Optimize <code>strncat</code></h3>
! <p>glibc optimizes <code>strncat</code> with constant source and
  maximum length.  If the maximum length exceeds the length of the
  source string, it is optimized to <code>strcat</code>; GCC could do
  this (including when the maximum length equals the length of the
  source string).  Otherwise, on architectures where glibc has an
  inline assembler <code>strchr</code> and it is used, glibc converts
  the <code>strncat</code> to a <code>memcpy</code>, but fails to add
! the terminating null character.</p>
  
! <h3><a name="optimize_strcmp">Optimize <code>strcmp</code></h3>
! <p>glibc has various complicated optimizations for
  <code>strcmp</code>.  The following in GCC would completely cover
  them: comparisons of constant strings should be done at compile time;
  comparisons where one string is constant and of length less than 4
  should be inlined to compare successive bytes to the known constant
  ones (further optimization to compare more than one byte at once is in
  general unsafe as it might access too much memory).  Certain of these
! cases could also be inlined for <code>memcmp</code>.</p>
  
! <h3><a name="optimize_strncmp">Optimize <code>strncmp</code></h3>
! <p>glibc optimizes <code>strncmp</code>, where one string is constant
  and strictly shorter than the maximum number of characters to be
  compared, by replacing it with <code>strcmp</code> (which may then be
  further optimized).  This may not be safe for GCC except in the cases
  where it handles <code>strcmp</code> internally as above, since
  <code>strcmp</code> may require both strings to be null-terminated
! whereas <code>strncmp</code> doesn't.</p>
  
! <h3><a name="optimize_strcspn">Optimize <code>strcspn</code></h3>
! <p>glibc optimizes <code>strcspn</code> where the string of excluded
  characters is constant and of length not greater than three.  GCC
  could readily optimize the specific case where the length is zero,
! converting it to <code>strlen</code>.</p>
  
! <h3><a name="optimize_strspn">Optimize <code>strspn</code></h3>
! <p>Similarly, glibc optimizes <code>strspn</code> where not more than
  three characters are involved.  Where there are zero characters
  acceptable in the initial segment, GCC could optimize to the integer
! constant 0.</p>
  
! <h3><a name="optimize_strpbrk">Optimize <code>strpbrk</code></h3>
! <p>glibc also has similar optimizations for <code>strpbrk</code>.
  The cases of finding the first occurrence of zero characters (return a
  null pointer) or one character (convert to <code>strchr</code>) could
! readily be optimized by GCC.</p>
  
  
! <h2><a name="format_checking">Format (<code>printf</code>, <code>scanf</code> and
  <code>strftime</code>) checking:</h2>
  
  <p>Contact <a href=" mailto:jsm28@cam.ac.uk" ;>jsm28@cam.ac.uk</a> before
*************** functions.</li>
*** 358,364 ****
  
  </ul>
  
! <h2>Installation:</h2>
  
  <p>Contact <a href=" mailto:zackw@stanford.edu" ;>zackw@stanford.edu</a>
  before working on improvements to installation.</p>
--- 465,471 ----
  
  </ul>
  
! <h2><a name="improve_the_installation_procedure">Improve the installation procedure</h2>
  
  <p>Contact <a href=" mailto:zackw@stanford.edu" ;>zackw@stanford.edu</a>
  before working on improvements to installation.</p>
*************** other/346</a>.</li>
*** 416,439 ****
  
  <hr>
  
! <h1>The old PROJECTS file</h1>
  
  <p>Stuff I know has been done has been deleted.
  Stuff in progress has a contact name associated with it.</p>
  
  <p>Better optimization.
  
- <ol>
- <li>Putting constants in special sections.
  
  <p>If a function has been placed in a special
  section via attributes, we may want to put its static data and string
  constants in a special section too.  But which one?  (Being able to
  specify a section for string constants would be useful for the Linux
! kernel.)
  
! <li>Optimize a sequence of if statements whose conditions are
! exclusive.
  
  <p>It is possible to optimize
  
--- 523,546 ----
  
  <hr>
  
! <h2><a name="the_old_projects_file">The old PROJECTS file</h2>
  
  <p>Stuff I know has been done has been deleted.
  Stuff in progress has a contact name associated with it.</p>
  
  <p>Better optimization.
  
  
+ <h3><a name="putting_constants_in_special_sections">Putting constants in special sections.</h3>
+ 
  <p>If a function has been placed in a special
  section via attributes, we may want to put its static data and string
  constants in a special section too.  But which one?  (Being able to
  specify a section for string constants would be useful for the Linux
! kernel.)</p>
  
! <h3><a name="optimize_a_sequence_of_if_statements_whose_conditions_are">Optimize a sequence of if statements whose conditions are
! exclusive.</h3>
  
  <p>It is possible to optimize
  
*************** if (x == 1) ...;
*** 448,507 ****
  else if (x == 2) ...;
  else if (x == 3) ...;
  </pre>
! provided that x is not altered by the contents of the if statements.
  
  <p>It's not certain whether this is worth doing.  Perhaps programmers
  nearly always write the else's themselves, leaving few opportunities
! to improve anything.
  
! <li>Un-cse.
  
  <p>Perhaps we should have an un-cse step right after cse, which tries to
  replace a reg with its value if the value can be substituted for the
  reg everywhere, if that looks like an improvement.  Which is if the
  reg is used only a few times.  Use rtx_cost to determine if the
! change is really an improvement.
  
! <li>Clean up how cse works.
  
  <p>The scheme is that each value has just one hash entry.  The
! first_same_value and next_same_value chains are no longer needed.
  
  <p>For arithmetic, each hash table elt has the following slots:
  <ul>
  	<li>Operation.  This is an rtx code.
  	<li>Mode.
  	<li>Operands 0, 1 and 2.  These point to other hash table elements.
! </ul>
  
  <p>So, if we want to enter <code>(plus:SI (reg:SI 30) (const_int
  104))</code>, we first enter <code>(const_int 104)</code> and find the
  entry that <code>(reg:SI 30)</code> now points to.  Then we put these
  elts into operands 0 and 1 of a new elt.  We put PLUS and
! SI into the new elt.
  
  <p>Registers and mem refs would never be entered into the table as
  such.  However, the values they contain would be entered.  There would
  be a table indexed by regno which points at the hash entry for the
! value in that reg.
  
  <p>The hash entry index now plays the role of a qty number.  We still
  need qty_first_reg, reg_next_eqv, etc. to record which regs share a
! particular qty.
  
  <p>When a reg is used whose contents are unknown, we need to create a
  hash table entry whose contents say "unknown", as a place holder for
  whatever the reg contains.  If that reg is added to something, then
  the hash entry for the sum will refer to the "unknown" entry.  Use
! UNKNOWN for the rtx code in this entry.  This replaces make_new_qty.
  
  <p>For a constant, a unique hash entry would be made based on the
! value of the constant.
  
  <p>What about MEM?  Each time a memory address is referenced, we need
  a qty (a hash table elt) to represent what is in it.  (Just as for a
  register.)  If this isn't known, create one, just as for a reg whose
! contents are unknown.
  
  <p>We need a way to find all mem refs that still contain a certain
  value.  Do this with a chain of hash elts (for memory addresses) that
--- 555,614 ----
  else if (x == 2) ...;
  else if (x == 3) ...;
  </pre>
! provided that x is not altered by the contents of the if statements.</p>
  
  <p>It's not certain whether this is worth doing.  Perhaps programmers
  nearly always write the else's themselves, leaving few opportunities
! to improve anything.</p>
  
! <h3><a name="un_cse">Un-cse.</h3>
  
  <p>Perhaps we should have an un-cse step right after cse, which tries to
  replace a reg with its value if the value can be substituted for the
  reg everywhere, if that looks like an improvement.  Which is if the
  reg is used only a few times.  Use rtx_cost to determine if the
! change is really an improvement.</p>
  
! <h3><a name="clean_up_how_cse_works">Clean up how cse works.</h3>
  
  <p>The scheme is that each value has just one hash entry.  The
! first_same_value and next_same_value chains are no longer needed.</p>
  
  <p>For arithmetic, each hash table elt has the following slots:
  <ul>
  	<li>Operation.  This is an rtx code.
  	<li>Mode.
  	<li>Operands 0, 1 and 2.  These point to other hash table elements.
! </ul></p>
  
  <p>So, if we want to enter <code>(plus:SI (reg:SI 30) (const_int
  104))</code>, we first enter <code>(const_int 104)</code> and find the
  entry that <code>(reg:SI 30)</code> now points to.  Then we put these
  elts into operands 0 and 1 of a new elt.  We put PLUS and
! SI into the new elt.</p>
  
  <p>Registers and mem refs would never be entered into the table as
  such.  However, the values they contain would be entered.  There would
  be a table indexed by regno which points at the hash entry for the
! value in that reg.</p>
  
  <p>The hash entry index now plays the role of a qty number.  We still
  need qty_first_reg, reg_next_eqv, etc. to record which regs share a
! particular qty.</p>
  
  <p>When a reg is used whose contents are unknown, we need to create a
  hash table entry whose contents say "unknown", as a place holder for
  whatever the reg contains.  If that reg is added to something, then
  the hash entry for the sum will refer to the "unknown" entry.  Use
! UNKNOWN for the rtx code in this entry.  This replaces make_new_qty.</p>
  
  <p>For a constant, a unique hash entry would be made based on the
! value of the constant.</p>
  
  <p>What about MEM?  Each time a memory address is referenced, we need
  a qty (a hash table elt) to represent what is in it.  (Just as for a
  register.)  If this isn't known, create one, just as for a reg whose
! contents are unknown.</p>
  
  <p>We need a way to find all mem refs that still contain a certain
  value.  Do this with a chain of hash elts (for memory addresses) that
*************** point to locations that hold the value. 
*** 509,529 ****
  itself should point to the start of the chain.  It would be good for
  the hash elt for an address to point to the hash elt for the contents
  of that address (but this ptr can be null if the contents have never
! been entered).
  
  <p>With this data structure, nothing need ever be invalidated except
  the lists of which regs or mems hold a particular value.  It is easy
  to see if there is a reg or mem that is equiv to a particular value.
! If the value is constant, it is always explicitly constant.
  
! <li>Support more general tail-recursion among different functions.
  
  <p>This might be possible under certain circumstances, such as when
  the argument lists of the functions have the same lengths.  Perhaps it
! could be done with a special declaration.
  
  <p>You would need to verify in the calling function that it does not
! use the addresses of any local variables (?) and does not use setjmp.
  
  <p><code>-foptimize-sibling-calls</code> does at least some of this.</p>
  
--- 616,636 ----
  itself should point to the start of the chain.  It would be good for
  the hash elt for an address to point to the hash elt for the contents
  of that address (but this ptr can be null if the contents have never
! been entered).</p>
  
  <p>With this data structure, nothing need ever be invalidated except
  the lists of which regs or mems hold a particular value.  It is easy
  to see if there is a reg or mem that is equiv to a particular value.
! If the value is constant, it is always explicitly constant.</p>
  
! <h3><a name="support_more_general_tail_recursion_among_different_functions">Support more general tail-recursion among different functions.</h3>
  
  <p>This might be possible under certain circumstances, such as when
  the argument lists of the functions have the same lengths.  Perhaps it
! could be done with a special declaration.</p>
  
  <p>You would need to verify in the calling function that it does not
! use the addresses of any local variables (?) and does not use setjmp.</p>
  
  <p><code>-foptimize-sibling-calls</code> does at least some of this.</p>
  
*************** use the addresses of any local variables
*** 531,545 ****
  
  <p>Useful on the 68000/68020 and perhaps on the 32000 series, provided
  one has a linker that works with the feature.  This is said to make a
! 15% speedup on the 68000.
  
! <li>Keep global variables in registers.
  
  <p>Here is a scheme for doing this.  A global variable, or a local variable
  whose address is taken, can be kept in a register for an entire function
  if it does not use non-constant memory addresses and (for globals only)
  does not call other functions.  If the entire function does not meet
! this criterion, a loop may.
  
  <p>The VAR_DECL for such a variable would have to have two RTL
  expressions: the true home in memory, and the pseudo-register used
--- 638,652 ----
  
  <p>Useful on the 68000/68020 and perhaps on the 32000 series, provided
  one has a linker that works with the feature.  This is said to make a
! 15% speedup on the 68000.</p>
  
! <h3><a name="keep_global_variables_in_registers">Keep global variables in registers.</h3>
  
  <p>Here is a scheme for doing this.  A global variable, or a local variable
  whose address is taken, can be kept in a register for an entire function
  if it does not use non-constant memory addresses and (for globals only)
  does not call other functions.  If the entire function does not meet
! this criterion, a loop may.</p>
  
  <p>The VAR_DECL for such a variable would have to have two RTL
  expressions: the true home in memory, and the pseudo-register used
*************** location into the pseudo-register at the
*** 548,554 ****
  loop, and perhaps back out at the end.  These insns should have
  REG_EQUIV notes so that, if the pseudo-register does not get a hard
  register, it is spilled into the memory location which exists in any
! case.
  
  <p>The easiest way to set up these insns is to modify the routine
  put_var_into_stack so that it does not apply to the entire function
--- 655,661 ----
  loop, and perhaps back out at the end.  These insns should have
  REG_EQUIV notes so that, if the pseudo-register does not get a hard
  register, it is spilled into the memory location which exists in any
! case.</p>
  
  <p>The easiest way to set up these insns is to modify the routine
  put_var_into_stack so that it does not apply to the entire function
*************** put_var_into_stack so that it does not a
*** 556,568 ****
  the end of the function regardless of where in the function the
  address of a local variable is taken.  It would be called
  unconditionally at the end of the function for all relevant global
! variables.
  
  <p>For debugger output, the thing to do is to invent a new binding
  level around the appropriate loop and define the variable name as a
! register variable with that scope.
  
! <li>Live-range splitting.
  
  <p>Currently a variable is allocated a hard register either for the
  full extent of its use or not at all.  Sometimes it would be good to
--- 663,675 ----
  the end of the function regardless of where in the function the
  address of a local variable is taken.  It would be called
  unconditionally at the end of the function for all relevant global
! variables.</p>
  
  <p>For debugger output, the thing to do is to invent a new binding
  level around the appropriate loop and define the variable name as a
! register variable with that scope.</p>
  
! <h3><a name="live_range_splitting">Live-range splitting.</h3>
  
  <p>Currently a variable is allocated a hard register either for the
  full extent of its use or not at all.  Sometimes it would be good to
*************** latter is nice because it might let the 
*** 573,610 ****
  of the time even though the loop needs all the registers.)
  
  Contact <a href=" mailto:meissner@cygnus.com" ;>meissner@cygnus.com</a>
! before starting any work on live range splitting.
  
! <li>Detect dead stores into memory?
  
  <p>A store into memory is dead if it is followed by another store into
  the same location; and, in between, there is no reference to anything
  that might be that location (including no reference to a variable
! address).
  
  <p>This can be modeled as a partial redundancy elimination/lazy code
  motion problem.  Contact <a
  href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before working on dead
! store elimination optimizations.
  
! <li>Loop optimization.
  
  <p>Strength reduction and iteration variable elimination could be
  smarter.  They should know how to decide which iteration variables are
  not worth making explicit because they can be computed as part of an
  address calculation.  Based on this information, they should decide
  when it is desirable to eliminate one iteration variable and create
! another in its place.
  
  <p>It should be possible to compute what the value of an iteration
  variable will be at the end of the loop, and eliminate the variable
! within the loop by computing that value at the loop end.
  
  <p>When a loop has a simple increment that adds 1, instead of jumping
  in after the increment, decrement the loop count and jump to the
! increment.  This allows aob insns to be used.
  
! <li>Using constraints on values.
  
  <p>Many operations could be simplified based on knowledge of the
  minimum and maximum possible values of a register at any particular
--- 680,717 ----
  of the time even though the loop needs all the registers.)
  
  Contact <a href=" mailto:meissner@cygnus.com" ;>meissner@cygnus.com</a>
! before starting any work on live range splitting.</p>
  
! <h3><a name="detect_dead_stores_into_memory">Detect dead stores into memory?</h3>
  
  <p>A store into memory is dead if it is followed by another store into
  the same location; and, in between, there is no reference to anything
  that might be that location (including no reference to a variable
! address).</p>
  
  <p>This can be modeled as a partial redundancy elimination/lazy code
  motion problem.  Contact <a
  href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before working on dead
! store elimination optimizations.</p>
  
! <h3><a name="loop_optimization">Loop optimization.</h3>
  
  <p>Strength reduction and iteration variable elimination could be
  smarter.  They should know how to decide which iteration variables are
  not worth making explicit because they can be computed as part of an
  address calculation.  Based on this information, they should decide
  when it is desirable to eliminate one iteration variable and create
! another in its place.</p>
  
  <p>It should be possible to compute what the value of an iteration
  variable will be at the end of the loop, and eliminate the variable
! within the loop by computing that value at the loop end.</p>
  
  <p>When a loop has a simple increment that adds 1, instead of jumping
  in after the increment, decrement the loop count and jump to the
! increment.  This allows aob insns to be used.</p>
  
! <h3><a name="using_constraints_on_values">Using constraints on values.</h3>
  
  <p>Many operations could be simplified based on knowledge of the
  minimum and maximum possible values of a register at any particular
*************** rtl generation, or they can be deduced f
*** 613,678 ****
  performed.  For example, the result of an <code>and</code> operation
  one of whose operands is 7 must be in the range 0 to 7.  Compare
  instructions also tell something about the possible values of the
! operand, in the code beyond the test.
  
  <p>Value constraints can be used to determine the results of a further
  comparison.  They can also indicate that certain <code>and</code>
  operations are redundant.  Constraints might permit a decrement and
  branch instruction that checks zeroness to be used when the user has
! specified to exit if negative.
  
  <p>John Wehle (john@feith.com) implemented a <a
  href=" http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00968.html" ;>value
  range propagation pass</a> which isn't yet in GCC.</p>
  
! <li>Change the type of a variable.
  
  <p>Sometimes a variable is declared as <code>int</code>, it is
  assigned only once from a value of type <code>char</code>, and then it
  is used only by comparison against constants.  On many machines,
  better code would result if the variable had type <code>char</code>.
  If the compiler could detect this case, it could change the
! declaration of the variable and change all the places that use it.
  
! <li>Better handling for very sparse switches.
  
  <p>There may be cases where it would be better to compile a switch
  statement to use a fixed hash table rather than the current
! combination of jump tables and binary search.
  
! <li>Order of subexpressions.
  
  <p>It might be possible to make better code by paying attention to the
! order in which to generate code for subexpressions of an expression.
  
! <li>More code motion.
  
! <p>Consider hoisting common code up past conditional branches or tablejumps.
  
  <p>Contact <a href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before
! working on code hoisting.
  
! <li>Trace scheduling.
  
  <p>This technique is said to be able to figure out which way a jump
  will usually go, and rearrange the code to make that path the
! faster one.
  
! <li>Distributive law.
  
  <p>The C expression <code>*(X + 4 * (Y + C))</code> compiles better on
  certain machines if rewritten as <code>*(X + 4*C + 4*Y)</code> because
  of known addressing modes.  It may be tricky to determine when, and
! for which machines, to use each alternative.
  
! <p>Some work has been done on this, in combine.c.
  
! <li>Can optimize by changing <code>if (x) y; else z;</code> into
  <code>z; if (x) y;</code> if z and x do not interfere and z has no
  effects not undone by y.  This is desirable if z is faster than
! jumping.
  
! <li>For a two-insn loop on the 68020, such as
  <pre>
  foo:	movb	a2@+,a3@+
  	jne	foo
--- 720,787 ----
  performed.  For example, the result of an <code>and</code> operation
  one of whose operands is 7 must be in the range 0 to 7.  Compare
  instructions also tell something about the possible values of the
! operand, in the code beyond the test.</p>
  
  <p>Value constraints can be used to determine the results of a further
  comparison.  They can also indicate that certain <code>and</code>
  operations are redundant.  Constraints might permit a decrement and
  branch instruction that checks zeroness to be used when the user has
! specified to exit if negative.</p>
  
  <p>John Wehle (john@feith.com) implemented a <a
  href=" http://gcc.gnu.org/ml/gcc-patches/2000-07/msg00968.html" ;>value
  range propagation pass</a> which isn't yet in GCC.</p>
  
! <h3><a name="change_the_type_of_a_variable">Change the type of a variable.</h3>
  
  <p>Sometimes a variable is declared as <code>int</code>, it is
  assigned only once from a value of type <code>char</code>, and then it
  is used only by comparison against constants.  On many machines,
  better code would result if the variable had type <code>char</code>.
  If the compiler could detect this case, it could change the
! declaration of the variable and change all the places that use it.</p>
  
! <h3><a name="better_handling_for_very_sparse_switches">Better handling for very sparse switches.</h3>
  
  <p>There may be cases where it would be better to compile a switch
  statement to use a fixed hash table rather than the current
! combination of jump tables and binary search.</p>
  
! <h3><a name="order_of_subexpressions">Order of subexpressions.</h3>
  
  <p>It might be possible to make better code by paying attention to the
! order in which to generate code for subexpressions of an expression.</p>
  
! <h3><a name="more_code_motion">More code motion.</h3>
  
! <p>Consider hoisting common code up past conditional branches or tablejumps.</p>
  
  <p>Contact <a href=" mailto:law@cygnus.com" ;>law@cygnus.com</a> before
! working on code hoisting.</p>
  
! <h3><a name="trace_scheduling">Trace scheduling.</h3>
  
  <p>This technique is said to be able to figure out which way a jump
  will usually go, and rearrange the code to make that path the
! faster one.</p>
  
! <h3><a name="distributive_law">Distributive law.</h3>
  
  <p>The C expression <code>*(X + 4 * (Y + C))</code> compiles better on
  certain machines if rewritten as <code>*(X + 4*C + 4*Y)</code> because
  of known addressing modes.  It may be tricky to determine when, and
! for which machines, to use each alternative.</p>
  
! <p>Some work has been done on this, in combine.c.</p>
  
! <h3><a name="restructuring_conditionals">Restructuring conditionals</h3>
! <p>Can optimize by changing <code>if (x) y; else z;</code> into
  <code>z; if (x) y;</code> if z and x do not interfere and z has no
  effects not undone by y.  This is desirable if z is faster than
! jumping.</p>
  
! <h3><a name="how_to_call_this">??? How to call this???</h3>
! <p>For a two-insn loop on the 68020, such as
  <pre>
  foo:	movb	a2@+,a3@+
  	jne	foo
*************** foo:	movb	a2@+,a3@+
*** 680,696 ****
  it is better to insert <code>dbeq d0,foo</code> before the jne.
  <code>d0</code> can be a junk register.  The challenge is to fit this
  into a portable framework: when can you detect this situation and
! still be able to allocate a junk register?
! </ol>
  
! <h2>Simpler porting</h2>
  
  <p>Right now, describing the target machine's instructions is done
  cleanly, but describing its addressing mode is done with several
  ad-hoc macro definitions.  Porting would be much easier if there were
  an RTL description for addressing modes like that for instructions.
  Tools analogous to genflags and genrecog would generate macros from
! this description.
  
  <p>There would be one pattern in the address-description file for each
  kind of addressing, and this pattern would have:
--- 789,805 ----
  it is better to insert <code>dbeq d0,foo</code> before the jne.
  <code>d0</code> can be a junk register.  The challenge is to fit this
  into a portable framework: when can you detect this situation and
! still be able to allocate a junk register?</p>
! 
  
! <h2><a name="simpler_porting">Simpler porting</h2>
  
  <p>Right now, describing the target machine's instructions is done
  cleanly, but describing its addressing mode is done with several
  ad-hoc macro definitions.  Porting would be much easier if there were
  an RTL description for addressing modes like that for instructions.
  Tools analogous to genflags and genrecog would generate macros from
! this description.</p>
  
  <p>There would be one pattern in the address-description file for each
  kind of addressing, and this pattern would have:
*************** kind of addressing, and this pattern wou
*** 704,724 ****
        (This would replace LEGITIMIZE_ADDRESS).
    <li>Register constraints for all indeterminates that appear
        in the RTL expression.
! </ul>
  
! <h2>Other languages</h2>
  
  <p>We currently have front ends for C, C++, Objective C, CHILL,
  Fortran, and Java.  Pascal and Ada front ends exist but have not yet
! been integrated.
  
  <p>Cobol and Modula-2 front ends might be useful, and are being worked
  on.</p>
  
  <p>Pascal, Modula-2 and Ada require the implementation of functions
! within functions.  Some of the mechanisms for this already exist.
  
! <h2>More extensions</h2>
  
  <ul>
  <li>Generated unique labels.  Have some way of generating distinct
--- 813,833 ----
        (This would replace LEGITIMIZE_ADDRESS).
    <li>Register constraints for all indeterminates that appear
        in the RTL expression.
! </ul></p>
  
! <h2><a name="other_languages">Other languages</h2>
  
  <p>We currently have front ends for C, C++, Objective C, CHILL,
  Fortran, and Java.  Pascal and Ada front ends exist but have not yet
! been integrated.</p>
  
  <p>Cobol and Modula-2 front ends might be useful, and are being worked
  on.</p>
  
  <p>Pascal, Modula-2 and Ada require the implementation of functions
! within functions.  Some of the mechanisms for this already exist.</p>
  
! <h2><a name="more_extensions">More extensions</h2>
  
  <ul>
  <li>Generated unique labels.  Have some way of generating distinct
*************** This would call foo, which returns a str
*** 745,763 ****
  several components of the structure into the variables a, b, and c.
  </ul>
  
! <h2>Generalize the machine model</h2>
  
  <p>Some new compiler features may be needed to do a good job on
! machines where static data needs to be addressed using base registers.
  
  <p>Some machines have two stacks in different areas of memory, one
  used for scalars and another for large objects.  The compiler does not
! now have a way to understand this.
  
  <p>The scheduler does not do very well on recent RISC machines.  Haifa
! helps but not enough.
  
! <h2>More warnings</h2>
  
  <p>Warn about statements that are undefined because the order of
  evaluation of increment operators makes a big difference.  Here is an
--- 854,872 ----
  several components of the structure into the variables a, b, and c.
  </ul>
  
! <h2><a name="generalize_the_machine_model">Generalize the machine model</h2>
  
  <p>Some new compiler features may be needed to do a good job on
! machines where static data needs to be addressed using base registers.</p>
  
  <p>Some machines have two stacks in different areas of memory, one
  used for scalars and another for large objects.  The compiler does not
! now have a way to understand this.</p>
  
  <p>The scheduler does not do very well on recent RISC machines.  Haifa
! helps but not enough.</p>
  
! <h2><a name="more_warnings">More warnings</h2>
  
  <p>Warn about statements that are undefined because the order of
  evaluation of increment operators makes a big difference.  Here is an
*************** example:
*** 765,775 ****
  <pre>
  *foo++ = hack (*foo);
  </pre>
! 
  <p><code>-Wsequence-point</code> does some of this, but not that
  particular case.</p>
  
! <h2>Better documentation of how GCC works and how to port it</h2>
  
  <p>Here is an outline proposed by Allan Adler.
  
--- 874,884 ----
  <pre>
  *foo++ = hack (*foo);
  </pre>
! </p>
  <p><code>-Wsequence-point</code> does some of this, but not that
  particular case.</p>
  
! <h2><a name="better_documentation_of_how_gcc_works_and_how_to_port_it">Better documentation of how GCC works and how to port it</h2>
  
  <p>Here is an outline proposed by Allan Adler.
  
*************** particular case.</p>
*** 866,872 ****
  
  <hr>
  
! <h1>The old PROBLEMS file</h1>
  
  <p>The following used to be in a file <code>PROBLEMS</code> in the GCC
  distribution.  Probably much of it is no longer relevant as of GCC 3.0
--- 975,981 ----
  
  <hr>
  
! <h2><a name="the_old_problems_file">The old PROBLEMS file</h2>
  
  <p>The following used to be in a file <code>PROBLEMS</code> in the GCC
  distribution.  Probably much of it is no longer relevant as of GCC 3.0



More information about the Gcc-patches mailing list