This commit was generated by cvs2svn to compensate for changes in r132718,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
Alexander Kabaev 2004-07-28 03:11:36 +00:00
commit 4609cf73ba
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132719
876 changed files with 283732 additions and 165863 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1251,7 +1251,7 @@ Wed Apr 14 13:59:27 1999 Martin von Loewis <loewis@informatik.hu-berlin.de>
Wed Apr 14 00:18:22 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.md (SImode logical compare): Avoid outputing non-pariable testw
* i386.md (SImode logical compare): Avoid outputting non-pariable testw
and testl on Pentium.
(register and memory bit tests): Likewise.
(setcc, normal and reversed conditional branches): Use shorter
@ -3212,7 +3212,7 @@ Tue Mar 16 13:44:50 1999 Jim Wilson <wilson@cygnus.com>
unless it's necessary.
* cpplib.h (parse_marker): Removed.
(struct cpp_buffer): Line_base is now a unsigned char *; add
(struct cpp_buffer): Line_base is now an unsigned char *; add
`mark' [long], remove `marks' [struct parse_marker *].
(parse_set_mark, parse_clear_mark, parse_goto_mark): Update
prototypes.

16352
contrib/gcc/ChangeLog.10 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4782,7 +4782,7 @@ Tue Oct 19 15:26:11 1999 Richard Earnshaw (rearnsha@arm.com)
Tue Oct 19 14:01:34 1999 Nick Clifton <nickc@cygnus.com>
* toplev.c (main): Do not generate an error message if an
unrecognized command line switch is recognisable by another
unrecognized command line switch is recognizable by another
language. If extra_warnings are enabled, then generate a
warning message instead.
@ -10733,7 +10733,7 @@ Thu Aug 19 11:51:22 EDT 1999 John Wehle (john@feith.com)
Thu Aug 19 15:02:01 1999 Nick Clifton <nickc@cygnus.com>
* config/rs6000/rs6000.c (rs6000_override_options): Fix test for
unrecognisable switches.
unrecognizable switches.
Wed Aug 18 23:31:57 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
@ -10855,7 +10855,7 @@ Fri Aug 13 15:20:43 1999 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
Fri Aug 13 10:21:28 1999 Nick Clifton <nickc@cygnus.com>
* toplev.c (rest_of_compilation): Allow machine dependent
reorganisation pass to place information into the RTL dump
reorganization pass to place information into the RTL dump
file if it so wishes.
Sun Aug 15 12:41:21 1999 Jim Wilson <wilson@cygnus.com>

View File

@ -6424,7 +6424,7 @@ Mon Apr 17 14:59:36 MET DST 2000 Jan Hubicka <jh@suse.cz>
* i370.c (mvs_add_label): Change spacing for coding conventions.
* i370.h (ASM_OUTPUT_CASE_LABEL): Change to the data CSECT for the
outputing case vectors.
outputting case vectors.
(ASM_OUTPUT_CASE_END): New, put assembler back into code CSECT.
(ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Remove page check,
since vector in in the data CSECT.
@ -14863,9 +14863,9 @@ Mon Jan 24 16:56:10 2000 Jim Wilson <wilson@cygnus.com>
2000-01-24 Richard Henderson <rth@cygnus.com>
* rtl.def: Add unordered fp comparisions.
* rtl.def: Add unordered fp comparisons.
* tree.def: Likewise.
* tree.h: Add ISO C 9x unordered fp comparision builtins.
* tree.h: Add ISO C 9x unordered fp comparison builtins.
* builtins.c (expand_tree_builtin): New function.
* c-typeck.c (build_function_call): Use it.

View File

@ -14230,7 +14230,7 @@ Fri Jul 14 10:25:53 2000 Clinton Popetz <cpopetz@cygnus.com>
(cpp_pop_buffer): Use _cpp_pop_file_buffer.
* cpplex.c: Move all prototypes and structure declarations to the
top of the file. Properly parenthesise some macro arguments.
top of the file. Properly parenthesize some macro arguments.
(cpp_scan_line): New function.
(special_symbol [case T_INCLUDE_DEPTH]): Use pfile->include_depth,
don't need to walk up the stack counting.

View File

@ -3283,7 +3283,7 @@ Sat May 19 18:23:04 2001 Richard Henderson <rth@redhat.com>
* c-parse.in (parm_declarator): Split into
parm_declarator_starttypename and parm_declarator_nostarttypename.
(parm_declarator_starttypename, parm_declarator_nostarttypename):
New. Allow parenthesised sub-declarators which don't begin with a
New. Allow parenthesized sub-declarators which don't begin with a
TYPENAME. Fixes PR c/166.
2001-05-19 Mark Mitchell <mark@codesourcery.com>

View File

@ -10043,7 +10043,7 @@ Tue Sep 25 17:13:56 CEST 2001 Jan Hubicka <jh@suse.cz>
* config/i386/i386.c (ix86_init_builtins): Correct return type
building v4hi_ftype_v4hi_int_int tree node.
(ix86_expand_sse_comi): Fix typo swapping operands.
Don't swap comparision condition, it is already swapped.
Don't swap comparison condition, it is already swapped.
(ix86_expand_sse_compare): Before swapping operands
move operand 1 into new rtx and not the target rtx.
Don't swap comparison condition, it is already swapped.
@ -15034,12 +15034,12 @@ Tue Aug 7 14:56:16 CEST 2001 Jan Hubicka <jh@suse.cz>
2001-08-05 Jan Hubicka <jh@suse.cz>
* Makefile.in (reload1.o): Add dedendancy on except.h
* Makefile.in (reload1.o): Add dependency on except.h
* basic-block.h (purge_all_dead_edges, purge_dead_edges): Update
prototypes.
* flow.c (purge_dead_edges, purge_all_dead_edges): Return bool
indicating wehther edges has been cleaned up.
* reload1.c: Inlucde except.h
indicating whether edges has been cleaned up.
* reload1.c: Include except.h.
(fixup_abnormal_edges): Accept deleted insns.
* toplev.c (rest_of_compilation): Purge dead edges unconditionally
after combine.

View File

@ -8244,7 +8244,7 @@ Wed May 8 11:10:31 CEST 2002 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Jan Hubicka <jh@suse.cz>
* basic-block.h (note_prediction_to_br_prob): declare.
* c-semantics.c: Inlucde predit.h
* c-semantics.c: Include predit.h
(expand_stmt): predict GOTO_STMT as not taken.
* cfgcleanup.c: (delete_unreachable_blocks): Make global.
(cleanup_cfg): Do not free tail_recursion_list.
@ -12648,7 +12648,7 @@ Thu Mar 28 16:35:31 2002 Jeffrey A Law (law@redhat.com)
Thu Mar 28 19:13:36 CET 2002 Jan Hubicka <jh@suse.cz>
* ifcvt.c (if_convert): Clear aux_for_blocks early enought.
* ifcvt.c (if_convert): Clear aux_for_blocks early enough.
Thu Mar 28 13:21:53 CET 2002 Jan Hubicka <jh@suse.cz>

14448
contrib/gcc/ChangeLog.8 Normal file

File diff suppressed because it is too large Load Diff

21488
contrib/gcc/ChangeLog.9 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
Copyright (C) 2000 Free Software Foundation, Inc.
Copyright (C) 2000, 2003 Free Software Foundation, Inc.
This file is intended to contain a few notes about writing C code
within GCC so that it compiles without error on the full range of
@ -10,65 +10,28 @@ This knowledge until know has been sparsely spread around, so I
thought I'd collect it in one useful place. Please add and correct
any problems as you come across them.
I'm going to start from a base of the ISO C89 standard, since that is
I'm going to start from a base of the ISO C90 standard, since that is
probably what most people code to naturally. Obviously using
constructs introduced after that is not a good idea.
The first section of this file deals strictly with portability issues,
the second with common coding pitfalls.
Portability Issues
==================
Unary +
-------
K+R C compilers and preprocessors have no notion of unary '+'. Thus
the following code snippet contains 2 portability problems.
int x = +2; /* int x = 2; */
#if +1 /* #if 1 */
#endif
Pointers to void
----------------
K+R C compilers did not have a void pointer, and used char * as the
pointer to anything. The macro PTR is defined as either void * or
char * depending on whether you have a standards compliant compiler or
a K+R one. Thus
free ((void *) h->value.expansion);
should be written
free ((PTR) h->value.expansion);
Further, an initial investigation indicates that pointers to functions
returning void are okay. Thus the example given by "Calling functions
through pointers to functions" below appears not to cause a problem.
For the complete coding style conventions used in GCC, please read
http://gcc.gnu.org/codingconventions.html
String literals
---------------
Some SGI compilers choke on the parentheses in:-
Irix6 "cc -n32" and OSF4 "cc" have problems with constant string
initializers with parens around it, e.g.
const char string[] = ("A string");
This is unfortunate since this is what the GNU gettext macro N_
produces. You need to find a different way to code it.
K+R C did not allow concatenation of string literals like
"This is a " "single string literal".
Moreover, some compilers like MSVC++ have fairly low limits on the
maximum length of a string literal; 509 is the lowest we've come
across. You may need to break up a long printf statement into many
smaller ones.
Some compilers like MSVC++ have fairly low limits on the maximum
length of a string literal; 509 is the lowest we've come across. You
may need to break up a long printf statement into many smaller ones.
Empty macro arguments
@ -88,140 +51,6 @@ foo (bar, )
needs to be coded in some other way.
signed keyword
--------------
The signed keyword did not exist in K+R compilers; it was introduced
in ISO C89, so you cannot use it. In both K+R and standard C,
unqualified char and bitfields may be signed or unsigned. There is no
way to portably declare signed chars or signed bitfields.
All other arithmetic types are signed unless you use the 'unsigned'
qualifier. For instance, it is safe to write
short paramc;
instead of
signed short paramc;
If you have an algorithm that depends on signed char or signed
bitfields, you must find another way to write it before it can be
integrated into GCC.
Function prototypes
-------------------
You need to provide a function prototype for every function before you
use it, and functions must be defined K+R style. The function
prototype should use the PARAMS macro, which takes a single argument.
Therefore the parameter list must be enclosed in parentheses. For
example,
int myfunc PARAMS ((double, int *));
int
myfunc (var1, var2)
double var1;
int *var2;
{
...
}
This implies that if the function takes no arguments, it should be
declared and defined as follows:
int myfunc PARAMS ((void));
int
myfunc ()
{
...
}
You also need to use PARAMS when referring to function protypes in
other circumstances, for example see "Calling functions through
pointers to functions" below.
Variable-argument functions are best described by example:-
void cpp_ice PARAMS ((cpp_reader *, const char *msgid, ...));
void
cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
{
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, cpp_reader *, pfile);
VA_FIXEDARG (ap, const char *, msgid);
...
VA_CLOSE (ap);
}
See ansidecl.h for the definitions of the above macros and more.
One aspect of using K+R style function declarations, is you cannot
have arguments whose types are char, short, or float, since without
prototypes (ie, K+R rules), these types are promoted to int, int, and
double respectively.
Calling functions through pointers to functions
-----------------------------------------------
K+R C compilers require parentheses around the dereferenced function
pointer expression in the call, whereas ISO C relaxes the syntax. For
example
typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
*p->handler (pfile, p->arg);
needs to become
(*p->handler) (pfile, p->arg);
Macros
------
The rules under K+R C and ISO C for achieving stringification and
token pasting are quite different. Therefore some macros have been
defined which will get it right depending upon the compiler.
CONCAT2(a,b) CONCAT3(a,b,c) and CONCAT4(a,b,c,d)
will paste the tokens passed as arguments. You must not leave any
space around the commas. Also,
STRINGX(x)
will stringify an argument; to get the same result on K+R and ISO
compilers x should not have spaces around it.
Passing structures by value
---------------------------
Avoid passing structures by value, either to or from functions. It
seems some K+R compilers handle this differently or not at all.
Enums
-----
In K+R C, you have to cast enum types to use them as integers, and
some compilers in particular give lots of warnings for using an enum
as an array index.
Bitfields
---------
See also "signed keyword" above. In K+R C only unsigned int bitfields
were defined (i.e. unsigned char, unsigned short, unsigned long.
Using plain int/short/long was not allowed).
free and realloc
----------------
@ -232,37 +61,16 @@ pointer. Thus if mem might be null, you need to write
free (mem);
Reserved Keywords
-----------------
K+R C has "entry" as a reserved keyword, so you should not use it for
your variable names.
Type promotions
---------------
K+R used unsigned-preserving rules for arithmetic expresssions, while
ISO uses value-preserving. This means an unsigned char compared to an
int is done as an unsigned comparison in K+R (since unsigned char
promotes to unsigned) while it is signed in ISO (since all of the
values in unsigned char fit in an int, it promotes to int).
Trigraphs
---------
You weren't going to use them anyway, but trigraphs were not defined
in K+R C, and some otherwise ISO C compliant compilers do not accept
them.
You weren't going to use them anyway, but some otherwise ISO C
compliant compilers do not accept trigraphs.
Suffixes on Integer Constants
-----------------------------
K+R C did not accept a 'u' suffix on integer constants. If you want
to declare a constant to be be unsigned, you must use an explicit
cast.
You should never use a 'l' suffix on integer constants ('L' is fine),
since it can easily be confused with the number '1'.
@ -300,22 +108,19 @@ long and int are not the same size.
Second, if you write a function definition with no return type at
all:
operate (a, b)
int a, b;
operate (int a, int b)
{
...
}
that function is expected to return int, *not* void. GCC will warn
about this. K+R C has no problem with 'void' as a return type, so you
need not worry about that.
about this.
Implicit function declarations always have return type int. So if you
correct the above definition to
void
operate (a, b)
int a, b;
operate (int a, int b)
...
but operate() is called above its definition, you will get an error
@ -368,7 +173,7 @@ WITH UMLAUT.
Other common pitfalls
---------------------
o Expecting 'plain' char to be either sign or unsigned extending
o Expecting 'plain' char to be either sign or unsigned extending.
o Shifting an item by a negative amount or by greater than or equal to
the number of bits in a type (expecting shifts by 32 to be sensible
@ -389,3 +194,4 @@ o Passing incorrect types to fprintf and friends.
o Adding a function declaration for a module declared in another file to
a .c file instead of to a .h file.

1088
contrib/gcc/aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

367
contrib/gcc/alloc-pool.c Normal file
View File

@ -0,0 +1,367 @@
/* Functions to support a pool of allocatable objects.
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
Contributed by Daniel Berlin <dan@cgsoftware.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "alloc-pool.h"
#include "hashtab.h"
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic
is duplicated in rtl.h and tree.h because every file that needs the
special abort includes one or both. toplev.h gets too few files,
system.h gets too many. */
extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN;
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
#define align_eight(x) (((x+7) >> 3) << 3)
/* The internal allocation object. */
typedef struct allocation_object_def
{
#ifdef ENABLE_CHECKING
/* The ID of alloc pool which the object was allocated from. */
ALLOC_POOL_ID_TYPE id;
#endif
union
{
/* The data of the object. */
char data[1];
/* Because we want any type of data to be well aligned after the ID,
the following elements are here. They are never accessed so
the allocated object may be even smaller than this structure. */
char *align_p;
HOST_WIDEST_INT align_i;
long double align_ld;
} u;
} allocation_object;
/* Convert a pointer to allocation_object from a pointer to user data. */
#define ALLOCATION_OBJECT_PTR_FROM_USER_PTR(X) \
((allocation_object *) (((char *) (X)) \
- offsetof (allocation_object, u.data)))
/* Convert a pointer to user data from a pointer to allocation_object. */
#define USER_PTR_FROM_ALLOCATION_OBJECT_PTR(X) \
((void *) (((allocation_object *) (X))->u.data))
#ifdef ENABLE_CHECKING
/* Last used ID. */
static ALLOC_POOL_ID_TYPE last_id;
#endif
#ifdef GATHER_STATISTICS
/* Store infromation about each particular alloc_pool. */
struct alloc_pool_descriptor
{
const char *name;
int allocated;
int created;
int peak;
int current;
};
/* Hashtable mapping alloc_pool names to descriptors. */
static htab_t alloc_pool_hash;
/* Hashtable helpers. */
static hashval_t
hash_descriptor (const void *p)
{
const struct alloc_pool_descriptor *d = p;
return htab_hash_pointer (d->name);
}
static int
eq_descriptor (const void *p1, const void *p2)
{
const struct alloc_pool_descriptor *d = p1;
return d->name == p2;
}
/* For given name, return descriptor, create new if needed. */
static struct alloc_pool_descriptor *
alloc_pool_descriptor (const char *name)
{
struct alloc_pool_descriptor **slot;
if (!alloc_pool_hash)
alloc_pool_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
slot = (struct alloc_pool_descriptor **)
htab_find_slot_with_hash (alloc_pool_hash, name,
htab_hash_pointer (name),
1);
if (*slot)
return *slot;
*slot = xcalloc (sizeof (**slot), 1);
(*slot)->name = name;
return *slot;
}
#endif
/* Create a pool of things of size SIZE, with NUM in each block we
allocate. */
alloc_pool
create_alloc_pool (const char *name, size_t size, size_t num)
{
alloc_pool pool;
size_t pool_size, header_size;
#ifdef GATHER_STATISTICS
struct alloc_pool_descriptor *desc;
#endif
if (!name)
abort ();
/* Make size large enough to store the list header. */
if (size < sizeof (alloc_pool_list))
size = sizeof (alloc_pool_list);
/* Now align the size to a multiple of 4. */
size = align_eight (size);
#ifdef ENABLE_CHECKING
/* Add the aligned size of ID. */
size += offsetof (allocation_object, u.data);
#endif
/* Um, we can't really allocate 0 elements per block. */
if (num == 0)
abort ();
/* Find the size of the pool structure, and the name. */
pool_size = sizeof (struct alloc_pool_def);
/* and allocate that much memory. */
pool = xmalloc (pool_size);
/* Now init the various pieces of our pool structure. */
pool->name = /*xstrdup (name)*/name;
#ifdef GATHER_STATISTICS
desc = alloc_pool_descriptor (name);
desc->created++;
#endif
pool->elt_size = size;
pool->elts_per_block = num;
/* List header size should be a multiple of 8. */
header_size = align_eight (sizeof (struct alloc_pool_list_def));
pool->block_size = (size * num) + header_size;
pool->free_list = NULL;
pool->elts_allocated = 0;
pool->elts_free = 0;
pool->blocks_allocated = 0;
pool->block_list = NULL;
#ifdef ENABLE_CHECKING
/* Increase the last used ID and use it for this pool.
ID == 0 is used for free elements of pool so skip it. */
last_id++;
if (last_id == 0)
last_id++;
pool->id = last_id;
#endif
return (pool);
}
/* Free all memory allocated for the given memory pool. */
void
free_alloc_pool (alloc_pool pool)
{
alloc_pool_list block, next_block;
#ifdef GATHER_STATISTICS
struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
#endif
#ifdef ENABLE_CHECKING
if (!pool)
abort ();
#endif
/* Free each block allocated to the pool. */
for (block = pool->block_list; block != NULL; block = next_block)
{
next_block = block->next;
free (block);
#ifdef GATHER_STATISTICS
desc->current -= pool->block_size;
#endif
}
/* Lastly, free the pool. */
#ifdef ENABLE_CHECKING
memset (pool, 0xaf, sizeof (*pool));
#endif
free (pool);
}
/* Allocates one element from the pool specified. */
void *
pool_alloc (alloc_pool pool)
{
alloc_pool_list header;
char *block;
#ifdef GATHER_STATISTICS
struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
desc->allocated+=pool->elt_size;
#endif
#ifdef ENABLE_CHECKING
if (!pool)
abort ();
#endif
/* If there are no more free elements, make some more!. */
if (!pool->free_list)
{
size_t i;
alloc_pool_list block_header;
/* Make the block. */
block = xmalloc (pool->block_size);
block_header = (alloc_pool_list) block;
block += align_eight (sizeof (struct alloc_pool_list_def));
#ifdef GATHER_STATISTICS
desc->current += pool->block_size;
if (desc->peak < desc->current)
desc->peak = desc->current;
#endif
/* Throw it on the block list. */
block_header->next = pool->block_list;
pool->block_list = block_header;
/* Now put the actual block pieces onto the free list. */
for (i = 0; i < pool->elts_per_block; i++, block += pool->elt_size)
{
#ifdef ENABLE_CHECKING
/* Mark the element to be free. */
((allocation_object *) block)->id = 0;
#endif
header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block);
header->next = pool->free_list;
pool->free_list = header;
}
/* Also update the number of elements we have free/allocated, and
increment the allocated block count. */
pool->elts_allocated += pool->elts_per_block;
pool->elts_free += pool->elts_per_block;
pool->blocks_allocated += 1;
}
/* Pull the first free element from the free list, and return it. */
header = pool->free_list;
pool->free_list = header->next;
pool->elts_free--;
#ifdef ENABLE_CHECKING
/* Set the ID for element. */
ALLOCATION_OBJECT_PTR_FROM_USER_PTR (header)->id = pool->id;
#endif
return ((void *) header);
}
/* Puts PTR back on POOL's free list. */
void
pool_free (alloc_pool pool, void *ptr)
{
alloc_pool_list header;
#ifdef ENABLE_CHECKING
if (!ptr)
abort ();
memset (ptr, 0xaf, pool->elt_size - offsetof (allocation_object, u.data));
/* Check whether the PTR was allocated from POOL. */
if (pool->id != ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id)
abort ();
/* Mark the element to be free. */
ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id = 0;
#else
/* Check if we free more than we allocated, which is Bad (TM). */
if (pool->elts_free + 1 > pool->elts_allocated)
abort ();
#endif
header = (alloc_pool_list) ptr;
header->next = pool->free_list;
pool->free_list = header;
pool->elts_free++;
}
/* Output per-alloc_pool statistics. */
#ifdef GATHER_STATISTICS
/* Used to accumulate statistics about alloc_pool sizes. */
struct output_info
{
int count;
int size;
};
/* Called via htab_traverse. Output alloc_pool descriptor pointed out by SLOT
and update statistics. */
static int
print_statistics (void **slot, void *b)
{
struct alloc_pool_descriptor *d = (struct alloc_pool_descriptor *) *slot;
struct output_info *i = (struct output_info *) b;
if (d->allocated)
{
fprintf (stderr, "%-21s %6d %10d %10d %10d\n", d->name,
d->created, d->allocated, d->peak, d->current);
i->size += d->allocated;
i->count += d->created;
}
return 1;
}
#endif
/* Output per-alloc_pool memory usage statistics. */
void dump_alloc_pool_statistics (void)
{
#ifdef GATHER_STATISTICS
struct output_info info;
fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
fprintf (stderr, "-------------------------------------------------------------\n");
info.count = 0;
info.size = 0;
htab_traverse (alloc_pool_hash, print_statistics, &info);
fprintf (stderr, "-------------------------------------------------------------\n");
fprintf (stderr, "%-20s %7d %10d\n",
"Total", info.count, info.size);
fprintf (stderr, "-------------------------------------------------------------\n");
#endif
}

55
contrib/gcc/alloc-pool.h Normal file
View File

@ -0,0 +1,55 @@
/* Functions to support a pool of allocatable objects
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
Contributed by Daniel Berlin <dan@cgsoftware.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef ALLOC_POOL_H
#define ALLOC_POOL_H
typedef unsigned long ALLOC_POOL_ID_TYPE;
typedef struct alloc_pool_list_def
{
struct alloc_pool_list_def *next;
}
*alloc_pool_list;
typedef struct alloc_pool_def
{
const char *name;
#ifdef ENABLE_CHECKING
ALLOC_POOL_ID_TYPE id;
#endif
size_t elts_per_block;
alloc_pool_list free_list;
size_t elts_allocated;
size_t elts_free;
size_t blocks_allocated;
alloc_pool_list block_list;
size_t block_size;
size_t elt_size;
}
*alloc_pool;
extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
extern void free_alloc_pool (alloc_pool);
extern void *pool_alloc (alloc_pool);
extern void pool_free (alloc_pool, void *);
extern void dump_alloc_pool_statistics (void);
#endif

View File

@ -312,15 +312,4 @@ So instead we use the macro below and test it against specific values. */
#define __extension__
#endif
/* Bootstrap support: Adjust certain macros defined by Autoconf,
which are only valid for the stage1 compiler. If we detect
a modern version of GCC, we are probably in stage2 or beyond,
so unconditionally reset the values. Note that const, inline,
etc. have been dealt with above. */
#if (GCC_VERSION >= 2007)
# ifndef HAVE_LONG_DOUBLE
# define HAVE_LONG_DOUBLE 1
# endif
#endif /* GCC >= 2.7 */
#endif /* ansidecl.h */

View File

@ -1,6 +1,6 @@
/* Functions dealing with attribute handling, used by most front ends.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002 Free Software Foundation, Inc.
2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "toplev.h"
@ -33,7 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "langhooks.h"
static void init_attributes PARAMS ((void));
static void init_attributes (void);
/* Table of the tables of attributes (common, language, format, machine)
searched. */
@ -51,7 +53,7 @@ static const struct attribute_spec empty_attribute_table[] =
if --enable-checking. */
static void
init_attributes ()
init_attributes (void)
{
size_t i;
@ -132,16 +134,10 @@ init_attributes ()
information, in the form of a bitwise OR of flags in enum attribute_flags
from tree.h. Depending on these flags, some attributes may be
returned to be applied at a later stage (for example, to apply
a decl attribute to the declaration rather than to its type). If
ATTR_FLAG_BUILT_IN is not set and *NODE is a DECL, then also consider
whether there might be some default attributes to apply to this DECL;
if so, decl_attributes will be called recursively with those attributes
and ATTR_FLAG_BUILT_IN set. */
a decl attribute to the declaration rather than to its type). */
tree
decl_attributes (node, attributes, flags)
tree *node, attributes;
int flags;
decl_attributes (tree *node, tree attributes, int flags)
{
tree a;
tree returned_attrs = NULL_TREE;
@ -151,10 +147,6 @@ decl_attributes (node, attributes, flags)
(*targetm.insert_attributes) (*node, &attributes);
if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL
&& !(flags & (int) ATTR_FLAG_BUILT_IN))
(*lang_hooks.insert_default_attributes) (*node);
for (a = attributes; a; a = TREE_CHAIN (a))
{
tree name = TREE_PURPOSE (a);
@ -162,6 +154,7 @@ decl_attributes (node, attributes, flags)
tree *anode = node;
const struct attribute_spec *spec = NULL;
bool no_add_attrs = 0;
tree fn_ptr_tmp = NULL_TREE;
size_t i;
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
@ -230,9 +223,18 @@ decl_attributes (node, attributes, flags)
&& (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
{
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
*anode = build_type_copy (*anode);
anode = &TREE_TYPE (*anode);
/* OK, this is a bit convoluted. We can't just make a copy
of the pointer type and modify its TREE_TYPE, because if
we change the attributes of the target type the pointer
type needs to have a different TYPE_MAIN_VARIANT. So we
pull out the target type now, frob it as appropriate, and
rebuild the pointer type later.
This would all be simpler if attributes were part of the
declarator, grumble grumble. */
fn_ptr_tmp = TREE_TYPE (*anode);
anode = &fn_ptr_tmp;
flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
}
else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
{
@ -299,6 +301,19 @@ decl_attributes (node, attributes, flags)
old_attrs));
}
}
if (fn_ptr_tmp)
{
/* Rebuild the function pointer type and put it in the
appropriate place. */
fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
if (DECL_P (*node))
TREE_TYPE (*node) = fn_ptr_tmp;
else if (TREE_CODE (*node) == POINTER_TYPE)
*node = fn_ptr_tmp;
else
abort ();
}
}
return returned_attrs;
@ -315,9 +330,7 @@ decl_attributes (node, attributes, flags)
resulting attributes together the way decl_attributes expects them. */
void
split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
tree specs_attrs;
tree *declspecs, *prefix_attributes;
split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
{
tree t, s, a, next, specs, attrs;
@ -392,8 +405,7 @@ split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
A warning is issued for every ignored attribute. */
tree
strip_attrs (specs_attrs)
tree specs_attrs;
strip_attrs (tree specs_attrs)
{
tree specs, attrs;
@ -408,4 +420,3 @@ strip_attrs (specs_attrs)
return specs;
}

View File

@ -1,5 +1,5 @@
/* Define control and data flow tables, and regsets.
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@ -72,7 +72,7 @@ typedef bitmap regset;
#define REGNO_REG_SET_P(TO, REG) bitmap_bit_p (TO, REG)
/* Copy the hard registers in a register set to the hard register set. */
extern void reg_set_to_hard_reg_set PARAMS ((HARD_REG_SET *, bitmap));
extern void reg_set_to_hard_reg_set (HARD_REG_SET *, bitmap);
#define REG_SET_TO_HARD_REG_SET(TO, FROM) \
do { \
CLEAR_HARD_REG_SET (TO); \
@ -113,7 +113,11 @@ do { \
be done, other than zero the statistics on the first allocation. */
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
/* Type we use to hold basic block counters. Should be at least 64bit. */
/* Type we use to hold basic block counters. Should be at least
64bit. Although a counter cannot be negative, we use a signed
type, because erroneous negative counts can be generated when the
flow graph is manipulated by various optimizations. A signed type
makes those easy to detect. */
typedef HOST_WIDEST_INT gcov_type;
/* Control flow edge information. */
@ -146,9 +150,20 @@ typedef struct edge_def {
#define EDGE_DFS_BACK 32 /* A backwards edge */
#define EDGE_CAN_FALLTHRU 64 /* Candidate for straight line
flow. */
#define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */
#define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */
#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */
#define EDGE_ALL_FLAGS 1023
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
/* Counter summary from the last set of coverage counts read by
profile.c. */
extern const struct gcov_ctr_summary *profile_info;
/* Declared in cfgloop.h. */
struct loop;
struct loops;
/* A basic block is a sequence of instructions with only entry and
only one exit. If any one of the instructions are executed, they
@ -178,7 +193,7 @@ typedef struct edge_def {
/* Basic block information indexed by block number. */
typedef struct basic_block_def {
/* The first and last insns of the block. */
rtx head, end;
rtx head_, end_;
/* The first and last trees of the block. */
tree head_tree;
@ -219,6 +234,9 @@ typedef struct basic_block_def {
/* Outermost loop containing the block. */
struct loop *loop_father;
/* The dominance and postdominance information node. */
struct et_node *dom[2];
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@ -227,6 +245,9 @@ typedef struct basic_block_def {
/* Various flags. See BB_* below. */
int flags;
/* Additional data maintained by cfg_layout routines. */
struct reorder_block_def *rbi;
} *basic_block;
#define BB_FREQ_MAX 10000
@ -236,6 +257,8 @@ typedef struct basic_block_def {
#define BB_NEW 2
#define BB_REACHABLE 4
#define BB_VISITED 8
#define BB_IRREDUCIBLE_LOOP 16
#define BB_SUPERBLOCK 32
/* Number of basic blocks in the current function. */
@ -296,11 +319,8 @@ extern struct obstack flow_obstack;
/* Stuff for recording basic block info. */
#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head)
#define BLOCK_END(B) (BASIC_BLOCK (B)->end)
#define BLOCK_HEAD_TREE(B) (BASIC_BLOCK (B)->head_tree)
#define BLOCK_END_TREE(B) (BASIC_BLOCK (B)->end_tree)
#define BB_HEAD(B) (B)->head_
#define BB_END(B) (B)->end_
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
@ -317,214 +337,44 @@ extern struct basic_block_def entry_exit_blocks[2];
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
extern void compute_bb_for_insn PARAMS ((void));
extern void free_bb_for_insn PARAMS ((void));
extern void update_bb_for_insn PARAMS ((basic_block));
extern void compute_bb_for_insn (void);
extern void free_bb_for_insn (void);
extern void update_bb_for_insn (basic_block);
extern void free_basic_block_vars PARAMS ((int));
extern void free_basic_block_vars (int);
extern edge split_block PARAMS ((basic_block, rtx));
extern basic_block split_edge PARAMS ((edge));
extern void insert_insn_on_edge PARAMS ((rtx, edge));
extern void insert_insn_on_edge (rtx, edge);
bool safe_insert_insn_on_edge (rtx, edge);
extern void commit_edge_insertions PARAMS ((void));
extern void commit_edge_insertions_watch_calls PARAMS ((void));
extern void commit_edge_insertions (void);
extern void commit_edge_insertions_watch_calls (void);
extern void remove_fake_edges PARAMS ((void));
extern void add_noreturn_fake_exit_edges PARAMS ((void));
extern void connect_infinite_loops_to_exit PARAMS ((void));
extern int flow_call_edges_add PARAMS ((sbitmap));
extern edge cached_make_edge PARAMS ((sbitmap *, basic_block,
basic_block, int));
extern edge unchecked_make_edge PARAMS ((basic_block,
basic_block, int));
extern edge make_edge PARAMS ((basic_block,
basic_block, int));
extern edge make_single_succ_edge PARAMS ((basic_block,
basic_block, int));
extern void remove_edge PARAMS ((edge));
extern void redirect_edge_succ PARAMS ((edge, basic_block));
extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
extern int flow_delete_block PARAMS ((basic_block));
extern int flow_delete_block_noexpunge PARAMS ((basic_block));
extern void clear_bb_flags PARAMS ((void));
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
basic_block));
extern void tidy_fallthru_edges PARAMS ((void));
extern void flow_reverse_top_sort_order_compute PARAMS ((int *));
extern int flow_depth_first_order_compute PARAMS ((int *, int *));
extern void flow_preorder_transversal_compute PARAMS ((int *));
extern void dump_edge_info PARAMS ((FILE *, edge, int));
extern void clear_edges PARAMS ((void));
extern void mark_critical_edges PARAMS ((void));
extern rtx first_insn_after_basic_block_note PARAMS ((basic_block));
/* Dominator information for basic blocks. */
typedef struct dominance_info *dominance_info;
/* Structure to hold information for each natural loop. */
struct loop
{
/* Index into loops array. */
int num;
/* Basic block of loop header. */
basic_block header;
/* Basic block of loop latch. */
basic_block latch;
/* Basic block of loop pre-header or NULL if it does not exist. */
basic_block pre_header;
/* Array of edges along the pre-header extended basic block trace.
The source of the first edge is the root node of pre-header
extended basic block, if it exists. */
edge *pre_header_edges;
/* Number of edges along the pre_header extended basic block trace. */
int num_pre_header_edges;
/* The first block in the loop. This is not necessarily the same as
the loop header. */
basic_block first;
/* The last block in the loop. This is not necessarily the same as
the loop latch. */
basic_block last;
/* Bitmap of blocks contained within the loop. */
sbitmap nodes;
/* Number of blocks contained within the loop. */
int num_nodes;
/* Array of edges that enter the loop. */
edge *entry_edges;
/* Number of edges that enter the loop. */
int num_entries;
/* Array of edges that exit the loop. */
edge *exit_edges;
/* Number of edges that exit the loop. */
int num_exits;
/* Bitmap of blocks that dominate all exits of the loop. */
sbitmap exits_doms;
/* The loop nesting depth. */
int depth;
/* Superloops of the loop. */
struct loop **pred;
/* The height of the loop (enclosed loop levels) within the loop
hierarchy tree. */
int level;
/* The outer (parent) loop or NULL if outermost loop. */
struct loop *outer;
/* The first inner (child) loop or NULL if innermost loop. */
struct loop *inner;
/* Link to the next (sibling) loop. */
struct loop *next;
/* Nonzero if the loop is invalid (e.g., contains setjmp.). */
int invalid;
/* Auxiliary info specific to a pass. */
void *aux;
/* The following are currently used by loop.c but they are likely to
disappear as loop.c is converted to use the CFG. */
/* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
rtx vtop;
/* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
A continue statement will generate a branch to NEXT_INSN (cont). */
rtx cont;
/* The NOTE_INSN_LOOP_BEG. */
rtx start;
/* The NOTE_INSN_LOOP_END. */
rtx end;
/* For a rotated loop that is entered near the bottom,
this is the label at the top. Otherwise it is zero. */
rtx top;
/* Place in the loop where control enters. */
rtx scan_start;
/* The position where to sink insns out of the loop. */
rtx sink;
/* List of all LABEL_REFs which refer to code labels outside the
loop. Used by routines that need to know all loop exits, such as
final_biv_value and final_giv_value.
This does not include loop exits due to return instructions.
This is because all bivs and givs are pseudos, and hence must be
dead after a return, so the presense of a return does not affect
any of the optimizations that use this info. It is simpler to
just not include return instructions on this list. */
rtx exit_labels;
/* The number of LABEL_REFs on exit_labels for this loop and all
loops nested inside it. */
int exit_count;
};
/* Structure to hold CFG information about natural loops within a function. */
struct loops
{
/* Number of natural loops in the function. */
int num;
/* Maxium nested loop level in the function. */
int levels;
/* Array of natural loop descriptors (scanning this array in reverse order
will find the inner loops before their enclosing outer loops). */
struct loop *array;
/* The above array is unused in new loop infrastructure and is kept only for
purposes of the old loop optimizer. Instead we store just pointers to
loops here. */
struct loop **parray;
/* Pointer to root of loop heirachy tree. */
struct loop *tree_root;
/* Information derived from the CFG. */
struct cfg
{
/* The bitmap vector of dominators or NULL if not computed. */
dominance_info dom;
/* The ordering of the basic blocks in a depth first search. */
int *dfs_order;
/* The reverse completion ordering of the basic blocks found in a
depth first search. */
int *rc_order;
} cfg;
/* Headers shared by multiple loops that should be merged. */
sbitmap shared_headers;
};
extern void remove_fake_edges (void);
extern void add_noreturn_fake_exit_edges (void);
extern void connect_infinite_loops_to_exit (void);
extern int flow_call_edges_add (sbitmap);
extern edge unchecked_make_edge (basic_block, basic_block, int);
extern edge cached_make_edge (sbitmap *, basic_block, basic_block, int);
extern edge make_edge (basic_block, basic_block, int);
extern edge make_single_succ_edge (basic_block, basic_block, int);
extern void remove_edge (edge);
extern void redirect_edge_succ (edge, basic_block);
extern edge redirect_edge_succ_nodup (edge, basic_block);
extern void redirect_edge_pred (edge, basic_block);
extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
extern void clear_bb_flags (void);
extern void tidy_fallthru_edge (edge, basic_block, basic_block);
extern void tidy_fallthru_edges (void);
extern void flow_reverse_top_sort_order_compute (int *);
extern int flow_depth_first_order_compute (int *, int *);
extern void flow_preorder_transversal_compute (int *);
extern int dfs_enumerate_from (basic_block, int,
bool (*)(basic_block, void *),
basic_block *, int, void *);
extern void dump_edge_info (FILE *, edge, int);
extern void clear_edges (void);
extern void mark_critical_edges (void);
extern rtx first_insn_after_basic_block_note (basic_block);
/* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This
@ -553,19 +403,6 @@ typedef struct ce_if_block
} ce_if_block_t;
extern int flow_loops_find PARAMS ((struct loops *, int flags));
extern int flow_loops_update PARAMS ((struct loops *, int flags));
extern void flow_loops_free PARAMS ((struct loops *));
extern void flow_loops_dump PARAMS ((const struct loops *, FILE *,
void (*)(const struct loop *,
FILE *, int), int));
extern void flow_loop_dump PARAMS ((const struct loop *, FILE *,
void (*)(const struct loop *,
FILE *, int), int));
extern int flow_loop_scan PARAMS ((struct loops *, struct loop *, int));
extern void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
extern void flow_loop_tree_node_remove PARAMS ((struct loop *));
/* This structure maintains an edge list vector. */
struct edge_list
{
@ -610,12 +447,11 @@ struct edge_list
#define EDGE_CRITICAL_P(e) ((e)->src->succ->succ_next \
&& (e)->dest->pred->pred_next)
struct edge_list * create_edge_list PARAMS ((void));
void free_edge_list PARAMS ((struct edge_list *));
void print_edge_list PARAMS ((FILE *, struct edge_list *));
void verify_edge_list PARAMS ((FILE *, struct edge_list *));
int find_edge_index PARAMS ((struct edge_list *,
basic_block, basic_block));
struct edge_list * create_edge_list (void);
void free_edge_list (struct edge_list *);
void print_edge_list (FILE *, struct edge_list *);
void verify_edge_list (FILE *, struct edge_list *);
int find_edge_index (struct edge_list *, basic_block, basic_block);
enum update_life_extent
@ -637,13 +473,19 @@ enum update_life_extent
#define PROP_AUTOINC 64 /* Create autoinc mem references. */
#define PROP_EQUAL_NOTES 128 /* Take into account REG_EQUAL notes. */
#define PROP_SCAN_DEAD_STORES 256 /* Scan for dead code. */
#define PROP_ASM_SCAN 512 /* Internal flag used within flow.c
to flag analysis of asms. */
#define PROP_FINAL (PROP_DEATH_NOTES | PROP_LOG_LINKS \
| PROP_REG_INFO | PROP_KILL_DEAD_CODE \
| PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
| PROP_ALLOW_CFG_CHANGES \
| PROP_SCAN_DEAD_STORES)
#define PROP_POSTRELOAD (PROP_DEATH_NOTES \
| PROP_KILL_DEAD_CODE \
| PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
| PROP_SCAN_DEAD_STORES)
#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
except for edge forwarding */
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
@ -656,155 +498,115 @@ enum update_life_extent
#define CLEANUP_THREADING 64 /* Do jump threading. */
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
insns. */
/* Flags for loop discovery. */
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
#define LOOP_PRE_HEADER 2 /* Analyse loop pre-header. */
#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
#define LOOP_ALL 15 /* All of the above */
extern void life_analysis PARAMS ((rtx, FILE *, int));
extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
int));
extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
int));
#define CLEANUP_CFGLAYOUT 256 /* Do cleanup in cfglayout mode. */
#define CLEANUP_LOG_LINKS 512 /* Update log links. */
extern void life_analysis (rtx, FILE *, int);
extern int update_life_info (sbitmap, enum update_life_extent, int);
extern int update_life_info_in_dirty_blocks (enum update_life_extent, int);
extern int count_or_remove_death_notes (sbitmap, int);
extern int propagate_block (basic_block, regset, regset, regset, int);
struct propagate_block_info;
extern rtx propagate_one_insn PARAMS ((struct propagate_block_info *, rtx));
extern rtx propagate_one_insn (struct propagate_block_info *, rtx);
extern struct propagate_block_info *init_propagate_block_info
PARAMS ((basic_block, regset, regset, regset, int));
extern void free_propagate_block_info PARAMS ((struct propagate_block_info *));
(basic_block, regset, regset, regset, int);
extern void free_propagate_block_info (struct propagate_block_info *);
/* In lcm.c */
extern struct edge_list *pre_edge_lcm PARAMS ((FILE *, int, sbitmap *,
sbitmap *, sbitmap *,
sbitmap *, sbitmap **,
sbitmap **));
extern struct edge_list *pre_edge_rev_lcm PARAMS ((FILE *, int, sbitmap *,
sbitmap *, sbitmap *,
sbitmap *, sbitmap **,
sbitmap **));
extern void compute_available PARAMS ((sbitmap *, sbitmap *,
sbitmap *, sbitmap *));
extern int optimize_mode_switching PARAMS ((FILE *));
extern struct edge_list *pre_edge_lcm (FILE *, int, sbitmap *, sbitmap *,
sbitmap *, sbitmap *, sbitmap **,
sbitmap **);
extern struct edge_list *pre_edge_rev_lcm (FILE *, int, sbitmap *,
sbitmap *, sbitmap *,
sbitmap *, sbitmap **,
sbitmap **);
extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
extern int optimize_mode_switching (FILE *);
/* In emit-rtl.c. */
extern rtx emit_block_insn_after PARAMS ((rtx, rtx, basic_block));
extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
extern rtx emit_block_insn_after (rtx, rtx, basic_block);
extern rtx emit_block_insn_before (rtx, rtx, basic_block);
/* In predict.c */
extern void estimate_probability PARAMS ((struct loops *));
extern void note_prediction_to_br_prob PARAMS ((void));
extern void expected_value_to_br_prob PARAMS ((void));
extern void note_prediction_to_br_prob PARAMS ((void));
extern bool maybe_hot_bb_p PARAMS ((basic_block));
extern bool probably_cold_bb_p PARAMS ((basic_block));
extern bool probably_never_executed_bb_p PARAMS ((basic_block));
extern void estimate_probability (struct loops *);
extern void note_prediction_to_br_prob (void);
extern void expected_value_to_br_prob (void);
extern bool maybe_hot_bb_p (basic_block);
extern bool probably_cold_bb_p (basic_block);
extern bool probably_never_executed_bb_p (basic_block);
/* In flow.c */
extern void init_flow PARAMS ((void));
extern void reorder_basic_blocks PARAMS ((void));
extern void dump_bb PARAMS ((basic_block, FILE *));
extern void debug_bb PARAMS ((basic_block));
extern void debug_bb_n PARAMS ((int));
extern void dump_regset PARAMS ((regset, FILE *));
extern void debug_regset PARAMS ((regset));
extern void allocate_reg_life_data PARAMS ((void));
extern void allocate_bb_life_data PARAMS ((void));
extern void expunge_block PARAMS ((basic_block));
extern void link_block PARAMS ((basic_block, basic_block));
extern void unlink_block PARAMS ((basic_block));
extern void compact_blocks PARAMS ((void));
extern basic_block alloc_block PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void));
extern int delete_noop_moves PARAMS ((rtx));
extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
extern basic_block force_nonfallthru PARAMS ((edge));
extern bool redirect_edge_and_branch PARAMS ((edge, basic_block));
extern rtx block_label PARAMS ((basic_block));
extern bool forwarder_block_p PARAMS ((basic_block));
extern bool purge_all_dead_edges PARAMS ((int));
extern bool purge_dead_edges PARAMS ((basic_block));
extern void find_sub_basic_blocks PARAMS ((basic_block));
extern void find_many_sub_basic_blocks PARAMS ((sbitmap));
extern bool can_fallthru PARAMS ((basic_block, basic_block));
extern void flow_nodes_print PARAMS ((const char *, const sbitmap,
FILE *));
extern void flow_edge_list_print PARAMS ((const char *, const edge *,
int, FILE *));
extern void alloc_aux_for_block PARAMS ((basic_block, int));
extern void alloc_aux_for_blocks PARAMS ((int));
extern void clear_aux_for_blocks PARAMS ((void));
extern void free_aux_for_blocks PARAMS ((void));
extern void alloc_aux_for_edge PARAMS ((edge, int));
extern void alloc_aux_for_edges PARAMS ((int));
extern void clear_aux_for_edges PARAMS ((void));
extern void free_aux_for_edges PARAMS ((void));
extern void init_flow (void);
extern void dump_bb (basic_block, FILE *);
extern void debug_bb (basic_block);
extern basic_block debug_bb_n (int);
extern void dump_regset (regset, FILE *);
extern void debug_regset (regset);
extern void allocate_reg_life_data (void);
extern void allocate_bb_life_data (void);
extern void expunge_block (basic_block);
extern void link_block (basic_block, basic_block);
extern void unlink_block (basic_block);
extern void compact_blocks (void);
extern basic_block alloc_block (void);
extern void find_unreachable_blocks (void);
extern int delete_noop_moves (rtx);
extern basic_block force_nonfallthru (edge);
extern rtx block_label (basic_block);
extern bool forwarder_block_p (basic_block);
extern bool purge_all_dead_edges (int);
extern bool purge_dead_edges (basic_block);
extern void find_sub_basic_blocks (basic_block);
extern void find_many_sub_basic_blocks (sbitmap);
extern bool can_fallthru (basic_block, basic_block);
extern void flow_nodes_print (const char *, const sbitmap, FILE *);
extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
extern void alloc_aux_for_block (basic_block, int);
extern void alloc_aux_for_blocks (int);
extern void clear_aux_for_blocks (void);
extern void free_aux_for_blocks (void);
extern void alloc_aux_for_edge (edge, int);
extern void alloc_aux_for_edges (int);
extern void clear_aux_for_edges (void);
extern void free_aux_for_edges (void);
/* This function is always defined so it can be called from the
debugger, and it is declared extern so we don't get warnings about
it being unused. */
extern void verify_flow_info PARAMS ((void));
extern bool flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
extern bool flow_loop_nested_p PARAMS ((const struct loop *,
const struct loop *));
extern bool flow_bb_inside_loop_p PARAMS ((const struct loop *,
const basic_block));
extern basic_block *get_loop_body PARAMS ((const struct loop *));
extern int dfs_enumerate_from PARAMS ((basic_block, int,
bool (*)(basic_block, void *),
basic_block *, int, void *));
extern edge loop_preheader_edge PARAMS ((struct loop *));
extern edge loop_latch_edge PARAMS ((struct loop *));
extern void add_bb_to_loop PARAMS ((basic_block, struct loop *));
extern void remove_bb_from_loops PARAMS ((basic_block));
extern struct loop * find_common_loop PARAMS ((struct loop *, struct loop *));
extern void verify_loop_structure PARAMS ((struct loops *, int));
#define VLS_EXPECT_PREHEADERS 1
#define VLS_EXPECT_SIMPLE_LATCHES 2
extern void verify_flow_info (void);
typedef struct conflict_graph_def *conflict_graph;
/* Callback function when enumerating conflicts. The arguments are
the smaller and larger regno in the conflict. Returns zero if
enumeration is to continue, nonzero to halt enumeration. */
typedef int (*conflict_graph_enum_fn) PARAMS ((int, int, void *));
typedef int (*conflict_graph_enum_fn) (int, int, void *);
/* Prototypes of operations on conflict graphs. */
extern conflict_graph conflict_graph_new
PARAMS ((int));
extern void conflict_graph_delete PARAMS ((conflict_graph));
extern int conflict_graph_add PARAMS ((conflict_graph,
int, int));
extern int conflict_graph_conflict_p PARAMS ((conflict_graph,
int, int));
extern void conflict_graph_enum PARAMS ((conflict_graph, int,
conflict_graph_enum_fn,
void *));
extern void conflict_graph_merge_regs PARAMS ((conflict_graph, int,
int));
extern void conflict_graph_print PARAMS ((conflict_graph, FILE*));
extern conflict_graph conflict_graph_compute
PARAMS ((regset,
partition));
extern bool mark_dfs_back_edges PARAMS ((void));
extern void set_edge_can_fallthru_flag PARAMS ((void));
extern void update_br_prob_note PARAMS ((basic_block));
extern void fixup_abnormal_edges PARAMS ((void));
extern bool can_hoist_insn_p PARAMS ((rtx, rtx, regset));
extern rtx hoist_insn_after PARAMS ((rtx, rtx, rtx, rtx));
extern rtx hoist_insn_to_edge PARAMS ((rtx, edge, rtx, rtx));
extern bool control_flow_insn_p PARAMS ((rtx));
(int);
extern void conflict_graph_delete (conflict_graph);
extern int conflict_graph_add (conflict_graph, int, int);
extern int conflict_graph_conflict_p (conflict_graph, int, int);
extern void conflict_graph_enum (conflict_graph, int, conflict_graph_enum_fn,
void *);
extern void conflict_graph_merge_regs (conflict_graph, int, int);
extern void conflict_graph_print (conflict_graph, FILE*);
extern conflict_graph conflict_graph_compute (regset, partition);
extern bool mark_dfs_back_edges (void);
extern void set_edge_can_fallthru_flag (void);
extern void update_br_prob_note (basic_block);
extern void fixup_abnormal_edges (void);
extern bool can_hoist_insn_p (rtx, rtx, regset);
extern rtx hoist_insn_after (rtx, rtx, rtx, rtx);
extern rtx hoist_insn_to_edge (rtx, edge, rtx, rtx);
extern bool inside_basic_block_p (rtx);
extern bool control_flow_insn_p (rtx);
/* In bb-reorder.c */
extern void reorder_basic_blocks (unsigned int);
/* In dominance.c */
@ -814,21 +616,37 @@ enum cdi_direction
CDI_POST_DOMINATORS
};
extern dominance_info calculate_dominance_info PARAMS ((enum cdi_direction));
extern void free_dominance_info PARAMS ((dominance_info));
extern basic_block nearest_common_dominator PARAMS ((dominance_info,
basic_block, basic_block));
extern void set_immediate_dominator PARAMS ((dominance_info,
basic_block, basic_block));
extern basic_block get_immediate_dominator PARAMS ((dominance_info,
basic_block));
extern bool dominated_by_p PARAMS ((dominance_info, basic_block, basic_block));
extern int get_dominated_by PARAMS ((dominance_info, basic_block, basic_block **));
extern void add_to_dominance_info PARAMS ((dominance_info, basic_block));
extern void delete_from_dominance_info PARAMS ((dominance_info, basic_block));
basic_block recount_dominator PARAMS ((dominance_info, basic_block));
extern void redirect_immediate_dominators PARAMS ((dominance_info, basic_block,
basic_block));
void iterate_fix_dominators PARAMS ((dominance_info, basic_block *, int));
extern void verify_dominators PARAMS ((dominance_info));
enum dom_state
{
DOM_NONE, /* Not computed at all. */
DOM_CONS_OK, /* The data is conservatively OK, i.e. if it says you that A dominates B,
it indeed does. */
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
DOM_OK /* Everything is ok. */
};
extern enum dom_state dom_computed[2];
extern void calculate_dominance_info (enum cdi_direction);
extern void free_dominance_info (enum cdi_direction);
extern basic_block nearest_common_dominator (enum cdi_direction,
basic_block, basic_block);
extern void set_immediate_dominator (enum cdi_direction, basic_block,
basic_block);
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
extern bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **);
extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
basic_block recount_dominator (enum cdi_direction, basic_block);
extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
basic_block);
extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int);
extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block);
extern bool try_redirect_by_replacing_jump (edge, basic_block, bool);
#include "cfghooks.h"
#endif /* GCC_BASIC_BLOCK_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "flags.h"
#include "obstack.h"
@ -44,18 +46,16 @@ bitmap_element bitmap_zero_bits; /* An element of all zero bits. */
static bitmap_element *bitmap_free; /* Freelist of bitmap elements. */
static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
static void bitmap_elem_to_freelist PARAMS ((bitmap, bitmap_element *));
static void bitmap_element_free PARAMS ((bitmap, bitmap_element *));
static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
static int bitmap_element_zerop PARAMS ((bitmap_element *));
static void bitmap_element_link PARAMS ((bitmap, bitmap_element *));
static bitmap_element *bitmap_find_bit PARAMS ((bitmap, unsigned int));
static void bitmap_elem_to_freelist (bitmap, bitmap_element *);
static void bitmap_element_free (bitmap, bitmap_element *);
static bitmap_element *bitmap_element_allocate (bitmap);
static int bitmap_element_zerop (bitmap_element *);
static void bitmap_element_link (bitmap, bitmap_element *);
static bitmap_element *bitmap_find_bit (bitmap, unsigned int);
/* Add ELEM to the appropriate freelist. */
static INLINE void
bitmap_elem_to_freelist (head, elt)
bitmap head;
bitmap_element *elt;
bitmap_elem_to_freelist (bitmap head, bitmap_element *elt)
{
if (head->using_obstack)
{
@ -73,9 +73,7 @@ bitmap_elem_to_freelist (head, elt)
bitmap_obstack, "free" actually means "put onto the freelist". */
static INLINE void
bitmap_element_free (head, elt)
bitmap head;
bitmap_element *elt;
bitmap_element_free (bitmap head, bitmap_element *elt)
{
bitmap_element *next = elt->next;
bitmap_element *prev = elt->prev;
@ -103,8 +101,7 @@ bitmap_element_free (head, elt)
/* Allocate a bitmap element. The bits are cleared, but nothing else is. */
static INLINE bitmap_element *
bitmap_element_allocate (head)
bitmap head;
bitmap_element_allocate (bitmap head)
{
bitmap_element *element;
@ -123,31 +120,18 @@ bitmap_element_allocate (head)
if (!bitmap_obstack_init)
{
bitmap_obstack_init = TRUE;
/* Let particular systems override the size of a chunk. */
#ifndef OBSTACK_CHUNK_SIZE
#define OBSTACK_CHUNK_SIZE 0
#endif
/* Let them override the alloc and free routines too. */
#ifndef OBSTACK_CHUNK_ALLOC
#define OBSTACK_CHUNK_ALLOC xmalloc
#endif
#ifndef OBSTACK_CHUNK_FREE
#define OBSTACK_CHUNK_FREE free
#endif
#if !defined(__GNUC__) || (__GNUC__ < 2)
#define __alignof__(type) 0
#endif
obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (bitmap_element),
(void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
(void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
obstack_chunk_alloc,
obstack_chunk_free);
}
element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
sizeof (bitmap_element));
element = obstack_alloc (&bitmap_obstack, sizeof (bitmap_element));
}
}
else
@ -169,7 +153,7 @@ bitmap_element_allocate (head)
/* Release any memory allocated by bitmaps. */
void
bitmap_release_memory ()
bitmap_release_memory (void)
{
bitmap_free = 0;
if (bitmap_obstack_init)
@ -182,8 +166,7 @@ bitmap_release_memory ()
/* Return nonzero if all bits in an element are zero. */
static INLINE int
bitmap_element_zerop (element)
bitmap_element *element;
bitmap_element_zerop (bitmap_element *element)
{
#if BITMAP_ELEMENT_WORDS == 2
return (element->bits[0] | element->bits[1]) == 0;
@ -201,9 +184,7 @@ bitmap_element_zerop (element)
/* Link the bitmap element into the current bitmap linked list. */
static INLINE void
bitmap_element_link (head, element)
bitmap head;
bitmap_element *element;
bitmap_element_link (bitmap head, bitmap_element *element)
{
unsigned int indx = element->indx;
bitmap_element *ptr;
@ -258,8 +239,7 @@ bitmap_element_link (head, element)
/* Clear a bitmap by freeing the linked list. */
INLINE void
bitmap_clear (head)
bitmap head;
bitmap_clear (bitmap head)
{
bitmap_element *element, *next;
@ -275,9 +255,7 @@ bitmap_clear (head)
/* Copy a bitmap to another bitmap. */
void
bitmap_copy (to, from)
bitmap to;
bitmap from;
bitmap_copy (bitmap to, bitmap from)
{
bitmap_element *from_ptr, *to_ptr = 0;
#if BITMAP_ELEMENT_WORDS != 2
@ -286,7 +264,7 @@ bitmap_copy (to, from)
bitmap_clear (to);
/* Copy elements in forward direction one at a time */
/* Copy elements in forward direction one at a time. */
for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
{
bitmap_element *to_elt = bitmap_element_allocate (to);
@ -326,9 +304,7 @@ bitmap_copy (to, from)
faster. */
static INLINE bitmap_element *
bitmap_find_bit (head, bit)
bitmap head;
unsigned int bit;
bitmap_find_bit (bitmap head, unsigned int bit)
{
bitmap_element *element;
unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
@ -362,9 +338,7 @@ bitmap_find_bit (head, bit)
/* Clear a single bit in a bitmap. */
void
bitmap_clear_bit (head, bit)
bitmap head;
int bit;
bitmap_clear_bit (bitmap head, int bit)
{
bitmap_element *ptr = bitmap_find_bit (head, bit);
@ -374,7 +348,7 @@ bitmap_clear_bit (head, bit)
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
ptr->bits[word_num] &= ~ (((BITMAP_WORD) 1) << bit_num);
/* If we cleared the entire word, free up the element */
/* If we cleared the entire word, free up the element. */
if (bitmap_element_zerop (ptr))
bitmap_element_free (head, ptr);
}
@ -383,9 +357,7 @@ bitmap_clear_bit (head, bit)
/* Set a single bit in a bitmap. */
void
bitmap_set_bit (head, bit)
bitmap head;
int bit;
bitmap_set_bit (bitmap head, int bit)
{
bitmap_element *ptr = bitmap_find_bit (head, bit);
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
@ -406,9 +378,7 @@ bitmap_set_bit (head, bit)
/* Return whether a bit is set within a bitmap. */
int
bitmap_bit_p (head, bit)
bitmap head;
int bit;
bitmap_bit_p (bitmap head, int bit)
{
bitmap_element *ptr;
unsigned bit_num;
@ -428,8 +398,7 @@ bitmap_bit_p (head, bit)
if the bitmap is empty. */
int
bitmap_first_set_bit (a)
bitmap a;
bitmap_first_set_bit (bitmap a)
{
bitmap_element *ptr = a->first;
BITMAP_WORD word;
@ -481,8 +450,7 @@ bitmap_first_set_bit (a)
if the bitmap is empty. */
int
bitmap_last_set_bit (a)
bitmap a;
bitmap_last_set_bit (bitmap a)
{
bitmap_element *ptr = a->first;
BITMAP_WORD word;
@ -534,11 +502,8 @@ bitmap_last_set_bit (a)
a specific bit manipulation. Return true if TO changes. */
int
bitmap_operation (to, from1, from2, operation)
bitmap to;
bitmap from1;
bitmap from2;
enum bitmap_bits operation;
bitmap_operation (bitmap to, bitmap from1, bitmap from2,
enum bitmap_bits operation)
{
#define HIGHEST_INDEX (unsigned int) ~0
@ -697,14 +662,12 @@ bitmap_operation (to, from1, from2, operation)
/* Return true if two bitmaps are identical. */
int
bitmap_equal_p (a, b)
bitmap a;
bitmap b;
bitmap_equal_p (bitmap a, bitmap b)
{
bitmap_head c;
int ret;
memset (&c, 0, sizeof (c));
memset (&c, 0, sizeof (c));
ret = ! bitmap_operation (&c, a, b, BITMAP_XOR);
bitmap_clear (&c);
@ -715,10 +678,7 @@ bitmap_equal_p (a, b)
bitmap FROM2. */
void
bitmap_ior_and_compl (to, from1, from2)
bitmap to;
bitmap from1;
bitmap from2;
bitmap_ior_and_compl (bitmap to, bitmap from1, bitmap from2)
{
bitmap_head tmp;
@ -731,11 +691,7 @@ bitmap_ior_and_compl (to, from1, from2)
}
int
bitmap_union_of_diff (dst, a, b, c)
bitmap dst;
bitmap a;
bitmap b;
bitmap c;
bitmap_union_of_diff (bitmap dst, bitmap a, bitmap b, bitmap c)
{
bitmap_head tmp;
int changed;
@ -753,13 +709,11 @@ bitmap_union_of_diff (dst, a, b, c)
/* Initialize a bitmap header. */
bitmap
bitmap_initialize (head, using_obstack)
bitmap head;
int using_obstack;
bitmap_initialize (bitmap head, int using_obstack)
{
if (head == NULL && ! using_obstack)
head = ggc_alloc (sizeof (*head));
head->first = head->current = 0;
head->using_obstack = using_obstack;
@ -769,29 +723,21 @@ bitmap_initialize (head, using_obstack)
/* Debugging function to print out the contents of a bitmap. */
void
debug_bitmap_file (file, head)
FILE *file;
bitmap head;
debug_bitmap_file (FILE *file, bitmap head)
{
bitmap_element *ptr;
fprintf (file, "\nfirst = ");
fprintf (file, HOST_PTR_PRINTF, (PTR) head->first);
fprintf (file, " current = ");
fprintf (file, HOST_PTR_PRINTF, (PTR) head->current);
fprintf (file, " indx = %u\n", head->indx);
fprintf (file, "\nfirst = " HOST_PTR_PRINTF
" current = " HOST_PTR_PRINTF " indx = %u\n",
(void *) head->first, (void *) head->current, head->indx);
for (ptr = head->first; ptr; ptr = ptr->next)
{
unsigned int i, j, col = 26;
fprintf (file, "\t");
fprintf (file, HOST_PTR_PRINTF, (PTR) ptr);
fprintf (file, " next = ");
fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->next);
fprintf (file, " prev = ");
fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->prev);
fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
fprintf (file, "\t" HOST_PTR_PRINTF " next = " HOST_PTR_PRINTF
" prev = " HOST_PTR_PRINTF " indx = %u\n\t\tbits = {",
(void*) ptr, (void*) ptr->next, (void*) ptr->prev, ptr->indx);
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
for (j = 0; j < BITMAP_WORD_BITS; j++)
@ -816,8 +762,7 @@ debug_bitmap_file (file, head)
of a bitmap. */
void
debug_bitmap (head)
bitmap head;
debug_bitmap (bitmap head)
{
debug_bitmap_file (stdout, head);
}
@ -826,11 +771,7 @@ debug_bitmap (head)
it does not print anything but the bits. */
void
bitmap_print (file, head, prefix, suffix)
FILE *file;
bitmap head;
const char *prefix;
const char *suffix;
bitmap_print (FILE *file, bitmap head, const char *prefix, const char *suffix)
{
const char *comma = "";
int i;

View File

@ -79,57 +79,56 @@ enum bitmap_bits {
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
/* Clear a bitmap by freeing up the linked list. */
extern void bitmap_clear PARAMS ((bitmap));
extern void bitmap_clear (bitmap);
/* Copy a bitmap to another bitmap. */
extern void bitmap_copy PARAMS ((bitmap, bitmap));
extern void bitmap_copy (bitmap, bitmap);
/* True if two bitmaps are identical. */
extern int bitmap_equal_p PARAMS ((bitmap, bitmap));
extern int bitmap_equal_p (bitmap, bitmap);
/* Perform an operation on two bitmaps, yielding a third. */
extern int bitmap_operation PARAMS ((bitmap, bitmap, bitmap, enum bitmap_bits));
extern int bitmap_operation (bitmap, bitmap, bitmap, enum bitmap_bits);
/* `or' into one bitmap the `and' of a second bitmap witih the complement
of a third. */
extern void bitmap_ior_and_compl PARAMS ((bitmap, bitmap, bitmap));
extern void bitmap_ior_and_compl (bitmap, bitmap, bitmap);
/* Clear a single register in a register set. */
extern void bitmap_clear_bit PARAMS ((bitmap, int));
extern void bitmap_clear_bit (bitmap, int);
/* Set a single register in a register set. */
extern void bitmap_set_bit PARAMS ((bitmap, int));
extern void bitmap_set_bit (bitmap, int);
/* Return true if a register is set in a register set. */
extern int bitmap_bit_p PARAMS ((bitmap, int));
extern int bitmap_bit_p (bitmap, int);
/* Debug functions to print a bitmap linked list. */
extern void debug_bitmap PARAMS ((bitmap));
extern void debug_bitmap_file PARAMS ((FILE *, bitmap));
extern void debug_bitmap (bitmap);
extern void debug_bitmap_file (FILE *, bitmap);
/* Print a bitmap */
extern void bitmap_print PARAMS ((FILE *, bitmap, const char *, const char *));
/* Print a bitmap. */
extern void bitmap_print (FILE *, bitmap, const char *, const char *);
/* Initialize a bitmap header. If HEAD is NULL, a new header will be
allocated. USING_OBSTACK indicates how elements should be allocated. */
extern bitmap bitmap_initialize PARAMS ((bitmap head,
int using_obstack));
extern bitmap bitmap_initialize (bitmap head, int using_obstack);
/* Release all memory used by the bitmap obstack. */
extern void bitmap_release_memory PARAMS ((void));
extern void bitmap_release_memory (void);
/* A few compatibility/functions macros for compatibility with sbitmaps */
#define dump_bitmap(file, bitmap) bitmap_print (file, bitmap, "", "\n")
#define bitmap_zero(a) bitmap_clear (a)
#define bitmap_a_or_b(a,b,c) bitmap_operation (a, b, c, BITMAP_IOR)
#define bitmap_a_and_b(a,b,c) bitmap_operation (a, b, c, BITMAP_AND)
extern int bitmap_union_of_diff PARAMS((bitmap, bitmap, bitmap, bitmap));
extern int bitmap_first_set_bit PARAMS((bitmap));
extern int bitmap_last_set_bit PARAMS((bitmap));
extern int bitmap_union_of_diff (bitmap, bitmap, bitmap, bitmap);
extern int bitmap_first_set_bit (bitmap);
extern int bitmap_last_set_bit (bitmap);
/* Allocate a bitmap with oballoc. */
#define BITMAP_OBSTACK_ALLOC(OBSTACK) \
bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
bitmap_initialize (obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
/* Allocate a bitmap with ggc_alloc. */
#define BITMAP_GGC_ALLOC() \
@ -137,7 +136,7 @@ extern int bitmap_last_set_bit PARAMS((bitmap));
/* Allocate a bitmap with xmalloc. */
#define BITMAP_XMALLOC() \
bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)), 1)
bitmap_initialize (xmalloc (sizeof (bitmap_head)), 1)
/* Do any cleanup needed on a bitmap when it is no longer used. */
#define BITMAP_FREE(BITMAP) \
@ -249,7 +248,7 @@ do { \
ptr2_ = ptr2_->next; \
\
tmp2_ = ((ptr2_ != 0 && ptr2_->indx == ptr1_->indx) \
? ptr2_ : &bitmap_zero_bits); \
? ptr2_ : &bitmap_zero_bits); \
\
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
{ \
@ -306,7 +305,7 @@ do { \
\
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
{ \
/* Advance BITMAP2 to the equivalent link */ \
/* Advance BITMAP2 to the equivalent link. */ \
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
ptr2_ = ptr2_->next; \
\

1377
contrib/gcc/bt-load.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -41,23 +41,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
DEF_ATTR_TREE_LIST (ENUM, PURPOSE, VALUE, CHAIN)
Constructs a TREE_LIST with given PURPOSE, VALUE and CHAIN (given
as previous ENUM names).
DEF_FN_ATTR (NAME, ATTRS, PREDICATE)
Specifies that the function with name NAME (a previous ENUM for an
IDENTIFIER_NODE) has attributes ATTRS (a previous ENUM) if
PREDICATE is true. */
as previous ENUM names). */
DEF_ATTR_NULL_TREE (ATTR_NULL)
/* Note that below we must avoid whitespace in arguments of CONCAT*. */
/* Construct a tree for a given integer and a list containing it. */
#define DEF_ATTR_FOR_INT(VALUE) \
DEF_ATTR_INT (CONCAT2 (ATTR_,VALUE), VALUE) \
DEF_ATTR_TREE_LIST (CONCAT2 (ATTR_LIST_,VALUE), ATTR_NULL, \
CONCAT2 (ATTR_,VALUE), ATTR_NULL)
DEF_ATTR_INT (ATTR_##VALUE, VALUE) \
DEF_ATTR_TREE_LIST (ATTR_LIST_##VALUE, ATTR_NULL, \
ATTR_##VALUE, ATTR_NULL)
DEF_ATTR_FOR_INT (0)
DEF_ATTR_FOR_INT (1)
DEF_ATTR_FOR_INT (2)
@ -67,8 +59,8 @@ DEF_ATTR_FOR_INT (4)
/* Construct a tree for a list of two integers. */
#define DEF_LIST_INT_INT(VALUE1, VALUE2) \
DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_LIST_,VALUE1,_,VALUE2), ATTR_NULL, \
CONCAT2 (ATTR_,VALUE1), CONCAT2 (ATTR_LIST_,VALUE2))
DEF_ATTR_TREE_LIST (ATTR_LIST_##VALUE1##_##VALUE2, ATTR_NULL, \
ATTR_##VALUE1, ATTR_LIST_##VALUE2)
DEF_LIST_INT_INT (1,0)
DEF_LIST_INT_INT (1,2)
DEF_LIST_INT_INT (2,0)
@ -86,6 +78,10 @@ DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
DEF_ATTR_IDENT (ATTR_PRINTF, "printf")
DEF_ATTR_IDENT (ATTR_ASM_FPRINTF, "asm_fprintf")
DEF_ATTR_IDENT (ATTR_GCC_DIAG, "gcc_diag")
DEF_ATTR_IDENT (ATTR_GCC_CDIAG, "gcc_cdiag")
DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag")
DEF_ATTR_IDENT (ATTR_PURE, "pure")
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
@ -102,19 +98,37 @@ DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
ATTR_NOTHROW_LIST)
/* Nothrow functions whose first and second parameters are nonnull pointers. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_2, ATTR_NONNULL, ATTR_LIST_2, \
ATTR_NOTHROW_NONNULL_1)
/* Nothrow functions whose first and fourth parameters are nonnull pointers. */
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_4, ATTR_NONNULL, ATTR_LIST_4, \
ATTR_NOTHROW_NONNULL_1)
/* Nothrow const functions whose first parameter is a nonnull pointer. */
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL_1, ATTR_CONST, ATTR_NULL, \
ATTR_NOTHROW_NONNULL_1)
/* Nothrow pure functions whose first parameter is a nonnull pointer. */
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1, ATTR_PURE, ATTR_NULL, \
ATTR_NOTHROW_NONNULL_1)
/* Nothrow pure functions whose first and second parameters are nonnull pointers. */
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1_2, ATTR_PURE, ATTR_NULL, \
ATTR_NOTHROW_NONNULL_1_2)
/* Nothrow malloc functions whose first parameter is a nonnull pointer. */
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_NONNULL_1, ATTR_MALLOC, ATTR_NULL, \
ATTR_NOTHROW_NONNULL_1)
/* Construct a tree for a format attribute. */
#define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL, \
CONCAT2 (ATTR_,TYPE), CONCAT2 (ATTR_LIST_,VALUES)) \
DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_FORMAT_,TYPE,_,VALUES), ATTR_FORMAT, \
CONCAT4 (ATTR_,TYPE,_,VALUES), CONCAT2 (ATTR_NONNULL_,FA))
DEF_ATTR_TREE_LIST (ATTR_##TYPE##_##VALUES, ATTR_NULL, \
ATTR_##TYPE, ATTR_LIST_##VALUES) \
DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_##VALUES, ATTR_FORMAT, \
ATTR_##TYPE##_##VALUES, ATTR_NOTHROW_NONNULL_##FA)
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_2)
DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_0)
@ -131,49 +145,9 @@ DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
/* Construct a tree for a format_arg attribute. */
#define DEF_FORMAT_ARG_ATTRIBUTE(FA) \
DEF_ATTR_TREE_LIST (CONCAT2 (ATTR_FORMAT_ARG_,FA), ATTR_FORMAT_ARG, \
CONCAT2 (ATTR_LIST_,FA), CONCAT2 (ATTR_NONNULL_,FA))
DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_##FA, ATTR_FORMAT_ARG, \
ATTR_LIST_##FA, ATTR_NOTHROW_NONNULL_##FA)
DEF_FORMAT_ARG_ATTRIBUTE(1)
DEF_FORMAT_ARG_ATTRIBUTE(2)
#undef DEF_FORMAT_ARG_ATTRIBUTE
/* Define an attribute for a function, along with the IDENTIFIER_NODE. */
#define DEF_FN_ATTR_IDENT(NAME, ATTRS, PREDICATE) \
DEF_ATTR_IDENT (CONCAT2(ATTR_,NAME), STRINGX(NAME)) \
DEF_FN_ATTR (CONCAT2(ATTR_,NAME), ATTRS, PREDICATE)
/* The ISO C functions are always checked (whether <stdio.h> is
included or not), since it is common to call printf without
including <stdio.h>. There shouldn't be a problem with this,
since ISO C reserves these function names whether you include the
header file or not. In any case, the checking is harmless. With
-ffreestanding, these default attributes are disabled, and must be
specified manually if desired. */
/* Functions from ISO/IEC 9899:1990. */
#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3)
DEF_C89_ATTR (vfprintf, ATTR_FORMAT_PRINTF_2_0)
DEF_C89_ATTR (strftime, ATTR_FORMAT_STRFTIME_3_0)
#undef DEF_C89_ATTR
/* ISO C99 adds the snprintf and vscanf family functions. */
#define DEF_C99_ATTR(NAME, ATTRS) \
DEF_FN_ATTR_IDENT (NAME, ATTRS, \
(flag_hosted \
&& (flag_isoc99 || flag_noniso_default_format_attributes)))
DEF_C99_ATTR (vfscanf, ATTR_FORMAT_SCANF_2_0)
#undef DEF_C99_ATTR
/* Functions not in any version of ISO C. */
#define DEF_EXT_ATTR(NAME, ATTRS) \
DEF_FN_ATTR_IDENT (NAME, ATTRS, \
flag_hosted && flag_noniso_default_format_attributes)
/* Uniforum/GNU gettext functions. */
DEF_EXT_ATTR (gettext, ATTR_FORMAT_ARG_1)
DEF_EXT_ATTR (dgettext, ATTR_FORMAT_ARG_2)
DEF_EXT_ATTR (dcgettext, ATTR_FORMAT_ARG_2)
/* X/Open strfmon function. */
DEF_EXT_ATTR (strfmon, ATTR_FORMAT_STRFMON_3_4)
#undef DEF_EXT_ATTR
#undef DEF_FN_ATTR_IDENT

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -64,18 +64,24 @@ DEF_PRIMITIVE_TYPE (BT_INT, integer_type_node)
DEF_PRIMITIVE_TYPE (BT_UNSIGNED, unsigned_type_node)
DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node)
DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 0))
DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
DEF_PRIMITIVE_TYPE (BT_LONG_DOUBLE, long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONG_DOUBLE, complex_long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_CONST_PTR, const_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
DEF_PRIMITIVE_TYPE (BT_INT_PTR, integer_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_FLOAT_PTR, float_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_DOUBLE_PTR, double_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE_PTR, long_double_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_SIZE, size_type_node)
DEF_PRIMITIVE_TYPE (BT_SSIZE, signed_size_type_node)
DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
@ -87,31 +93,45 @@ DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED)
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
DEF_FUNCTION_TYPE_0 (BT_FN_LONG_DOUBLE, BT_LONG_DOUBLE)
/* For "long double" we use LONGDOUBLE (not LONG_DOUBLE) to
distinguish it from two types in sequence, "long" followed by
"double". */
DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_INTMAX_INTMAX, BT_INTMAX, BT_INTMAX)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_FLOAT, BT_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_LONG_DOUBLE,
BT_LONG_DOUBLE, BT_LONG_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
BT_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
BT_COMPLEX_LONG_DOUBLE, BT_COMPLEX_LONG_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_COMPLEX_FLOAT,
BT_FLOAT, BT_COMPLEX_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_COMPLEX_DOUBLE,
BT_DOUBLE, BT_COMPLEX_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
BT_LONG_DOUBLE, BT_COMPLEX_LONG_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE,
BT_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_UNSIGNED, BT_PTR, BT_UNSIGNED)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_SIZE, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONG, BT_INT, BT_LONG)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGLONG, BT_INT, BT_LONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_FLOAT, BT_INT, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_DOUBLE, BT_INT, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_FLOAT, BT_LONG, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE, BT_LONG, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONGDOUBLE, BT_LONG, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_FLOAT, BT_LONGLONG, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_DOUBLE, BT_LONGLONG, BT_DOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGDOUBLE, BT_LONGLONG, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTR, BT_VOID, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_SIZE_CONST_STRING, BT_SIZE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_CONST_STRING, BT_INT, BT_CONST_STRING)
@ -120,8 +140,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VALIST_REF, BT_VOID, BT_VALIST_REF)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_CONST_STRING,
BT_LONG_DOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
BT_LONGDOUBLE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,
@ -148,8 +170,56 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_PTR_CONST_STRING,
BT_INT, BT_PTR, BT_CONST_STRING)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_SIZE,
BT_VOID, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOAT,
BT_FLOAT, BT_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE,
BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOATPTR,
BT_FLOAT, BT_FLOAT, BT_FLOAT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
BT_DOUBLE, BT_DOUBLE, BT_DOUBLE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_LONGDOUBLE,
BT_FLOAT, BT_FLOAT, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_LONGDOUBLE,
BT_DOUBLE, BT_DOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_INT,
BT_FLOAT, BT_FLOAT, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_INT,
BT_DOUBLE, BT_DOUBLE, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_INT,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_INTPTR,
BT_FLOAT, BT_FLOAT, BT_INT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_INTPTR,
BT_DOUBLE, BT_DOUBLE, BT_INT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_INT_FLOAT,
BT_FLOAT, BT_INT, BT_FLOAT)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_INT_DOUBLE,
BT_DOUBLE, BT_INT, BT_DOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_INT_LONGDOUBLE,
BT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_LONG,
BT_FLOAT, BT_FLOAT, BT_LONG)
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_LONG,
BT_DOUBLE, BT_DOUBLE, BT_LONG)
DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONG,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONG)
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_VALIST_ARG,
BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_2 (BT_FN_PTR_SIZE_SIZE,
BT_PTR, BT_SIZE, BT_SIZE)
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT,
BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
@ -163,15 +233,41 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE,
BT_PTR, BT_PTR, BT_INT, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT,
BT_VOID, BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_PTR_SIZE,
BT_VOID, BT_CONST_PTR, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTR_CONST_STRING_VALIST_ARG,
BT_INT, BT_PTR, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
BT_STRING, BT_CONST_STRING, BT_CONST_STRING, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_FLOAT,
BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE,
BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_INT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR,
BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR,
BT_VOID, BT_FLOAT, BT_FLOAT_PTR, BT_FLOAT_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
BT_VOID, BT_DOUBLE, BT_DOUBLE_PTR, BT_DOUBLE_PTR)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR,
BT_VOID, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR, BT_LONGDOUBLE_PTR)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR)
DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR,
BT_SIZE, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_CONST_PTR)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
@ -193,6 +289,8 @@ DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR,
BT_SSIZE, BT_STRING, BT_SIZE, BT_CONST_STRING)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
on information stored in GCC's tree structure. This code implements the
-aux-info option.
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
1999, 2000 Free Software Foundation, Inc.
1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@segfault.us.com).
This file is part of GCC.
@ -24,10 +24,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "toplev.h"
#include "coretypes.h"
#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "c-tree.h"
#include "toplev.h"
enum formals_style_enum {
ansi,
@ -39,12 +41,12 @@ typedef enum formals_style_enum formals_style;
static const char *data_type;
static char *affix_data_type PARAMS ((const char *)) ATTRIBUTE_MALLOC;
static const char *gen_formal_list_for_type PARAMS ((tree, formals_style));
static int deserves_ellipsis PARAMS ((tree));
static const char *gen_formal_list_for_func_def PARAMS ((tree, formals_style));
static const char *gen_type PARAMS ((const char *, tree, formals_style));
static const char *gen_decl PARAMS ((tree, int, formals_style));
static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
static const char *gen_formal_list_for_type (tree, formals_style);
static int deserves_ellipsis (tree);
static const char *gen_formal_list_for_func_def (tree, formals_style);
static const char *gen_type (const char *, tree, formals_style);
static const char *gen_decl (tree, int, formals_style);
/* Given a string representing an entire type or an entire declaration
which only lacks the actual "data-type" specifier (at its left end),
@ -61,8 +63,7 @@ static const char *gen_decl PARAMS ((tree, int, formals_style));
that look as expected. */
static char *
affix_data_type (param)
const char *param;
affix_data_type (const char *param)
{
char *const type_or_decl = ASTRDUP (param);
char *p = type_or_decl;
@ -108,9 +109,7 @@ affix_data_type (param)
of empty parens here. */
static const char *
gen_formal_list_for_type (fntype, style)
tree fntype;
formals_style style;
gen_formal_list_for_type (tree fntype, formals_style style)
{
const char *formal_list = "";
tree formal_type;
@ -192,8 +191,7 @@ gen_formal_list_for_type (fntype, style)
if the "function type" parameter list should end with an ellipsis. */
static int
deserves_ellipsis (fntype)
tree fntype;
deserves_ellipsis (tree fntype)
{
tree formal_type;
@ -228,9 +226,7 @@ deserves_ellipsis (fntype)
function formal parameter list. */
static const char *
gen_formal_list_for_func_def (fndecl, style)
tree fndecl;
formals_style style;
gen_formal_list_for_func_def (tree fndecl, formals_style style)
{
const char *formal_list = "";
tree formal_decl;
@ -303,10 +299,7 @@ gen_formal_list_for_func_def (fndecl, style)
string onto the returned "seed". */
static const char *
gen_type (ret_val, t, style)
const char *ret_val;
tree t;
formals_style style;
gen_type (const char *ret_val, tree t, formals_style style)
{
tree chain_p;
@ -432,13 +425,13 @@ gen_type (ret_val, t, style)
case TYPE_DECL:
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
break;
case INTEGER_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
/* Normally, `unsigned' is part of the deal. Not so if it comes
with a type qualifier. */
with a type qualifier. */
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
data_type = concat ("unsigned ", data_type, NULL);
data_type = concat ("unsigned ", data_type, NULL);
break;
case REAL_TYPE:
@ -477,10 +470,7 @@ gen_type (ret_val, t, style)
an attached list of DECL nodes for function formal arguments is present. */
static const char *
gen_decl (decl, is_func_definition, style)
tree decl;
int is_func_definition;
formals_style style;
gen_decl (tree decl, int is_func_definition, formals_style style)
{
const char *ret_val;
@ -558,11 +548,8 @@ extern FILE *aux_info_file;
function definition (even the implicit ones). */
void
gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped)
tree fndecl;
int is_definition;
int is_implicit;
int is_prototyped;
gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
int is_prototyped)
{
if (flag_gen_aux_info)
{

View File

@ -25,9 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Tree nodes relevant to both C and C++. These were originally in
cp-tree.def in the cp subdir. */
/* A node to remember a source position. */
DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)

View File

@ -1,5 +1,6 @@
/* Language-level data type conversion for GNU C.
Copyright (C) 1987, 1988, 1991, 1998, 2002 Free Software Foundation, Inc.
Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@ -26,6 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "convert.h"
@ -60,8 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
not permitted by the language being compiled. */
tree
convert (type, expr)
tree type, expr;
convert (tree type, tree expr)
{
tree e = expr;
enum tree_code code = TREE_CODE (type);

591
contrib/gcc/c-cppbuiltin.c Normal file
View File

@ -0,0 +1,591 @@
/* Define builtin-in macros for the C family front ends.
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "real.h"
#include "c-common.h"
#include "c-pragma.h"
#include "output.h"
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
#include "toplev.h"
#include "tm_p.h" /* Target prototypes. */
#ifndef TARGET_OS_CPP_BUILTINS
# define TARGET_OS_CPP_BUILTINS()
#endif
#ifndef TARGET_OBJFMT_CPP_BUILTINS
# define TARGET_OBJFMT_CPP_BUILTINS()
#endif
#ifndef REGISTER_PREFIX
#define REGISTER_PREFIX ""
#endif
/* Non-static as some targets don't use it. */
void builtin_define_std (const char *) ATTRIBUTE_UNUSED;
static void builtin_define_with_value_n (const char *, const char *,
size_t);
static void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
static void builtin_define_with_hex_fp_value (const char *, tree,
int, const char *,
const char *);
static void builtin_define_type_max (const char *, tree, int);
static void builtin_define_type_precision (const char *, tree);
static void builtin_define_float_constants (const char *, const char *,
tree);
static void define__GNUC__ (void);
/* Define NAME with value TYPE precision. */
static void
builtin_define_type_precision (const char *name, tree type)
{
builtin_define_with_int_value (name, TYPE_PRECISION (type));
}
/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX. */
static void
builtin_define_float_constants (const char *name_prefix, const char *fp_suffix, tree type)
{
/* Used to convert radix-based values to base 10 values in several cases.
In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
least 6 significant digits for correct results. Using the fraction
formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
intermediate; perhaps someone can find a better approximation, in the
mean time, I suspect using doubles won't harm the bootstrap here. */
const double log10_2 = .30102999566398119521;
double log10_b;
const struct real_format *fmt;
char name[64], buf[128];
int dig, min_10_exp, max_10_exp;
int decimal_dig;
fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
/* The radix of the exponent representation. */
if (type == float_type_node)
builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
log10_b = log10_2 * fmt->log2_b;
/* The number of radix digits, p, in the floating-point significand. */
sprintf (name, "__%s_MANT_DIG__", name_prefix);
builtin_define_with_int_value (name, fmt->p);
/* The number of decimal digits, q, such that any floating-point number
with q decimal digits can be rounded into a floating-point number with
p radix b digits and back again without change to the q decimal digits,
p log10 b if b is a power of 10
floor((p - 1) log10 b) otherwise
*/
dig = (fmt->p - 1) * log10_b;
sprintf (name, "__%s_DIG__", name_prefix);
builtin_define_with_int_value (name, dig);
/* The minimum negative int x such that b**(x-1) is a normalized float. */
sprintf (name, "__%s_MIN_EXP__", name_prefix);
sprintf (buf, "(%d)", fmt->emin);
builtin_define_with_value (name, buf, 0);
/* The minimum negative int x such that 10**x is a normalized float,
ceil (log10 (b ** (emin - 1)))
= ceil (log10 (b) * (emin - 1))
Recall that emin is negative, so the integer truncation calculates
the ceiling, not the floor, in this case. */
min_10_exp = (fmt->emin - 1) * log10_b;
sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
sprintf (buf, "(%d)", min_10_exp);
builtin_define_with_value (name, buf, 0);
/* The maximum int x such that b**(x-1) is a representable float. */
sprintf (name, "__%s_MAX_EXP__", name_prefix);
builtin_define_with_int_value (name, fmt->emax);
/* The maximum int x such that 10**x is in the range of representable
finite floating-point numbers,
floor (log10((1 - b**-p) * b**emax))
= floor (log10(1 - b**-p) + log10(b**emax))
= floor (log10(1 - b**-p) + log10(b)*emax)
The safest thing to do here is to just compute this number. But since
we don't link cc1 with libm, we cannot. We could implement log10 here
a series expansion, but that seems too much effort because:
Note that the first term, for all extant p, is a number exceedingly close
to zero, but slightly negative. Note that the second term is an integer
scaling an irrational number, and that because of the floor we are only
interested in its integral portion.
In order for the first term to have any effect on the integral portion
of the second term, the second term has to be exceedingly close to an
integer itself (e.g. 123.000000000001 or something). Getting a result
that close to an integer requires that the irrational multiplicand have
a long series of zeros in its expansion, which doesn't occur in the
first 20 digits or so of log10(b).
Hand-waving aside, crunching all of the sets of constants above by hand
does not yield a case for which the first term is significant, which
in the end is all that matters. */
max_10_exp = fmt->emax * log10_b;
sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
builtin_define_with_int_value (name, max_10_exp);
/* The number of decimal digits, n, such that any floating-point number
can be rounded to n decimal digits and back again without change to
the value.
p * log10(b) if b is a power of 10
ceil(1 + p * log10(b)) otherwise
The only macro we care about is this number for the widest supported
floating type, but we want this value for rendering constants below. */
{
double d_decimal_dig = 1 + fmt->p * log10_b;
decimal_dig = d_decimal_dig;
if (decimal_dig < d_decimal_dig)
decimal_dig++;
}
if (type == long_double_type_node)
builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
/* Since, for the supported formats, B is always a power of 2, we
construct the following numbers directly as a hexadecimal
constants. */
/* The maximum representable finite floating-point number,
(1 - b**-p) * b**emax */
{
int i, n;
char *p;
strcpy (buf, "0x0.");
n = fmt->p * fmt->log2_b;
for (i = 0, p = buf + 4; i + 3 < n; i += 4)
*p++ = 'f';
if (i < n)
*p++ = "08ce"[n - i];
sprintf (p, "p%d", fmt->emax * fmt->log2_b);
if (fmt->pnan < fmt->p)
{
/* This is an IBM extended double format made up of two IEEE
doubles. The value of the long double is the sum of the
values of the two parts. The most significant part is
required to be the value of the long double rounded to the
nearest double. Rounding means we need a slightly smaller
value for LDBL_MAX. */
buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4];
}
}
sprintf (name, "__%s_MAX__", name_prefix);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* The minimum normalized positive floating-point number,
b**(emin-1). */
sprintf (name, "__%s_MIN__", name_prefix);
sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* The difference between 1 and the least value greater than 1 that is
representable in the given floating point type, b**(1-p). */
sprintf (name, "__%s_EPSILON__", name_prefix);
sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
/* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
positive floating-point number, b**(emin-p). Zero for formats that
don't support denormals. */
sprintf (name, "__%s_DENORM_MIN__", name_prefix);
if (fmt->has_denorm)
{
sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
builtin_define_with_hex_fp_value (name, type, decimal_dig,
buf, fp_suffix);
}
else
{
sprintf (buf, "0.0%s", fp_suffix);
builtin_define_with_value (name, buf, 0);
}
/* For C++ std::numeric_limits<T>::has_infinity. */
sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
builtin_define_with_int_value (name,
MODE_HAS_INFINITIES (TYPE_MODE (type)));
/* For C++ std::numeric_limits<T>::has_quiet_NaN. We do not have a
predicate to distinguish a target that has both quiet and
signalling NaNs from a target that has only quiet NaNs or only
signalling NaNs, so we assume that a target that has any kind of
NaN has quiet NaNs. */
sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
}
/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
static void
define__GNUC__ (void)
{
/* The format of the version string, enforced below, is
([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
const char *q, *v = version_string;
while (*v && ! ISDIGIT (*v))
v++;
if (!*v || (v > version_string && v[-1] != '-'))
abort ();
q = v;
while (ISDIGIT (*v))
v++;
builtin_define_with_value_n ("__GNUC__", q, v - q);
if (c_dialect_cxx ())
builtin_define_with_value_n ("__GNUG__", q, v - q);
if (*v != '.' || !ISDIGIT (v[1]))
abort ();
q = ++v;
while (ISDIGIT (*v))
v++;
builtin_define_with_value_n ("__GNUC_MINOR__", q, v - q);
if (*v == '.')
{
if (!ISDIGIT (v[1]))
abort ();
q = ++v;
while (ISDIGIT (*v))
v++;
builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", q, v - q);
}
else
builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", "0", 1);
if (*v && *v != ' ' && *v != '-')
abort ();
}
/* Hook that registers front end and target-specific built-ins. */
void
c_cpp_builtins (cpp_reader *pfile)
{
/* -undef turns off target-specific built-ins. */
if (flag_undef)
return;
define__GNUC__ ();
/* For stddef.h. They require macros defined in c-common.c. */
c_stddef_cpp_builtins ();
if (c_dialect_cxx ())
{
if (SUPPORTS_ONE_ONLY)
cpp_define (pfile, "__GXX_WEAK__=1");
else
cpp_define (pfile, "__GXX_WEAK__=0");
if (warn_deprecated)
cpp_define (pfile, "__DEPRECATED");
}
/* Note that we define this for C as well, so that we know if
__attribute__((cleanup)) will interface with EH. */
if (flag_exceptions)
cpp_define (pfile, "__EXCEPTIONS");
/* Represents the C++ ABI version, always defined so it can be used while
preprocessing C and assembler. */
if (flag_abi_version == 0)
/* Use a very large value so that:
#if __GXX_ABI_VERSION >= <value for version X>
will work whether the user explicitly says "-fabi-version=x" or
"-fabi-version=0". Do not use INT_MAX because that will be
different from system to system. */
builtin_define_with_int_value ("__GXX_ABI_VERSION", 999999);
else if (flag_abi_version == 1)
/* Due to an historical accident, this version had the value
"102". */
builtin_define_with_int_value ("__GXX_ABI_VERSION", 102);
else
/* Newer versions have values 1002, 1003, .... */
builtin_define_with_int_value ("__GXX_ABI_VERSION",
1000 + flag_abi_version);
/* libgcc needs to know this. */
if (USING_SJLJ_EXCEPTIONS)
cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__");
/* limits.h needs to know these. */
builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node, 0);
builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node, 0);
builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
/* float.h needs to know these. */
builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
TARGET_FLT_EVAL_METHOD);
builtin_define_float_constants ("FLT", "F", float_type_node);
builtin_define_float_constants ("DBL", "", double_type_node);
builtin_define_float_constants ("LDBL", "L", long_double_type_node);
/* For use in assembly language. */
builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
/* Misc. */
builtin_define_with_value ("__VERSION__", version_string, 1);
/* Definitions for LP64 model. */
if (TYPE_PRECISION (long_integer_type_node) == 64
&& POINTER_SIZE == 64
&& TYPE_PRECISION (integer_type_node) == 32)
{
cpp_define (pfile, "_LP64");
cpp_define (pfile, "__LP64__");
}
/* Other target-independent built-ins determined by command-line
options. */
if (optimize_size)
cpp_define (pfile, "__OPTIMIZE_SIZE__");
if (optimize)
cpp_define (pfile, "__OPTIMIZE__");
if (fast_math_flags_set_p ())
cpp_define (pfile, "__FAST_MATH__");
if (flag_really_no_inline)
cpp_define (pfile, "__NO_INLINE__");
if (flag_signaling_nans)
cpp_define (pfile, "__SUPPORT_SNAN__");
if (flag_finite_math_only)
cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
else
cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
if (flag_iso)
cpp_define (pfile, "__STRICT_ANSI__");
if (!flag_signed_char)
cpp_define (pfile, "__CHAR_UNSIGNED__");
if (c_dialect_cxx () && TREE_UNSIGNED (wchar_type_node))
cpp_define (pfile, "__WCHAR_UNSIGNED__");
/* Make the choice of ObjC runtime visible to source code. */
if (c_dialect_objc () && flag_next_runtime)
cpp_define (pfile, "__NEXT_RUNTIME__");
/* A straightforward target hook doesn't work, because of problems
linking that hook's body when part of non-C front ends. */
# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
# define builtin_define(TXT) cpp_define (pfile, TXT)
# define builtin_assert(TXT) cpp_assert (pfile, TXT)
TARGET_CPU_CPP_BUILTINS ();
TARGET_OS_CPP_BUILTINS ();
TARGET_OBJFMT_CPP_BUILTINS ();
}
/* Pass an object-like macro. If it doesn't lie in the user's
namespace, defines it unconditionally. Otherwise define a version
with two leading underscores, and another version with two leading
and trailing underscores, and define the original only if an ISO
standard was not nominated.
e.g. passing "unix" defines "__unix", "__unix__" and possibly
"unix". Passing "_mips" defines "__mips", "__mips__" and possibly
"_mips". */
void
builtin_define_std (const char *macro)
{
size_t len = strlen (macro);
char *buff = alloca (len + 5);
char *p = buff + 2;
char *q = p + len;
/* prepend __ (or maybe just _) if in user's namespace. */
memcpy (p, macro, len + 1);
if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1]))))
{
if (*p != '_')
*--p = '_';
if (p[1] != '_')
*--p = '_';
}
cpp_define (parse_in, p);
/* If it was in user's namespace... */
if (p != buff + 2)
{
/* Define the macro with leading and following __. */
if (q[-1] != '_')
*q++ = '_';
if (q[-2] != '_')
*q++ = '_';
*q = '\0';
cpp_define (parse_in, p);
/* Finally, define the original macro if permitted. */
if (!flag_iso)
cpp_define (parse_in, macro);
}
}
/* Pass an object-like macro and a value to define it to. The third
parameter says whether or not to turn the value into a string
constant. */
void
builtin_define_with_value (const char *macro, const char *expansion, int is_str)
{
char *buf;
size_t mlen = strlen (macro);
size_t elen = strlen (expansion);
size_t extra = 2; /* space for an = and a NUL */
if (is_str)
extra += 2; /* space for two quote marks */
buf = alloca (mlen + elen + extra);
if (is_str)
sprintf (buf, "%s=\"%s\"", macro, expansion);
else
sprintf (buf, "%s=%s", macro, expansion);
cpp_define (parse_in, buf);
}
/* Pass an object-like macro and a value to define it to. The third
parameter is the length of the expansion. */
static void
builtin_define_with_value_n (const char *macro, const char *expansion, size_t elen)
{
char *buf;
size_t mlen = strlen (macro);
/* Space for an = and a NUL. */
buf = alloca (mlen + elen + 2);
memcpy (buf, macro, mlen);
buf[mlen] = '=';
memcpy (buf + mlen + 1, expansion, elen);
buf[mlen + elen + 1] = '\0';
cpp_define (parse_in, buf);
}
/* Pass an object-like macro and an integer value to define it to. */
static void
builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
{
char *buf;
size_t mlen = strlen (macro);
size_t vlen = 18;
size_t extra = 2; /* space for = and NUL. */
buf = alloca (mlen + vlen + extra);
memcpy (buf, macro, mlen);
buf[mlen] = '=';
sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
cpp_define (parse_in, buf);
}
/* Pass an object-like macro a hexadecimal floating-point value. */
static void
builtin_define_with_hex_fp_value (const char *macro,
tree type ATTRIBUTE_UNUSED, int digits,
const char *hex_str, const char *fp_suffix)
{
REAL_VALUE_TYPE real;
char dec_str[64], buf[256];
/* Hex values are really cool and convenient, except that they're
not supported in strict ISO C90 mode. First, the "p-" sequence
is not valid as part of a preprocessor number. Second, we get a
pedwarn from the preprocessor, which has no context, so we can't
suppress the warning with __extension__.
So instead what we do is construct the number in hex (because
it's easy to get the exact correct value), parse it as a real,
then print it back out as decimal. */
real_from_string (&real, hex_str);
real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
cpp_define (parse_in, buf);
}
/* Define MAX for TYPE based on the precision of the type. IS_LONG is
1 for type "long" and 2 for "long long". We have to handle
unsigned types, since wchar_t might be unsigned. */
static void
builtin_define_type_max (const char *macro, tree type, int is_long)
{
static const char *const values[]
= { "127", "255",
"32767", "65535",
"2147483647", "4294967295",
"9223372036854775807", "18446744073709551615",
"170141183460469231731687303715884105727",
"340282366920938463463374607431768211455" };
static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
const char *value, *suffix;
char *buf;
size_t idx;
/* Pre-rendering the values mean we don't have to futz with printing a
multi-word decimal value. There are also a very limited number of
precisions that we support, so it's really a waste of time. */
switch (TYPE_PRECISION (type))
{
case 8: idx = 0; break;
case 16: idx = 2; break;
case 32: idx = 4; break;
case 64: idx = 6; break;
case 128: idx = 8; break;
default: abort ();
}
value = values[idx + TREE_UNSIGNED (type)];
suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
sprintf (buf, "%s=%s%s", macro, value, suffix);
cpp_define (parse_in, buf);
}

View File

@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "tree-dump.h"
@ -28,9 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Dump information common to statements from STMT. */
void
dump_stmt (di, t)
dump_info_p di;
tree t;
dump_stmt (dump_info_p di, tree t)
{
dump_int (di, "line", STMT_LINENO (t));
}
@ -38,19 +38,15 @@ dump_stmt (di, t)
/* Dump the next statement after STMT. */
void
dump_next_stmt (di, t)
dump_info_p di;
tree t;
dump_next_stmt (dump_info_p di, tree t)
{
dump_child ("next", TREE_CHAIN (t));
}
/* Dump any C-specific tree codes and attributes of common codes. */
int
c_dump_tree (dump_info, t)
void *dump_info;
tree t;
bool
c_dump_tree (void *dump_info, tree t)
{
enum tree_code code;
dump_info_p di = (dump_info_p) dump_info;
@ -192,5 +188,5 @@ c_dump_tree (dump_info, t)
break;
}
return 0;
return false;
}

View File

@ -1,5 +1,5 @@
/* Various diagnostic subroutines for the GNU C language.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "tm_p.h"
@ -30,14 +32,32 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Issue an ISO C99 pedantic warning MSGID. */
void
pedwarn_c99 VPARAMS ((const char *msgid, ...))
pedwarn_c99 (const char *msgid, ...)
{
diagnostic_info diagnostic;
VA_OPEN (ap, msgid);
VA_FIXEDARG (ap, const char *, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
va_list ap;
va_start (ap, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
report_diagnostic (&diagnostic);
VA_CLOSE (ap);
va_end (ap);
}
/* Issue an ISO C90 pedantic warning MSGID. This function is supposed to
be used for matters that are allowed in ISO C99 but not supported in
ISO C90, thus we explicitly don't pedwarn when C99 is specified.
(There is no flag_c90.) */
void
pedwarn_c90 (const char *msgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
va_start (ap, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
report_diagnostic (&diagnostic);
va_end (ap);
}

364
contrib/gcc/c-incpath.c Normal file
View File

@ -0,0 +1,364 @@
/* Set up combined include path chain for the preprocessor.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "cpplib.h"
#include "prefix.h"
#include "intl.h"
#include "c-incpath.h"
#include "cppdefault.h"
/* Windows does not natively support inodes, and neither does MSDOS.
Cygwin's emulation can generate non-unique inodes, so don't use it.
VMS has non-numeric inodes. */
#ifdef VMS
# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
#else
# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
# define INO_T_EQ(A, B) 0
# else
# define INO_T_EQ(A, B) ((A) == (B))
# endif
# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
#endif
static void add_env_var_paths (const char *, int);
static void add_standard_paths (const char *, const char *, int);
static void free_path (struct cpp_dir *, int);
static void merge_include_chains (cpp_reader *, int);
static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
struct cpp_dir *,
struct cpp_dir *, int);
/* Include chains heads and tails. */
static struct cpp_dir *heads[4];
static struct cpp_dir *tails[4];
static bool quote_ignores_source_dir;
enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
/* Free an element of the include chain, possibly giving a reason. */
static void
free_path (struct cpp_dir *path, int reason)
{
switch (reason)
{
case REASON_DUP:
case REASON_DUP_SYS:
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
if (reason == REASON_DUP_SYS)
fprintf (stderr,
_(" as it is a non-system directory that duplicates a system directory\n"));
break;
case REASON_NOENT:
fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
path->name);
break;
case REASON_QUIET:
default:
break;
}
free (path->name);
free (path);
}
/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
append all the names to the search path CHAIN. */
static void
add_env_var_paths (const char *env_var, int chain)
{
char *p, *q, *path;
GET_ENVIRONMENT (q, env_var);
if (!q)
return;
for (p = q; *q; p = q + 1)
{
q = p;
while (*q != 0 && *q != PATH_SEPARATOR)
q++;
if (p == q)
path = xstrdup (".");
else
{
path = xmalloc (q - p + 1);
memcpy (path, p, q - p);
path[q - p] = '\0';
}
add_path (path, chain, chain == SYSTEM);
}
}
/* Append the standard include chain defined in cppdefault.c. */
static void
add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
{
const struct default_include *p;
size_t len;
if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
{
/* Look for directories that start with the standard prefix.
"Translate" them, ie. replace /usr/local/lib/gcc... with
IPREFIX and search them first. */
for (p = cpp_include_defaults; p->fname; p++)
{
if (!p->cplusplus || cxx_stdinc)
{
/* Should we be translating sysrooted dirs too? Assume
that iprefix and sysroot are mutually exclusive, for
now. */
if (sysroot && p->add_sysroot)
continue;
if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
{
char *str = concat (iprefix, p->fname + len, NULL);
add_path (str, SYSTEM, p->cxx_aware);
}
}
}
}
for (p = cpp_include_defaults; p->fname; p++)
{
if (!p->cplusplus || cxx_stdinc)
{
char *str;
/* Should this directory start with the sysroot? */
if (sysroot && p->add_sysroot)
str = concat (sysroot, p->fname, NULL);
else
str = update_path (p->fname, p->component);
add_path (str, SYSTEM, p->cxx_aware);
}
}
}
/* For each duplicate path in chain HEAD, keep just the first one.
Remove each path in chain HEAD that also exists in chain SYSTEM.
Set the NEXT pointer of the last path in the resulting chain to
JOIN, unless it duplicates JOIN in which case the last path is
removed. Return the head of the resulting chain. Any of HEAD,
JOIN and SYSTEM can be NULL. */
static struct cpp_dir *
remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
struct cpp_dir *system, struct cpp_dir *join,
int verbose)
{
struct cpp_dir **pcur, *tmp, *cur;
struct stat st;
for (pcur = &head; *pcur; )
{
int reason = REASON_QUIET;
cur = *pcur;
if (stat (cur->name, &st))
{
/* Dirs that don't exist are silently ignored, unless verbose. */
if (errno != ENOENT)
cpp_errno (pfile, CPP_DL_ERROR, cur->name);
else
reason = REASON_NOENT;
}
else if (!S_ISDIR (st.st_mode))
cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
"%s: not a directory", cur->name);
else
{
INO_T_COPY (cur->ino, st.st_ino);
cur->dev = st.st_dev;
/* Remove this one if it is in the system chain. */
reason = REASON_DUP_SYS;
for (tmp = system; tmp; tmp = tmp->next)
if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
break;
if (!tmp)
{
/* Duplicate of something earlier in the same chain? */
reason = REASON_DUP;
for (tmp = head; tmp != cur; tmp = tmp->next)
if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
break;
if (tmp == cur
/* Last in the chain and duplicate of JOIN? */
&& !(cur->next == NULL && join
&& INO_T_EQ (cur->ino, join->ino)
&& cur->dev == join->dev))
{
/* Unique, so keep this directory. */
pcur = &cur->next;
continue;
}
}
}
/* Remove this entry from the chain. */
*pcur = cur->next;
free_path (cur, verbose ? reason: REASON_QUIET);
}
*pcur = join;
return head;
}
/* Merge the four include chains together in the order quote, bracket,
system, after. Remove duplicate dirs (as determined by
INO_T_EQ()).
We can't just merge the lists and then uniquify them because then
we may lose directories from the <> search path that should be
there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe
to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
-Iquux. */
static void
merge_include_chains (cpp_reader *pfile, int verbose)
{
/* Join the SYSTEM and AFTER chains. Remove duplicates in the
resulting SYSTEM chain. */
if (heads[SYSTEM])
tails[SYSTEM]->next = heads[AFTER];
else
heads[SYSTEM] = heads[AFTER];
heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
/* Remove duplicates from BRACKET that are in itself or SYSTEM, and
join it to SYSTEM. */
heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
heads[SYSTEM], verbose);
/* Remove duplicates from QUOTE that are in itself or SYSTEM, and
join it to BRACKET. */
heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
heads[BRACKET], verbose);
/* If verbose, print the list of dirs to search. */
if (verbose)
{
struct cpp_dir *p;
fprintf (stderr, _("#include \"...\" search starts here:\n"));
for (p = heads[QUOTE];; p = p->next)
{
if (p == heads[BRACKET])
fprintf (stderr, _("#include <...> search starts here:\n"));
if (!p)
break;
fprintf (stderr, " %s\n", p->name);
}
fprintf (stderr, _("End of search list.\n"));
}
}
/* Use given -I paths for #include "..." but not #include <...>, and
don't search the directory of the present file for #include "...".
(Note that -I. -I- is not the same as the default setup; -I. uses
the compiler's working dir.) */
void
split_quote_chain (void)
{
heads[QUOTE] = heads[BRACKET];
tails[QUOTE] = tails[BRACKET];
heads[BRACKET] = NULL;
tails[BRACKET] = NULL;
/* This is NOT redundant. */
quote_ignores_source_dir = true;
}
/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
NUL-terminated. */
void
add_path (char *path, int chain, int cxx_aware)
{
struct cpp_dir *p;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Convert all backslashes to slashes. The native CRT stat()
function does not recognise a directory that ends in a backslash
(unless it is a drive root dir, such "c:\"). Forward slashes,
trailing or otherwise, cause no problems for stat(). */
char* c;
for (c = path; *c; c++)
if (*c == '\\') *c = '/';
#endif
p = xmalloc (sizeof (struct cpp_dir));
p->next = NULL;
p->name = path;
if (chain == SYSTEM || chain == AFTER)
p->sysp = 1 + !cxx_aware;
else
p->sysp = 0;
if (tails[chain])
tails[chain]->next = p;
else
heads[chain] = p;
tails[chain] = p;
}
/* Exported function to handle include chain merging, duplicate
removal, and registration with cpplib. */
void
register_include_chains (cpp_reader *pfile, const char *sysroot,
const char *iprefix, int stdinc, int cxx_stdinc,
int verbose)
{
static const char *const lang_env_vars[] =
{ "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
"OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
cpp_options *cpp_opts = cpp_get_options (pfile);
size_t idx = (cpp_opts->objc ? 2: 0);
if (cpp_opts->cplusplus)
idx++;
else
cxx_stdinc = false;
/* CPATH and language-dependent environment variables may add to the
include chain. */
add_env_var_paths ("CPATH", BRACKET);
add_env_var_paths (lang_env_vars[idx], SYSTEM);
/* Finally chain on the standard directories. */
if (stdinc)
add_standard_paths (sysroot, iprefix, cxx_stdinc);
merge_include_chains (pfile, verbose);
cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
quote_ignores_source_dir);
}

23
contrib/gcc/c-incpath.h Normal file
View File

@ -0,0 +1,23 @@
/* Set up combined include path for the preprocessor.
Copyright (C) 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern void split_quote_chain (void);
extern void add_path (char *, int, int);
extern void register_include_chains (cpp_reader *, const char *,
const char *, int, int, int);
enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };

View File

@ -1,6 +1,6 @@
/* Language-specific hook definitions for C front end.
Copyright (C) 1991, 1995, 1997, 1998,
1999, 2000, 2001 Free Software Foundation, Inc.
1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -22,14 +22,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "c-common.h"
#include "ggc.h"
#include "langhooks.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "c-pretty-print.h"
static void c_init_options PARAMS ((void));
static void c_initialize_diagnostics (diagnostic_context *);
enum c_language_kind c_language = clk_c;
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
@ -40,9 +46,13 @@ static void c_init_options PARAMS ((void));
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
#define LANG_HOOKS_INIT_OPTIONS c_init_options
#undef LANG_HOOKS_DECODE_OPTION
#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS c_initialize_diagnostics
#undef LANG_HOOKS_HANDLE_OPTION
#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
#undef LANG_HOOKS_MISSING_ARGUMENT
#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
@ -57,14 +67,16 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
#undef LANG_HOOKS_STATICP
#define LANG_HOOKS_STATICP c_staticp
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
#undef LANG_HOOKS_NO_BODY_BLOCKS
#define LANG_HOOKS_NO_BODY_BLOCKS true
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
#undef LANG_HOOKS_PRINT_IDENTIFIER
@ -75,6 +87,11 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
#undef LANG_HOOKS_DECL_UNINIT
#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_RTL_EXPAND_STMT
#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
@ -94,9 +111,14 @@ static void c_init_options PARAMS ((void));
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
#undef LANG_HOOKS_TYPE_FOR_MODE
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
#undef LANG_HOOKS_TYPE_FOR_SIZE
@ -111,6 +133,11 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
@ -152,69 +179,23 @@ const char *const tree_code_name[] = {
};
#undef DEFTREECODE
static void
c_init_options ()
{
c_common_init_options (clk_c);
}
/* Used by c-lex.c, but only for objc. */
tree
lookup_interface (arg)
tree arg ATTRIBUTE_UNUSED;
{
return 0;
}
tree
is_class_name (arg)
tree arg ATTRIBUTE_UNUSED;
{
return 0;
}
tree
objc_is_id (arg)
tree arg ATTRIBUTE_UNUSED;
{
return 0;
}
void
objc_check_decl (decl)
tree decl ATTRIBUTE_UNUSED;
{
}
int
objc_comptypes (lhs, rhs, reflexive)
tree lhs ATTRIBUTE_UNUSED;
tree rhs ATTRIBUTE_UNUSED;
int reflexive ATTRIBUTE_UNUSED;
{
return -1;
}
tree
objc_message_selector ()
{
return 0;
}
/* Used by c-typeck.c (build_external_ref), but only for objc. */
tree
lookup_objc_ivar (id)
tree id ATTRIBUTE_UNUSED;
{
return 0;
}
void
finish_file ()
finish_file (void)
{
c_objc_common_finish_file ();
}
static void
c_initialize_diagnostics (diagnostic_context *context)
{
pretty_printer *base = context->printer;
c_pretty_printer *pp = xmalloc (sizeof (c_pretty_printer));
memcpy (pp_base (pp), base, sizeof (pretty_printer));
pp_c_pretty_printer_init (pp);
context->printer = (pretty_printer *) pp;
/* It is safe to free this object because it was previously malloc()'d. */
free (base);
}
#include "gtype-c.h"

View File

@ -1,5 +1,5 @@
/* Some code common to C and ObjC front ends.
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "insn-config.h"
@ -35,18 +37,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "langhooks.h"
#include "target.h"
#include "cgraph.h"
static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
static void expand_deferred_fns PARAMS ((void));
static tree start_cdtor PARAMS ((int));
static void finish_cdtor PARAMS ((tree));
static GTY(()) varray_type deferred_fns;
static bool c_tree_printer (pretty_printer *, text_info *);
static tree start_cdtor (int);
static void finish_cdtor (tree);
int
c_missing_noreturn_ok_p (decl)
tree decl;
c_missing_noreturn_ok_p (tree decl)
{
/* A missing noreturn is not ok for freestanding implementations and
ok for the `main' function in hosted implementations. */
@ -58,124 +56,51 @@ c_missing_noreturn_ok_p (decl)
such functions always being inlined when optimizing. */
int
c_disregard_inline_limits (fn)
tree fn;
c_disregard_inline_limits (tree fn)
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
}
static tree
inline_forbidden_p (nodep, walk_subtrees, fn)
tree *nodep;
int *walk_subtrees ATTRIBUTE_UNUSED;
void *fn;
{
tree node = *nodep;
tree t;
switch (TREE_CODE (node))
{
case CALL_EXPR:
t = get_callee_fndecl (node);
if (! t)
break;
/* We cannot inline functions that call setjmp. */
if (setjmp_call_p (t))
return node;
switch (DECL_FUNCTION_CODE (t))
{
/* We cannot inline functions that take a variable number of
arguments. */
case BUILT_IN_VA_START:
case BUILT_IN_STDARG_START:
case BUILT_IN_NEXT_ARG:
case BUILT_IN_VA_END:
#if 0
/* Functions that need information about the address of the
caller can't (shouldn't?) be inlined. */
case BUILT_IN_RETURN_ADDRESS:
#endif
return node;
default:
break;
}
break;
case DECL_STMT:
/* We cannot inline functions that contain other functions. */
if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
&& DECL_INITIAL (TREE_OPERAND (node, 0)))
return node;
break;
case GOTO_STMT:
case GOTO_EXPR:
t = TREE_OPERAND (node, 0);
/* We will not inline a function which uses computed goto. The
addresses of its local labels, which may be tucked into
global storage, are of course not constant across
instantiations, which causes unexpected behavior. */
if (TREE_CODE (t) != LABEL_DECL)
return node;
/* We cannot inline a nested function that jumps to a nonlocal
label. */
if (TREE_CODE (t) == LABEL_DECL
&& DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
return node;
break;
case RECORD_TYPE:
case UNION_TYPE:
/* We cannot inline a function of the form
void F (int i) { struct S { int ar[i]; } s; }
Attempting to do so produces a catch-22 in tree-inline.c.
If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
UNION_TYPE nodes, then it goes into infinite recursion on a
structure containing a pointer to its own type. If it doesn't,
then the type node for S doesn't get adjusted properly when
F is inlined, and we abort in find_function_data. */
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
if (variably_modified_type_p (TREE_TYPE (t)))
return node;
default:
break;
}
return NULL_TREE;
return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn)
&& DECL_EXTERNAL (fn));
}
int
c_cannot_inline_tree_fn (fnp)
tree *fnp;
c_cannot_inline_tree_fn (tree *fnp)
{
tree fn = *fnp;
tree t;
bool do_warning = (warn_inline
&& DECL_INLINE (fn)
&& DECL_DECLARED_INLINE_P (fn)
&& !DECL_IN_SYSTEM_HEADER (fn));
if (flag_really_no_inline
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
{
if (do_warning)
warning ("%Jfunction '%F' can never be inlined because it "
"is suppressed using -fno-inline", fn, fn);
goto cannot_inline;
}
/* Don't auto-inline anything that might not be bound within
/* Don't auto-inline anything that might not be bound within
this unit of translation. */
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
goto cannot_inline;
{
if (do_warning)
warning ("%Jfunction '%F' can never be inlined because it might not "
"be bound within this unit of translation", fn, fn);
goto cannot_inline;
}
if (! function_attribute_inlinable_p (fn))
goto cannot_inline;
{
if (do_warning)
warning ("%Jfunction '%F' can never be inlined because it uses "
"attributes conflicting with inlining", fn, fn);
goto cannot_inline;
}
/* If a function has pending sizes, we must not defer its
compilation, and we can't inline it as a tree. */
@ -185,39 +110,26 @@ c_cannot_inline_tree_fn (fnp)
put_pending_sizes (t);
if (t)
goto cannot_inline;
{
if (do_warning)
warning ("%Jfunction '%F' can never be inlined because it has "
"pending sizes", fn, fn);
goto cannot_inline;
}
}
if (DECL_CONTEXT (fn))
if (! DECL_FILE_SCOPE_P (fn))
{
/* If a nested function has pending sizes, we may have already
saved them. */
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
goto cannot_inline;
{
if (do_warning)
warning ("%Jnested function '%F' can never be inlined because it "
"has possibly saved pending sizes", fn, fn);
goto cannot_inline;
}
}
else
{
/* We rely on the fact that this function is called upfront,
just before we start expanding a function. If FN is active
(i.e., it's the current_function_decl or a parent thereof),
we have to walk FN's saved tree. Otherwise, we can safely
assume we have done it before and, if we didn't mark it as
uninlinable (in which case we wouldn't have been called), it
is inlinable. Unfortunately, this strategy doesn't work for
nested functions, because they're only expanded as part of
their enclosing functions, so the inlinability test comes in
late. */
t = current_function_decl;
while (t && t != fn)
t = DECL_CONTEXT (t);
if (! t)
return 0;
}
if (walk_tree_without_duplicates
(&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
goto cannot_inline;
return 0;
@ -229,8 +141,7 @@ c_cannot_inline_tree_fn (fnp)
/* Called from check_global_declarations. */
bool
c_warn_unused_global_decl (decl)
tree decl;
c_warn_unused_global_decl (tree decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
@ -241,15 +152,19 @@ c_warn_unused_global_decl (decl)
}
/* Initialization common to C and Objective-C front ends. */
const char *
c_objc_common_init (filename)
const char *filename;
bool
c_objc_common_init (void)
{
static const enum tree_code stmt_codes[] = {
c_common_stmt_codes
};
INIT_STATEMENT_CODES (stmt_codes);
c_init_decl_processing ();
filename = c_common_init (filename);
if (filename == NULL)
return NULL;
if (c_common_init () == false)
return false;
lang_expand_decl_stmt = c_expand_decl_stmt;
@ -269,50 +184,11 @@ c_objc_common_init (filename)
mesg_implicit_function_declaration = 0;
}
VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
return filename;
}
/* Register a function tree, so that its optimization and conversion
to RTL is only done at the end of the compilation. */
int
defer_fn (fn)
tree fn;
{
VARRAY_PUSH_TREE (deferred_fns, fn);
return 1;
}
/* Expand deferred functions for C and ObjC. */
static void
expand_deferred_fns ()
{
unsigned int i;
for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
{
tree decl = VARRAY_TREE (deferred_fns, i);
if (! TREE_ASM_WRITTEN (decl))
{
/* For static inline functions, delay the decision whether to
emit them or not until wrapup_global_declarations. */
if (! TREE_PUBLIC (decl))
DECL_DEFER_OUTPUT (decl) = 1;
c_expand_deferred_function (decl);
}
}
deferred_fns = 0;
return true;
}
static tree
start_cdtor (method_type)
int method_type;
start_cdtor (int method_type)
{
tree fnname = get_file_function_name (method_type);
tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
@ -338,8 +214,7 @@ start_cdtor (method_type)
}
static void
finish_cdtor (body)
tree body;
finish_cdtor (tree body)
{
tree scope;
tree block;
@ -351,15 +226,23 @@ finish_cdtor (body)
RECHAIN_STMTS (body, COMPOUND_BODY (body));
finish_function (0, 0);
finish_function ();
}
/* Called at end of parsing, but before end-of-file processing. */
void
c_objc_common_finish_file ()
c_objc_common_finish_file (void)
{
expand_deferred_fns ();
if (pch_file)
c_common_write_pch ();
/* If multiple translation units were built, copy information between
them based on linkage rules. */
merge_translation_unit_decls ();
cgraph_finalize_compilation_unit ();
cgraph_optimize ();
if (static_ctors)
{
@ -399,6 +282,7 @@ c_objc_common_finish_file ()
source-level entity onto BUFFER. The meaning of the format specifiers
is as follows:
%D: a general decl,
%E: An expression,
%F: a function declaration,
%T: a type.
@ -407,28 +291,44 @@ c_objc_common_finish_file ()
Please notice when called, the `%' part was already skipped by the
diagnostic machinery. */
static bool
c_tree_printer (buffer, text)
output_buffer *buffer;
text_info *text;
c_tree_printer (pretty_printer *pp, text_info *text)
{
tree t = va_arg (*text->args_ptr, tree);
const char *n = "({anonymous})";
switch (*text->format_spec)
{
case 'D':
case 'F':
if (DECL_NAME (t))
n = (*lang_hooks.decl_printable_name) (t, 2);
break;
case 'T':
{
const char *n = DECL_NAME (t)
? (*lang_hooks.decl_printable_name) (t, 2)
: "({anonymous})";
output_add_string (buffer, n);
}
return true;
if (TREE_CODE (t) == TYPE_DECL)
{
if (DECL_NAME (t))
n = (*lang_hooks.decl_printable_name) (t, 2);
}
else
{
t = TYPE_NAME (t);
if (t)
n = IDENTIFIER_POINTER (t);
}
break;
case 'E':
if (TREE_CODE (t) == IDENTIFIER_NODE)
n = IDENTIFIER_POINTER (t);
else
return false;
break;
default:
return false;
}
}
#include "gt-c-objc-common.h"
pp_string (pp, n);
return true;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

433
contrib/gcc/c-pch.c Normal file
View File

@ -0,0 +1,433 @@
/* Precompiled header implementation for the C languages.
Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "version.h"
#include "cpplib.h"
#include "tree.h"
#include "flags.h"
#include "c-common.h"
#include "output.h"
#include "toplev.h"
#include "debug.h"
#include "c-pragma.h"
#include "ggc.h"
#include "langhooks.h"
#include "hosthooks.h"
#include "target.h"
/* This structure is read very early when validating the PCH, and
might be read for a PCH which is for a completely different compiler
for a different operating system. Thus, it should really only contain
'unsigned char' entries, at least in the initial entries.
If you add or change entries before version_length, you should increase
the version number in get_ident().
There are a bunch of fields named *_length; those are lengths of data that
follows this structure in the same order as the fields in the structure.
The flags_info field is used to verify that certain flags settings that
have to be the same during the compilation of the PCH and a compilation
using the PCH are indeed the same. */
struct c_pch_validity
{
unsigned char host_machine_length;
unsigned char target_machine_length;
unsigned char version_length;
unsigned char debug_info_type;
unsigned int flags_info;
void (*pch_init) (void);
size_t target_data_length;
};
/* If -funit-at-a-time is set, we require that it was also set during the
compilation of the PCH we may be using. */
#define FLAG_UNIT_AT_A_TIME_SET 1 << 0
struct c_pch_header
{
unsigned long asm_size;
};
#define IDENT_LENGTH 8
/* The file we'll be writing the PCH to. */
static FILE *pch_outfile;
/* The position in the assembler output file when pch_init was called. */
static long asm_file_startpos;
/* The host and target machines. */
static const char host_machine[] = HOST_MACHINE;
static const char target_machine[] = TARGET_MACHINE;
static const char *get_ident (void);
/* Compute an appropriate 8-byte magic number for the PCH file, so that
utilities like file(1) can identify it, and so that GCC can quickly
ignore non-PCH files and PCH files that are of a completely different
format. */
static const char *
get_ident(void)
{
static char result[IDENT_LENGTH];
static const char template[IDENT_LENGTH] = "gpch.012";
static const char c_language_chars[] = "Co+O";
memcpy (result, template, IDENT_LENGTH);
result[4] = c_language_chars[c_language];
return result;
}
/* Prepare to write a PCH file. This is called at the start of
compilation. */
void
pch_init (void)
{
FILE *f;
struct c_pch_validity v;
void *target_validity;
static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
unsigned int current_flags_info = 0;
if (! pch_file)
return;
if (flag_unit_at_a_time)
current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
f = fopen (pch_file, "w+b");
if (f == NULL)
fatal_error ("can't create precompiled header %s: %m", pch_file);
pch_outfile = f;
if (strlen (host_machine) > 255 || strlen (target_machine) > 255
|| strlen (version_string) > 255)
abort ();
v.host_machine_length = strlen (host_machine);
v.target_machine_length = strlen (target_machine);
v.version_length = strlen (version_string);
v.debug_info_type = write_symbols;
v.flags_info = current_flags_info;
v.pch_init = &pch_init;
target_validity = targetm.get_pch_validity (&v.target_data_length);
if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
|| fwrite (&v, sizeof (v), 1, f) != 1
|| fwrite (host_machine, v.host_machine_length, 1, f) != 1
|| fwrite (target_machine, v.target_machine_length, 1, f) != 1
|| fwrite (version_string, v.version_length, 1, f) != 1
|| fwrite (target_validity, v.target_data_length, 1, f) != 1)
fatal_error ("can't write to %s: %m", pch_file);
/* We need to be able to re-read the output. */
/* The driver always provides a valid -o option. */
if (asm_file_name == NULL
|| strcmp (asm_file_name, "-") == 0)
fatal_error ("`%s' is not a valid output file", asm_file_name);
asm_file_startpos = ftell (asm_out_file);
/* Let the debugging format deal with the PCHness. */
(*debug_hooks->handle_pch) (0);
cpp_save_state (parse_in, f);
}
/* Write the PCH file. This is called at the end of a compilation which
will produce a PCH file. */
void
c_common_write_pch (void)
{
char *buf;
long asm_file_end;
long written;
struct c_pch_header h;
(*debug_hooks->handle_pch) (1);
cpp_write_pch_deps (parse_in, pch_outfile);
asm_file_end = ftell (asm_out_file);
h.asm_size = asm_file_end - asm_file_startpos;
if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
fatal_error ("can't write %s: %m", pch_file);
buf = xmalloc (16384);
fflush (asm_out_file);
if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
fatal_error ("can't seek in %s: %m", asm_file_name);
for (written = asm_file_startpos; written < asm_file_end; )
{
long size = asm_file_end - written;
if (size > 16384)
size = 16384;
if (fread (buf, size, 1, asm_out_file) != 1)
fatal_error ("can't read %s: %m", asm_file_name);
if (fwrite (buf, size, 1, pch_outfile) != 1)
fatal_error ("can't write %s: %m", pch_file);
written += size;
}
free (buf);
/* asm_out_file can be written afterwards, so must be flushed first. */
fflush (asm_out_file);
gt_pch_save (pch_outfile);
cpp_write_pch_state (parse_in, pch_outfile);
if (fseek (pch_outfile, 0, SEEK_SET) != 0
|| fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
fatal_error ("can't write %s: %m", pch_file);
fclose (pch_outfile);
}
/* Check the PCH file called NAME, open on FD, to see if it can be
used in this compilation. Return 1 if valid, 0 if the file can't
be used now but might be if it's seen later in the compilation, and
2 if this file could never be used in the compilation. */
int
c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
{
int sizeread;
int result;
char ident[IDENT_LENGTH];
char short_strings[256 * 3];
int strings_length;
const char *pch_ident;
struct c_pch_validity v;
unsigned int current_flags_info = 0;
if (flag_unit_at_a_time)
current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
/* Perform a quick test of whether this is a valid
precompiled header for the current language
and with the current flag settings. */
sizeread = read (fd, ident, IDENT_LENGTH);
if (sizeread == -1)
fatal_error ("can't read %s: %m", name);
else if (sizeread != IDENT_LENGTH)
return 2;
pch_ident = get_ident();
if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
{
if (memcmp (ident, pch_ident, 5) == 0)
/* It's a PCH, for the right language, but has the wrong version.
*/
cpp_error (pfile, CPP_DL_WARNING,
"%s: not compatible with this GCC version", name);
else if (memcmp (ident, pch_ident, 4) == 0)
/* It's a PCH for the wrong language. */
cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
lang_hooks.name);
else
/* Not any kind of PCH. */
cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
}
return 2;
}
/* At this point, we know it's a PCH file, so it ought to be long enough
that we can read a c_pch_validity structure. */
if (read (fd, &v, sizeof (v)) != sizeof (v))
fatal_error ("can't read %s: %m", name);
strings_length = (v.host_machine_length + v.target_machine_length
+ v.version_length);
if (read (fd, short_strings, strings_length) != strings_length)
fatal_error ("can't read %s: %m", name);
if (v.host_machine_length != strlen (host_machine)
|| memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: created on host `%.*s', but used on host `%s'", name,
v.host_machine_length, short_strings, host_machine);
return 2;
}
if (v.target_machine_length != strlen (target_machine)
|| memcmp (target_machine, short_strings + v.host_machine_length,
strlen (target_machine)) != 0)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: created for target `%.*s', but used for target `%s'",
name, v.target_machine_length,
short_strings + v.host_machine_length, target_machine);
return 2;
}
if (v.version_length != strlen (version_string)
|| memcmp (version_string,
(short_strings + v.host_machine_length
+ v.target_machine_length),
v.version_length) != 0)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: created by version `%.*s', but this is version `%s'",
name, v.version_length,
(short_strings + v.host_machine_length
+ v.target_machine_length),
version_string);
return 2;
}
if (v.flags_info != current_flags_info)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: created using different flags",
name);
return 2;
}
/* The allowable debug info combinations are that either the PCH file
was built with the same as is being used now, or the PCH file was
built for some kind of debug info but now none is in use. */
if (v.debug_info_type != write_symbols
&& write_symbols != NO_DEBUG)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: created with -g%s, but used with -g%s", name,
debug_type_names[v.debug_info_type],
debug_type_names[write_symbols]);
return 2;
}
/* If the text segment was not loaded at the same address as it was
when the PCH file was created, function pointers loaded from the
PCH will not be valid. We could in theory remap all the function
pointers, but no support for that exists at present. */
if (v.pch_init != &pch_init)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING,
"%s: had text segment at different address", name);
return 2;
}
/* Check the target-specific validity data. */
{
void *this_file_data = xmalloc (v.target_data_length);
const char *msg;
if ((size_t) read (fd, this_file_data, v.target_data_length)
!= v.target_data_length)
fatal_error ("can't read %s: %m", name);
msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
free (this_file_data);
if (msg != NULL)
{
if (cpp_get_options (pfile)->warn_invalid_pch)
cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
return 2;
}
}
/* Check the preprocessor macros are the same as when the PCH was
generated. */
result = cpp_valid_state (pfile, name, fd);
if (result == -1)
return 2;
else
return result == 0;
}
/* Load in the PCH file NAME, open on FD. It was originally searched for
by ORIG_NAME. */
void
c_common_read_pch (cpp_reader *pfile, const char *name,
int fd, const char *orig_name ATTRIBUTE_UNUSED)
{
FILE *f;
struct c_pch_header h;
char *buf;
unsigned long written;
struct save_macro_data *smd;
f = fdopen (fd, "rb");
if (f == NULL)
{
cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
return;
}
cpp_get_callbacks (parse_in)->valid_pch = NULL;
if (fread (&h, sizeof (h), 1, f) != 1)
{
cpp_errno (pfile, CPP_DL_ERROR, "reading");
return;
}
buf = xmalloc (16384);
for (written = 0; written < h.asm_size; )
{
long size = h.asm_size - written;
if (size > 16384)
size = 16384;
if (fread (buf, size, 1, f) != 1
|| fwrite (buf, size, 1, asm_out_file) != 1)
cpp_errno (pfile, CPP_DL_ERROR, "reading");
written += size;
}
free (buf);
cpp_prepare_state (pfile, &smd);
gt_pch_restore (f);
if (cpp_read_state (pfile, name, f, smd) != 0)
return;
fclose (f);
}
/* Indicate that no more PCH files should be read. */
void
c_common_no_more_pch (void)
{
if (cpp_get_callbacks (parse_in)->valid_pch)
{
cpp_get_callbacks (parse_in)->valid_pch = NULL;
host_hooks.gt_pch_use_address (NULL, 0);
}
}

415
contrib/gcc/c-ppoutput.c Normal file
View File

@ -0,0 +1,415 @@
/* Preprocess only, using cpplib.
Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "cpplib.h"
#include "cpphash.h"
#include "tree.h"
#include "c-common.h" /* For flags. */
#include "c-pragma.h" /* For parse_in. */
/* Encapsulates state used to convert a stream of tokens into a text
file. */
static struct
{
FILE *outf; /* Stream to write to. */
const struct line_map *map; /* Logical to physical line mappings. */
const cpp_token *prev; /* Previous token. */
const cpp_token *source; /* Source token for spacing. */
fileline line; /* Line currently being written. */
unsigned char printed; /* Nonzero if something output at line. */
} print;
/* General output routines. */
static void scan_translation_unit (cpp_reader *);
static void scan_translation_unit_trad (cpp_reader *);
static void account_for_newlines (const unsigned char *, size_t);
static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
static void print_line (const struct line_map *, fileline, const char *);
static void maybe_print_line (const struct line_map *, fileline);
/* Callback routines for the parser. Most of these are active only
in specific modes. */
static void cb_line_change (cpp_reader *, const cpp_token *, int);
static void cb_define (cpp_reader *, fileline, cpp_hashnode *);
static void cb_undef (cpp_reader *, fileline, cpp_hashnode *);
static void cb_include (cpp_reader *, fileline, const unsigned char *,
const char *, int);
static void cb_ident (cpp_reader *, fileline, const cpp_string *);
static void cb_def_pragma (cpp_reader *, fileline);
/* Preprocess and output. */
void
preprocess_file (cpp_reader *pfile)
{
/* A successful cpp_read_main_file guarantees that we can call
cpp_scan_nooutput or cpp_get_token next. */
if (flag_no_output)
{
/* Scan -included buffers, then the main file. */
while (pfile->buffer->prev)
cpp_scan_nooutput (pfile);
cpp_scan_nooutput (pfile);
}
else if (cpp_get_options (pfile)->traditional)
scan_translation_unit_trad (pfile);
else
scan_translation_unit (pfile);
/* -dM command line option. Should this be elsewhere? */
if (flag_dump_macros == 'M')
cpp_forall_identifiers (pfile, dump_macro, NULL);
/* Flush any pending output. */
if (print.printed)
putc ('\n', print.outf);
}
/* Set up the callbacks as appropriate. */
void
init_pp_output (FILE *out_stream)
{
cpp_callbacks *cb = cpp_get_callbacks (parse_in);
if (!flag_no_output)
{
cb->line_change = cb_line_change;
/* Don't emit #pragma or #ident directives if we are processing
assembly language; the assembler may choke on them. */
if (cpp_get_options (parse_in)->lang != CLK_ASM)
{
cb->ident = cb_ident;
cb->def_pragma = cb_def_pragma;
}
}
if (flag_dump_includes)
cb->include = cb_include;
if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
{
cb->define = cb_define;
cb->undef = cb_undef;
}
/* Initialize the print structure. Setting print.line to -1 here is
a trick to guarantee that the first token of the file will cause
a linemarker to be output by maybe_print_line. */
print.line = (fileline) -1;
print.printed = 0;
print.prev = 0;
print.map = 0;
print.outf = out_stream;
}
/* Writes out the preprocessed file, handling spacing and paste
avoidance issues. */
static void
scan_translation_unit (cpp_reader *pfile)
{
bool avoid_paste = false;
print.source = NULL;
for (;;)
{
const cpp_token *token = cpp_get_token (pfile);
if (token->type == CPP_PADDING)
{
avoid_paste = true;
if (print.source == NULL
|| (!(print.source->flags & PREV_WHITE)
&& token->val.source == NULL))
print.source = token->val.source;
continue;
}
if (token->type == CPP_EOF)
break;
/* Subtle logic to output a space if and only if necessary. */
if (avoid_paste)
{
if (print.source == NULL)
print.source = token;
if (print.source->flags & PREV_WHITE
|| (print.prev
&& cpp_avoid_paste (pfile, print.prev, token))
|| (print.prev == NULL && token->type == CPP_HASH))
putc (' ', print.outf);
}
else if (token->flags & PREV_WHITE)
putc (' ', print.outf);
avoid_paste = false;
print.source = NULL;
print.prev = token;
cpp_output_token (token, print.outf);
if (token->type == CPP_COMMENT)
account_for_newlines (token->val.str.text, token->val.str.len);
}
}
/* Adjust print.line for newlines embedded in output. */
static void
account_for_newlines (const unsigned char *str, size_t len)
{
while (len--)
if (*str++ == '\n')
print.line++;
}
/* Writes out a traditionally preprocessed file. */
static void
scan_translation_unit_trad (cpp_reader *pfile)
{
while (_cpp_read_logical_line_trad (pfile))
{
size_t len = pfile->out.cur - pfile->out.base;
maybe_print_line (print.map, pfile->out.first_line);
fwrite (pfile->out.base, 1, len, print.outf);
print.printed = 1;
if (!CPP_OPTION (pfile, discard_comments))
account_for_newlines (pfile->out.base, len);
}
}
/* If the token read on logical line LINE needs to be output on a
different line to the current one, output the required newlines or
a line marker, and return 1. Otherwise return 0. */
static void
maybe_print_line (const struct line_map *map, fileline line)
{
/* End the previous line of text. */
if (print.printed)
{
putc ('\n', print.outf);
print.line++;
print.printed = 0;
}
if (line >= print.line && line < print.line + 8)
{
while (line > print.line)
{
putc ('\n', print.outf);
print.line++;
}
}
else
print_line (map, line, "");
}
/* Output a line marker for logical line LINE. Special flags are "1"
or "2" indicating entering or leaving a file. */
static void
print_line (const struct line_map *map, fileline line, const char *special_flags)
{
/* End any previous line of text. */
if (print.printed)
putc ('\n', print.outf);
print.printed = 0;
print.line = line;
if (!flag_no_line_commands)
{
size_t to_file_len = strlen (map->to_file);
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
unsigned char *p;
/* cpp_quote_string does not nul-terminate, so we have to do it
ourselves. */
p = cpp_quote_string (to_file_quoted,
(unsigned char *)map->to_file, to_file_len);
*p = '\0';
fprintf (print.outf, "# %u \"%s\"%s",
SOURCE_LINE (map, print.line),
to_file_quoted, special_flags);
if (map->sysp == 2)
fputs (" 3 4", print.outf);
else if (map->sysp == 1)
fputs (" 3", print.outf);
putc ('\n', print.outf);
}
}
/* Called when a line of output is started. TOKEN is the first token
of the line, and at end of file will be CPP_EOF. */
static void
cb_line_change (cpp_reader *pfile, const cpp_token *token,
int parsing_args)
{
if (token->type == CPP_EOF || parsing_args)
return;
maybe_print_line (print.map, token->line);
print.prev = 0;
print.source = 0;
/* Supply enough spaces to put this token in its original column,
one space per column greater than 2, since scan_translation_unit
will provide a space if PREV_WHITE. Don't bother trying to
reconstruct tabs; we can't get it right in general, and nothing
ought to care. Some things do care; the fault lies with them. */
if (!CPP_OPTION (pfile, traditional))
{
print.printed = 1;
if (token->col > 2)
{
unsigned int spaces = token->col - 2;
while (spaces--)
putc (' ', print.outf);
}
}
}
static void
cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
const cpp_string *str)
{
maybe_print_line (print.map, line);
fprintf (print.outf, "#ident \"%s\"\n", str->text);
print.line++;
}
static void
cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
{
maybe_print_line (print.map, line);
fputs ("#define ", print.outf);
/* 'D' is whole definition; 'N' is name only. */
if (flag_dump_macros == 'D')
fputs ((const char *) cpp_macro_definition (pfile, node),
print.outf);
else
fputs ((const char *) NODE_NAME (node), print.outf);
putc ('\n', print.outf);
print.line++;
}
static void
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
cpp_hashnode *node)
{
maybe_print_line (print.map, line);
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
print.line++;
}
static void
cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
const unsigned char *dir, const char *header, int angle_brackets)
{
maybe_print_line (print.map, line);
if (angle_brackets)
fprintf (print.outf, "#%s <%s>\n", dir, header);
else
fprintf (print.outf, "#%s \"%s\"\n", dir, header);
print.line++;
}
/* Callback called when -fworking-director and -E to emit working
diretory in cpp output file. */
void
pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
{
size_t to_file_len = strlen (dir);
unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
unsigned char *p;
/* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len);
*p = '\0';
fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
}
/* The file name, line number or system header flags have changed, as
described in MAP. From this point on, the old print.map might be
pointing to freed memory, and so must not be dereferenced. */
void
pp_file_change (const struct line_map *map)
{
const char *flags = "";
if (flag_no_line_commands || flag_no_output)
return;
if (map != NULL)
{
/* First time? */
if (print.map == NULL)
{
/* Avoid printing foo.i when the main file is foo.c. */
if (!cpp_get_options (parse_in)->preprocessed)
print_line (map, map->from_line, flags);
}
else
{
/* Bring current file to correct line when entering a new file. */
if (map->reason == LC_ENTER)
maybe_print_line (map - 1, map->from_line - 1);
if (map->reason == LC_ENTER)
flags = " 1";
else if (map->reason == LC_LEAVE)
flags = " 2";
print_line (map, map->from_line, flags);
}
}
print.map = map;
}
/* Copy a #pragma directive to the preprocessed output. */
static void
cb_def_pragma (cpp_reader *pfile, fileline line)
{
maybe_print_line (print.map, line);
fputs ("#pragma ", print.outf);
cpp_output_line (pfile, print.outf);
print.line++;
}
/* Dump out the hash table. */
static int
dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
{
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
{
fputs ("#define ", print.outf);
fputs ((const char *) cpp_macro_definition (pfile, node),
print.outf);
putc ('\n', print.outf);
print.line++;
}
return 1;
}

View File

@ -1,5 +1,5 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "function.h"
@ -47,7 +49,7 @@ typedef struct align_stack GTY(())
static GTY(()) struct align_stack * alignment_stack;
#ifdef HANDLE_PRAGMA_PACK
static void handle_pragma_pack PARAMS ((cpp_reader *));
static void handle_pragma_pack (cpp_reader *);
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
/* If we have a "global" #pragma pack(<n>) in effect when the first
@ -59,14 +61,12 @@ static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
(default_alignment = maximum_field_alignment = (ALIGN))
static void push_alignment PARAMS ((int, tree));
static void pop_alignment PARAMS ((tree));
static void push_alignment (int, tree);
static void pop_alignment (tree);
/* Push an alignment value onto the stack. */
static void
push_alignment (alignment, id)
int alignment;
tree id;
push_alignment (int alignment, tree id)
{
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
@ -74,7 +74,7 @@ push_alignment (alignment, id)
{
align_stack * entry;
entry = (align_stack *) ggc_alloc (sizeof (* entry));
entry = ggc_alloc (sizeof (* entry));
entry->alignment = alignment;
entry->num_pushes = 1;
@ -97,8 +97,7 @@ push_alignment (alignment, id)
/* Undo a push of an alignment onto the stack. */
static void
pop_alignment (id)
tree id;
pop_alignment (tree id)
{
align_stack * entry;
@ -155,8 +154,7 @@ pop_alignment (id)
#pragma pack (pop)
#pragma pack (pop, ID) */
static void
handle_pragma_pack (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree x, id = 0;
int align = -1;
@ -259,12 +257,11 @@ handle_pragma_pack (dummy)
static GTY(()) tree pending_weaks;
#ifdef HANDLE_PRAGMA_WEAK
static void apply_pragma_weak PARAMS ((tree, tree));
static void handle_pragma_weak PARAMS ((cpp_reader *));
static void apply_pragma_weak (tree, tree);
static void handle_pragma_weak (cpp_reader *);
static void
apply_pragma_weak (decl, value)
tree decl, value;
apply_pragma_weak (tree decl, tree value)
{
if (value)
{
@ -276,15 +273,16 @@ apply_pragma_weak (decl, value)
}
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
&& !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
warning ("%Japplying #pragma weak '%D' after first use results "
"in unspecified behavior", decl, decl);
declare_weak (decl);
}
void
maybe_apply_pragma_weak (decl)
tree decl;
maybe_apply_pragma_weak (tree decl)
{
tree *p, t, id;
@ -316,8 +314,7 @@ maybe_apply_pragma_weak (decl)
/* #pragma weak name [= value] */
static void
handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
handle_pragma_weak (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree name, value, x, decl;
enum cpp_ttype t;
@ -348,8 +345,7 @@ handle_pragma_weak (dummy)
}
#else
void
maybe_apply_pragma_weak (decl)
tree decl ATTRIBUTE_UNUSED;
maybe_apply_pragma_weak (tree decl ATTRIBUTE_UNUSED)
{
}
#endif /* HANDLE_PRAGMA_WEAK */
@ -357,12 +353,11 @@ maybe_apply_pragma_weak (decl)
static GTY(()) tree pending_redefine_extname;
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
static void handle_pragma_redefine_extname (cpp_reader *);
/* #pragma redefined_extname oldname newname */
static void
handle_pragma_redefine_extname (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree oldname, newname, decl, x;
enum cpp_ttype t;
@ -382,12 +377,13 @@ handle_pragma_redefine_extname (dummy)
warning ("junk at end of #pragma redefine_extname");
decl = identifier_global_value (oldname);
if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
if (decl && (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL))
{
if (DECL_ASSEMBLER_NAME_SET_P (decl)
&& DECL_ASSEMBLER_NAME (decl) != newname)
warning ("#pragma redefine_extname conflicts with declaration");
SET_DECL_ASSEMBLER_NAME (decl, newname);
change_decl_assembler_name (decl, newname);
}
else
add_to_renaming_pragma_list(oldname, newname);
@ -395,8 +391,7 @@ handle_pragma_redefine_extname (dummy)
#endif
void
add_to_renaming_pragma_list (oldname, newname)
tree oldname, newname;
add_to_renaming_pragma_list (tree oldname, tree newname)
{
pending_redefine_extname
= tree_cons (oldname, newname, pending_redefine_extname);
@ -405,12 +400,11 @@ add_to_renaming_pragma_list (oldname, newname)
static GTY(()) tree pragma_extern_prefix;
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
static void handle_pragma_extern_prefix (cpp_reader *);
/* #pragma extern_prefix "prefix" */
static void
handle_pragma_extern_prefix (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
handle_pragma_extern_prefix (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree prefix, x;
enum cpp_ttype t;
@ -429,12 +423,11 @@ handle_pragma_extern_prefix (dummy)
}
#endif
/* Hook from the front ends to apply the results of one of the preceeding
/* Hook from the front ends to apply the results of one of the preceding
pragmas that rename variables. */
tree
maybe_apply_renaming_pragma (decl, asmname)
tree decl, asmname;
maybe_apply_renaming_pragma (tree decl, tree asmname)
{
tree oldname;
@ -488,26 +481,34 @@ maybe_apply_renaming_pragma (decl, asmname)
return asmname;
}
/* Front-end wrapper for pragma registration to avoid dragging
cpplib.h in almost everywhere. */
void
init_pragma ()
c_register_pragma (const char *space, const char *name,
void (*handler) (struct cpp_reader *))
{
cpp_register_pragma (parse_in, space, name, handler);
}
/* Set up front-end pragmas. */
void
init_pragma (void)
{
#ifdef HANDLE_PRAGMA_PACK
cpp_register_pragma (parse_in, 0, "pack", handle_pragma_pack);
c_register_pragma (0, "pack", handle_pragma_pack);
#endif
#ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
c_register_pragma (0, "weak", handle_pragma_weak);
#endif
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
cpp_register_pragma (parse_in, 0, "redefine_extname",
handle_pragma_redefine_extname);
c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
cpp_register_pragma (parse_in, 0, "extern_prefix",
handle_pragma_extern_prefix);
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);
REGISTER_TARGET_PRAGMAS ();
#endif
}

View File

@ -1,5 +1,5 @@
/* Pragma related interfaces.
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@ -26,15 +26,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define YYDEBUG 1
extern int yydebug;
struct cpp_reader;
extern struct cpp_reader* parse_in;
#ifdef HANDLE_SYSV_PRAGMA
#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
|| defined (ASM_WEAKEN_DECL))
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
#endif
#ifdef HANDLE_SYSV_PRAGMA
/* We always support #pragma pack for SYSV pragmas. */
#ifndef HANDLE_PRAGMA_PACK
#define HANDLE_PRAGMA_PACK 1
@ -48,22 +44,17 @@ extern struct cpp_reader* parse_in;
#define HANDLE_PRAGMA_PACK 1
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
extern void init_pragma PARAMS ((void));
extern void init_pragma (void);
/* Duplicate prototypes for the register_pragma stuff and the typedef for
cpp_reader, to avoid dragging cpplib.h in almost everywhere... */
#ifndef GCC_CPPLIB_H
typedef struct cpp_reader cpp_reader;
/* Front-end wrapper for pragma registration to avoid dragging
cpplib.h in almost everywhere. */
extern void c_register_pragma (const char *, const char *,
void (*) (struct cpp_reader *));
extern void maybe_apply_pragma_weak (tree);
extern tree maybe_apply_renaming_pragma (tree, tree);
extern void add_to_renaming_pragma_list (tree, tree);
extern void cpp_register_pragma PARAMS ((cpp_reader *,
const char *, const char *,
void (*) PARAMS ((cpp_reader *))));
#endif
extern void maybe_apply_pragma_weak PARAMS ((tree));
extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
extern void add_to_renaming_pragma_list PARAMS ((tree, tree));
extern int c_lex PARAMS ((tree *));
extern int c_lex (tree *);
extern int c_lex_with_flags (tree *, unsigned char *);
#endif /* GCC_C_PRAGMA_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Various declarations for the C and C++ pretty-printers.
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@ -27,139 +27,174 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "pretty-print.h"
typedef enum
{
pp_c_flag_abstract = 1 << 1,
pp_c_flag_last_bit = 2
} pp_c_pretty_print_flags;
/* The data type used to bundle information necessary for pretty-printing
a C or C++ entity. */
typedef struct c_pretty_print_info *c_pretty_printer;
typedef struct c_pretty_print_info c_pretty_printer;
/* The type of a C pretty-printer 'member' function. */
typedef void (*c_pretty_print_fn) PARAMS ((c_pretty_printer, tree));
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
/* The datatype that contains information necessary for pretty-printing
a tree that represents a C construct. Any pretty-printer for a
language using C/c++ syntax can derive from this datatype and reuse
facilities provided here. It can do so by having a subobject of type
c_pretty_printer and override the macro pp_c_base to return a pointer
to that subobject. Such a pretty-printer has the responsibility to
initialize the pp_base() part, then call pp_c_pretty_printer_init
to set up the components that are specific to the C pretty-printer.
A derived pretty-printer can override any function listed in the
vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
for an example of derivation. */
struct c_pretty_print_info
{
struct pretty_print_info base;
pretty_printer base;
/* Points to the first element of an array of offset-list.
Not used yet. */
int *offset_list;
/* These must be overriden by each of the C and C++ front-end to
reflect their understanding of syntatic productions when they differ. */
pp_flags flags;
/* These must be overridden by each of the C and C++ front-end to
reflect their understanding of syntactic productions when they differ. */
c_pretty_print_fn declaration;
c_pretty_print_fn declaration_specifiers;
c_pretty_print_fn type_specifier;
c_pretty_print_fn declarator;
c_pretty_print_fn abstract_declarator;
c_pretty_print_fn direct_abstract_declarator;
c_pretty_print_fn type_specifier_seq;
c_pretty_print_fn direct_declarator;
c_pretty_print_fn parameter_declaration;
c_pretty_print_fn ptr_operator;
c_pretty_print_fn parameter_list;
c_pretty_print_fn type_id;
c_pretty_print_fn simple_type_specifier;
c_pretty_print_fn function_specifier;
c_pretty_print_fn storage_class_specifier;
c_pretty_print_fn initializer;
c_pretty_print_fn statement;
c_pretty_print_fn id_expression;
c_pretty_print_fn primary_expression;
c_pretty_print_fn postfix_expression;
c_pretty_print_fn unary_expression;
c_pretty_print_fn initializer;
c_pretty_print_fn multiplicative_expression;
c_pretty_print_fn conditional_expression;
c_pretty_print_fn assignment_expression;
c_pretty_print_fn expression;
};
#define pp_c_left_paren(PPI) \
do { \
pp_left_paren (PPI); \
pp_c_base (PPI)->base.padding = pp_none; \
} while (0)
#define pp_c_right_paren(PPI) \
do { \
pp_right_paren (PPI); \
pp_c_base (PPI)->base.padding = pp_none; \
} while (0)
#define pp_c_left_bracket(PPI) \
do { \
pp_left_bracket (PPI); \
pp_c_base (PPI)->base.padding = pp_none; \
} while (0)
#define pp_c_right_bracket(PPI) \
do { \
pp_right_bracket (PPI); \
pp_c_base (PPI)->base.padding = pp_none; \
} while (0)
#define pp_c_whitespace(PPI) \
do { \
pp_whitespace (PPI); \
pp_c_base (PPI)->base.padding = pp_none; \
} while (0)
#define pp_c_maybe_whitespace(PPI) \
do { \
if (pp_c_base (PPI)->base.padding != pp_none) \
pp_c_whitespace (PPI); \
} while (0)
#define pp_c_identifier(PPI, ID) \
do { \
pp_c_maybe_whitespace (PPI); \
pp_identifier (PPI, ID); \
pp_c_base (PPI)->base.padding = pp_before; \
} while (0)
/* Override the pp_base macro. Derived pretty-printers should not
touch this macro. Instead they should override pp_c_base instead. */
#undef pp_base
#define pp_base(PP) (&pp_c_base (PP)->base)
#define pp_c_tree_identifier(PPI, ID) \
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
/* Returns the 'output_buffer *' associated with a PRETTY-PRINTER, the latter
being something digestible by pp_c_base. */
#define pp_buffer(PPI) pp_c_base (PPI)->base.buffer
#define pp_declaration(PPI, T) \
(*pp_c_base (PPI)->declaration) (pp_c_base (PPI), T)
pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
#define pp_declaration_specifiers(PPI, D) \
(*pp_c_base (PPI)->declaration_specifiers) (pp_c_base (PPI), D)
#define pp_type_specifier(PPI, D) \
(*pp_c_base (PPI)->type_specifier) (pp_c_base (PPI), D)
pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
#define pp_abstract_declarator(PP, D) \
pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
#define pp_type_specifier_seq(PPI, D) \
pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
#define pp_declarator(PPI, D) \
(*pp_c_base (PPI)->declarator) (pp_c_base (PPI), D)
pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
#define pp_direct_declarator(PPI, D) \
(*pp_c_base (PPI)->direct_declarator) (pp_c_base (PPI), D)
#define pp_parameter_declaration(PPI, T) \
(*pp_c_base (PPI)->parameter_declaration) (pp_c_base (PPI), T)
pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
#define pp_direct_abstract_declarator(PP, D) \
pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
#define pp_ptr_operator(PP, D) \
pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
#define pp_parameter_list(PPI, T) \
pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
#define pp_type_id(PPI, D) \
(*pp_c_base (PPI)->type_id) (pp_c_base (PPI), D)
pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
#define pp_simple_type_specifier(PP, T) \
pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
#define pp_function_specifier(PP, D) \
pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
#define pp_storage_class_specifier(PP, D) \
pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
#define pp_statement(PPI, S) \
(*pp_c_base (PPI)->statement) (pp_c_base (PPI), S)
pp_c_base (PPI)->statement (pp_c_base (PPI), S)
#define pp_id_expression(PP, E) \
pp_c_base (PP)->id_expression (pp_c_base (PP), E)
#define pp_primary_expression(PPI, E) \
(*pp_c_base (PPI)->primary_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
#define pp_postfix_expression(PPI, E) \
(*pp_c_base (PPI)->postfix_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
#define pp_unary_expression(PPI, E) \
(*pp_c_base (PPI)->unary_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
#define pp_initializer(PPI, E) \
(*pp_c_base (PPI)->initializer) (pp_c_base (PPI), E)
pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
#define pp_multiplicative_expression(PPI, E) \
(*pp_c_base (PPI)->multiplicative_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
#define pp_conditional_expression(PPI, E) \
(*pp_c_base (PPI)->conditional_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
#define pp_assignment_expression(PPI, E) \
(*pp_c_base (PPI)->assignment_expression) (pp_c_base (PPI), E)
pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
#define pp_expression(PP, E) \
pp_c_base (PP)->expression (pp_c_base (PP), E)
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
macro must be overriden by any subclass of c_pretty_print_info. */
macro must be overridden by any subclass of c_pretty_print_info. */
#define pp_c_base(PP) (PP)
extern void pp_c_pretty_printer_init PARAMS ((c_pretty_printer));
extern void pp_c_pretty_printer_init (c_pretty_printer *);
void pp_c_whitespace (c_pretty_printer *);
void pp_c_left_paren (c_pretty_printer *);
void pp_c_right_paren (c_pretty_printer *);
void pp_c_left_brace (c_pretty_printer *);
void pp_c_right_brace (c_pretty_printer *);
void pp_c_dot (c_pretty_printer *);
void pp_c_ampersand (c_pretty_printer *);
void pp_c_arrow (c_pretty_printer *);
void pp_c_semicolon (c_pretty_printer *);
void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
/* Declarations. */
void pp_c_attributes PARAMS ((c_pretty_printer, tree));
void pp_c_cv_qualifier PARAMS ((c_pretty_printer, int));
void pp_c_parameter_declaration_clause PARAMS ((c_pretty_printer, tree));
void pp_c_declaration PARAMS ((c_pretty_printer, tree));
void pp_c_function_definition (c_pretty_printer *, tree);
void pp_c_attributes (c_pretty_printer *, tree);
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
void pp_c_parameter_type_list (c_pretty_printer *, tree);
void pp_c_declaration (c_pretty_printer *, tree);
void pp_c_declaration_specifiers (c_pretty_printer *, tree);
void pp_c_declarator (c_pretty_printer *, tree);
void pp_c_direct_declarator (c_pretty_printer *, tree);
void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
void pp_c_function_specifier (c_pretty_printer *, tree);
void pp_c_type_id (c_pretty_printer *, tree);
void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
void pp_c_type_specifier (c_pretty_printer *, tree);
void pp_c_storage_class_specifier (c_pretty_printer *, tree);
/* Statements. */
void pp_c_statement PARAMS ((c_pretty_printer, tree));
void pp_c_statement (c_pretty_printer *, tree);
/* Expressions. */
void pp_c_expression PARAMS ((c_pretty_printer, tree));
void pp_c_logical_or_expression PARAMS ((c_pretty_printer, tree));
void pp_c_expression_list PARAMS ((c_pretty_printer, tree));
void pp_c_cast_expression PARAMS ((c_pretty_printer, tree));
void pp_c_postfix_expression PARAMS ((c_pretty_printer, tree));
void pp_c_initializer PARAMS ((c_pretty_printer, tree));
void pp_c_literal PARAMS ((c_pretty_printer, tree));
void pp_c_expression (c_pretty_printer *, tree);
void pp_c_logical_or_expression (c_pretty_printer *, tree);
void pp_c_expression_list (c_pretty_printer *, tree);
void pp_c_call_argument_list (c_pretty_printer *, tree);
void pp_c_unary_expression (c_pretty_printer *, tree);
void pp_c_cast_expression (c_pretty_printer *, tree);
void pp_c_postfix_expression (c_pretty_printer *, tree);
void pp_c_primary_expression (c_pretty_printer *, tree);
void pp_c_init_declarator (c_pretty_printer *, tree);
void pp_c_constant (c_pretty_printer *, tree);
void pp_c_id_expression (c_pretty_printer *, tree);
void pp_c_identifier (c_pretty_printer *, const char *);
void pp_c_string_literal (c_pretty_printer *, tree);
#endif /* GCC_C_PRETTY_PRINTER */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

825
contrib/gcc/c.opt Normal file
View File

@ -0,0 +1,825 @@
; Options for the C, ObjC, C++ and ObjC++ front ends.
; Copyright (C) 2003 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 2, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING. If not, write to the Free
; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
; 02111-1307, USA.
; This file is processed by the script opts.sh. It is a database of
; command line options, with each record separated by a blank line,
; and each field appearing on its own line. The first field is the
; command-line switch with the leading "-" removed. All options
; beginning with "f" or "W" are implicitly assumed to take a "no-"
; form; this form should not be listed. If you do not want this
; negative form and you want it to be automatically rejected, add
; RejectNegative to the second field.
; The second field is a space-separated list of which parts of the
; compiler recognize the switch, as declared by "Language" entries.
; If the switch takes an argument, then you should also specify
; "Joined" and/or "Separate" to indicate where the argument can
; appear. If a Joined argument can legitimately be omitted, specify
; "JoinedOrMissing" instead of "Joined". If the argument to a switch
; is a non-negative integer, you can specify "UInteger" and the switch
; decoder will convert the argument for you, or complain to the user
; if the argument is invalid.
; The third field is the help text to output with --help. This is
; automatically line-wrapped on output. Normally the switch is output
; automatically, with the help text on the right hand side of the
; output. However, if the help text contains a tab character, the
; text to the left of the tab is output instead of the switch, and the
; text to its right forms the help. This is useful for elaborating on
; what type of argument a switch takes, for example. If the second
; field contains "Undocumented" then nothing is output with --help.
; Only do this with good reason like the switch being internal between
; the driver and the front end - it is not an excuse to leave a switch
; undocumented.
; Comments can appear on their own line anwhere in the file, preceded
; by a semicolon. Whitespace is permitted before the semicolon.
; For each switch XXX below, an enumeration constant is created by the
; script opts.sh spelt OPT_XXX, but with all non-alphanumeric
; characters replaced with an underscore.
; Please try to keep this file in ASCII collating order.
Language
C
Language
ObjC
Language
C++
Language
ObjC++
-output-pch=
C ObjC C++ ObjC++ Joined Separate
A
C ObjC C++ ObjC++ Joined Separate
-A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question>
C
C ObjC C++ ObjC++
Do not discard comments
CC
C ObjC C++ ObjC++
Do not discard comments in macro expansions
D
C ObjC C++ ObjC++ Joined Separate
-D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1
E
C ObjC C++ ObjC++ Undocumented
H
C ObjC C++ ObjC++
Print the name of header files as they are used
I
C ObjC C++ ObjC++ Joined Separate
-I <dir> Add <dir> to the end of the main include path. -I- gives more include path control; see info documentation
M
C ObjC C++ ObjC++
Generate make dependencies
MD
C ObjC C++ ObjC++ Separate
Generate make dependencies and compile
MF
C ObjC C++ ObjC++ Joined Separate
-MF <file> Write dependency output to the given file
MG
C ObjC C++ ObjC++
Treat missing header files as generated files
MM
C ObjC C++ ObjC++
Like -M but ignore system header files
MMD
C ObjC C++ ObjC++ Separate
Like -MD but ignore system header files
MP
C ObjC C++ ObjC++
Generate phony targets for all headers
MQ
C ObjC C++ ObjC++ Joined Separate
-MQ <target> Add a MAKE-quoted target
MT
C ObjC C++ ObjC++ Joined Separate
-MT <target> Add an unquoted target
P
C ObjC C++ ObjC++
Do not generate #line directives
U
C ObjC C++ ObjC++ Joined Separate
-U<macro> Undefine <macro>
Wabi
C++ ObjC++
Wall
C ObjC C++ ObjC++
Enable most warning messages
Wbad-function-cast
C ObjC
Warn about casting functions to incompatible types
Wcast-qual
C ObjC C++ ObjC++
Warn about casts which discard qualifiers
Wchar-subscripts
C ObjC C++ ObjC++
Warn about subscripts whose type is \"char\"
Wcomment
C ObjC C++ ObjC++
Warn about possibly nested block comments, and C++ comments spanning more than one physical line
Wcomments
C ObjC C++ ObjC++
Synonym for -Wcomment
Wconversion
C ObjC C++ ObjC++
Warn about possibly confusing type conversions
Wctor-dtor-privacy
C++ ObjC++
Warn when all constructors and destructors are private
Wdeclaration-after-statement
C ObjC
Warn when a declaration is found after a statement
Wdeprecated
C++ ObjC++
Warn about deprecated compiler features
Wdiv-by-zero
C ObjC
Warn about compile-time integer division by zero
Weffc++
C++ ObjC++
Warn about violations of Effective C++ style rules
Wendif-labels
C ObjC C++ ObjC++
Warn about stray tokens after #elif and #endif
Werror
C ObjC C++ ObjC++
; Documented in common.opt
Werror-implicit-function-declaration
C ObjC RejectNegative
Make implicit function declarations an error
Wfloat-equal
C ObjC C++ ObjC++
Warn if testing floating point numbers for equality
Wformat
C ObjC C++ ObjC++
Warn about printf/scanf/strftime/strfmon format string anomalies
Wformat-extra-args
C ObjC C++ ObjC++
Warn if passing too many arguments to a function for its format string
Wformat-nonliteral
C ObjC C++ ObjC++
Warn about format strings that are not literals
Wformat-security
C ObjC C++ ObjC++
Warn about possible security problems with format functions
Wformat-y2k
C ObjC C++ ObjC++
Warn about strftime formats yielding 2-digit years
Wformat-zero-length
C ObjC
Wformat=
C ObjC C++ ObjC++ Joined
Winit-self
C ObjC C++ ObjC++
Warn about variables which are initialized to themselves.
Wimplicit
C ObjC C++ ObjC++
Wimplicit-function-declaration
C ObjC
Warn about implicit function declarations
Wimplicit-int
C ObjC
Warn when a declaration does not specify a type
Wimport
C ObjC C++ ObjC++
Deprecated. This switch has no effect.
Winvalid-offsetof
C++ ObjC++
Warn about invalid uses of the \"offsetof\" macro
Winvalid-pch
C ObjC C++ ObjC++
Warn about PCH files that are found but not used
Wlong-long
C ObjC C++ ObjC++
Do not warn about using \"long long\" when -pedantic
Wmain
C ObjC
Warn about suspicious declarations of \"main\"
Wmissing-braces
C ObjC C++ ObjC++
Warn about possibly missing braces around initializers
Wmissing-declarations
C ObjC
Warn about global functions without previous declarations
Wmissing-format-attribute
C ObjC C++ ObjC++
Warn about functions which might be candidates for format attributes
Wmissing-prototypes
C ObjC
Warn about global functions without prototypes
Wmultichar
C ObjC C++ ObjC++
Warn about use of multi-character character constants
Wnested-externs
C ObjC
Warn about \"extern\" declarations not at file scope
Wnon-template-friend
C++ ObjC++
Warn when non-templatized friend functions are declared within a template
Wnon-virtual-dtor
C++ ObjC++
Warn about non-virtual destructors
Wnonnull
C ObjC
Wold-style-cast
C++ ObjC++
Warn if a C-style cast is used in a program
Wold-style-definition
C ObjC
Warn if an old-style parameter definition is used
Woverloaded-virtual
C++ ObjC++
Warn about overloaded virtual function names
Wparentheses
C ObjC C++ ObjC++
Warn about possibly missing parentheses
Wpmf-conversions
C++ ObjC++
Warn when converting the type of pointers to member functions
Wpointer-arith
C ObjC C++ ObjC++
Warn about function pointer arithmetic
Wprotocol
ObjC ObjC++
Warn if inherited methods are unimplemented
Wredundant-decls
C ObjC C++ ObjC++
Warn about multiple declarations of the same object
Wreorder
C++ ObjC++
Warn when the compiler reorders code
Wreturn-type
C ObjC C++ ObjC++
Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
Wselector
ObjC ObjC++
Warn if a selector has multiple methods
Wsequence-point
C ObjC
Warn about possible violations of sequence point rules
Wsign-compare
C ObjC C++ ObjC++
Warn about signed-unsigned comparisons
Wsign-promo
C++ ObjC++
Warn when overload promotes from unsigned to signed
Wstrict-prototypes
C ObjC
Warn about unprototyped function declarations
Wsynth
C++ ObjC++
Warn when synthesis behavior differs from Cfront
Wsystem-headers
C ObjC C++ ObjC++
Do not suppress warnings from system headers
Wtraditional
C ObjC
Warn about features not present in traditional C
Wtrigraphs
C ObjC C++ ObjC++
Warn if trigraphs are encountered that might affect the meaning of the program
Wundeclared-selector
ObjC ObjC++
Wundef
C ObjC C++ ObjC++
Warn if an undefined macro is used in an #if directive
Wunknown-pragmas
C ObjC C++ ObjC++
Warn about unrecognized pragmas
Wunused-macros
C ObjC C++ ObjC++
Warn about macros defined in the main file that are not used
Wwrite-strings
C ObjC C++ ObjC++
Give strings the type \"array of char\"
ansi
C ObjC C++ ObjC++
A synonym for -std=c89. In a future version of GCC it will become synonymous with -std=c99 instead
d
C ObjC C++ ObjC++ Joined
; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
faccess-control
C++ ObjC++
Enforce class member access control semantics
fall-virtual
C++ ObjC++
falt-external-templates
C++ ObjC++
Change when template instances are emitted
fasm
C ObjC C++ ObjC++
Recognize the \"asm\" keyword
fbuiltin
C ObjC C++ ObjC++
Recognize built-in functions
fbuiltin-
C ObjC C++ ObjC++ Joined
fcheck-new
C++ ObjC++
Check the return value of new
fcond-mismatch
C ObjC C++ ObjC++
Allow the arguments of the '?' operator to have different types
fconserve-space
C++ ObjC++
Reduce the size of object files
fconst-strings
C++ ObjC++
Make string literals \"const char[]\" not \"char[]\"
fconstant-string-class=
ObjC ObjC++ Joined
-fconst-string-class=<name> Use class <name> for constant strings
fdefault-inline
C++ ObjC++
Inline member functions by default
fdollars-in-identifiers
C ObjC C++ ObjC++
Permit '$' as an identifier character
fdump-
C ObjC C++ ObjC++ Joined RejectNegative
-fdump-<type> Dump various compiler internals to a file
felide-constructors
C++ ObjC++
fenforce-eh-specs
C++ ObjC++
Generate code to check exception specifications
fenum-int-equiv
C++ ObjC++
fexec-charset=
C ObjC C++ ObjC++ Joined RejectNegative
-fexec-charset=<cset> Convert all strings and character constants to character set <cset>
finput-charset=
C ObjC C++ ObjC++ Joined RejectNegative
-finput-charset=<cset> Specify the default character set for source files.
fexternal-templates
C++ ObjC++
ffixed-form
C ObjC
ffixed-line-length-
C ObjC Joined
ffor-scope
C++ ObjC++
Scope of for-init-statement variables is local to the loop
ffreestanding
C ObjC
Do not assume that standard C libraries and \"main\" exist
fgnu-keywords
C++ ObjC++
Recognize GNU-defined keywords
fgnu-runtime
ObjC ObjC++
Generate code for GNU runtime environment
fguiding-decls
C++ ObjC++
fhandle-exceptions
C++ ObjC++
fhonor-std
C++ ObjC++
fhosted
C ObjC
Assume normal C execution environment
fhuge-objects
C++ ObjC++
Enable support for huge objects
fimplement-inlines
C++ ObjC++
Export functions even if they can be inlined
fimplicit-inline-templates
C++ ObjC++
Emit implicit instantiations of inline templates
fimplicit-templates
C++ ObjC++
Emit implicit instantiations of templates
flabels-ok
C++ ObjC++
fms-extensions
C ObjC C++ ObjC++
Don't warn about uses of Microsoft extensions
fname-mangling-version-
C++ ObjC++ Joined
fnew-abi
C++ ObjC++
fnext-runtime
ObjC ObjC++
Generate code for NeXT (Apple Mac OS X) runtime environment
fnil-receivers
ObjC ObjC++
Assume that receivers of Objective-C messages may be nil
fnonansi-builtins
C++ ObjC++
fnonnull-objects
C++ ObjC++
fobjc-exceptions
ObjC ObjC++
Enable Objective-C exception and synchronization syntax
foperator-names
C++ ObjC++
Recognize C++ kewords like \"compl\" and \"xor\"
foptional-diags
C++ ObjC++
Enable optional diagnostics
fpch-deps
C ObjC C++ ObjC++
fpermissive
C++ ObjC++
Downgrade conformance errors to warnings
fpreprocessed
C ObjC C++ ObjC++
Treat the input file as already preprocessed
freplace-objc-classes
ObjC ObjC++
Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime
frepo
C++ ObjC++
Enable automatic template instantiation
frtti
C++ ObjC++
Generate run time type descriptor information
fshort-double
C ObjC C++ ObjC++
Use the same size for double as for float
fshort-enums
C ObjC C++ ObjC++
Use the narrowest integer type possible for enumeration types
fshort-wchar
C ObjC C++ ObjC++
Force the underlying type for \"wchar_t\" to be \"unsigned short\"
fshow-column
C ObjC C++ ObjC++
fsigned-bitfields
C ObjC C++ ObjC++
When \"signed\" or \"unsigned\" is not given make the bitfield signed
fsigned-char
C ObjC C++ ObjC++
Make \"char\" signed by default
fsquangle
C++ ObjC++
fstats
C++ ObjC++
Display statistics accumulated during compilation
fstrict-prototype
C++ ObjC++
ftabstop=
C ObjC C++ ObjC++ Joined RejectNegative UInteger
-ftabstop=<number> Distance between tab stops for column reporting
ftemplate-depth-
C++ ObjC++ Joined RejectNegative UInteger
-ftemplate-depth-<number> Specify maximum template instantiation depth
fthis-is-variable
C++ ObjC++
funsigned-bitfields
C ObjC C++ ObjC++
When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
funsigned-char
C ObjC C++ ObjC++
Make \"char\" unsigned by default
fuse-cxa-atexit
C++ ObjC++
Use __cxa_atexit to register destructors
fvtable-gc
C++ ObjC++
Discard unused virtual functions
fvtable-thunks
C++ ObjC++
Implement vtables using thunks
fweak
C++ ObjC++
Emit common-like symbols as weak symbols
fwide-exec-charset=
C ObjC C++ ObjC++ Joined RejectNegative
-fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset>
fworking-directory
C ObjC C++ ObjC++
Generate a #line directive pointing at the current working directory
fxref
C++ ObjC++
Emit cross referencing information
fzero-link
ObjC ObjC++
Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode
gen-decls
ObjC ObjC++
Dump declarations to a .decl file
idirafter
C ObjC C++ ObjC++ Joined Separate
-idirafter <dir> Add <dir> to the end of the system include path
imacros
C ObjC C++ ObjC++ Joined Separate
-imacros <file> Accept definition of macros in <file>
include
C ObjC C++ ObjC++ Joined Separate
-include <file> Include the contents of <file> before other files
iprefix
C ObjC C++ ObjC++ Joined Separate
-iprefix <path> Specify <path> as a prefix for next two options
isysroot
C ObjC C++ ObjC++ Joined Separate
-isysroot <dir> Set <dir> to be the system root directory
isystem
C ObjC C++ ObjC++ Joined Separate
-isystem <dir> Add <dir> to the start of the system include path
iwithprefix
C ObjC C++ ObjC++ Joined Separate
-iwithprefix <dir> Add <dir> to the end of the system include path
iwithprefixbefore
C ObjC C++ ObjC++ Joined Separate
-iwithprefixbefore <dir> Add <dir> to the end of the main include path
lang-asm
C Undocumented
lang-objc
C ObjC C++ ObjC++ Undocumented
nostdinc
C ObjC C++ ObjC++
Do not search standard system include directories (those specified with -isystem will still be used)
nostdinc++
C++ ObjC++
Do not search standard system include directories for C++
o
C ObjC C++ ObjC++ Joined Separate
; Documented in common.opt
pedantic
C ObjC C++ ObjC++
; Documented in common.opt
pedantic-errors
C ObjC C++ ObjC++
; Documented in common.opt
print-objc-runtime-info
ObjC ObjC++
Generate C header of platform-specific features
remap
C ObjC C++ ObjC++
Remap file names when including files
std=c++98
C++ ObjC++
Conform to the ISO 1998 C++ standard
std=c89
C ObjC
Conform to the ISO 1990 C standard
std=c99
C ObjC
Conform to the ISO 1999 C standard
std=c9x
C ObjC
Deprecated in favor of -std=c99
std=gnu++98
C++ ObjC++
Conform to the ISO 1998 C++ standard with GNU extensions
std=gnu89
C ObjC
Conform to the ISO 1990 C standard with GNU extensions
std=gnu99
C ObjC
Conform to the ISO 1999 C standard with GNU extensions
std=gnu9x
C ObjC
Deprecated in favor of -std=gnu99
std=iso9899:1990
C ObjC
Deprecated in favor of -std=c89
std=iso9899:199409
C ObjC
Conform to the ISO 1990 C standard as amended in 1994
std=iso9899:1999
C ObjC
Deprecated in favor of -std=c99
std=iso9899:199x
C ObjC
Deprecated in favor of -std=c99
traditional-cpp
C ObjC C++ ObjC++
Enable traditional preprocessing
trigraphs
C ObjC C++ ObjC++
-trigraphs Support ISO C trigraphs
undef
C ObjC C++ ObjC++
Do not predefine system-specific and GCC-specific macros
v
C ObjC C++ ObjC++
Enable verbose output
w
C ObjC C++ ObjC++
; Documented in common.opt
; This comment is to ensure we retain the blank line above.

View File

@ -1,6 +1,6 @@
/* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998,
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "insn-config.h"
#include "flags.h"
@ -49,13 +51,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
register because it is live we first try to save in multi-register modes.
If that is not possible the save is done one register at a time. */
static enum machine_mode
static enum machine_mode
regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
/* For each hard register, a place on the stack where it can be saved,
if needed. */
static rtx
static rtx
regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
/* We will only make a register eligible for caller-save if it can be
@ -66,7 +68,7 @@ static rtx
static int
reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
static int
static int
reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
/* Set of hard regs currently residing in save area (during insn scan). */
@ -86,29 +88,28 @@ static HARD_REG_SET referenced_regs;
static HARD_REG_SET this_insn_sets;
static void mark_set_regs PARAMS ((rtx, rtx, void *));
static void mark_referenced_regs PARAMS ((rtx));
static int insert_save PARAMS ((struct insn_chain *, int, int,
HARD_REG_SET *,
enum machine_mode *));
static int insert_restore PARAMS ((struct insn_chain *, int, int,
int, enum machine_mode *));
static struct insn_chain *insert_one_insn PARAMS ((struct insn_chain *, int,
int, rtx));
static void add_stored_regs PARAMS ((rtx, rtx, void *));
static void mark_set_regs (rtx, rtx, void *);
static void mark_referenced_regs (rtx);
static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
enum machine_mode *);
static int insert_restore (struct insn_chain *, int, int, int,
enum machine_mode *);
static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
rtx);
static void add_stored_regs (rtx, rtx, void *);
/* Initialize for caller-save.
Look at all the hard registers that are used by a call and for which
regclass.c has not already excluded from being used across a call.
Ensure that we can find a mode to save the register and that there is a
Ensure that we can find a mode to save the register and that there is a
simple insn to save and restore the register. This latter check avoids
problems that would occur if we tried to save the MQ register of some
machines directly into memory. */
void
init_caller_save ()
init_caller_save (void)
{
rtx addr_reg;
int offset;
@ -182,7 +183,7 @@ init_caller_save ()
address = addr_reg;
/* Next we try to form an insn to save and restore the register. We
see if such an insn is recognized and meets its constraints.
see if such an insn is recognized and meets its constraints.
To avoid lots of unnecessary RTL allocation, we construct all the RTL
once, then modify the memory and register operands in-place. */
@ -254,7 +255,7 @@ init_caller_save ()
/* Initialize save areas by showing that we haven't allocated any yet. */
void
init_save_areas ()
init_save_areas (void)
{
int i, j;
@ -272,17 +273,17 @@ init_save_areas ()
Future work:
In the fallback case we should iterate backwards across all possible
modes for the save, choosing the largest available one instead of
modes for the save, choosing the largest available one instead of
falling back to the smallest mode immediately. (eg TF -> DF -> SF).
We do not try to use "move multiple" instructions that exist
on some machines (such as the 68k moveml). It could be a win to try
on some machines (such as the 68k moveml). It could be a win to try
and use them when possible. The hard part is doing it in a way that is
machine independent since they might be saving non-consecutive
machine independent since they might be saving non-consecutive
registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
void
setup_save_areas ()
setup_save_areas (void)
{
int i, j, k;
unsigned int r;
@ -298,7 +299,7 @@ setup_save_areas ()
if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
{
unsigned int regno = reg_renumber[i];
unsigned int endregno
unsigned int endregno
= regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
for (r = regno; r < endregno; r++)
@ -365,7 +366,7 @@ setup_save_areas ()
/* Find the places where hard regs are live across calls and save them. */
void
save_call_clobbered_regs ()
save_call_clobbered_regs (void)
{
struct insn_chain *chain, *next;
enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
@ -407,7 +408,7 @@ save_call_clobbered_regs ()
regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
}
if (code == CALL_INSN)
if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
{
int regno;
HARD_REG_SET hard_regs_to_save;
@ -486,7 +487,7 @@ save_call_clobbered_regs ()
regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN,
regno, MOVE_MAX_WORDS, save_mode);
}
}
}
}
/* Here from note_stores when an insn stores a value in a register.
@ -494,10 +495,8 @@ save_call_clobbered_regs ()
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
static void
mark_set_regs (reg, setter, data)
rtx reg;
rtx setter ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED)
{
int regno, endregno, i;
enum machine_mode mode = GET_MODE (reg);
@ -527,10 +526,7 @@ mark_set_regs (reg, setter, data)
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
static void
add_stored_regs (reg, setter, data)
rtx reg;
rtx setter;
void *data;
add_stored_regs (rtx reg, rtx setter, void *data)
{
int regno, endregno, i;
enum machine_mode mode = GET_MODE (reg);
@ -560,8 +556,7 @@ add_stored_regs (reg, setter, data)
/* Walk X and record all referenced registers in REFERENCED_REGS. */
static void
mark_referenced_regs (x)
rtx x;
mark_referenced_regs (rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@ -573,8 +568,10 @@ mark_referenced_regs (x)
{
x = SET_DEST (x);
code = GET_CODE (x);
if (code == REG || code == PC || code == CC0
if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
|| code == PC || code == CC0
|| (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
/* If we're setting only part of a multi-word register,
we shall mark it as referenced, because the words
that are not being set should be restored. */
@ -637,12 +634,8 @@ mark_referenced_regs (x)
Return the extra number of registers saved. */
static int
insert_restore (chain, before_p, regno, maxrestore, save_mode)
struct insn_chain *chain;
int before_p;
int regno;
int maxrestore;
enum machine_mode *save_mode;
insert_restore (struct insn_chain *chain, int before_p, int regno,
int maxrestore, enum machine_mode *save_mode)
{
int i, k;
rtx pat = NULL_RTX;
@ -679,7 +672,7 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
ok = 0;
break;
}
/* Must do this one restore at a time */
/* Must do this one restore at a time. */
if (! ok)
continue;
@ -693,7 +686,7 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
&& numregs == (unsigned int) HARD_REGNO_NREGS (regno, save_mode [regno]))
mem = adjust_address (mem, save_mode[regno], 0);
pat = gen_rtx_SET (VOIDmode,
gen_rtx_REG (GET_MODE (mem),
gen_rtx_REG (GET_MODE (mem),
regno), mem);
code = reg_restore_code[regno][GET_MODE (mem)];
new = insert_one_insn (chain, before_p, code, pat);
@ -706,19 +699,15 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
n_regs_saved--;
}
/* Tell our callers how many extra registers we saved/restored */
/* Tell our callers how many extra registers we saved/restored. */
return numregs - 1;
}
/* Like insert_restore above, but save registers instead. */
static int
insert_save (chain, before_p, regno, to_save, save_mode)
struct insn_chain *chain;
int before_p;
int regno;
HARD_REG_SET *to_save;
enum machine_mode *save_mode;
insert_save (struct insn_chain *chain, int before_p, int regno,
HARD_REG_SET (*to_save), enum machine_mode *save_mode)
{
int i;
unsigned int k;
@ -740,7 +729,7 @@ insert_save (chain, before_p, regno, to_save, save_mode)
/* Get the pattern to emit and update our status.
See if we can save several registers with a single instruction.
See if we can save several registers with a single instruction.
Work backwards to the single register case. */
for (i = MOVE_MAX_WORDS; i > 0; i--)
{
@ -755,7 +744,7 @@ insert_save (chain, before_p, regno, to_save, save_mode)
ok = 0;
break;
}
/* Must do this one save at a time */
/* Must do this one save at a time. */
if (! ok)
continue;
@ -782,21 +771,17 @@ insert_save (chain, before_p, regno, to_save, save_mode)
n_regs_saved++;
}
/* Tell our callers how many extra registers we saved/restored */
/* Tell our callers how many extra registers we saved/restored. */
return numregs - 1;
}
/* Emit a new caller-save insn and set the code. */
static struct insn_chain *
insert_one_insn (chain, before_p, code, pat)
struct insn_chain *chain;
int before_p;
int code;
rtx pat;
insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
{
rtx insn = chain->insn;
struct insn_chain *new;
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an
@ -849,8 +834,8 @@ insert_one_insn (chain, before_p, code, pat)
}
}
CLEAR_REG_SET (&new->dead_or_set);
if (chain->insn == BLOCK_HEAD (chain->block))
BLOCK_HEAD (chain->block) = new->insn;
if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;
}
else
{
@ -869,8 +854,8 @@ insert_one_insn (chain, before_p, code, pat)
note_stores (PATTERN (chain->insn), add_stored_regs,
&new->live_throughout);
CLEAR_REG_SET (&new->dead_or_set);
if (chain->insn == BLOCK_END (chain->block))
BLOCK_END (chain->block) = new->insn;
if (chain->insn == BB_END (BASIC_BLOCK (chain->block)))
BB_END (BASIC_BLOCK (chain->block)) = new->insn;
}
new->block = chain->block;
new->is_caller_save_insn = 1;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@ -20,7 +20,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This file contains low level functions to manipulate the CFG and
analyze it. All other modules should not transform the datastructure
analyze it. All other modules should not transform the data structure
directly and use abstraction instead. The file is supposed to be
ordered bottom-up and should not contain any code dependent on a
particular intermediate language (RTL or trees).
@ -39,10 +39,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- Allocation of AUX fields for basic blocks
alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
- clear_bb_flags
- Consistency checking
verify_flow_info
- Dumping and debugging
print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
*/
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@ -55,12 +61,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "tm_p.h"
#include "obstack.h"
#include "alloc-pool.h"
/* The obstack on which the flow graph components are allocated. */
struct obstack flow_obstack;
static char *flow_firstobj;
/* Basic block object pool. */
static alloc_pool bb_pool;
/* Edge object pool. */
static alloc_pool edge_pool;
/* Number of basic blocks in the current function. */
int n_basic_blocks;
@ -73,11 +88,6 @@ int last_basic_block;
int n_edges;
/* First edge in the deleted edges chain. */
edge first_deleted_edge;
static basic_block first_deleted_block;
/* The basic block array. */
varray_type basic_block_info;
@ -101,9 +111,11 @@ struct basic_block_def entry_exit_blocks[2]
EXIT_BLOCK_PTR, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
{ NULL, NULL }, /* dom */
0, /* count */
0, /* frequency */
0 /* flags */
0, /* flags */
NULL /* rbi */
},
{
NULL, /* head */
@ -122,56 +134,59 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
{ NULL, NULL }, /* dom */
0, /* count */
0, /* frequency */
0 /* flags */
0, /* flags */
NULL /* rbi */
}
};
void debug_flow_info PARAMS ((void));
static void free_edge PARAMS ((edge));
void debug_flow_info (void);
static void free_edge (edge);
/* Called once at initialization time. */
void
init_flow ()
init_flow (void)
{
static int initialized;
first_deleted_edge = 0;
first_deleted_block = 0;
n_edges = 0;
if (!initialized)
{
gcc_obstack_init (&flow_obstack);
flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
flow_firstobj = obstack_alloc (&flow_obstack, 0);
initialized = 1;
}
else
{
free_alloc_pool (bb_pool);
free_alloc_pool (edge_pool);
obstack_free (&flow_obstack, flow_firstobj);
flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
flow_firstobj = obstack_alloc (&flow_obstack, 0);
}
bb_pool = create_alloc_pool ("Basic block pool",
sizeof (struct basic_block_def), 100);
edge_pool = create_alloc_pool ("Edge pool",
sizeof (struct edge_def), 100);
}
/* Helper function for remove_edge and clear_edges. Frees edge structure
without actually unlinking it from the pred/succ lists. */
static void
free_edge (e)
edge e;
free_edge (edge e)
{
n_edges--;
memset (e, 0, sizeof *e);
e->succ_next = first_deleted_edge;
first_deleted_edge = e;
pool_free (edge_pool, e);
}
/* Free the memory associated with the edge structures. */
void
clear_edges ()
clear_edges (void)
{
basic_block bb;
edge e;
@ -211,28 +226,17 @@ clear_edges ()
/* Allocate memory for basic_block. */
basic_block
alloc_block ()
alloc_block (void)
{
basic_block bb;
if (first_deleted_block)
{
bb = first_deleted_block;
first_deleted_block = (basic_block) bb->succ;
bb->succ = NULL;
}
else
{
bb = (basic_block) obstack_alloc (&flow_obstack, sizeof *bb);
memset (bb, 0, sizeof *bb);
}
bb = pool_alloc (bb_pool);
memset (bb, 0, sizeof (*bb));
return bb;
}
/* Link block B to chain after AFTER. */
void
link_block (b, after)
basic_block b, after;
link_block (basic_block b, basic_block after)
{
b->next_bb = after->next_bb;
b->prev_bb = after;
@ -242,8 +246,7 @@ link_block (b, after)
/* Unlink block B from chain. */
void
unlink_block (b)
basic_block b;
unlink_block (basic_block b)
{
b->next_bb->prev_bb = b->prev_bb;
b->prev_bb->next_bb = b->next_bb;
@ -251,11 +254,11 @@ unlink_block (b)
/* Sequentially order blocks and compact the arrays. */
void
compact_blocks ()
compact_blocks (void)
{
int i;
basic_block bb;
i = 0;
FOR_EACH_BB (bb)
{
@ -270,22 +273,15 @@ compact_blocks ()
last_basic_block = n_basic_blocks;
}
/* Remove block B from the basic block array. */
void
expunge_block (b)
basic_block b;
expunge_block (basic_block b)
{
unlink_block (b);
BASIC_BLOCK (b->index) = NULL;
n_basic_blocks--;
/* Invalidate data to make bughunting easier. */
memset (b, 0, sizeof *b);
b->index = -3;
b->succ = (edge) first_deleted_block;
first_deleted_block = (basic_block) b;
pool_free (bb_pool, b);
}
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
@ -293,22 +289,11 @@ expunge_block (b)
possibly already exist. */
edge
unchecked_make_edge (src, dst, flags)
basic_block src, dst;
int flags;
unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
edge e;
if (first_deleted_edge)
{
e = first_deleted_edge;
first_deleted_edge = e->succ_next;
}
else
{
e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
memset (e, 0, sizeof *e);
}
e = pool_alloc (edge_pool);
memset (e, 0, sizeof (*e));
n_edges++;
e->succ_next = src->succ;
@ -322,14 +307,12 @@ unchecked_make_edge (src, dst, flags)
return e;
}
/* Create an edge connecting SRC and DST with FLAGS optionally using
edge cache CACHE. Return the new edge, NULL if already exist. */
edge
cached_make_edge (edge_cache, src, dst, flags)
sbitmap *edge_cache;
basic_block src, dst;
int flags;
cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
{
int use_edge_cache;
edge e;
@ -351,7 +334,7 @@ cached_make_edge (edge_cache, src, dst, flags)
if (flags == 0)
return NULL;
/* FALLTHRU */
/* Fall through. */
case 0:
for (e = src->succ; e; e = e->succ_next)
if (e->dest == dst)
@ -374,9 +357,7 @@ cached_make_edge (edge_cache, src, dst, flags)
created edge or NULL if already exist. */
edge
make_edge (src, dest, flags)
basic_block src, dest;
int flags;
make_edge (basic_block src, basic_block dest, int flags)
{
return cached_make_edge (NULL, src, dest, flags);
}
@ -385,9 +366,7 @@ make_edge (src, dest, flags)
that it is the single edge leaving SRC. */
edge
make_single_succ_edge (src, dest, flags)
basic_block src, dest;
int flags;
make_single_succ_edge (basic_block src, basic_block dest, int flags)
{
edge e = make_edge (src, dest, flags);
@ -399,8 +378,7 @@ make_single_succ_edge (src, dest, flags)
/* This function will remove an edge from the flow graph. */
void
remove_edge (e)
edge e;
remove_edge (edge e)
{
edge last_pred = NULL;
edge last_succ = NULL;
@ -435,9 +413,7 @@ remove_edge (e)
/* Redirect an edge's successor from one block to another. */
void
redirect_edge_succ (e, new_succ)
edge e;
basic_block new_succ;
redirect_edge_succ (edge e, basic_block new_succ)
{
edge *pe;
@ -455,9 +431,7 @@ redirect_edge_succ (e, new_succ)
/* Like previous but avoid possible duplicate edge. */
edge
redirect_edge_succ_nodup (e, new_succ)
edge e;
basic_block new_succ;
redirect_edge_succ_nodup (edge e, basic_block new_succ)
{
edge s;
@ -485,9 +459,7 @@ redirect_edge_succ_nodup (e, new_succ)
/* Redirect an edge's predecessor from one block to another. */
void
redirect_edge_pred (e, new_pred)
edge e;
basic_block new_pred;
redirect_edge_pred (edge e, basic_block new_pred)
{
edge *pe;
@ -504,7 +476,7 @@ redirect_edge_pred (e, new_pred)
}
void
clear_bb_flags ()
clear_bb_flags (void)
{
basic_block bb;
@ -513,8 +485,7 @@ clear_bb_flags ()
}
void
dump_flow_info (file)
FILE *file;
dump_flow_info (FILE *file)
{
int i;
int max_regno = max_reg_num ();
@ -522,48 +493,49 @@ dump_flow_info (file)
static const char * const reg_class_names[] = REG_CLASS_NAMES;
fprintf (file, "%d registers.\n", max_regno);
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (REG_N_REFS (i))
{
enum reg_class class, altclass;
if (reg_n_info)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (REG_N_REFS (i))
{
enum reg_class class, altclass;
fprintf (file, "\nRegister %d used %d times across %d insns",
i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
if (REG_BASIC_BLOCK (i) >= 0)
fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
if (REG_N_SETS (i))
fprintf (file, "; set %d time%s", REG_N_SETS (i),
(REG_N_SETS (i) == 1) ? "" : "s");
if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
fprintf (file, "; user var");
if (REG_N_DEATHS (i) != 1)
fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
if (REG_N_CALLS_CROSSED (i) == 1)
fprintf (file, "; crosses 1 call");
else if (REG_N_CALLS_CROSSED (i))
fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
if (regno_reg_rtx[i] != NULL
&& PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
fprintf (file, "\nRegister %d used %d times across %d insns",
i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
if (REG_BASIC_BLOCK (i) >= 0)
fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
if (REG_N_SETS (i))
fprintf (file, "; set %d time%s", REG_N_SETS (i),
(REG_N_SETS (i) == 1) ? "" : "s");
if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
fprintf (file, "; user var");
if (REG_N_DEATHS (i) != 1)
fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
if (REG_N_CALLS_CROSSED (i) == 1)
fprintf (file, "; crosses 1 call");
else if (REG_N_CALLS_CROSSED (i))
fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
if (regno_reg_rtx[i] != NULL
&& PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
class = reg_preferred_class (i);
altclass = reg_alternate_class (i);
if (class != GENERAL_REGS || altclass != ALL_REGS)
{
if (altclass == ALL_REGS || class == ALL_REGS)
fprintf (file, "; pref %s", reg_class_names[(int) class]);
else if (altclass == NO_REGS)
fprintf (file, "; %s or none", reg_class_names[(int) class]);
else
fprintf (file, "; pref %s, else %s",
reg_class_names[(int) class],
reg_class_names[(int) altclass]);
}
class = reg_preferred_class (i);
altclass = reg_alternate_class (i);
if (class != GENERAL_REGS || altclass != ALL_REGS)
{
if (altclass == ALL_REGS || class == ALL_REGS)
fprintf (file, "; pref %s", reg_class_names[(int) class]);
else if (altclass == NO_REGS)
fprintf (file, "; %s or none", reg_class_names[(int) class]);
else
fprintf (file, "; pref %s, else %s",
reg_class_names[(int) class],
reg_class_names[(int) altclass]);
}
if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
fprintf (file, "; pointer");
fprintf (file, ".\n");
}
if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
fprintf (file, "; pointer");
fprintf (file, ".\n");
}
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
FOR_EACH_BB (bb)
@ -573,7 +545,7 @@ dump_flow_info (file)
gcov_type lsum;
fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
fprintf (file, "prev %d, next %d, ",
bb->prev_bb->index, bb->next_bb->index);
fprintf (file, "loop_depth %d, count ", bb->loop_depth);
@ -603,7 +575,7 @@ dump_flow_info (file)
/* Check the consistency of profile information. We can't do that
in verify_flow_info, as the counts may get invalid for incompletely
solved graphs, later elliminating of conditionals or roundoff errors.
solved graphs, later eliminating of conditionals or roundoff errors.
It is still practical to have them reported for debugging of simple
testcases. */
sum = 0;
@ -637,16 +609,13 @@ dump_flow_info (file)
}
void
debug_flow_info ()
debug_flow_info (void)
{
dump_flow_info (stderr);
}
void
dump_edge_info (file, e, do_succ)
FILE *file;
edge e;
int do_succ;
dump_edge_info (FILE *file, edge e, int do_succ)
{
basic_block side = (do_succ ? e->dest : e->src);
@ -668,8 +637,10 @@ dump_edge_info (file, e, do_succ)
if (e->flags)
{
static const char * const bitnames[]
= {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
static const char * const bitnames[] = {
"fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
"can_fallthru", "irreducible", "sibcall", "loop_exit"
};
int comma = 0;
int i, flags = e->flags;
@ -703,9 +674,7 @@ static void *first_edge_aux_obj = 0;
be first initialized by alloc_aux_for_blocks. */
inline void
alloc_aux_for_block (bb, size)
basic_block bb;
int size;
alloc_aux_for_block (basic_block bb, int size)
{
/* Verify that aux field is clear. */
if (bb->aux || !first_block_aux_obj)
@ -718,8 +687,7 @@ alloc_aux_for_block (bb, size)
alloc_aux_for_block for each basic block. */
void
alloc_aux_for_blocks (size)
int size;
alloc_aux_for_blocks (int size)
{
static int initialized;
@ -732,7 +700,7 @@ alloc_aux_for_blocks (size)
/* Check whether AUX data are still allocated. */
else if (first_block_aux_obj)
abort ();
first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
if (size)
{
basic_block bb;
@ -745,7 +713,7 @@ alloc_aux_for_blocks (size)
/* Clear AUX pointers of all blocks. */
void
clear_aux_for_blocks ()
clear_aux_for_blocks (void)
{
basic_block bb;
@ -757,7 +725,7 @@ clear_aux_for_blocks ()
of all blocks. */
void
free_aux_for_blocks ()
free_aux_for_blocks (void)
{
if (!first_block_aux_obj)
abort ();
@ -771,9 +739,7 @@ free_aux_for_blocks ()
be first initialized by alloc_aux_for_edges. */
inline void
alloc_aux_for_edge (e, size)
edge e;
int size;
alloc_aux_for_edge (edge e, int size)
{
/* Verify that aux field is clear. */
if (e->aux || !first_edge_aux_obj)
@ -786,8 +752,7 @@ alloc_aux_for_edge (e, size)
alloc_aux_for_edge for each basic edge. */
void
alloc_aux_for_edges (size)
int size;
alloc_aux_for_edges (int size)
{
static int initialized;
@ -801,7 +766,7 @@ alloc_aux_for_edges (size)
else if (first_edge_aux_obj)
abort ();
first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
if (size)
{
basic_block bb;
@ -819,7 +784,7 @@ alloc_aux_for_edges (size)
/* Clear AUX pointers of all edges. */
void
clear_aux_for_edges ()
clear_aux_for_edges (void)
{
basic_block bb;
edge e;
@ -835,7 +800,7 @@ clear_aux_for_edges ()
of all edges. */
void
free_aux_for_edges ()
free_aux_for_edges (void)
{
if (!first_edge_aux_obj)
abort ();
@ -844,3 +809,186 @@ free_aux_for_edges ()
clear_aux_for_edges ();
}
/* Verify the CFG consistency.
Currently it does following checks edge and basic block list correctness
and calls into IL dependent checking then. */
void
verify_flow_info (void)
{
size_t *edge_checksum;
int num_bb_notes, err = 0;
basic_block bb, last_bb_seen;
basic_block *last_visited;
last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
/* Check bb chain & numbers. */
last_bb_seen = ENTRY_BLOCK_PTR;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
{
if (bb != EXIT_BLOCK_PTR
&& bb != BASIC_BLOCK (bb->index))
{
error ("bb %d on wrong place", bb->index);
err = 1;
}
if (bb->prev_bb != last_bb_seen)
{
error ("prev_bb of %d should be %d, not %d",
bb->index, last_bb_seen->index, bb->prev_bb->index);
err = 1;
}
last_bb_seen = bb;
}
/* Now check the basic blocks (boundaries etc.) */
FOR_EACH_BB_REVERSE (bb)
{
int n_fallthru = 0;
edge e;
if (bb->count < 0)
{
error ("verify_flow_info: Wrong count of block %i %i",
bb->index, (int)bb->count);
err = 1;
}
if (bb->frequency < 0)
{
error ("verify_flow_info: Wrong frequency of block %i %i",
bb->index, bb->frequency);
err = 1;
}
for (e = bb->succ; e; e = e->succ_next)
{
if (last_visited [e->dest->index + 2] == bb)
{
error ("verify_flow_info: Duplicate edge %i->%i",
e->src->index, e->dest->index);
err = 1;
}
if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
{
error ("verify_flow_info: Wrong probability of edge %i->%i %i",
e->src->index, e->dest->index, e->probability);
err = 1;
}
if (e->count < 0)
{
error ("verify_flow_info: Wrong count of edge %i->%i %i",
e->src->index, e->dest->index, (int)e->count);
err = 1;
}
last_visited [e->dest->index + 2] = bb;
if (e->flags & EDGE_FALLTHRU)
n_fallthru++;
if (e->src != bb)
{
error ("verify_flow_info: Basic block %d succ edge is corrupted",
bb->index);
fprintf (stderr, "Predecessor: ");
dump_edge_info (stderr, e, 0);
fprintf (stderr, "\nSuccessor: ");
dump_edge_info (stderr, e, 1);
fprintf (stderr, "\n");
err = 1;
}
edge_checksum[e->dest->index + 2] += (size_t) e;
}
if (n_fallthru > 1)
{
error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
err = 1;
}
for (e = bb->pred; e; e = e->pred_next)
{
if (e->dest != bb)
{
error ("basic block %d pred edge is corrupted", bb->index);
fputs ("Predecessor: ", stderr);
dump_edge_info (stderr, e, 0);
fputs ("\nSuccessor: ", stderr);
dump_edge_info (stderr, e, 1);
fputc ('\n', stderr);
err = 1;
}
edge_checksum[e->dest->index + 2] -= (size_t) e;
}
}
/* Complete edge checksumming for ENTRY and EXIT. */
{
edge e;
for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
edge_checksum[e->dest->index + 2] += (size_t) e;
for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
edge_checksum[e->dest->index + 2] -= (size_t) e;
}
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
if (edge_checksum[bb->index + 2])
{
error ("basic block %i edge lists are corrupted", bb->index);
err = 1;
}
num_bb_notes = 0;
last_bb_seen = ENTRY_BLOCK_PTR;
/* Clean up. */
free (last_visited);
free (edge_checksum);
err |= cfg_hooks->cfgh_verify_flow_info ();
if (err)
internal_error ("verify_flow_info failed");
}
/* Print out one basic block with live information at start and end. */
void
dump_bb (basic_block bb, FILE *outf)
{
edge e;
fprintf (outf, ";; Basic block %d, loop depth %d, count ",
bb->index, bb->loop_depth);
fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
putc ('\n', outf);
fputs (";; Predecessors: ", outf);
for (e = bb->pred; e; e = e->pred_next)
dump_edge_info (outf, e, 0);
putc ('\n', outf);
cfg_hooks->dump_bb (bb, outf);
fputs (";; Successors: ", outf);
for (e = bb->succ; e; e = e->succ_next)
dump_edge_info (outf, e, 1);
putc ('\n', outf);
}
void
debug_bb (basic_block bb)
{
dump_bb (bb, stderr);
}
basic_block
debug_bb_n (int n)
{
basic_block bb = BASIC_BLOCK (n);
dump_bb (bb, stderr);
return bb;
}

View File

@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* This file contains various simple utilities to analyze the CFG. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
@ -44,29 +46,25 @@ struct depth_first_search_dsS {
};
typedef struct depth_first_search_dsS *depth_first_search_ds;
static void flow_dfs_compute_reverse_init
PARAMS ((depth_first_search_ds));
static void flow_dfs_compute_reverse_add_bb
PARAMS ((depth_first_search_ds, basic_block));
static basic_block flow_dfs_compute_reverse_execute
PARAMS ((depth_first_search_ds));
static void flow_dfs_compute_reverse_finish
PARAMS ((depth_first_search_ds));
static void remove_fake_successors PARAMS ((basic_block));
static bool need_fake_edge_p PARAMS ((rtx));
static bool flow_active_insn_p PARAMS ((rtx));
static void flow_dfs_compute_reverse_init (depth_first_search_ds);
static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
basic_block);
static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds);
static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
static void remove_fake_successors (basic_block);
static bool need_fake_edge_p (rtx);
static bool flow_active_insn_p (rtx);
/* Like active_insn_p, except keep the return value clobber around
even after reload. */
static bool
flow_active_insn_p (insn)
rtx insn;
flow_active_insn_p (rtx insn)
{
if (active_insn_p (insn))
return true;
/* A clobber of the function return value exists for buggy
/* A clobber of the function return value exists for buggy
programs that fail to return a value. Its effect is to
keep the return value from being live across the entire
function. If we allow it to be skipped, we introduce the
@ -83,8 +81,7 @@ flow_active_insn_p (insn)
its single destination. */
bool
forwarder_block_p (bb)
basic_block bb;
forwarder_block_p (basic_block bb)
{
rtx insn;
@ -92,7 +89,7 @@ forwarder_block_p (bb)
|| !bb->succ || bb->succ->succ_next)
return false;
for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
@ -104,16 +101,15 @@ forwarder_block_p (bb)
/* Return nonzero if we can reach target from src by falling through. */
bool
can_fallthru (src, target)
basic_block src, target;
can_fallthru (basic_block src, basic_block target)
{
rtx insn = src->end;
rtx insn2 = target->head;
rtx insn = BB_END (src);
rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : BB_HEAD (target);
if (src->next_bb != target)
return 0;
if (!active_insn_p (insn2))
if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
@ -131,7 +127,7 @@ can_fallthru (src, target)
and heavily borrowed from flow_depth_first_order_compute. */
bool
mark_dfs_back_edges ()
mark_dfs_back_edges (void)
{
edge *stack;
int *pre;
@ -143,11 +139,11 @@ mark_dfs_back_edges ()
bool found = false;
/* Allocate the preorder and postorder number arrays. */
pre = (int *) xcalloc (last_basic_block, sizeof (int));
post = (int *) xcalloc (last_basic_block, sizeof (int));
pre = xcalloc (last_basic_block, sizeof (int));
post = xcalloc (last_basic_block, sizeof (int));
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@ -215,7 +211,7 @@ mark_dfs_back_edges ()
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
void
set_edge_can_fallthru_flag ()
set_edge_can_fallthru_flag (void)
{
basic_block bb;
@ -232,15 +228,15 @@ set_edge_can_fallthru_flag ()
e->flags |= EDGE_CAN_FALLTHRU;
}
/* If the BB ends with an invertable condjump all (2) edges are
/* If the BB ends with an invertible condjump all (2) edges are
CAN_FALLTHRU edges. */
if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
continue;
if (!any_condjump_p (bb->end))
if (!any_condjump_p (BB_END (bb)))
continue;
if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
continue;
invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
bb->succ->flags |= EDGE_CAN_FALLTHRU;
bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
}
@ -250,8 +246,7 @@ set_edge_can_fallthru_flag ()
Helper function for the flow_call_edges_add. */
static bool
need_fake_edge_p (insn)
rtx insn;
need_fake_edge_p (rtx insn)
{
if (!INSN_P (insn))
return false;
@ -280,8 +275,7 @@ need_fake_edge_p (insn)
that all subsequent instructions must be executed. */
int
flow_call_edges_add (blocks)
sbitmap blocks;
flow_call_edges_add (sbitmap blocks)
{
int i;
int blocks_split = 0;
@ -311,10 +305,10 @@ flow_call_edges_add (blocks)
if (check_last_block)
{
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
rtx insn = bb->end;
rtx insn = BB_END (bb);
/* Back up past insns that must be kept in the same block as a call. */
while (insn != bb->head
while (insn != BB_HEAD (bb)
&& keep_with_call_p (insn))
insn = PREV_INSN (insn);
@ -339,6 +333,7 @@ flow_call_edges_add (blocks)
for (i = 0; i < last_bb; i++)
{
basic_block bb = BASIC_BLOCK (i);
rtx libcall_end = NULL_RTX;
rtx insn;
rtx prev_insn;
@ -348,7 +343,7 @@ flow_call_edges_add (blocks)
if (blocks && !TEST_BIT (blocks, i))
continue;
for (insn = bb->end; ; insn = prev_insn)
for (insn = BB_END (bb); ; insn = prev_insn)
{
prev_insn = PREV_INSN (insn);
if (need_fake_edge_p (insn))
@ -356,10 +351,14 @@ flow_call_edges_add (blocks)
edge e;
rtx split_at_insn = insn;
/* Don't split libcalls. */
if (libcall_end)
split_at_insn = libcall_end;
/* Don't split the block between a call and an insn that should
remain in the same block as the call. */
if (GET_CODE (insn) == CALL_INSN)
while (split_at_insn != bb->end
else if (GET_CODE (insn) == CALL_INSN)
while (split_at_insn != BB_END (bb)
&& keep_with_call_p (NEXT_INSN (split_at_insn)))
split_at_insn = NEXT_INSN (split_at_insn);
@ -369,7 +368,7 @@ flow_call_edges_add (blocks)
cause us to mark that edge as fake and remove it later. */
#ifdef ENABLE_CHECKING
if (split_at_insn == bb->end)
if (split_at_insn == BB_END (bb))
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
abort ();
@ -377,7 +376,7 @@ flow_call_edges_add (blocks)
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
if (split_at_insn != bb->end)
if (split_at_insn != BB_END (bb))
{
e = split_block (bb, split_at_insn);
if (e)
@ -387,7 +386,15 @@ flow_call_edges_add (blocks)
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
if (insn == bb->head)
/* Watch out for REG_LIBCALL/REG_RETVAL notes so that we know
whether we are currently in a libcall or not. Remember that
we are scanning backwards! */
if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
libcall_end = insn;
if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
libcall_end = NULL_RTX;
if (insn == BB_HEAD (bb))
break;
}
}
@ -403,13 +410,12 @@ flow_call_edges_add (blocks)
block is reachable. */
void
find_unreachable_blocks ()
find_unreachable_blocks (void)
{
edge e;
basic_block *tos, *worklist, bb;
tos = worklist =
(basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* Clear all the reachability flags. */
@ -459,7 +465,7 @@ find_unreachable_blocks ()
and the data structure is filled in. */
struct edge_list *
create_edge_list ()
create_edge_list (void)
{
struct edge_list *elist;
edge e;
@ -479,10 +485,10 @@ create_edge_list ()
num_edges++;
}
elist = (struct edge_list *) xmalloc (sizeof (struct edge_list));
elist = xmalloc (sizeof (struct edge_list));
elist->num_blocks = block_count;
elist->num_edges = num_edges;
elist->index_to_edge = (edge *) xmalloc (sizeof (edge) * num_edges);
elist->index_to_edge = xmalloc (sizeof (edge) * num_edges);
num_edges = 0;
@ -497,8 +503,7 @@ create_edge_list ()
/* This function free's memory associated with an edge list. */
void
free_edge_list (elist)
struct edge_list *elist;
free_edge_list (struct edge_list *elist)
{
if (elist)
{
@ -510,9 +515,7 @@ free_edge_list (elist)
/* This function provides debug output showing an edge list. */
void
print_edge_list (f, elist)
FILE *f;
struct edge_list *elist;
print_edge_list (FILE *f, struct edge_list *elist)
{
int x;
@ -539,9 +542,7 @@ print_edge_list (f, elist)
extra edges. */
void
verify_edge_list (f, elist)
FILE *f;
struct edge_list *elist;
verify_edge_list (FILE *f, struct edge_list *elist)
{
int pred, succ, index;
edge e;
@ -606,9 +607,7 @@ verify_edge_list (f, elist)
a specified predecessor and successor. */
int
find_edge_index (edge_list, pred, succ)
struct edge_list *edge_list;
basic_block pred, succ;
find_edge_index (struct edge_list *edge_list, basic_block pred, basic_block succ)
{
int x;
@ -623,10 +622,7 @@ find_edge_index (edge_list, pred, succ)
/* Dump the list of basic blocks in the bitmap NODES. */
void
flow_nodes_print (str, nodes, file)
const char *str;
const sbitmap nodes;
FILE *file;
flow_nodes_print (const char *str, const sbitmap nodes, FILE *file)
{
int node;
@ -641,11 +637,7 @@ flow_nodes_print (str, nodes, file)
/* Dump the list of edges in the array EDGE_LIST. */
void
flow_edge_list_print (str, edge_list, num_edges, file)
const char *str;
const edge *edge_list;
int num_edges;
FILE *file;
flow_edge_list_print (const char *str, const edge *edge_list, int num_edges, FILE *file)
{
int i;
@ -666,8 +658,7 @@ flow_edge_list_print (str, edge_list, num_edges, file)
list it is in. */
static void
remove_fake_successors (bb)
basic_block bb;
remove_fake_successors (basic_block bb)
{
edge e;
@ -686,7 +677,7 @@ remove_fake_successors (bb)
fake predecessors. */
void
remove_fake_edges ()
remove_fake_edges (void)
{
basic_block bb;
@ -699,7 +690,7 @@ remove_fake_edges ()
edges to exist. */
void
add_noreturn_fake_exit_edges ()
add_noreturn_fake_exit_edges (void)
{
basic_block bb;
@ -720,7 +711,7 @@ add_noreturn_fake_exit_edges ()
nodes not reachable from the exit block. */
void
connect_infinite_loops_to_exit ()
connect_infinite_loops_to_exit (void)
{
basic_block unvisited_block;
struct depth_first_search_dsS dfs_ds;
@ -745,11 +736,10 @@ connect_infinite_loops_to_exit ()
return;
}
/* Compute reverse top sort order */
/* Compute reverse top sort order. */
void
flow_reverse_top_sort_order_compute (rts_order)
int *rts_order;
flow_reverse_top_sort_order_compute (int *rts_order)
{
edge *stack;
int sp;
@ -757,7 +747,7 @@ flow_reverse_top_sort_order_compute (rts_order)
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@ -817,9 +807,7 @@ flow_reverse_top_sort_order_compute (rts_order)
possible. */
int
flow_depth_first_order_compute (dfs_order, rc_order)
int *dfs_order;
int *rc_order;
flow_depth_first_order_compute (int *dfs_order, int *rc_order)
{
edge *stack;
int sp;
@ -828,7 +816,7 @@ flow_depth_first_order_compute (dfs_order, rc_order)
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@ -920,8 +908,7 @@ struct dfst_node
2) Walking the resulting tree from right to left. */
void
flow_preorder_transversal_compute (pot_order)
int *pot_order;
flow_preorder_transversal_compute (int *pot_order)
{
edge e;
edge *stack;
@ -934,12 +921,11 @@ flow_preorder_transversal_compute (pot_order)
basic_block bb;
/* Allocate stack for back-tracking up CFG. */
stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate the tree. */
dfst = (struct dfst_node *) xcalloc (last_basic_block,
sizeof (struct dfst_node));
dfst = xcalloc (last_basic_block, sizeof (struct dfst_node));
FOR_EACH_BB (bb)
{
@ -949,9 +935,7 @@ flow_preorder_transversal_compute (pot_order)
dfst[bb->index].node
= (max_successors
? (struct dfst_node **) xcalloc (max_successors,
sizeof (struct dfst_node *))
: NULL);
? xcalloc (max_successors, sizeof (struct dfst_node *)) : NULL);
}
/* Allocate bitmap to track nodes that have been visited. */
@ -1060,12 +1044,11 @@ flow_preorder_transversal_compute (pot_order)
element on the stack. */
static void
flow_dfs_compute_reverse_init (data)
depth_first_search_ds data;
flow_dfs_compute_reverse_init (depth_first_search_ds data)
{
/* Allocate stack for back-tracking up CFG. */
data->stack = (basic_block *) xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
* sizeof (basic_block));
data->stack = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
* sizeof (basic_block));
data->sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@ -1082,9 +1065,7 @@ flow_dfs_compute_reverse_init (data)
block. */
static void
flow_dfs_compute_reverse_add_bb (data, bb)
depth_first_search_ds data;
basic_block bb;
flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb)
{
data->stack[data->sp++] = bb;
SET_BIT (data->visited_blocks, bb->index - (INVALID_BLOCK + 1));
@ -1096,8 +1077,7 @@ flow_dfs_compute_reverse_add_bb (data, bb)
available. */
static basic_block
flow_dfs_compute_reverse_execute (data)
depth_first_search_ds data;
flow_dfs_compute_reverse_execute (depth_first_search_ds data)
{
basic_block bb;
edge e;
@ -1125,8 +1105,7 @@ flow_dfs_compute_reverse_execute (data)
reverse graph. */
static void
flow_dfs_compute_reverse_finish (data)
depth_first_search_ds data;
flow_dfs_compute_reverse_finish (depth_first_search_ds data)
{
free (data->stack);
sbitmap_free (data->visited_blocks);
@ -1136,13 +1115,9 @@ flow_dfs_compute_reverse_finish (data)
if REVERSE, go against direction of edges. Returns number of blocks
found and their list in RSLT. RSLT can contain at most RSLT_MAX items. */
int
dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data)
basic_block bb;
int reverse;
bool (*predicate) PARAMS ((basic_block, void *));
basic_block *rslt;
int rslt_max;
void *data;
dfs_enumerate_from (basic_block bb, int reverse,
bool (*predicate) (basic_block, void *),
basic_block *rslt, int rslt_max, void *data)
{
basic_block *st, lbb;
int sp = 0, tv = 0;

View File

@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@ -46,24 +48,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "timevar.h"
static int count_basic_blocks PARAMS ((rtx));
static void find_basic_blocks_1 PARAMS ((rtx));
static rtx find_label_refs PARAMS ((rtx, rtx));
static void make_edges PARAMS ((rtx, basic_block,
basic_block, int));
static void make_label_edge PARAMS ((sbitmap *, basic_block,
rtx, int));
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
static void find_bb_boundaries PARAMS ((basic_block));
static void compute_outgoing_frequencies PARAMS ((basic_block));
static bool inside_basic_block_p PARAMS ((rtx));
static int count_basic_blocks (rtx);
static void find_basic_blocks_1 (rtx);
static rtx find_label_refs (rtx, rtx);
static void make_edges (rtx, basic_block, basic_block, int);
static void make_label_edge (sbitmap *, basic_block, rtx, int);
static void make_eh_edge (sbitmap *, basic_block, rtx);
static void find_bb_boundaries (basic_block);
static void compute_outgoing_frequencies (basic_block);
/* Return true if insn is something that should be contained inside basic
block. */
static bool
inside_basic_block_p (insn)
rtx insn;
bool
inside_basic_block_p (rtx insn)
{
switch (GET_CODE (insn))
{
@ -95,8 +93,7 @@ inside_basic_block_p (insn)
the basic block. */
bool
control_flow_insn_p (insn)
rtx insn;
control_flow_insn_p (rtx insn)
{
rtx note;
@ -124,7 +121,7 @@ control_flow_insn_p (insn)
return (flag_non_call_exceptions && can_throw_internal (insn));
case BARRIER:
/* It is nonsence to reach barrier when looking for the
/* It is nonsense to reach barrier when looking for the
end of basic block, but before dead code is eliminated
this may happen. */
return false;
@ -137,8 +134,7 @@ control_flow_insn_p (insn)
/* Count the basic blocks of the function. */
static int
count_basic_blocks (f)
rtx f;
count_basic_blocks (rtx f)
{
int count = 0;
bool saw_insn = false;
@ -146,7 +142,7 @@ count_basic_blocks (f)
for (insn = f; insn; insn = NEXT_INSN (insn))
{
/* Code labels and barriers causes curent basic block to be
/* Code labels and barriers causes current basic block to be
terminated at previous real insn. */
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
&& saw_insn)
@ -179,9 +175,7 @@ count_basic_blocks (f)
This is used to scan the alternatives of a call placeholder. */
static rtx
find_label_refs (f, lvl)
rtx f;
rtx lvl;
find_label_refs (rtx f, rtx lvl)
{
rtx insn;
@ -228,11 +222,7 @@ find_label_refs (f, lvl)
/* Create an edge from a basic block to a label. */
static void
make_label_edge (edge_cache, src, label, flags)
sbitmap *edge_cache;
basic_block src;
rtx label;
int flags;
make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
{
if (GET_CODE (label) != CODE_LABEL)
abort ();
@ -251,10 +241,7 @@ make_label_edge (edge_cache, src, label, flags)
/* Create the edges generated by INSN in REGION. */
static void
make_eh_edge (edge_cache, src, insn)
sbitmap *edge_cache;
basic_block src;
rtx insn;
make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
{
int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
rtx handlers, i;
@ -277,10 +264,7 @@ make_eh_edge (edge_cache, src, insn)
the list of exception regions active at the end of the basic block. */
static void
make_edges (label_value_list, min, max, update_p)
rtx label_value_list;
basic_block min, max;
int update_p;
make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p)
{
basic_block bb;
sbitmap *edge_cache = NULL;
@ -319,13 +303,14 @@ make_edges (label_value_list, min, max, update_p)
enum rtx_code code;
int force_fallthru = 0;
if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALT_ENTRY_P (bb->head))
if (GET_CODE (BB_HEAD (bb)) == CODE_LABEL
&& LABEL_ALT_ENTRY_P (BB_HEAD (bb)))
cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
/* Examine the last instruction of the block, and discover the
ways we can leave the block. */
insn = bb->end;
insn = BB_END (bb);
code = GET_CODE (insn);
/* A branch. */
@ -342,12 +327,8 @@ make_edges (label_value_list, min, max, update_p)
else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
;
/* ??? Recognize a tablejump and do the right thing. */
else if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
&& (tmp = NEXT_INSN (tmp)) != NULL_RTX
&& GET_CODE (tmp) == JUMP_INSN
&& (GET_CODE (PATTERN (tmp)) == ADDR_VEC
|| GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
/* Recognize a tablejump and do the right thing. */
else if (tablejump_p (insn, NULL, &tmp))
{
rtvec vec;
int j;
@ -410,7 +391,7 @@ make_edges (label_value_list, min, max, update_p)
in the first place. */
if (code == CALL_INSN && SIBLING_CALL_P (insn))
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR,
EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
EDGE_SIBCALL | EDGE_ABNORMAL);
/* If this is a CALL_INSN, then mark it as reaching the active EH
handler for this CALL_INSN. If we're handling non-call
@ -442,15 +423,17 @@ make_edges (label_value_list, min, max, update_p)
}
/* Find out if we can drop through to the next block. */
insn = next_nonnote_insn (insn);
insn = NEXT_INSN (insn);
while (insn
&& GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
insn = NEXT_INSN (insn);
if (!insn || (bb->next_bb == EXIT_BLOCK_PTR && force_fallthru))
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
else if (bb->next_bb != EXIT_BLOCK_PTR)
{
rtx tmp = bb->next_bb->head;
if (GET_CODE (tmp) == NOTE)
tmp = next_nonnote_insn (tmp);
if (force_fallthru || insn == tmp)
if (force_fallthru || insn == BB_HEAD (bb->next_bb))
cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
}
}
@ -465,8 +448,7 @@ make_edges (label_value_list, min, max, update_p)
will be used in make_edges for use with computed gotos. */
static void
find_basic_blocks_1 (f)
rtx f;
find_basic_blocks_1 (rtx f)
{
rtx insn, next;
rtx bb_note = NULL_RTX;
@ -605,10 +587,8 @@ find_basic_blocks_1 (f)
numbers in use. */
void
find_basic_blocks (f, nregs, file)
rtx f;
int nregs ATTRIBUTE_UNUSED;
FILE *file ATTRIBUTE_UNUSED;
find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
FILE *file ATTRIBUTE_UNUSED)
{
basic_block bb;
@ -623,7 +603,7 @@ find_basic_blocks (f, nregs, file)
tag for reuse during create_basic_block, just in case some pass
copies around basic block notes improperly. */
FOR_EACH_BB (bb)
bb->aux = NULL;
bb->aux = NULL;
VARRAY_FREE (basic_block_info);
}
@ -668,15 +648,14 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
and create new basic blocks in the progress. */
static void
find_bb_boundaries (bb)
basic_block bb;
find_bb_boundaries (basic_block bb)
{
rtx insn = bb->head;
rtx end = bb->end;
rtx insn = BB_HEAD (bb);
rtx end = BB_END (bb);
rtx flow_transfer_insn = NULL_RTX;
edge fallthru = NULL;
if (insn == bb->end)
if (insn == BB_END (bb))
return;
if (GET_CODE (insn) == CODE_LABEL)
@ -692,7 +671,7 @@ find_bb_boundaries (bb)
{
fallthru = split_block (bb, PREV_INSN (insn));
if (flow_transfer_insn)
bb->end = flow_transfer_insn;
BB_END (bb) = flow_transfer_insn;
bb = fallthru->dest;
remove_edge (fallthru);
@ -706,7 +685,7 @@ find_bb_boundaries (bb)
if (flow_transfer_insn && inside_basic_block_p (insn))
{
fallthru = split_block (bb, PREV_INSN (insn));
bb->end = flow_transfer_insn;
BB_END (bb) = flow_transfer_insn;
bb = fallthru->dest;
remove_edge (fallthru);
flow_transfer_insn = NULL_RTX;
@ -723,7 +702,7 @@ find_bb_boundaries (bb)
return and barrier, or possibly other sequence not behaving like
ordinary jump, we need to take care and move basic block boundary. */
if (flow_transfer_insn)
bb->end = flow_transfer_insn;
BB_END (bb) = flow_transfer_insn;
/* We've possibly replaced the conditional jump by conditional jump
followed by cleanup at fallthru edge, so the outgoing edges may
@ -735,22 +714,19 @@ find_bb_boundaries (bb)
and probabilities of outgoing edges. */
static void
compute_outgoing_frequencies (b)
basic_block b;
compute_outgoing_frequencies (basic_block b)
{
edge e, f;
if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
{
rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
int probability;
if (!note)
return;
probability = INTVAL (XEXP (find_reg_note (b->end,
REG_BR_PROB, NULL),
0));
probability = INTVAL (XEXP (note, 0));
e = BRANCH_EDGE (b);
e->probability = probability;
e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
@ -772,8 +748,7 @@ compute_outgoing_frequencies (b)
basic block. Update the data structure. */
void
find_many_sub_basic_blocks (blocks)
sbitmap blocks;
find_many_sub_basic_blocks (sbitmap blocks)
{
basic_block bb, min, max;
@ -810,7 +785,7 @@ find_many_sub_basic_blocks (blocks)
{
bb->count = 0;
bb->frequency = 0;
for (e = bb->pred; e; e=e->pred_next)
for (e = bb->pred; e; e = e->pred_next)
{
bb->count += e->count;
bb->frequency += EDGE_FREQUENCY (e);
@ -827,8 +802,7 @@ find_many_sub_basic_blocks (blocks)
/* Like above but for single basic block only. */
void
find_sub_basic_blocks (bb)
basic_block bb;
find_sub_basic_blocks (basic_block bb)
{
basic_block min, max, b;
basic_block next = bb->next_bb;
@ -851,7 +825,7 @@ find_sub_basic_blocks (bb)
{
b->count = 0;
b->frequency = 0;
for (e = b->pred; e; e=e->pred_next)
for (e = b->pred; e; e = e->pred_next)
{
b->count += e->count;
b->frequency += EDGE_FREQUENCY (e);

File diff suppressed because it is too large Load Diff

48
contrib/gcc/cfghooks.c Normal file
View File

@ -0,0 +1,48 @@
/* Hooks for cfg representation specific functions.
Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Sebastian Pop <s.pop@laposte.net>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "basic-block.h"
extern struct cfg_hooks rtl_cfg_hooks;
extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
/* A pointer to one of the hooks containers. */
struct cfg_hooks *cfg_hooks;
/* Initialization of functions specific to the rtl IR. */
void
rtl_register_cfg_hooks (void)
{
cfg_hooks = &rtl_cfg_hooks;
}
/* Initialization of functions specific to the rtl IR. */
void
cfg_layout_rtl_register_cfg_hooks (void)
{
cfg_hooks = &cfg_layout_rtl_cfg_hooks;
}

83
contrib/gcc/cfghooks.h Normal file
View File

@ -0,0 +1,83 @@
/* Hooks for cfg representation specific functions.
Copyright (C) 2003 Free Software Foundation, Inc.
Contributed by Sebastian Pop <s.pop@laposte.net>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef GCC_CFGHOOKS_H
#define GCC_CFGHOOKS_H
struct cfg_hooks
{
/* Debugging. Do not use macros to hook these so they can be called from
debugger! */
int (*cfgh_verify_flow_info) (void);
void (*dump_bb) (basic_block, FILE *);
/* Basic CFG manipulation. */
/* Return new basic block. */
basic_block (*create_basic_block) (void *head, void *end, basic_block after);
/* Redirect edge E to the given basic block B and update underlying program
representation. Returns false when edge is not easily redirectable for
whatever reason. */
bool (*redirect_edge_and_branch) (edge e, basic_block b);
/* Same as the above but allows redirecting of fallthru edges. In that case
newly created forwarder basic block is returned. It aborts when called
on abnormal edge. */
basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
/* Remove given basic block and all edges possibly pointing into it. */
void (*delete_block) (basic_block);
/* Split basic block B after specified instruction I. */
edge (*split_block) (basic_block b, void * i);
/* Return true when blocks A and B can be merged into single basic block. */
bool (*can_merge_blocks_p) (basic_block a, basic_block b);
/* Merge blocks A and B. */
void (*merge_blocks) (basic_block a, basic_block b);
/* Higher level functions representable by primitive operations above if
we didn't have some oddities in RTL and Tree representations. */
basic_block (*cfgh_split_edge) (edge);
};
#define redirect_edge_and_branch(e,b) cfg_hooks->redirect_edge_and_branch (e,b)
#define redirect_edge_and_branch_force(e,b) cfg_hooks->redirect_edge_and_branch_force (e,b)
#define split_block(e,i) cfg_hooks->split_block (e,i)
#define delete_block(b) cfg_hooks->delete_block (b)
#define split_edge(e) cfg_hooks->cfgh_split_edge (e)
#define create_basic_block(h,e,a) cfg_hooks->create_basic_block (h,e,a)
#define can_merge_blocks_p(a,b) cfg_hooks->can_merge_blocks_p (a,b)
#define merge_blocks(a,b) cfg_hooks->merge_blocks (a,b)
/* Hooks containers. */
extern struct cfg_hooks rtl_cfg_hooks;
/* A pointer to one of the hooks containers. */
extern struct cfg_hooks *cfg_hooks;
/* Declarations. */
extern void rtl_register_cfg_hooks (void);
extern void cfg_layout_rtl_register_cfg_hooks (void);
#endif /* GCC_CFGHOOKS_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
Copyright (C) 2000 Free Software Foundation, Inc.
Copyright (C) 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -25,17 +25,23 @@ typedef struct reorder_block_def
rtx footer;
basic_block next;
basic_block original;
/* Used by loop copying. */
basic_block copy;
int duplicated;
/* These fields are used by bb-reorder pass. */
int visited;
} *reorder_block_def;
#define RBI(BB) ((reorder_block_def) (BB)->aux)
extern rtx cfg_layout_function_footer;
extern void cfg_layout_initialize PARAMS ((void));
extern void cfg_layout_finalize PARAMS ((void));
extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
extern void scope_to_insns_initialize PARAMS ((void));
extern void scope_to_insns_finalize PARAMS ((void));
extern void cfg_layout_redirect_edge PARAMS ((edge, basic_block));
extern void cfg_layout_initialize (unsigned int);
extern void cfg_layout_finalize (void);
extern bool cfg_layout_can_duplicate_bb_p (basic_block);
extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
extern void insn_locators_initialize (void);
extern void reemit_insn_block_notes (void);
extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *,
edge *, unsigned, edge *, struct loop *);
extern void cfg_layout_initialize_rbi (basic_block);

View File

@ -1,5 +1,5 @@
/* Natural loop discovery code for GNU compiler.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@ -20,43 +20,42 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "toplev.h"
#include "cfgloop.h"
#include "flags.h"
/* Ratio of frequencies of edges so that one of more latch edges is
considered to belong to inner loop with same header. */
#define HEAVY_EDGE_RATIO 8
static void flow_loops_cfg_dump PARAMS ((const struct loops *,
FILE *));
static void flow_loop_entry_edges_find PARAMS ((struct loop *));
static void flow_loop_exit_edges_find PARAMS ((struct loop *));
static int flow_loop_nodes_find PARAMS ((basic_block, struct loop *));
static void flow_loop_pre_header_scan PARAMS ((struct loop *));
static basic_block flow_loop_pre_header_find PARAMS ((basic_block,
dominance_info));
static int flow_loop_level_compute PARAMS ((struct loop *));
static int flow_loops_level_compute PARAMS ((struct loops *));
static basic_block make_forwarder_block PARAMS ((basic_block, int, int,
edge, int));
static void canonicalize_loop_headers PARAMS ((void));
static bool glb_enum_p PARAMS ((basic_block, void *));
static void redirect_edge_with_latch_update PARAMS ((edge, basic_block));
static void flow_loop_free PARAMS ((struct loop *));
static void flow_loops_cfg_dump (const struct loops *, FILE *);
static void flow_loop_entry_edges_find (struct loop *);
static void flow_loop_exit_edges_find (struct loop *);
static int flow_loop_nodes_find (basic_block, struct loop *);
static void flow_loop_pre_header_scan (struct loop *);
static basic_block flow_loop_pre_header_find (basic_block);
static int flow_loop_level_compute (struct loop *);
static int flow_loops_level_compute (struct loops *);
static void establish_preds (struct loop *);
static basic_block make_forwarder_block (basic_block, int, int, edge, int);
static void canonicalize_loop_headers (void);
static bool glb_enum_p (basic_block, void *);
static void redirect_edge_with_latch_update (edge, basic_block);
/* Dump loop related CFG information. */
static void
flow_loops_cfg_dump (loops, file)
const struct loops *loops;
FILE *file;
flow_loops_cfg_dump (const struct loops *loops, FILE *file)
{
int i;
basic_block bb;
if (! loops->num || ! file || ! loops->cfg.dom)
if (! loops->num || ! file)
return;
FOR_EACH_BB (bb)
@ -93,9 +92,7 @@ flow_loops_cfg_dump (loops, file)
/* Return nonzero if the nodes of LOOP are a subset of OUTER. */
bool
flow_loop_nested_p (outer, loop)
const struct loop *outer;
const struct loop *loop;
flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
{
return loop->depth > outer->depth
&& loop->pred[outer->depth] == outer;
@ -105,14 +102,12 @@ flow_loop_nested_p (outer, loop)
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
flow_loop_dump (loop, file, loop_dump_aux, verbose)
const struct loop *loop;
FILE *file;
void (*loop_dump_aux) PARAMS((const struct loop *, FILE *, int));
int verbose;
flow_loop_dump (const struct loop *loop, FILE *file,
void (*loop_dump_aux) (const struct loop *, FILE *, int),
int verbose)
{
basic_block *bbs;
int i;
unsigned i;
if (! loop || ! loop->header)
return;
@ -150,11 +145,7 @@ flow_loop_dump (loop, file, loop_dump_aux, verbose)
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
flow_loops_dump (loops, file, loop_dump_aux, verbose)
const struct loops *loops;
FILE *file;
void (*loop_dump_aux) PARAMS((const struct loop *, FILE *, int));
int verbose;
flow_loops_dump (const struct loops *loops, FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
{
int i;
int num_loops;
@ -181,9 +172,8 @@ flow_loops_dump (loops, file, loop_dump_aux, verbose)
}
/* Free data allocated for LOOP. */
static void
flow_loop_free (loop)
struct loop *loop;
void
flow_loop_free (struct loop *loop)
{
if (loop->pre_header_edges)
free (loop->pre_header_edges);
@ -199,12 +189,11 @@ flow_loop_free (loop)
/* Free all the memory allocated for LOOPS. */
void
flow_loops_free (loops)
struct loops *loops;
flow_loops_free (struct loops *loops)
{
if (loops->parray)
{
int i;
unsigned i;
if (! loops->num)
abort ();
@ -223,9 +212,6 @@ flow_loops_free (loops)
free (loops->parray);
loops->parray = NULL;
if (loops->cfg.dom)
free_dominance_info (loops->cfg.dom);
if (loops->cfg.dfs_order)
free (loops->cfg.dfs_order);
if (loops->cfg.rc_order)
@ -236,9 +222,8 @@ flow_loops_free (loops)
/* Find the entry edges into the LOOP. */
static void
flow_loop_entry_edges_find (loop)
struct loop *loop;
static void
flow_loop_entry_edges_find (struct loop *loop)
{
edge e;
int num_entries;
@ -253,7 +238,7 @@ flow_loop_entry_edges_find (loop)
if (! num_entries)
abort ();
loop->entry_edges = (edge *) xmalloc (num_entries * sizeof (edge *));
loop->entry_edges = xmalloc (num_entries * sizeof (edge *));
num_entries = 0;
for (e = loop->header->pred; e; e = e->pred_next)
@ -268,12 +253,11 @@ flow_loop_entry_edges_find (loop)
/* Find the exit edges from the LOOP. */
static void
flow_loop_exit_edges_find (loop)
struct loop *loop;
flow_loop_exit_edges_find (struct loop *loop)
{
edge e;
basic_block node, *bbs;
int num_exits, i;
unsigned num_exits, i;
loop->exit_edges = NULL;
loop->num_exits = 0;
@ -301,7 +285,7 @@ flow_loop_exit_edges_find (loop)
return;
}
loop->exit_edges = (edge *) xmalloc (num_exits * sizeof (edge *));
loop->exit_edges = xmalloc (num_exits * sizeof (edge *));
/* Store all exiting edges into an array. */
num_exits = 0;
@ -324,35 +308,31 @@ flow_loop_exit_edges_find (loop)
Return the number of nodes within the loop. */
static int
flow_loop_nodes_find (header, loop)
basic_block header;
struct loop *loop;
flow_loop_nodes_find (basic_block header, struct loop *loop)
{
basic_block *stack;
int sp;
int num_nodes = 1;
int findex, lindex;
header->loop_father = loop;
header->loop_depth = loop->depth;
findex = lindex = header->index;
if (loop->latch->loop_father != loop)
{
stack = (basic_block *) xmalloc (n_basic_blocks * sizeof (basic_block));
stack = xmalloc (n_basic_blocks * sizeof (basic_block));
sp = 0;
num_nodes++;
stack[sp++] = loop->latch;
loop->latch->loop_father = loop;
loop->latch->loop_depth = loop->depth;
while (sp)
{
basic_block node;
edge e;
node = stack[--sp];
for (e = node->pred; e; e = e->pred_next)
{
basic_block ancestor = e->src;
@ -376,8 +356,7 @@ flow_loop_nodes_find (header, loop)
the edges along the trace from the root node to the loop header. */
static void
flow_loop_pre_header_scan (loop)
struct loop *loop;
flow_loop_pre_header_scan (struct loop *loop)
{
int num;
basic_block ebb;
@ -398,7 +377,7 @@ flow_loop_pre_header_scan (loop)
num++)
ebb = ebb->pred->src;
loop->pre_header_edges = (edge *) xmalloc (num * sizeof (edge));
loop->pre_header_edges = xmalloc (num * sizeof (edge));
loop->num_pre_header_edges = num;
/* Store edges in order that they are followed. The source of the first edge
@ -409,13 +388,10 @@ flow_loop_pre_header_scan (loop)
}
/* Return the block for the pre-header of the loop with header
HEADER where DOM specifies the dominator information. Return NULL if
there is no pre-header. */
HEADER. Return NULL if there is no pre-header. */
static basic_block
flow_loop_pre_header_find (header, dom)
basic_block header;
dominance_info dom;
flow_loop_pre_header_find (basic_block header)
{
basic_block pre_header;
edge e;
@ -428,7 +404,7 @@ flow_loop_pre_header_find (header, dom)
basic_block node = e->src;
if (node != ENTRY_BLOCK_PTR
&& ! dominated_by_p (dom, node, header))
&& ! dominated_by_p (CDI_DOMINATORS, node, header))
{
if (pre_header == NULL)
pre_header = node;
@ -445,29 +421,40 @@ flow_loop_pre_header_find (header, dom)
return pre_header;
}
static void
establish_preds (struct loop *loop)
{
struct loop *ploop, *father = loop->outer;
loop->depth = father->depth + 1;
if (loop->pred)
free (loop->pred);
loop->pred = xmalloc (sizeof (struct loop *) * loop->depth);
memcpy (loop->pred, father->pred, sizeof (struct loop *) * father->depth);
loop->pred[father->depth] = father;
for (ploop = loop->inner; ploop; ploop = ploop->next)
establish_preds (ploop);
}
/* Add LOOP to the loop hierarchy tree where FATHER is father of the
added loop. */
added loop. If LOOP has some children, take care of that their
pred field will be initialized correctly. */
void
flow_loop_tree_node_add (father, loop)
struct loop *father;
struct loop *loop;
flow_loop_tree_node_add (struct loop *father, struct loop *loop)
{
loop->next = father->inner;
father->inner = loop;
loop->outer = father;
loop->depth = father->depth + 1;
loop->pred = xmalloc (sizeof (struct loop *) * loop->depth);
memcpy (loop->pred, father->pred, sizeof (struct loop *) * father->depth);
loop->pred[father->depth] = father;
establish_preds (loop);
}
/* Remove LOOP from the loop hierarchy tree. */
void
flow_loop_tree_node_remove (loop)
struct loop *loop;
flow_loop_tree_node_remove (struct loop *loop)
{
struct loop *prev, *father;
@ -492,8 +479,7 @@ flow_loop_tree_node_remove (loop)
for the natural loop specified by LOOP. Returns the loop level. */
static int
flow_loop_level_compute (loop)
struct loop *loop;
flow_loop_level_compute (struct loop *loop)
{
struct loop *inner;
int level = 1;
@ -523,8 +509,7 @@ flow_loop_level_compute (loop)
level. */
static int
flow_loops_level_compute (loops)
struct loops *loops;
flow_loops_level_compute (struct loops *loops)
{
return flow_loop_level_compute (loops->tree_root);
}
@ -533,10 +518,7 @@ flow_loops_level_compute (loops)
about it specified by FLAGS. */
int
flow_loop_scan (loops, loop, flags)
struct loops *loops;
struct loop *loop;
int flags;
flow_loop_scan (struct loop *loop, int flags)
{
if (flags & LOOP_ENTRY_EDGES)
{
@ -555,8 +537,7 @@ flow_loop_scan (loops, loop, flags)
if (flags & LOOP_PRE_HEADER)
{
/* Look to see if the loop has a pre-header node. */
loop->pre_header
= flow_loop_pre_header_find (loop->header, loops->cfg.dom);
loop->pre_header = flow_loop_pre_header_find (loop->header);
/* Find the blocks within the extended basic block of
the loop pre-header. */
@ -571,9 +552,7 @@ flow_loop_scan (loops, loop, flags)
/* Redirect edge and update latch and header info. */
static void
redirect_edge_with_latch_update (e, to)
edge e;
basic_block to;
redirect_edge_with_latch_update (edge e, basic_block to)
{
basic_block jump;
@ -595,13 +574,7 @@ redirect_edge_with_latch_update (e, to)
part. */
static basic_block
make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
conn_latch)
basic_block bb;
int redirect_latch;
int redirect_nonlatch;
edge except;
int conn_latch;
make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch, edge except, int conn_latch)
{
edge e, next_e, fallthru;
basic_block dummy;
@ -609,6 +582,10 @@ make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
insn = PREV_INSN (first_insn_after_basic_block_note (bb));
/* For empty block split_block will return NULL. */
if (BB_END (bb) == insn)
emit_note_after (NOTE_INSN_DELETED, insn);
fallthru = split_block (bb, insn);
dummy = fallthru->src;
bb = fallthru->dest;
@ -643,14 +620,13 @@ make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
/* Takes care of merging natural loops with shared headers. */
static void
canonicalize_loop_headers ()
canonicalize_loop_headers (void)
{
dominance_info dom;
basic_block header;
edge e;
/* Compute the dominators. */
dom = calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_DOMINATORS);
alloc_aux_for_blocks (sizeof (int));
alloc_aux_for_edges (sizeof (int));
@ -669,7 +645,7 @@ canonicalize_loop_headers ()
have_abnormal_edge = 1;
if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (dom, latch, header))
&& dominated_by_p (CDI_DOMINATORS, latch, header))
{
num_latches++;
LATCH_EDGE (e) = 1;
@ -681,6 +657,8 @@ canonicalize_loop_headers ()
HEADER_BLOCK (header) = num_latches;
}
free_dominance_info (CDI_DOMINATORS);
if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
{
basic_block bb;
@ -688,7 +666,7 @@ canonicalize_loop_headers ()
/* We could not redirect edges freely here. On the other hand,
we can simply split the edge from entry block. */
bb = split_edge (ENTRY_BLOCK_PTR->succ);
alloc_aux_for_edge (bb->succ, sizeof (int));
LATCH_EDGE (bb->succ) = 0;
alloc_aux_for_block (bb, sizeof (int));
@ -746,7 +724,6 @@ canonicalize_loop_headers ()
free_aux_for_blocks ();
free_aux_for_edges ();
free_dominance_info (dom);
}
/* Find all the natural loops in the function and save in LOOPS structure and
@ -755,16 +732,13 @@ canonicalize_loop_headers ()
loops found. */
int
flow_loops_find (loops, flags)
struct loops *loops;
int flags;
flow_loops_find (struct loops *loops, int flags)
{
int i;
int b;
int num_loops;
edge e;
sbitmap headers;
dominance_info dom;
int *dfs_order;
int *rc_order;
basic_block header;
@ -790,7 +764,7 @@ flow_loops_find (loops, flags)
canonicalize_loop_headers ();
/* Compute the dominators. */
dom = loops->cfg.dom = calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_DOMINATORS);
/* Count the number of loop headers. This should be the
same as the number of natural loops. */
@ -801,7 +775,7 @@ flow_loops_find (loops, flags)
FOR_EACH_BB (header)
{
int more_latches = 0;
header->loop_depth = 0;
/* If we have an abnormal predecessor, do not consider the
@ -824,7 +798,8 @@ flow_loops_find (loops, flags)
node (header) that dominates all the nodes in the
loop. It also has single back edge to the header
from a latch node. */
if (latch != ENTRY_BLOCK_PTR && dominated_by_p (dom, latch, header))
if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (CDI_DOMINATORS, latch, header))
{
/* Shared headers should be eliminated by now. */
if (more_latches)
@ -837,7 +812,7 @@ flow_loops_find (loops, flags)
}
/* Allocate loop structures. */
loops->parray = (struct loop **) xcalloc (num_loops + 1, sizeof (struct loop *));
loops->parray = xcalloc (num_loops + 1, sizeof (struct loop *));
/* Dummy loop containing whole function. */
loops->parray[0] = xcalloc (1, sizeof (struct loop));
@ -864,12 +839,11 @@ flow_loops_find (loops, flags)
{
/* Compute depth first search order of the CFG so that outer
natural loops will be found before inner natural loops. */
dfs_order = (int *) xmalloc (n_basic_blocks * sizeof (int));
rc_order = (int *) xmalloc (n_basic_blocks * sizeof (int));
dfs_order = xmalloc (n_basic_blocks * sizeof (int));
rc_order = xmalloc (n_basic_blocks * sizeof (int));
flow_depth_first_order_compute (dfs_order, rc_order);
/* Save CFG derived information to avoid recomputing it. */
loops->cfg.dom = dom;
loops->cfg.dfs_order = dfs_order;
loops->cfg.rc_order = rc_order;
@ -885,7 +859,7 @@ flow_loops_find (loops, flags)
continue;
header = BASIC_BLOCK (rc_order[b]);
loop = loops->parray[num_loops] = xcalloc (1, sizeof (struct loop));
loop->header = header;
@ -898,7 +872,7 @@ flow_loops_find (loops, flags)
basic_block latch = e->src;
if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (dom, latch, header))
&& dominated_by_p (CDI_DOMINATORS, latch, header))
{
loop->latch = latch;
break;
@ -909,26 +883,27 @@ flow_loops_find (loops, flags)
loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
}
sbitmap_free (headers);
/* Assign the loop nesting depth and enclosed loop level for each
loop. */
loops->levels = flow_loops_level_compute (loops);
/* Scan the loops. */
for (i = 1; i < num_loops; i++)
flow_loop_scan (loops, loops->parray[i], flags);
flow_loop_scan (loops->parray[i], flags);
loops->num = num_loops;
}
else
{
loops->cfg.dom = NULL;
free_dominance_info (dom);
free_dominance_info (CDI_DOMINATORS);
}
sbitmap_free (headers);
loops->state = 0;
#ifdef ENABLE_CHECKING
verify_flow_info ();
verify_loop_structure (loops, 0);
verify_loop_structure (loops);
#endif
return loops->num;
@ -938,9 +913,7 @@ flow_loops_find (loops, flags)
specified by LOOPS. */
int
flow_loops_update (loops, flags)
struct loops *loops;
int flags;
flow_loops_update (struct loops *loops, int flags)
{
/* One day we may want to update the current loop data. For now
throw away the old stuff and rebuild what we need. */
@ -952,9 +925,7 @@ flow_loops_update (loops, flags)
/* Return nonzero if basic block BB belongs to LOOP. */
bool
flow_bb_inside_loop_p (loop, bb)
const struct loop *loop;
const basic_block bb;
flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
{
struct loop *source_loop;
@ -968,9 +939,7 @@ flow_bb_inside_loop_p (loop, bb)
/* Return nonzero if edge E enters header of LOOP from outside of LOOP. */
bool
flow_loop_outside_edge_p (loop, e)
const struct loop *loop;
edge e;
flow_loop_outside_edge_p (const struct loop *loop, edge e)
{
if (e->dest != loop->header)
abort ();
@ -979,20 +948,19 @@ flow_loop_outside_edge_p (loop, e)
/* Enumeration predicate for get_loop_body. */
static bool
glb_enum_p (bb, glb_header)
basic_block bb;
void *glb_header;
glb_enum_p (basic_block bb, void *glb_header)
{
return bb != (basic_block) glb_header;
}
/* Gets basic blocks of a loop. */
/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
order against direction of edges from latch. Specially, if
header != latch, latch is the 1-st block. */
basic_block *
get_loop_body (loop)
const struct loop *loop;
get_loop_body (const struct loop *loop)
{
basic_block *tovisit, bb;
int tv = 0;
unsigned tv = 0;
if (!loop->num_nodes)
abort ();
@ -1003,7 +971,7 @@ get_loop_body (loop)
if (loop->latch == EXIT_BLOCK_PTR)
{
/* There may be blocks unreachable from EXIT_BLOCK. */
if (loop->num_nodes != n_basic_blocks + 2)
if (loop->num_nodes != (unsigned) n_basic_blocks + 2)
abort ();
FOR_EACH_BB (bb)
tovisit[tv++] = bb;
@ -1021,14 +989,41 @@ get_loop_body (loop)
return tovisit;
}
/* Gets exit edges of a LOOP, returning their number in N_EDGES. */
edge *
get_loop_exit_edges (const struct loop *loop, unsigned int *n_edges)
{
edge *edges, e;
unsigned i, n;
basic_block * body;
if (loop->latch == EXIT_BLOCK_PTR)
abort ();
body = get_loop_body (loop);
n = 0;
for (i = 0; i < loop->num_nodes; i++)
for (e = body[i]->succ; e; e = e->succ_next)
if (!flow_bb_inside_loop_p (loop, e->dest))
n++;
edges = xmalloc (n * sizeof (edge));
*n_edges = n;
n = 0;
for (i = 0; i < loop->num_nodes; i++)
for (e = body[i]->succ; e; e = e->succ_next)
if (!flow_bb_inside_loop_p (loop, e->dest))
edges[n++] = e;
free (body);
return edges;
}
/* Adds basic block BB to LOOP. */
void
add_bb_to_loop (bb, loop)
basic_block bb;
struct loop *loop;
{
add_bb_to_loop (basic_block bb, struct loop *loop)
{
int i;
bb->loop_father = loop;
bb->loop_depth = loop->depth;
loop->num_nodes++;
@ -1038,9 +1033,8 @@ add_bb_to_loop (bb, loop)
/* Remove basic block BB from loops. */
void
remove_bb_from_loops (bb)
basic_block bb;
{
remove_bb_from_loops (basic_block bb)
{
int i;
struct loop *loop = bb->loop_father;
@ -1053,13 +1047,11 @@ remove_bb_from_loops (bb)
/* Finds nearest common ancestor in loop tree for given loops. */
struct loop *
find_common_loop (loop_s, loop_d)
struct loop *loop_s;
struct loop *loop_d;
find_common_loop (struct loop *loop_s, struct loop *loop_d)
{
if (!loop_s) return loop_d;
if (!loop_d) return loop_s;
if (loop_s->depth < loop_d->depth)
loop_d = loop_d->pred[loop_s->depth];
else if (loop_s->depth > loop_d->depth)
@ -1073,21 +1065,56 @@ find_common_loop (loop_s, loop_d)
return loop_s;
}
/* Checks that LOOPS are allright:
-- sizes of loops are allright
/* Cancels the LOOP; it must be innermost one. */
void
cancel_loop (struct loops *loops, struct loop *loop)
{
basic_block *bbs;
unsigned i;
if (loop->inner)
abort ();
/* Move blocks up one level (they should be removed as soon as possible). */
bbs = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++)
bbs[i]->loop_father = loop->outer;
/* Remove the loop from structure. */
flow_loop_tree_node_remove (loop);
/* Remove loop from loops array. */
loops->parray[loop->num] = NULL;
/* Free loop data. */
flow_loop_free (loop);
}
/* Cancels LOOP and all its subloops. */
void
cancel_loop_tree (struct loops *loops, struct loop *loop)
{
while (loop->inner)
cancel_loop_tree (loops, loop->inner);
cancel_loop (loops, loop);
}
/* Checks that LOOPS are all right:
-- sizes of loops are all right
-- results of get_loop_body really belong to the loop
-- loop header have just single entry edge and single latch edge
-- loop latches have only single successor that is header of their loop
-- irreducible loops are correctly marked
*/
void
verify_loop_structure (loops, flags)
struct loops *loops;
int flags;
verify_loop_structure (struct loops *loops)
{
int *sizes, i, j;
unsigned *sizes, i, j;
sbitmap irreds;
basic_block *bbs, bb;
struct loop *loop;
int err = 0;
edge e;
/* Check sizes. */
sizes = xcalloc (loops->num, sizeof (int));
@ -1137,14 +1164,14 @@ verify_loop_structure (loops, flags)
if (!loop)
continue;
if ((flags & VLS_EXPECT_PREHEADERS)
if ((loops->state & LOOPS_HAVE_PREHEADERS)
&& (!loop->header->pred->pred_next
|| loop->header->pred->pred_next->pred_next))
{
error ("Loop %d's header does not have exactly 2 entries.", i);
err = 1;
}
if (flags & VLS_EXPECT_SIMPLE_LATCHES)
if (loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
{
if (!loop->latch->succ
|| loop->latch->succ->succ_next)
@ -1168,6 +1195,68 @@ verify_loop_structure (loops, flags)
error ("Loop %d's header does not belong directly to it.", i);
err = 1;
}
if ((loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
&& (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
{
error ("Loop %d's latch is marked as part of irreducible region.", i);
err = 1;
}
}
/* Check irreducible loops. */
if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
{
/* Record old info. */
irreds = sbitmap_alloc (last_basic_block);
FOR_EACH_BB (bb)
{
if (bb->flags & BB_IRREDUCIBLE_LOOP)
SET_BIT (irreds, bb->index);
else
RESET_BIT (irreds, bb->index);
for (e = bb->succ; e; e = e->succ_next)
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
e->flags |= EDGE_ALL_FLAGS + 1;
}
/* Recount it. */
mark_irreducible_loops (loops);
/* Compare. */
FOR_EACH_BB (bb)
{
if ((bb->flags & BB_IRREDUCIBLE_LOOP)
&& !TEST_BIT (irreds, bb->index))
{
error ("Basic block %d should be marked irreducible.", bb->index);
err = 1;
}
else if (!(bb->flags & BB_IRREDUCIBLE_LOOP)
&& TEST_BIT (irreds, bb->index))
{
error ("Basic block %d should not be marked irreducible.", bb->index);
err = 1;
}
for (e = bb->succ; e; e = e->succ_next)
{
if ((e->flags & EDGE_IRREDUCIBLE_LOOP)
&& !(e->flags & (EDGE_ALL_FLAGS + 1)))
{
error ("Edge from %d to %d should be marked irreducible.",
e->src->index, e->dest->index);
err = 1;
}
else if (!(e->flags & EDGE_IRREDUCIBLE_LOOP)
&& (e->flags & (EDGE_ALL_FLAGS + 1)))
{
error ("Edge from %d to %d should not be marked irreducible.",
e->src->index, e->dest->index);
err = 1;
}
e->flags &= ~(EDGE_ALL_FLAGS + 1);
}
}
free (irreds);
}
if (err)
@ -1176,8 +1265,7 @@ verify_loop_structure (loops, flags)
/* Returns latch edge of LOOP. */
edge
loop_latch_edge (loop)
struct loop *loop;
loop_latch_edge (const struct loop *loop)
{
edge e;
@ -1189,8 +1277,7 @@ loop_latch_edge (loop)
/* Returns preheader edge of LOOP. */
edge
loop_preheader_edge (loop)
struct loop *loop;
loop_preheader_edge (const struct loop *loop)
{
edge e;
@ -1199,4 +1286,3 @@ loop_preheader_edge (loop)
return e;
}

341
contrib/gcc/cfgloop.h Normal file
View File

@ -0,0 +1,341 @@
/* Natural loop functions
Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* Structure to hold decision about unrolling/peeling. */
enum lpt_dec
{
LPT_NONE,
LPT_PEEL_COMPLETELY,
LPT_PEEL_SIMPLE,
LPT_UNROLL_CONSTANT,
LPT_UNROLL_RUNTIME,
LPT_UNROLL_STUPID
};
struct lpt_decision
{
enum lpt_dec decision;
unsigned times;
};
/* Description of loop for simple loop unrolling. */
struct loop_desc
{
int postincr; /* 1 if increment/decrement is done after loop exit condition. */
rtx stride; /* Value added to VAR in each iteration. */
rtx var; /* Loop control variable. */
enum machine_mode inner_mode;
/* The mode from that it is extended. */
enum rtx_code extend; /* With this extend. */
rtx var_alts; /* List of definitions of its initial value. */
rtx lim; /* Expression var is compared with. */
rtx lim_alts; /* List of definitions of its initial value. */
bool const_iter; /* True if it iterates constant number of times. */
unsigned HOST_WIDE_INT niter;
/* Number of iterations if it is constant. */
bool may_be_zero; /* If we cannot determine that the first iteration will pass. */
enum rtx_code cond; /* Exit condition. */
int neg; /* Set to 1 if loop ends when condition is satisfied. */
edge out_edge; /* The exit edge. */
edge in_edge; /* And the other one. */
int n_branches; /* Number of branches inside the loop. */
};
/* Structure to hold information for each natural loop. */
struct loop
{
/* Index into loops array. */
int num;
/* Basic block of loop header. */
basic_block header;
/* Basic block of loop latch. */
basic_block latch;
/* Basic block of loop preheader or NULL if it does not exist. */
basic_block pre_header;
/* For loop unrolling/peeling decision. */
struct lpt_decision lpt_decision;
/* Simple loop description. */
int simple;
struct loop_desc desc;
int has_desc;
/* Number of loop insns. */
unsigned ninsns;
/* Average number of executed insns per iteration. */
unsigned av_ninsns;
/* Array of edges along the preheader extended basic block trace.
The source of the first edge is the root node of preheader
extended basic block, if it exists. */
edge *pre_header_edges;
/* Number of edges along the pre_header extended basic block trace. */
int num_pre_header_edges;
/* The first block in the loop. This is not necessarily the same as
the loop header. */
basic_block first;
/* The last block in the loop. This is not necessarily the same as
the loop latch. */
basic_block last;
/* Bitmap of blocks contained within the loop. */
sbitmap nodes;
/* Number of blocks contained within the loop. */
unsigned num_nodes;
/* Array of edges that enter the loop. */
edge *entry_edges;
/* Number of edges that enter the loop. */
int num_entries;
/* Array of edges that exit the loop. */
edge *exit_edges;
/* Number of edges that exit the loop. */
int num_exits;
/* Bitmap of blocks that dominate all exits of the loop. */
sbitmap exits_doms;
/* The loop nesting depth. */
int depth;
/* Superloops of the loop. */
struct loop **pred;
/* The height of the loop (enclosed loop levels) within the loop
hierarchy tree. */
int level;
/* The outer (parent) loop or NULL if outermost loop. */
struct loop *outer;
/* The first inner (child) loop or NULL if innermost loop. */
struct loop *inner;
/* Link to the next (sibling) loop. */
struct loop *next;
/* Loop that is copy of this loop. */
struct loop *copy;
/* Nonzero if the loop is invalid (e.g., contains setjmp.). */
int invalid;
/* Auxiliary info specific to a pass. */
void *aux;
/* The following are currently used by loop.c but they are likely to
disappear as loop.c is converted to use the CFG. */
/* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
rtx vtop;
/* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
A continue statement will generate a branch to NEXT_INSN (cont). */
rtx cont;
/* The dominator of cont. */
rtx cont_dominator;
/* The NOTE_INSN_LOOP_BEG. */
rtx start;
/* The NOTE_INSN_LOOP_END. */
rtx end;
/* For a rotated loop that is entered near the bottom,
this is the label at the top. Otherwise it is zero. */
rtx top;
/* Place in the loop where control enters. */
rtx scan_start;
/* The position where to sink insns out of the loop. */
rtx sink;
/* List of all LABEL_REFs which refer to code labels outside the
loop. Used by routines that need to know all loop exits, such as
final_biv_value and final_giv_value.
This does not include loop exits due to return instructions.
This is because all bivs and givs are pseudos, and hence must be
dead after a return, so the presence of a return does not affect
any of the optimizations that use this info. It is simpler to
just not include return instructions on this list. */
rtx exit_labels;
/* The number of LABEL_REFs on exit_labels for this loop and all
loops nested inside it. */
int exit_count;
};
/* Flags for state of loop structure. */
enum
{
LOOPS_HAVE_PREHEADERS = 1,
LOOPS_HAVE_SIMPLE_LATCHES = 2,
LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4
};
/* Structure to hold CFG information about natural loops within a function. */
struct loops
{
/* Number of natural loops in the function. */
unsigned num;
/* Maximum nested loop level in the function. */
unsigned levels;
/* Array of natural loop descriptors (scanning this array in reverse order
will find the inner loops before their enclosing outer loops). */
struct loop *array;
/* The above array is unused in new loop infrastructure and is kept only for
purposes of the old loop optimizer. Instead we store just pointers to
loops here. */
struct loop **parray;
/* Pointer to root of loop hierarchy tree. */
struct loop *tree_root;
/* Information derived from the CFG. */
struct cfg
{
/* The ordering of the basic blocks in a depth first search. */
int *dfs_order;
/* The reverse completion ordering of the basic blocks found in a
depth first search. */
int *rc_order;
} cfg;
/* Headers shared by multiple loops that should be merged. */
sbitmap shared_headers;
/* State of loops. */
int state;
};
/* Flags for loop discovery. */
#define LOOP_TREE 1 /* Build loop hierarchy tree. */
#define LOOP_PRE_HEADER 2 /* Analyze loop preheader. */
#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
#define LOOP_ALL 15 /* All of the above */
/* Loop recognition. */
extern int flow_loops_find (struct loops *, int flags);
extern int flow_loops_update (struct loops *, int flags);
extern void flow_loops_free (struct loops *);
extern void flow_loops_dump (const struct loops *, FILE *,
void (*)(const struct loop *, FILE *, int), int);
extern void flow_loop_dump (const struct loop *, FILE *,
void (*)(const struct loop *, FILE *, int), int);
extern int flow_loop_scan (struct loop *, int);
extern void flow_loop_free (struct loop *);
void mark_irreducible_loops (struct loops *);
/* Loop data structure manipulation/querying. */
extern void flow_loop_tree_node_add (struct loop *, struct loop *);
extern void flow_loop_tree_node_remove (struct loop *);
extern bool flow_loop_outside_edge_p (const struct loop *, edge);
extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
extern struct loop * find_common_loop (struct loop *, struct loop *);
extern int num_loop_insns (struct loop *);
extern int average_num_loop_insns (struct loop *);
/* Loops & cfg manipulation. */
extern basic_block *get_loop_body (const struct loop *);
extern edge *get_loop_exit_edges (const struct loop *, unsigned *);
extern edge loop_preheader_edge (const struct loop *);
extern edge loop_latch_edge (const struct loop *);
extern void add_bb_to_loop (basic_block, struct loop *);
extern void remove_bb_from_loops (basic_block);
extern void cancel_loop (struct loops *, struct loop *);
extern void cancel_loop_tree (struct loops *, struct loop *);
extern basic_block loop_split_edge_with (edge, rtx);
extern int fix_loop_placement (struct loop *);
enum
{
CP_SIMPLE_PREHEADERS = 1
};
extern void create_preheaders (struct loops *, int);
extern void force_single_succ_latches (struct loops *);
extern void verify_loop_structure (struct loops *);
/* Loop analysis. */
extern bool simple_loop_p (struct loop *, struct loop_desc *);
extern rtx count_loop_iterations (struct loop_desc *, rtx, rtx);
extern bool just_once_each_iteration_p (struct loop *, basic_block);
extern unsigned expected_loop_iterations (const struct loop *);
/* Loop manipulation. */
extern bool can_duplicate_loop_p (struct loop *loop);
#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
duplicate_loop_to_header_edge. */
extern int duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
unsigned, sbitmap, edge, edge *,
unsigned *, int);
extern struct loop *loopify (struct loops *, edge, edge, basic_block);
extern void unloop (struct loops *, struct loop *);
extern bool remove_path (struct loops *, edge);
extern edge split_loop_bb (basic_block, rtx);
/* Loop optimizer initialization. */
extern struct loops *loop_optimizer_init (FILE *);
extern void loop_optimizer_finalize (struct loops *, FILE *);
/* Optimization passes. */
extern void unswitch_loops (struct loops *);
enum
{
UAP_PEEL = 1, /* Enables loop peeling. */
UAP_UNROLL = 2, /* Enables peeling of loops if it seems profitable. */
UAP_UNROLL_ALL = 4 /* Enables peeling of all loops. */
};
extern void unroll_and_peel_loops (struct loops *, int);
extern bool is_bct_cond (rtx);
extern rtx get_var_set_from_bct (rtx);

1482
contrib/gcc/cfgloopanal.c Normal file

File diff suppressed because it is too large Load Diff

1244
contrib/gcc/cfgloopmanip.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

644
contrib/gcc/cgraph.c Normal file
View File

@ -0,0 +1,644 @@
/* Callgraph handling code.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "langhooks.h"
#include "hashtab.h"
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
#include "debug.h"
#include "target.h"
#include "cgraph.h"
#include "varray.h"
#include "output.h"
#include "intl.h"
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
/* The linked list of cgraph nodes. */
struct cgraph_node *cgraph_nodes;
/* Queue of cgraph nodes scheduled to be lowered. */
struct cgraph_node *cgraph_nodes_queue;
/* Number of nodes in existence. */
int cgraph_n_nodes;
/* Maximal uid used in cgraph nodes. */
int cgraph_max_uid;
/* Set when whole unit has been analyzed so we can access global info. */
bool cgraph_global_info_ready = false;
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
/* Queue of cgraph nodes scheduled to be lowered and output. */
struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
/* Number of nodes in existence. */
int cgraph_varpool_n_nodes;
/* The linked list of cgraph varpool nodes. */
static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
static struct cgraph_edge *create_edge (struct cgraph_node *,
struct cgraph_node *);
static hashval_t hash_node (const void *);
static int eq_node (const void *, const void *);
/* Returns a hash code for P. */
static hashval_t
hash_node (const void *p)
{
return ((hashval_t)
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
(((struct cgraph_node *) p)->decl)));
}
/* Returns nonzero if P1 and P2 are equal. */
static int
eq_node (const void *p1, const void *p2)
{
return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
(tree) p2);
}
/* Return cgraph node assigned to DECL. Create new one when needed. */
struct cgraph_node *
cgraph_node (tree decl)
{
struct cgraph_node *node;
struct cgraph_node **slot;
if (TREE_CODE (decl) != FUNCTION_DECL)
abort ();
if (!cgraph_hash)
cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
slot = (struct cgraph_node **)
htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE
(DECL_ASSEMBLER_NAME (decl)), INSERT);
if (*slot)
return *slot;
node = ggc_alloc_cleared (sizeof (*node));
node->decl = decl;
node->next = cgraph_nodes;
node->uid = cgraph_max_uid++;
if (cgraph_nodes)
cgraph_nodes->previous = node;
node->previous = NULL;
cgraph_nodes = node;
cgraph_n_nodes++;
*slot = node;
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
{
node->origin = cgraph_node (DECL_CONTEXT (decl));
node->next_nested = node->origin->nested;
node->origin->nested = node;
}
return node;
}
/* Try to find existing function for identifier ID. */
struct cgraph_node *
cgraph_node_for_identifier (tree id)
{
struct cgraph_node **slot;
if (TREE_CODE (id) != IDENTIFIER_NODE)
abort ();
if (!cgraph_hash)
return NULL;
slot = (struct cgraph_node **)
htab_find_slot_with_hash (cgraph_hash, id,
IDENTIFIER_HASH_VALUE (id), NO_INSERT);
if (!slot)
return NULL;
return *slot;
}
/* Create edge from CALLER to CALLEE in the cgraph. */
static struct cgraph_edge *
create_edge (struct cgraph_node *caller, struct cgraph_node *callee)
{
struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
struct cgraph_edge *edge2;
if (!DECL_SAVED_TREE (callee->decl))
edge->inline_failed = N_("function body not available");
else if (callee->local.redefined_extern_inline)
edge->inline_failed = N_("redefined extern inline functions are not "
"considered for inlining");
else if (callee->local.inlinable)
edge->inline_failed = N_("function not considered for inlining");
else
edge->inline_failed = N_("function not inlinable");
/* At the moment we don't associate calls with specific CALL_EXPRs
as we probably ought to, so we must preserve inline_call flags to
be the same in all copies of the same edge. */
if (cgraph_global_info_ready)
for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee)
if (edge2->callee == callee)
{
edge->inline_failed = edge2->inline_failed;
break;
}
edge->caller = caller;
edge->callee = callee;
edge->next_caller = callee->callers;
edge->next_callee = caller->callees;
caller->callees = edge;
callee->callers = edge;
return edge;
}
/* Remove the edge from CALLER to CALLEE in the cgraph. */
void
cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee)
{
struct cgraph_edge **edge, **edge2;
for (edge = &callee->callers; *edge && (*edge)->caller != caller;
edge = &((*edge)->next_caller))
continue;
if (!*edge)
abort ();
*edge = (*edge)->next_caller;
for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
edge2 = &(*edge2)->next_callee)
continue;
if (!*edge2)
abort ();
*edge2 = (*edge2)->next_callee;
}
/* Remove the node from cgraph. */
void
cgraph_remove_node (struct cgraph_node *node)
{
void **slot;
while (node->callers)
cgraph_remove_edge (node->callers->caller, node);
while (node->callees)
cgraph_remove_edge (node, node->callees->callee);
while (node->nested)
cgraph_remove_node (node->nested);
if (node->origin)
{
struct cgraph_node **node2 = &node->origin->nested;
while (*node2 != node)
node2 = &(*node2)->next_nested;
*node2 = node->next_nested;
}
if (node->previous)
node->previous->next = node->next;
else
cgraph_nodes = node->next;
if (node->next)
node->next->previous = node->previous;
DECL_SAVED_TREE (node->decl) = NULL;
DECL_SAVED_INSNS (node->decl) = NULL;
DECL_ARGUMENTS (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node;
slot =
htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
(node->decl)), NO_INSERT);
if (slot == 0)
{
/* We use DECL_ASSEMBLER_NAME as key, which may not work in
all cases. See PR/15666. Gcc 3.5 uses DECL_UID as key,
which doesn't have this problem. */
if (!DECL_BUILT_IN (node->decl))
abort ();
}
else
htab_clear_slot (cgraph_hash, slot);
/* Do not free the structure itself so the walk over chain can continue. */
}
/* Notify finalize_compilation_unit that given node is reachable. */
void
cgraph_mark_reachable_node (struct cgraph_node *node)
{
if (!node->reachable && node->local.finalized)
{
notice_global_symbol (node->decl);
node->reachable = 1;
node->next_needed = cgraph_nodes_queue;
cgraph_nodes_queue = node;
/* At the moment frontend automatically emits all nested functions. */
if (node->nested)
{
struct cgraph_node *node2;
for (node2 = node->nested; node2; node2 = node2->next_nested)
if (!node2->reachable)
cgraph_mark_reachable_node (node2);
}
}
}
/* Likewise indicate that a node is needed, i.e. reachable via some
external means. */
void
cgraph_mark_needed_node (struct cgraph_node *node)
{
node->needed = 1;
cgraph_mark_reachable_node (node);
}
/* Record call from CALLER to CALLEE. */
struct cgraph_edge *
cgraph_record_call (tree caller, tree callee)
{
return create_edge (cgraph_node (caller), cgraph_node (callee));
}
void
cgraph_remove_call (tree caller, tree callee)
{
cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
}
/* Return true when CALLER_DECL calls CALLEE_DECL. */
bool
cgraph_calls_p (tree caller_decl, tree callee_decl)
{
struct cgraph_node *caller = cgraph_node (caller_decl);
struct cgraph_node *callee = cgraph_node (callee_decl);
struct cgraph_edge *edge;
for (edge = callee->callers; edge && (edge)->caller != caller;
edge = (edge->next_caller))
continue;
return edge != NULL;
}
/* Return local info for the compiled function. */
struct cgraph_local_info *
cgraph_local_info (tree decl)
{
struct cgraph_node *node;
if (TREE_CODE (decl) != FUNCTION_DECL)
abort ();
node = cgraph_node (decl);
return &node->local;
}
/* Return local info for the compiled function. */
struct cgraph_global_info *
cgraph_global_info (tree decl)
{
struct cgraph_node *node;
if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
abort ();
node = cgraph_node (decl);
return &node->global;
}
/* Return local info for the compiled function. */
struct cgraph_rtl_info *
cgraph_rtl_info (tree decl)
{
struct cgraph_node *node;
if (TREE_CODE (decl) != FUNCTION_DECL)
abort ();
node = cgraph_node (decl);
if (decl != current_function_decl
&& !TREE_ASM_WRITTEN (node->decl))
return NULL;
return &node->rtl;
}
/* Return name of the node used in debug output. */
const char *
cgraph_node_name (struct cgraph_node *node)
{
return (*lang_hooks.decl_printable_name) (node->decl, 2);
}
/* Dump the callgraph. */
void
dump_cgraph (FILE *f)
{
struct cgraph_node *node;
fprintf (f, "callgraph:\n\n");
for (node = cgraph_nodes; node; node = node->next)
{
struct cgraph_edge *edge;
fprintf (f, "%s:", cgraph_node_name (node));
if (node->local.self_insns)
fprintf (f, " %i insns", node->local.self_insns);
if (node->global.insns && node->global.insns != node->local.self_insns)
fprintf (f, " (%i after inlining)", node->global.insns);
if (node->origin)
fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
if (node->needed)
fprintf (f, " needed");
else if (node->reachable)
fprintf (f, " reachable");
if (DECL_SAVED_TREE (node->decl))
fprintf (f, " tree");
if (node->local.local)
fprintf (f, " local");
if (node->local.disregard_inline_limits)
fprintf (f, " always_inline");
else if (node->local.inlinable)
fprintf (f, " inlinable");
if (node->global.cloned_times > 1)
fprintf (f, " cloned %ix", node->global.cloned_times);
fprintf (f, "\n called by: ");
for (edge = node->callers; edge; edge = edge->next_caller)
{
fprintf (f, "%s ", cgraph_node_name (edge->caller));
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
}
fprintf (f, "\n calls: ");
for (edge = node->callees; edge; edge = edge->next_callee)
{
fprintf (f, "%s ", cgraph_node_name (edge->callee));
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
}
fprintf (f, "\n");
}
}
/* Returns a hash code for P. */
static hashval_t
cgraph_varpool_hash_node (const void *p)
{
return ((hashval_t)
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
(((struct cgraph_varpool_node *) p)->decl)));
}
/* Returns nonzero if P1 and P2 are equal. */
static int
eq_cgraph_varpool_node (const void *p1, const void *p2)
{
return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
(tree) p2);
}
/* Return cgraph_varpool node assigned to DECL. Create new one when needed. */
struct cgraph_varpool_node *
cgraph_varpool_node (tree decl)
{
struct cgraph_varpool_node *node;
struct cgraph_varpool_node **slot;
if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
abort ();
if (!cgraph_varpool_hash)
cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
eq_cgraph_varpool_node, NULL);
slot = (struct cgraph_varpool_node **)
htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
INSERT);
if (*slot)
return *slot;
node = ggc_alloc_cleared (sizeof (*node));
node->decl = decl;
cgraph_varpool_n_nodes++;
cgraph_varpool_nodes = node;
*slot = node;
return node;
}
/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
void
change_decl_assembler_name (tree decl, tree name)
{
struct cgraph_node *node = NULL;
struct cgraph_varpool_node *vnode = NULL;
void **slot;
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
{
SET_DECL_ASSEMBLER_NAME (decl, name);
return;
}
if (name == DECL_ASSEMBLER_NAME (decl))
return;
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
&& DECL_RTL_SET_P (decl))
warning ("%D renamed after being referenced in assembly", decl);
if (TREE_CODE (decl) == FUNCTION_DECL && cgraph_hash)
{
/* Take a look whether declaration is in the cgraph structure. */
slot =
htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
(decl)), NO_INSERT);
if (slot)
node = *slot;
/* It is, verify that we are the canonical node for this decl. */
if (node && node->decl == decl)
{
node = *slot;
htab_clear_slot (cgraph_hash, slot);
}
else
node = NULL;
}
if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && cgraph_varpool_hash)
{
/* Take a look whether declaration is in the cgraph structure. */
slot =
htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
(decl)), NO_INSERT);
if (slot)
vnode = *slot;
/* It is, verify that we are the canonical vnode for this decl. */
if (vnode && vnode->decl == decl)
{
vnode = *slot;
htab_clear_slot (cgraph_varpool_hash, slot);
}
else
vnode = NULL;
}
SET_DECL_ASSEMBLER_NAME (decl, name);
if (node)
{
slot =
htab_find_slot_with_hash (cgraph_hash, name,
IDENTIFIER_HASH_VALUE (name), INSERT);
if (*slot)
abort ();
*slot = node;
}
if (vnode)
{
slot =
htab_find_slot_with_hash (cgraph_varpool_hash, name,
IDENTIFIER_HASH_VALUE (name), INSERT);
if (*slot)
abort ();
*slot = vnode;
}
}
/* Try to find existing function for identifier ID. */
struct cgraph_varpool_node *
cgraph_varpool_node_for_identifier (tree id)
{
struct cgraph_varpool_node **slot;
if (TREE_CODE (id) != IDENTIFIER_NODE)
abort ();
if (!cgraph_varpool_hash)
return NULL;
slot = (struct cgraph_varpool_node **)
htab_find_slot_with_hash (cgraph_varpool_hash, id,
IDENTIFIER_HASH_VALUE (id), NO_INSERT);
if (!slot)
return NULL;
return *slot;
}
/* Notify finalize_compilation_unit that given node is reachable
or needed. */
void
cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
{
if (!node->needed && node->finalized)
{
node->next_needed = cgraph_varpool_nodes_queue;
cgraph_varpool_nodes_queue = node;
notice_global_symbol (node->decl);
}
node->needed = 1;
}
void
cgraph_varpool_finalize_decl (tree decl)
{
struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
/* The first declaration of a variable that comes through this function
decides whether it is global (in C, has external linkage)
or local (in C, has internal linkage). So do nothing more
if this function has already run. */
if (node->finalized)
return;
if (node->needed)
{
node->next_needed = cgraph_varpool_nodes_queue;
cgraph_varpool_nodes_queue = node;
notice_global_symbol (decl);
}
node->finalized = true;
if (/* Externally visible variables must be output. The exception are
COMDAT functions that must be output only when they are needed. */
(TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
/* Function whose name is output to the assembler file must be produced.
It is possible to assemble the name later after finalizing the function
and the fact is noticed in assemble_name then. */
|| (DECL_ASSEMBLER_NAME_SET_P (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
{
cgraph_varpool_mark_needed_node (node);
}
}
bool
cgraph_varpool_assemble_pending_decls (void)
{
bool changed = false;
while (cgraph_varpool_nodes_queue)
{
tree decl = cgraph_varpool_nodes_queue->decl;
struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
if (!TREE_ASM_WRITTEN (decl))
{
assemble_variable (decl, 0, 1, 0);
changed = true;
}
node->next_needed = NULL;
}
return changed;
}
/* Return true when the DECL can possibly be inlined. */
bool
cgraph_function_possibly_inlined_p (tree decl)
{
if (!cgraph_global_info_ready)
return (DECL_INLINE (decl)
&& (!flag_really_no_inline
|| (*lang_hooks.tree_inlining.disregard_inline_limits) (decl)));
return cgraph_node (decl)->global.inlined;
}
#include "gt-cgraph.h"

192
contrib/gcc/cgraph.h Normal file
View File

@ -0,0 +1,192 @@
/* Callgraph handling code.
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef GCC_CGRAPH_H
#define GCC_CGRAPH_H
/* Information about the function collected locally.
Available after function is analyzed. */
struct cgraph_local_info GTY(())
{
/* Size of the function before inlining. */
int self_insns;
/* Set when function function is visible in current compilation unit only
and it's address is never taken. */
bool local;
/* Set once it has been finalized so we consider it to be output. */
bool finalized;
/* False when there something makes inlining impossible (such as va_arg). */
bool inlinable;
/* True when function should be inlined independently on it's size. */
bool disregard_inline_limits;
/* True when the function has been originally extern inline, but it is
redefined now. */
bool redefined_extern_inline;
};
/* Information about the function that needs to be computed globally
once compilation is finished. Available only with -funit-at-time. */
struct cgraph_global_info GTY(())
{
/* Estimated size of the function after inlining. */
int insns;
/* Number of times given function will be cloned during output. */
int cloned_times;
/* Set when the function will be inlined exactly once. */
bool inline_once;
/* Set to true for all reachable functions before inlining is decided.
Once we inline all calls to the function and the function is local,
it is set to false. */
bool will_be_output;
/* Set iff at least one of the caller edges has inline_call flag set. */
bool inlined;
};
/* Information about the function that is propagated by the RTL backend.
Available only for functions that has been already assembled. */
struct cgraph_rtl_info GTY(())
{
bool const_function;
bool pure_function;
int preferred_incoming_stack_boundary;
};
/* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */
struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
{
tree decl;
struct cgraph_edge *callees;
struct cgraph_edge *callers;
struct cgraph_node *next;
struct cgraph_node *previous;
/* For nested functions points to function the node is nested in. */
struct cgraph_node *origin;
/* Points to first nested function, if any. */
struct cgraph_node *nested;
/* Pointer to the next function with same origin, if any. */
struct cgraph_node *next_nested;
/* Pointer to the next function in cgraph_nodes_queue. */
struct cgraph_node *next_needed;
PTR GTY ((skip (""))) aux;
struct cgraph_local_info local;
struct cgraph_global_info global;
struct cgraph_rtl_info rtl;
/* Unique id of the node. */
int uid;
/* Set when function must be output - it is externally visible
or it's address is taken. */
bool needed;
/* Set when function is reachable by call from other function
that is either reachable or needed. */
bool reachable;
/* Set once the function has been instantiated and its callee
lists created. */
bool analyzed;
/* Set when function is scheduled to be assembled. */
bool output;
};
struct cgraph_edge GTY(())
{
struct cgraph_node *caller;
struct cgraph_node *callee;
struct cgraph_edge *next_caller;
struct cgraph_edge *next_callee;
/* When NULL, inline this call. When non-NULL, points to the explanation
why function was not inlined. */
const char *inline_failed;
};
/* The cgraph_varpool data structure.
Each static variable decl has assigned cgraph_varpool_node. */
struct cgraph_varpool_node GTY(())
{
tree decl;
/* Pointer to the next function in cgraph_varpool_nodes_queue. */
struct cgraph_varpool_node *next_needed;
/* Set when function must be output - it is externally visible
or it's address is taken. */
bool needed;
/* Set once it has been finalized so we consider it to be output. */
bool finalized;
/* Set when function is scheduled to be assembled. */
bool output;
};
extern GTY(()) struct cgraph_node *cgraph_nodes;
extern GTY(()) int cgraph_n_nodes;
extern GTY(()) int cgraph_max_uid;
extern bool cgraph_global_info_ready;
extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
extern FILE *cgraph_dump_file;
extern GTY(()) int cgraph_varpool_n_nodes;
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
/* In cgraph.c */
void dump_cgraph (FILE *);
void cgraph_remove_edge (struct cgraph_node *, struct cgraph_node *);
void cgraph_remove_call (tree, tree);
void cgraph_remove_node (struct cgraph_node *);
struct cgraph_edge *cgraph_record_call (tree, tree);
struct cgraph_node *cgraph_node (tree decl);
struct cgraph_node *cgraph_node_for_identifier (tree id);
bool cgraph_calls_p (tree, tree);
struct cgraph_local_info *cgraph_local_info (tree);
struct cgraph_global_info *cgraph_global_info (tree);
struct cgraph_rtl_info *cgraph_rtl_info (tree);
const char * cgraph_node_name (struct cgraph_node *);
struct cgraph_varpool_node *cgraph_varpool_node (tree decl);
struct cgraph_varpool_node *cgraph_varpool_node_for_identifier (tree id);
void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
void cgraph_varpool_finalize_decl (tree);
bool cgraph_varpool_assemble_pending_decls (void);
bool cgraph_function_possibly_inlined_p (tree);
/* In cgraphunit.c */
bool cgraph_assemble_pending_functions (void);
void cgraph_finalize_function (tree, bool);
void cgraph_finalize_compilation_unit (void);
void cgraph_create_edges (tree, tree);
void cgraph_optimize (void);
void cgraph_mark_needed_node (struct cgraph_node *);
void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (tree, tree, const char **reason);
#endif /* GCC_CGRAPH_H */

1613
contrib/gcc/cgraphunit.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Header file for collect/tlink routines.
Copyright (C) 1998 Free Software Foundation, Inc.
/* Header file for collect/tlink routines.
Copyright (C) 1998, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@ -21,17 +21,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_COLLECT2_H
#define GCC_COLLECT2_H
extern void do_tlink PARAMS ((char **, char **));
extern void do_tlink (char **, char **);
extern void collect_execute PARAMS ((const char *, char **, const char *));
extern void collect_execute (const char *, char **, const char *);
extern void collect_exit PARAMS ((int)) ATTRIBUTE_NORETURN;
extern void collect_exit (int) ATTRIBUTE_NORETURN;
extern int collect_wait PARAMS ((const char *));
extern int collect_wait (const char *);
extern void dump_file PARAMS ((const char *));
extern void dump_file (const char *);
extern int file_exists PARAMS ((const char *));
extern int file_exists (const char *);
extern const char *ldout;
extern const char *c_file_name;
@ -39,12 +39,11 @@ extern struct obstack temporary_obstack;
extern char *temporary_firstobj;
extern int vflag, debug;
extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
extern void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
extern void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
extern void fatal PARAMS ((const char *, ...))
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
extern void fatal_perror PARAMS ((const char *, ...))
extern void fancy_abort (void) ATTRIBUTE_NORETURN;
extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
extern void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
extern void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
extern void fatal_perror (const char *, ...)
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
#endif /* ! GCC_COLLECT2_H */

File diff suppressed because it is too large Load Diff

808
contrib/gcc/common.opt Normal file
View File

@ -0,0 +1,808 @@
; Options for the language- and target-independent parts of the compiler.
; Copyright (C) 2003 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 2, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
; WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING. If not, write to the Free
; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
; 02111-1307, USA.
; See c.opt for a description of this file's format.
; Please try to keep this file in ASCII collating order.
-help
Common
Display this information
-param
Common Separate
--param <param>=<value> Set paramter <param> to value. See below for a complete list of parameters
-target-help
Common
-version
Common
G
Common Joined Separate UInteger
-G<number> Put global and static data smaller than <number> bytes into a special section (on some targets)
O
Common JoinedOrMissing
-O<number> Set optimization level to <number>
Os
Common
Optimize for space rather than speed
W
Common RejectNegative
This switch is deprecated; use -Wextra instead
Waggregate-return
Common
Warn about returning structures, unions or arrays
Wcast-align
Common
Warn about pointer casts which increase alignment
Wdeprecated-declarations
Common
Warn about uses of __attribute__((deprecated)) declarations
Wdisabled-optimization
Common
Warn when an optimization pass is disabled
Werror
Common
Treat all warnings as errors
Wextra
Common
Print extra (possibly unwanted) warnings
Winline
Common
Warn when an inlined function cannot be inlined
Wlarger-than-
Common RejectNegative Joined UInteger
-Wlarger-than-<number> Warn if an object is larger than <number> bytes
Wmissing-noreturn
Common
Warn about functions which might be candidates for __attribute__((noreturn))
Wpacked
Common
Warn when the packed attribute has no effect on struct layout
Wpadded
Common
Warn when padding is required to align structure members
Wshadow
Common
Warn when one local variable shadows another
Wstrict-aliasing
Common
Warn about code which might break strict aliasing rules
Wswitch
Common
Warn about enumerated switches, with no default, missing a case
Wswitch-default
Common
Warn about enumerated switches missing a \"default:\" statement
Wswitch-enum
Common
Warn about all enumerated switches missing a specific case
Wsystem-headers
Common
Do not suppress warnings from system headers
Wuninitialized
Common
Warn about uninitialized automatic variables
Wunreachable-code
Common
Warn about code that will never be executed
Wunused
Common
Enable all -Wunused- warnings
Wunused-function
Common
Warn when a function is unused
Wunused-label
Common
Warn when a label is unused
Wunused-parameter
Common
Warn when a function parameter is unused
Wunused-value
Common
Warn when an expression value is unused
Wunused-variable
Common
Warn when a variable is unused
aux-info
Common Separate
-aux-info <file> Emit declaration information into <file>
aux-info=
Common Joined
auxbase
Common Separate
auxbase-strip
Common Separate
d
Common Joined
-d<letters> Enable dumps from specific passes of the compiler
dumpbase
Common Separate
-dumpbase <file> Set the file basename to be used for dumps
fPIC
Common
fPIE
Common
fabi-version=
Common Joined UInteger
falign-functions
Common
Align the start of functions
falign-functions=
Common RejectNegative Joined UInteger
falign-jumps
Common
Align labels which are only reached by jumping
falign-jumps=
Common RejectNegative Joined UInteger
falign-labels
Common
Align all labels
falign-labels=
Common RejectNegative Joined UInteger
falign-loops
Common
Align the start of loops
falign-loops=
Common RejectNegative Joined UInteger
fargument-alias
Common
Specify that arguments may alias each other and globals
fargument-noalias
Common
Assume arguments may alias globals but not each other
fargument-noalias-global
Common
Assume arguments alias neither each other nor globals
fasynchronous-unwind-tables
Common
Generate unwind tables that are exact at each instruction boundary
fbounds-check
Common
Generate code to check bounds before indexing arrays
fbranch-count-reg
Common
Replace add, compare, branch with branch on count register
fbranch-probabilities
Common
Use profiling information for branch probabilities
fbranch-target-load-optimize
Common
Perform branch target load optimization before prologue / epilogue threading
fbranch-target-load-optimize2
Common
Perform branch target load optimization after prologue / epilogue threading
fcall-saved-
Common Joined RejectNegative
-fcall-saved-<register> Mark <register> as being preserved across functions
fcall-used-
Common Joined RejectNegative
-fcall-used-<register> Mark <register> as being corrupted by function calls
fcaller-saves
Common
Save registers around function calls
fcommon
Common
Do not put uninitialized globals in the common section
fcprop-registers
Common
Perform a register copy-propagation optimization pass
fcrossjumping
Common
Perform cross-jumping optimization
fcse-follow-jumps
Common
When running CSE, follow jumps to their targets
fcse-skip-blocks
Common
When running CSE, follow conditional jumps
fdata-sections
Common
Place data items into their own section
fdefer-pop
Common
Defer popping functions args from stack until later
fdelayed-branch
Common
Attempt to fill delay slots of branch instructions
fdelete-null-pointer-checks
Common
Delete useless null pointer checks
fdiagnostics-show-location=
Common Joined RejectNegative
-fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics
fdump-unnumbered
Common
Suppress output of instruction numbers and line number notes in debugging dumps
feliminate-dwarf2-dups
Common
Perform DWARF2 duplicate elimination
feliminate-unused-debug-symbols
Common
Perform unused type elimination in debug info
feliminate-unused-debug-types
Common
Perform unused type elimination in debug info
fexceptions
Common
Enable exception handling
fexpensive-optimizations
Common
Perform a number of minor, expensive optimizations
ffast-math
Common
ffinite-math-only
Common
Assume no NaNs or infinities are generated
ffixed-
Common Joined RejectNegative
-ffixed-<register> Mark <register> as being unavailable to the compiler
ffloat-store
Common
Do not store floats in registers
fforce-addr
Common
Copy memory address constants into registers before use
fforce-mem
Common
Copy memory operands into registers before use
ffunction-cse
Common
Allow function addresses to be held in registers
ffunction-sections
Common
Place each function into its own section
fgcse
Common
Perform global common subexpression elimination
fgcse-lm
Common
Perform enhanced load motion during global common subexpression elimination
fgcse-sm
Common
Perform store motion after global common subexpression elimination
fgcse-las
Common
Perform redundant load after store elimination in global common subexpression elimination
fguess-branch-probability
Common
Enable guessing of branch probabilities
fident
Common
Process #ident directives
fif-conversion
Common
Perform conversion of conditional jumps to branchless equivalents
fif-conversion2
Common
Perform conversion of conditional jumps to conditional execution
finhibit-size-directive
Common
Do not generate .size directives
finline
Common
Pay attention to the \"inline\" keyword
finline-functions
Common
Integrate simple functions into their callers
finline-limit-
Common RejectNegative Joined UInteger
finline-limit=
Common RejectNegative Joined UInteger
-finline-limit=<number> Limit the size of inlined functions to <number>
finstrument-functions
Common
Instrument function entry and exit with profiling calls
fkeep-inline-functions
Common
Generate code for functions even if they are fully inlined
fkeep-static-consts
Common
Emit static const variables even if they are not used
fleading-underscore
Common
Give external symbols a leading underscore
floop-optimize
Common
Perform loop optimizations
fmath-errno
Common
Set errno after built-in math functions
fmem-report
Common
Report on permanent memory allocation
fmerge-all-constants
Common
Attempt to merge identical constants and constant variables
fmerge-constants
Common
Attempt to merge identical constants across compilation units
fmessage-length=
Common RejectNegative Joined UInteger
-fmessage-length=<number> Limit diagnostics to <number> characters per line. 0 suppresses line-wrapping
fmove-all-movables
Common
Force all loop invariant computations out of loops
fnew-ra
Common
Use graph-coloring register allocation
fnon-call-exceptions
Common
Support synchronous non-call exceptions
fold-unroll-loops
Common
Perform loop unrolling when iteration count is known
fold-unroll-all-loops
Common
Perform loop unrolling for all loops
fomit-frame-pointer
Common
When possible do not generate stack frames
foptimize-register-move
Common
Do the full register move optimization pass
foptimize-sibling-calls
Common
Optimize sibling and tail recursive calls
fpack-struct
Common
Pack structure members together without holes
fpcc-struct-return
Common
Return small aggregates in memory, not registers
fpeel-loops
Common
Perform loop peeling
fpeephole
Common
Enable machine specific peephole optimizations
fpeephole2
Common
Enable an RTL peephole pass before sched2
fpic
Common
Generate position-independent code if possible
fpie
Common
Generate position-independent code for executables if possible
fprefetch-loop-arrays
Common
Generate prefetch instructions, if available, for arrays in loops
fprofile
Common
Enable basic program profiling code
fprofile-arcs
Common
Insert arc-based program profiling code
fprofile-generate
Common
Enable common options for generating profile info for profile feedback directed optimizations
fprofile-use
Common
Enable common options for performing profile feedback directed optimizations
fprofile-values
Common
Insert code to profile values of expressions
frandom-seed
Common
frandom-seed=
Common Joined RejectNegative
-frandom-seed=<string> Make compile reproducible using <string>
freduce-all-givs
Common
Strength reduce all loop general induction variables
freg-struct-return
Common
Return small aggregates in registers
fregmove
Common
Enables a register move optimization
frename-registers
Common
Perform a register renaming optimization pass
freorder-blocks
Common
Reorder basic blocks to improve code placement
freorder-functions
Common
Reorder functions to improve code placement
frerun-cse-after-loop
Common
Add a common subexpression elimination pass after loop optimizations
frerun-loop-opt
Common
Run the loop optimizer twice
frounding-math
Common
Disable optimizations that assume default FP rounding behavior
fsched-interblock
Common
Enable scheduling across basic blocks
fsched-spec
Common
Allow speculative motion of non-loads
fsched-spec-load
Common
Allow speculative motion of some loads
fsched-spec-load-dangerous
Common
Allow speculative motion of more loads
fsched-verbose=
Common RejectNegative Joined
-fsched-verbose=<number> Set the verbosity level of the scheduler
fsched2-use-superblocks
Common
If scheduling post reload, do superblock scheduling
fsched2-use-traces
Common
If scheduling post reload, do trace scheduling
fschedule-insns
Common
Reschedule instructions before register allocation
fschedule-insns2
Common
Reschedule instructions after register allocation
fsched-stalled-insns
Common
Allow premature scheduling of queued insns
fsched-stalled-insns=
Common RejectNegative Joined UInteger
-fsched-stalled-insns=<number> Set number of queued insns that can be prematurely scheduled
fsched-stalled-insns-dep
Common
Set dependence distance checking in premature scheduling of queued insns
fsched-stalled-insns-dep=
Common RejectNegative Joined UInteger
-fsched-stalled-insns-dep=<number> Set dependence distance checking in premature scheduling of queued insns
fshared-data
Common
Mark data as shared rather than private
fsignaling-nans
Common
Disable optimizations observable by IEEE signaling NaNs
fsingle-precision-constant
Common
Convert floating point constants to single precision constants
fstack-check
Common
Insert stack checking code into the program
fstack-limit
Common
fstack-limit-register=
Common RejectNegative Joined
-fstack-limit-register=<register> Trap if the stack goes past <register>
fstack-limit-symbol=
Common RejectNegative Joined
-fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>
fstrength-reduce
Common
Perform strength reduction optimizations
fstrict-aliasing
Common
Assume strict aliasing rules apply
fsyntax-only
Common
Check for syntax errors, then stop
ftest-coverage
Common
Create data files needed by \"gcov\"
fthread-jumps
Common
Perform jump threading optimizations
ftime-report
Common
Report the time taken by each compiler pass
ftls-model=
Common Joined RejectNegative
-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec] Set the default thread-local storage code generation model
ftracer
Common
Perform superblock formation via tail duplication
ftrapping-math
Common
Assume floating-point operations can trap
ftrapv
Common
Trap for signed overflow in addition, subtraction and multiplication
funit-at-a-time
Common
Compile whole compilation unit at a time
funroll-loops
Common
Perform loop unrolling when iteration count is known
funroll-all-loops
Common
Perform loop unrolling for all loops
funsafe-math-optimizations
Common
Allow math optimizations that may violate IEEE or ISO standards
funswitch-loops
Common
Perform loop unswitching
funwind-tables
Common
Just generate unwind tables for exception handling
fverbose-asm
Common
Add extra commentary to assembler output
fvpt
Common
Use expression value profiles in optimizations
fweb
Common
Construct webs and split unrelated uses of single variable
fwrapv
Common
Assume signed arithmetic overflow wraps around
fwritable-strings
Common
Store strings in writable data section
fzero-initialized-in-bss
Common
Put zero initialized data in the bss section
g
Common JoinedOrMissing
Generate debug information in default format
gcoff
Common JoinedOrMissing
Generate debug information in COFF format
gdwarf-2
Common JoinedOrMissing
Generate debug information in DWARF v2 format
ggdb
Common JoinedOrMissing
Generate debug information in default extended format
gstabs
Common JoinedOrMissing
Generate debug information in STABS format
gstabs+
Common JoinedOrMissing
Generate debug information in extended STABS format
gvms
Common JoinedOrMissing
Generate debug information in VMS format
gxcoff
Common JoinedOrMissing
Generate debug information in XCOFF format
gxcoff+
Common JoinedOrMissing
Generate debug information in extended XCOFF format
m
Common Joined
o
Common Joined Separate
-o <file> Place output into <file>
p
Common
Enable function profiling
pedantic
Common
Issue warnings needed for strict compliance to the standard
pedantic-errors
Common
Like -pedantic but issue them as errors
quiet
Common
Do not display functions compiled or elapsed time
version
Common
Display the compiler's version
w
Common
Suppress warnings
; This comment is to ensure we retain the blank line above.

123
contrib/gcc/config.build Normal file
View File

@ -0,0 +1,123 @@
# GCC build-specific configuration file.
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
#This file is part of GCC.
#GCC is free software; you can redistribute it and/or modify it under
#the terms of the GNU General Public License as published by the Free
#Software Foundation; either version 2, or (at your option) any later
#version.
#GCC is distributed in the hope that it will be useful, but WITHOUT
#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
#for more details.
#You should have received a copy of the GNU General Public License
#along with GCC; see the file COPYING. If not, write to the Free
#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#02111-1307, USA.
# This is the GCC build-specific configuration file
# where a configuration type is mapped to different system-specific
# definitions and files. This is invoked by the autoconf-generated
# configure script. Putting it in a separate shell file lets us skip
# running autoconf when modifying build-specific information.
# This file switches on the shell variable ${build}. As much of this
# as possible should be replaced with autoconf tests in the future.
# This file sets the following shell variables for use by the
# autoconf-generated configure script:
#
# build_xm_defines List of macros to define when compiling for the
# build machine.
#
# build_xm_file List of files to include when compiling for the
# build machine.
#
# build_install_headers_dir
# Target to use when installing header files.
#
# build_exeext Set to the suffix, if the build machine requires
# executables to have a file name suffix.
# Default settings.
build_xm_file=
build_xm_defines=
build_exeext=
build_install_headers_dir=install-headers-tar
# System-specific settings.
case $build in
alpha*-dec-osf4*)
# Some versions of OSF4 (specifically X4.0-9 296.7) have
# a broken tar, so we use cpio instead.
build_install_headers_dir=install-headers-cpio
;;
alpha*-dec-*vms*)
build_xm_file=alpha/xm-vms.h
build_exeext=.exe
build_install_headers_dir=install-headers-cp
prefix=/gnu
local_prefix=/gnu
;;
hppa1.0-*-hpux1[01]* | \
hppa*64*-*-hpux11* | \
hppa1.1-*-hpux11* | \
hppa2*-*-hpux11* )
build_install_headers_dir=install-headers-cpio
;;
i370-*-opened* | i370-*-mvs* )
# IBM 360/370/390 Architecture
build_xm_defines='FATAL_EXIT_CODE=12'
;;
i[34567]86-*-cygwin* | i[34567]86-*-pe )
build_xm_file=i386/xm-cygwin.h
build_exeext=.exe
;;
i[34567]86-*-mingw32*)
build_xm_file=i386/xm-mingw32.h
build_exeext=.exe
;;
i[34567]86-pc-msdosdjgpp*)
build_xm_file=i386/xm-djgpp.h
build_exeext=.exe
;;
i[34567]86-*-sco3.2v5*)
# 80386 running SCO Open Server 5
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
build_xm_defines="SMALL_ARG_MAX"
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-*-solaris2*)
build_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-*-sysv4*)
# Intel x86 running system V r4
build_xm_defines="SMALL_ARG_MAX"
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-*-udk*)
# Intel x86 on SCO UW/OSR5 Dev Kit
build_install_headers_dir=install-headers-cpio
;;
i[34567]86-*-uwin*)
build_exeext=.exe
;;
i386-*-vsta)
# Intel 80386's running VSTa kernel
;;
m68000-hp-hpux* | m68k-hp-hpux*)
# HP 9000 series 300
build_install_headers_dir=install-headers-cpio
;;
*-*-sysv*)
# All other System V variants.
build_install_headers_dir=install-headers-cpio
;;
esac

File diff suppressed because it is too large Load Diff

155
contrib/gcc/config.host Normal file
View File

@ -0,0 +1,155 @@
# GCC host-specific configuration file.
# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
#This file is part of GCC.
#GCC is free software; you can redistribute it and/or modify it under
#the terms of the GNU General Public License as published by the Free
#Software Foundation; either version 2, or (at your option) any later
#version.
#GCC is distributed in the hope that it will be useful, but WITHOUT
#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
#for more details.
#You should have received a copy of the GNU General Public License
#along with GCC; see the file COPYING. If not, write to the Free
#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#02111-1307, USA.
# This is the GCC host-specific configuration file
# where a configuration type is mapped to different system-specific
# definitions and files. This is invoked by the autoconf-generated
# configure script. Putting it in a separate shell file lets us skip
# running autoconf when modifying host-specific information.
# This file switches on the shell variable ${host}. As much of this as
# is reasonable should be replaced with autoconf tests in the future.
# This file sets the following shell variables for use by the
# autoconf-generated configure script:
#
# host_xm_file List of files to include when compiling for the
# host machine.
#
# host_xm_defines List of macros to define when compiling for the
# host machine.
#
# host_xmake_file List of host-specific makefile-fragments.
#
# host_exeext Set to the suffix, if the host machine requires
# executables to have a file name suffix.
#
# host_extra_objs List of extra host-dependent objects that should
# be linked into the compiler proper.
#
# host_extra_gcc_objs List of extra host-dependent objects that should
# be linked into the gcc driver.
#
# out_host_hook_obj An object file that provides the host hooks.
# When setting any of these variables, check to see if a corresponding
# variable is present in config.build; if so, you will likely want to
# set it in both places.
# Default settings.
host_xm_file=
host_xm_defines=
host_xmake_file=
host_exeext=
host_extra_objs=
host_extra_gcc_objs=
out_host_hook_obj=host-default.o
# Unsupported hosts list. Generally, only include hosts known to fail here,
# since we allow hosts not listed to be supported generically.
case ${host} in
i[34567]86-sequent-sysv \
| i[34567]86-sequent-sysv[123]* \
| i[34567]86-go32-* \
| i[34567]86-*-go32* \
| vax-*-vms*)
echo "*** Configuration for host ${host} not supported" 1>&2
exit 1
;;
esac
# Machine-specific settings.
case ${host} in
alpha*-dec-*vms*)
host_xm_file=alpha/xm-vms.h
host_xmake_file=alpha/x-vms
host_exeext=.exe
# This removes the cpu type and manufacturer components and
# replaces "." with "_" in the operating system version.
target_noncanonical=`echo $host | sed 's/.*-.*-\(.*\)$/\1/' | sed 's/\./_/g'`
prefix=/gnu
local_prefix=/gnu
;;
hppa1.1-*-pro*)
host_xmake_file="pa/x-ada"
;;
hppa1.1-*-osf*)
host_xmake_file="pa/x-ada"
;;
hppa1.1-*-rtems*)
host_xmake_file="pa/x-ada"
;;
hppa1.1-*-bsd*)
host_xmake_file="pa/x-ada"
;;
hppa1.0-*-hpux10* | hppa1.1-*-hpux10* | hppa2*-*-hpux10* | \
hppa1.0-*-hpux11* | hppa1.1-*-hpux11* | hppa2*-*-hpux11* | \
hppa*64*-*-hpux11*)
host_xmake_file="pa/x-ada"
;;
i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
host_xm_defines='FATAL_EXIT_CODE=12'
;;
i[34567]86-sequent-ptx4*)
host_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-*-solaris2*)
host_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
host_xm_defines="SMALL_ARG_MAX"
;;
i[34567]86-pc-msdosdjgpp*)
host_xm_file=i386/xm-djgpp.h
host_exeext=.exe
# Shorten $target_noncanonical for 8.3 filename conventions.
case ${target} in
*pc-msdosdjgpp*)
target_noncanonical=djgpp
;;
esac
;;
i[34567]86-*-pe | i[34567]86-*-cygwin*)
host_xm_file=i386/xm-cygwin.h
host_exeext=.exe
;;
i[34567]86-*-mingw32*)
host_xm_file=i386/xm-mingw32.h
host_xmake_file=i386/x-mingw32
host_exeext=.exe
;;
i[34567]86-*-uwin*)
echo "*** UWIN may not be used as a host platform because"
echo "*** linking with posix.dll is not allowed by the GNU GPL."
exit 1
;;
i[34567]86-*-interix3*)
host_xmake_file="x-interix"
;;
i860-*-sysv4*)
host_xmake_file=i860/x-sysv4
;;
powerpc-*-darwin*)
# powerpc-darwin host support.
out_host_hook_obj=host-darwin.o
host_xmake_file=rs6000/x-darwin
;;
esac

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
/* Alpha extra machine modes.
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* 128-bit floating point. This gets reset in alpha_override_options
if VAX float format is in use. */
FLOAT_MODE (TF, 16, ieee_quad_format);

View File

@ -1,182 +1,123 @@
/* Prototypes for alpha.c functions used in the md file & elsewhere.
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
extern int alpha_next_sequence_number;
extern void literal_section PARAMS ((void));
extern void override_options PARAMS ((void));
extern int zap_mask PARAMS ((HOST_WIDE_INT));
extern int direct_return PARAMS ((void));
extern void literal_section (void);
extern void override_options (void);
extern int zap_mask (HOST_WIDE_INT);
extern int direct_return (void);
extern int alpha_sa_size PARAMS ((void));
extern int alpha_pv_save_size PARAMS ((void));
extern int alpha_using_fp PARAMS ((void));
extern void alpha_write_verstamp PARAMS ((FILE *));
extern void alpha_expand_prologue PARAMS ((void));
extern void alpha_expand_epilogue PARAMS ((void));
extern void alpha_output_filename PARAMS ((FILE *, const char *));
extern void alpha_output_lineno PARAMS ((FILE *, int));
extern int alpha_sa_size (void);
extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int,
unsigned int);
extern int alpha_pv_save_size (void);
extern int alpha_using_fp (void);
extern void alpha_expand_prologue (void);
extern void alpha_expand_epilogue (void);
extern void alpha_output_filename (FILE *, const char *);
extern void alpha_output_lineno (FILE *, int);
extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_const_int_operand PARAMS ((rtx, enum machine_mode));
extern int cint8_operand PARAMS ((rtx, enum machine_mode));
extern int add_operand PARAMS ((rtx, enum machine_mode));
extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
extern int const48_operand PARAMS ((rtx, enum machine_mode));
extern int and_operand PARAMS ((rtx, enum machine_mode));
extern int or_operand PARAMS ((rtx, enum machine_mode));
extern int mode_width_operand PARAMS ((rtx, enum machine_mode));
extern int mode_mask_operand PARAMS ((rtx, enum machine_mode));
extern int mul8_operand PARAMS ((rtx, enum machine_mode));
extern int const0_operand PARAMS ((rtx, enum machine_mode));
extern int hard_fp_register_operand PARAMS ((rtx, enum machine_mode));
extern int hard_int_register_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
extern int some_operand PARAMS ((rtx, enum machine_mode));
extern int some_ni_operand PARAMS ((rtx, enum machine_mode));
extern int input_operand PARAMS ((rtx, enum machine_mode));
extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int dtp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int dtp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int gotdtp_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int tp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int tp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int gottp_symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int call_operand PARAMS ((rtx, enum machine_mode));
extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int alpha_zero_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int alpha_swapped_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int signed_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int alpha_fp_comparison_operator PARAMS ((rtx, enum machine_mode));
extern int divmod_operator PARAMS ((rtx, enum machine_mode));
extern int aligned_memory_operand PARAMS ((rtx, enum machine_mode));
extern int unaligned_memory_operand PARAMS ((rtx, enum machine_mode));
extern int reg_or_unaligned_mem_operand PARAMS ((rtx, enum machine_mode));
extern int any_memory_operand PARAMS ((rtx, enum machine_mode));
extern int reg_not_elim_operand PARAMS ((rtx, enum machine_mode));
extern int normal_memory_operand PARAMS ((rtx, enum machine_mode));
extern int reg_no_subreg_operand PARAMS ((rtx, enum machine_mode));
extern int addition_operation PARAMS ((rtx, enum machine_mode));
extern bool alpha_const_ok_for_letter_p (HOST_WIDE_INT, int);
extern bool alpha_const_double_ok_for_letter_p (rtx, int);
extern bool alpha_extra_constraint (rtx, int);
extern bool alpha_const_ok_for_letter_p PARAMS ((HOST_WIDE_INT, int));
extern bool alpha_const_double_ok_for_letter_p PARAMS ((rtx, int));
extern bool alpha_extra_constraint PARAMS ((rtx, int));
extern rtx alpha_tablejump_addr_vec (rtx);
extern rtx alpha_tablejump_best_label (rtx);
extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
extern rtx alpha_tablejump_best_label PARAMS ((rtx));
extern bool alpha_legitimate_address_p (enum machine_mode, rtx, int);
extern rtx alpha_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
int, int, int);
extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
int, int, int));
extern rtx split_small_symbolic_operand (rtx);
extern rtx split_small_symbolic_operand PARAMS ((rtx));
extern void get_aligned_mem (rtx, rtx *, rtx *);
extern rtx get_unaligned_address (rtx, int);
extern enum reg_class alpha_preferred_reload_class (rtx, enum reg_class);
extern enum reg_class secondary_reload_class (enum reg_class,
enum machine_mode, rtx, int);
extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
extern rtx get_unaligned_address PARAMS ((rtx, int));
extern enum reg_class alpha_preferred_reload_class PARAMS ((rtx,
enum reg_class));
extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
enum machine_mode,
rtx, int));
extern void alpha_set_memflags (rtx, rtx);
extern rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT, int);
extern rtx alpha_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
extern bool alpha_expand_mov (enum machine_mode, rtx *);
extern bool alpha_expand_mov_nobwx (enum machine_mode, rtx *);
extern void alpha_emit_floatuns (rtx[]);
extern rtx alpha_emit_conditional_move (rtx, enum machine_mode);
extern void alpha_split_tfmode_pair (rtx[]);
extern void alpha_split_tfmode_frobsign (rtx[], rtx (*)(rtx, rtx, rtx));
extern void alpha_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT, int);
extern void alpha_expand_unaligned_store (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT);
extern int alpha_expand_block_move (rtx []);
extern int alpha_expand_block_clear (rtx []);
extern rtx alpha_expand_zap_mask (HOST_WIDE_INT);
extern void alpha_expand_builtin_vector_binop (rtx (*)(rtx, rtx, rtx),
enum machine_mode,
rtx, rtx, rtx);
extern rtx alpha_return_addr (int, rtx);
extern rtx alpha_gp_save_rtx (void);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
extern void alpha_initialize_trampoline (rtx, rtx, rtx, int, int, int);
extern void alpha_set_memflags PARAMS ((rtx, rtx));
extern rtx alpha_emit_set_const PARAMS ((rtx, enum machine_mode,
HOST_WIDE_INT, int));
extern rtx alpha_emit_set_long_const PARAMS ((rtx, HOST_WIDE_INT,
HOST_WIDE_INT));
extern bool alpha_expand_mov PARAMS ((enum machine_mode, rtx *));
extern bool alpha_expand_mov_nobwx PARAMS ((enum machine_mode, rtx *));
extern void alpha_emit_floatuns PARAMS ((rtx[]));
extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode));
extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
rtx (*)(rtx, rtx, rtx)));
extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT, int));
extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT));
extern int alpha_expand_block_move PARAMS ((rtx []));
extern int alpha_expand_block_clear PARAMS ((rtx []));
extern rtx alpha_expand_zap_mask PARAMS ((HOST_WIDE_INT));
extern void alpha_expand_builtin_vector_binop PARAMS ((rtx (*)(rtx, rtx, rtx),
enum machine_mode,
rtx, rtx, rtx));
extern rtx alpha_return_addr PARAMS ((int, rtx));
extern rtx alpha_gp_save_rtx PARAMS ((void));
extern void print_operand PARAMS ((FILE *, rtx, int));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
extern void alpha_reorg PARAMS ((rtx));
extern void alpha_va_start (tree, rtx);
extern rtx alpha_va_arg (tree, tree);
extern rtx function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
extern rtx function_value (tree, tree, enum machine_mode);
extern tree alpha_build_va_list PARAMS ((void));
extern void alpha_va_start PARAMS ((tree, rtx));
extern rtx alpha_va_arg PARAMS ((tree, tree));
extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
tree, int));
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
extern void alpha_start_function (FILE *, const char *, tree);
extern void alpha_end_function (FILE *, const char *, tree);
extern int alpha_find_lo_sum_using_gp PARAMS ((rtx));
extern int alpha_find_lo_sum_using_gp (rtx);
#ifdef REAL_VALUE_TYPE
extern int check_float_value PARAMS ((enum machine_mode,
REAL_VALUE_TYPE *, int));
extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
#endif
#ifdef RTX_CODE
extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
rtx, rtx));
extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
extern rtx alpha_emit_conditional_branch (enum rtx_code);
extern rtx alpha_emit_setcc (enum rtx_code);
extern int alpha_split_conditional_move (enum rtx_code, rtx, rtx, rtx, rtx);
extern void alpha_emit_xfloating_arith (enum rtx_code, rtx[]);
extern void alpha_emit_xfloating_cvt (enum rtx_code, rtx[]);
#endif
extern rtx alpha_need_linkage PARAMS ((const char *, int));
extern rtx alpha_use_linkage PARAMS ((rtx, tree, int, int));
extern rtx alpha_need_linkage (const char *, int);
extern rtx alpha_use_linkage (rtx, tree, int, int);
#if TARGET_ABI_OPEN_VMS
#ifdef HAVE_MACHINE_MODES
extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
extern enum avms_arg_type alpha_arg_type (enum machine_mode);
extern rtx alpha_arg_info_reg_val (CUMULATIVE_ARGS);
#endif
extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
#endif /* TARGET_ABI_OPEN_VMS */
extern rtx unicosmk_add_call_info_word PARAMS ((rtx));
extern rtx unicosmk_add_call_info_word (rtx);
#if TARGET_ABI_UNICOSMK
extern void unicosmk_defer_case_vector PARAMS ((rtx, rtx));
extern void unicosmk_add_extern PARAMS ((const char *));
extern void unicosmk_output_align PARAMS ((FILE *, int));
extern char * unicosmk_text_section PARAMS ((void));
extern char * unicosmk_data_section PARAMS ((void));
extern void unicosmk_asm_file_start PARAMS ((FILE *));
extern void unicosmk_asm_file_end PARAMS ((FILE *));
extern void unicosmk_output_common PARAMS ((FILE *, const char *, int, int));
#endif /* TARGET_ABI_UNICOSMK */
extern void unicosmk_defer_case_vector (rtx, rtx);
extern void unicosmk_add_extern (const char *);
extern void unicosmk_output_align (FILE *, int);
extern char * unicosmk_text_section (void);
extern char * unicosmk_data_section (void);
extern void unicosmk_output_common (FILE *, const char *, int, int);
extern int unicosmk_initial_elimination_offset (int, int);
#endif

View File

@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002 Free Software Foundation, Inc.
2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -67,6 +67,8 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_IEEE_FP"); \
if (TARGET_IEEE_WITH_INEXACT) \
builtin_define ("_IEEE_FP_INEXACT"); \
if (TARGET_LONG_DOUBLE_128) \
builtin_define ("__LONG_DOUBLE_128__"); \
\
/* Macros dependent on the C dialect. */ \
SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
@ -78,14 +80,14 @@ Boston, MA 02111-1307, USA. */
{ \
if (preprocessing_asm_p ()) \
builtin_define_std ("LANGUAGE_ASSEMBLY"); \
else if (c_language == clk_c) \
builtin_define_std ("LANGUAGE_C"); \
else if (c_language == clk_cplusplus) \
else if (c_dialect_cxx ()) \
{ \
builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
} \
if (flag_objc) \
else \
builtin_define_std ("LANGUAGE_C"); \
if (c_dialect_objc ()) \
{ \
builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \
@ -112,9 +114,12 @@ Boston, MA 02111-1307, USA. */
mirrors this list, so changes to alpha.md must be made at the same time. */
enum processor_type
{PROCESSOR_EV4, /* 2106[46]{a,} */
{
PROCESSOR_EV4, /* 2106[46]{a,} */
PROCESSOR_EV5, /* 21164{a,pc,} */
PROCESSOR_EV6}; /* 21264 */
PROCESSOR_EV6, /* 21264 */
PROCESSOR_MAX
};
extern enum processor_type alpha_cpu;
@ -222,6 +227,15 @@ extern int alpha_tls_size;
#define MASK_TLS_KERNEL (1 << 14)
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
/* This means use direct branches to local functions. */
#define MASK_SMALL_TEXT (1 << 15)
#define TARGET_SMALL_TEXT (target_flags & MASK_SMALL_TEXT)
/* This means use IEEE quad-format for long double. Assumes the
presence of the GEM support library routines. */
#define MASK_LONG_DOUBLE_128 (1 << 16)
#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
/* This means that the processor is an EV5, EV56, or PCA56.
Unlike alpha_cpu this is not affected by -mtune= setting. */
#define MASK_CPU_EV5 (1 << 28)
@ -254,7 +268,7 @@ extern int alpha_tls_size;
#define TARGET_CAN_FAULT_IN_PROLOGUE 0
#endif
#ifndef TARGET_HAS_XFLOATING_LIBS
#define TARGET_HAS_XFLOATING_LIBS 0
#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128
#endif
#ifndef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 0
@ -310,8 +324,15 @@ extern int alpha_tls_size;
N_("Emit 16-bit relocations to the small data areas")}, \
{"large-data", -MASK_SMALL_DATA, \
N_("Emit 32-bit relocations to the small data areas")}, \
{"small-text", MASK_SMALL_TEXT, \
N_("Emit direct branches to local functions")}, \
{"large-text", -MASK_SMALL_TEXT, ""}, \
{"tls-kernel", MASK_TLS_KERNEL, \
N_("Emit rdval instead of rduniq for thread pointer")}, \
{"long-double-128", MASK_LONG_DOUBLE_128, \
N_("Use 128-bit long double")}, \
{"long-double-64", -MASK_LONG_DOUBLE_128, \
N_("Use 64-bit long double")}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
@ -340,27 +361,34 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string, \
N_("Use features of and schedule given CPU")}, \
N_("Use features of and schedule given CPU"), 0}, \
{"tune=", &alpha_tune_string, \
N_("Schedule given CPU")}, \
N_("Schedule given CPU"), 0}, \
{"fp-rounding-mode=", &alpha_fprm_string, \
N_("Control the generated fp rounding mode")}, \
N_("Control the generated fp rounding mode"), 0}, \
{"fp-trap-mode=", &alpha_fptm_string, \
N_("Control the IEEE trap mode")}, \
N_("Control the IEEE trap mode"), 0}, \
{"trap-precision=", &alpha_tp_string, \
N_("Control the precision given to fp exceptions")}, \
N_("Control the precision given to fp exceptions"), 0}, \
{"memory-latency=", &alpha_mlat_string, \
N_("Tune expected memory latency")}, \
N_("Tune expected memory latency"), 0}, \
{"tls-size=", &alpha_tls_size_string, \
N_("Specify bit size of immediate TLS offsets")}, \
N_("Specify bit size of immediate TLS offsets"), 0}, \
}
/* Support for a compile-time default CPU, et cetera. The rules are:
--with-cpu is ignored if -mcpu is specified.
--with-tune is ignored if -mtune is specified. */
#define OPTION_DEFAULT_SPECS \
{"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }
/* This macro defines names of additional specifications to put in the
specs that can be used in various specifications like CC1_SPEC. Its
definition is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
specification name, and a string constant that used by the GNU CC driver
specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@ -421,7 +449,18 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
/* Define this to set long double type size to use in libgcc2.c, which can
not depend on target_flags. */
#ifdef __LONG_DOUBLE_128__
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
#else
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
#endif
/* Work around target_flags dependency in ada/targtyps.c. */
#define WIDEST_HARDWARE_FP_SIZE 64
#define WCHAR_TYPE "unsigned int"
#define WCHAR_TYPE_SIZE 32
@ -444,15 +483,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
(MODE) = DImode; \
}
/* Define this if function arguments should also be promoted using the above
procedure. */
#define PROMOTE_FUNCTION_ARGS
/* Likewise, if the function return value is promoted. */
#define PROMOTE_FUNCTION_RETURN
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields.
@ -482,7 +512,7 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define PARM_BOUNDARY 64
/* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY 64
#define STACK_BOUNDARY 128
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@ -571,44 +601,30 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
/* List the order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS.
listed once, even those in FIXED_REGISTERS. */
We allocate in the following order:
$f10-$f15 (nonsaved floating-point register)
$f22-$f30 (likewise)
$f21-$f16 (likewise, but input args)
$f0 (nonsaved, but return value)
$f1 (nonsaved, but immediate before saved)
$f2-$f9 (saved floating-point registers)
$1-$8 (nonsaved integer registers)
$22-$25 (likewise)
$28 (likewise)
$0 (likewise, but return value)
$21-$16 (likewise, but input args)
$27 (procedure value in OSF, nonsaved in NT)
$9-$14 (saved integer registers)
$26 (return PC)
$15 (frame pointer)
$29 (global pointer)
$30, $31, $f31 (stack pointer and always zero/ap & fp) */
#define REG_ALLOC_ORDER \
{42, 43, 44, 45, 46, 47, \
54, 55, 56, 57, 58, 59, 60, 61, 62, \
53, 52, 51, 50, 49, 48, \
32, 33, \
34, 35, 36, 37, 38, 39, 40, 41, \
1, 2, 3, 4, 5, 6, 7, 8, \
22, 23, 24, 25, \
28, \
0, \
21, 20, 19, 18, 17, 16, \
27, \
9, 10, 11, 12, 13, 14, \
26, \
15, \
29, \
30, 31, 63 }
#define REG_ALLOC_ORDER { \
1, 2, 3, 4, 5, 6, 7, 8, /* nonsaved integer registers */ \
22, 23, 24, 25, 28, /* likewise */ \
0, /* likewise, but return value */ \
21, 20, 19, 18, 17, 16, /* likewise, but input args */ \
27, /* likewise, but OSF procedure value */ \
\
42, 43, 44, 45, 46, 47, /* nonsaved floating-point registers */ \
54, 55, 56, 57, 58, 59, /* likewise */ \
60, 61, 62, /* likewise */ \
32, 33, /* likewise, but return values */ \
53, 52, 51, 50, 49, 48, /* likewise, but input args */ \
\
9, 10, 11, 12, 13, 14, /* saved integer registers */ \
26, /* return address */ \
15, /* hard frame pointer */ \
\
34, 35, 36, 37, 38, 39, /* saved floating-point registers */ \
40, 41, /* likewise */ \
\
29, 30, 31, 63 /* gp, sp, ap, sfp */ \
}
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@ -620,12 +636,11 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On Alpha, the integer registers can hold any mode. The floating-point
registers can hold 32-bit and 64-bit integers as well, but not 16-bit
or 8-bit values. */
registers can hold 64-bit integers as well, but not smaller values. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO) >= 32 && (REGNO) <= 62 \
? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode \
: 1)
/* Value is 1 if MODE is a supported vector mode. */
@ -686,11 +701,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
current_file functions. Moreover, we do not expose the ldgp
until after reload, so we're probably safe. */
/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
/* Register in which address to store a structure value
arrives in the function. On the Alpha, the address is passed
as a hidden argument. */
#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@ -810,7 +820,7 @@ enum reg_class {
'U' is a symbolic operand.
'W' is a vector zero. */
'W' is a vector zero. */
#define EXTRA_CONSTRAINT alpha_extra_constraint
@ -953,19 +963,8 @@ extern int alpha_memory_latency;
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
{ if ((FROM) == FRAME_POINTER_REGNUM) \
(OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
+ alpha_sa_size ()); \
else if ((FROM) == ARG_POINTER_REGNUM) \
(OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
+ alpha_sa_size () \
+ (ALPHA_ROUND (get_frame_size () \
+ current_function_pretend_args_size) \
- current_function_pretend_args_size)); \
else \
abort (); \
}
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
((OFFSET) = alpha_initial_elimination_offset(FROM, TO))
/* Define this if stack space is still allocated for a parameter passed
in a register. */
@ -988,37 +987,14 @@ extern int alpha_memory_latency;
On Alpha the value is found in $0 for integer functions and
$f0 for floating-point functions. */
#define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
|| POINTER_TYPE_P (VALTYPE)) \
? word_mode : TYPE_MODE (VALTYPE), \
((TARGET_FPREGS \
&& (TREE_CODE (VALTYPE) == REAL_TYPE \
|| TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
? 32 : 0))
#define FUNCTION_VALUE(VALTYPE, FUNC) \
function_value (VALTYPE, FUNC, VOIDmode)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
gen_rtx_REG (MODE, \
(TARGET_FPREGS \
&& (GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
? 32 : 0))
/* The definition of this macro implies that there are cases where
a scalar value cannot be returned in registers.
For the Alpha, any structure or union type is returned in memory, as
are integers whose size is larger than 64 bits. */
#define RETURN_IN_MEMORY(TYPE) \
(TYPE_MODE (TYPE) == BLKmode \
|| TYPE_MODE (TYPE) == TFmode \
|| TYPE_MODE (TYPE) == TCmode \
|| (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64))
#define LIBCALL_VALUE(MODE) \
function_value (NULL, NULL, MODE)
/* 1 if N is a possible register number for a function value
as seen by the caller. */
@ -1048,7 +1024,8 @@ extern int alpha_memory_latency;
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(CUM) = 0
/* Define intermediate macro to compute the size (in registers) of an argument
for the Alpha. */
@ -1096,13 +1073,6 @@ extern int alpha_memory_latency;
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
((MODE) == TFmode || (MODE) == TCmode)
/* Specify the padding direction of arguments.
On the Alpha, we must pad upwards in order to be able to pass args in
registers. */
#define FUNCTION_ARG_PADDING(MODE, TYPE) upward
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero. */
@ -1111,68 +1081,6 @@ extern int alpha_memory_latency;
((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM) : 0)
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
CUM is as above.
MODE and TYPE are the mode and type of the current parameter.
PRETEND_SIZE is a variable that should be set to the amount of stack
that must be pushed by the prolog to pretend that our caller pushed
it.
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed.
On the Alpha, we allocate space for all 12 arg registers, but only
push those that are remaining.
However, if NO registers need to be saved, don't allocate any space.
This is not only because we won't need the space, but because AP includes
the current_pretend_args_size and we don't want to mess up any
ap-relative addresses already made.
If we are not to use the floating-point registers, save the integer
registers where we would put the floating-point registers. This is
not the most efficient way to implement varargs with just one register
class, but it isn't worth doing anything more efficient in this rare
case. */
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if ((CUM) < 6) \
{ \
if (! (NO_RTL)) \
{ \
rtx tmp; int set = get_varargs_alias_set (); \
tmp = gen_rtx_MEM (BLKmode, \
plus_constant (virtual_incoming_args_rtx, \
((CUM) + 6)* UNITS_PER_WORD)); \
set_mem_alias_set (tmp, set); \
move_block_from_reg \
(16 + CUM, tmp, \
6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
\
tmp = gen_rtx_MEM (BLKmode, \
plus_constant (virtual_incoming_args_rtx, \
(CUM) * UNITS_PER_WORD)); \
set_mem_alias_set (tmp, set); \
move_block_from_reg \
(16 + (TARGET_FPREGS ? 32 : 0) + CUM, tmp, \
6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
} \
PRETEND_SIZE = 12 * UNITS_PER_WORD; \
} \
}
/* We do not allow indirect calls to be optimized into sibling calls, nor
can we allow a call to a function in a different compilation unit to
be optimized into a sibcall. */
#define FUNCTION_OK_FOR_SIBCALL(DECL) \
(DECL \
&& (! TREE_PUBLIC (DECL) \
|| (TREE_ASM_WRITTEN (DECL) && (*targetm.binds_local_p) (DECL))))
/* Try to output insns to set TARGET equal to the constant C if it can be
done in less than N insns. Do all computations in MODE. Returns the place
where the output has been placed if it can be done and the insns have been
@ -1212,6 +1120,10 @@ extern struct alpha_compare alpha_compare;
#define PROFILE_BEFORE_PROLOGUE 1
/* Never use profile counters. */
#define NO_PROFILE_COUNTERS 1
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. Under OSF/1, profiling is enabled
by simply passing -pg to the assembler and linker. */
@ -1287,12 +1199,6 @@ do { \
/* Addressing modes, and classification of registers for them. */
/* #define HAVE_POST_INCREMENT 0 */
/* #define HAVE_POST_DECREMENT 0 */
/* #define HAVE_PRE_DECREMENT 0 */
/* #define HAVE_PRE_INCREMENT 0 */
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@ -1417,14 +1323,6 @@ do { \
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == AND) goto LABEL; }
/* Compute the cost of an address. For the Alpha, all valid addresses are
the same cost. */
#define ADDRESS_COST(X) 0
/* Machine-dependent reorg pass. */
#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X)
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
@ -1443,14 +1341,6 @@ do { \
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 1
/* This flag, if defined, says the same insns that convert to a signed fixnum
also convert validly to an unsigned one.
We actually lie a bit here as overflow conditions are different. But
they aren't being checked anyway. */
#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
/* Max number of bytes we can move to or from memory
in one reasonably fast instruction. */
@ -1494,10 +1384,9 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
/* We assume that the store-condition-codes instructions store 0 for false
and some other value for true. This is the value stored for true. */
#define STORE_FLAG_VALUE 1
/* The CIX ctlz and cttz instructions return 64 for zero. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
/* Define the value returned by a floating-point comparison instruction. */
@ -1548,162 +1437,6 @@ do { \
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
/* Compute the cost of computing a constant rtl expression RTX
whose rtx-code is CODE. The body of this macro is a portion
of a switch statement. If the code is computed here,
return it with a return statement. Otherwise, break from the switch.
If this is an 8-bit constant, return zero since it can be used
nearly anywhere with no cost. If it is a valid operand for an
ADD or AND, likewise return 0 if we know it will be used in that
context. Otherwise, return 2 since it might be used there later.
All other constants take at least two insns. */
#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
case CONST_INT: \
if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256) \
return 0; \
case CONST_DOUBLE: \
if ((RTX) == CONST0_RTX (GET_MODE (RTX))) \
return 0; \
else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \
|| ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \
return 0; \
else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \
return 2; \
else \
return COSTS_N_INSNS (2); \
case CONST: \
case SYMBOL_REF: \
case LABEL_REF: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
return COSTS_N_INSNS (3); \
case PROCESSOR_EV5: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (2); \
default: abort(); \
}
/* Provide the costs of a rtl expression. This is in the body of a
switch on CODE. */
#define RTX_COSTS(X,CODE,OUTER_CODE) \
case PLUS: case MINUS: \
if (FLOAT_MODE_P (GET_MODE (X))) \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
return COSTS_N_INSNS (6); \
case PROCESSOR_EV5: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (4); \
default: abort(); \
} \
else if (GET_CODE (XEXP (X, 0)) == MULT \
&& const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \
return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \
+ rtx_cost (XEXP (X, 1), OUTER_CODE)); \
break; \
case MULT: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
if (FLOAT_MODE_P (GET_MODE (X))) \
return COSTS_N_INSNS (6); \
return COSTS_N_INSNS (23); \
case PROCESSOR_EV5: \
if (FLOAT_MODE_P (GET_MODE (X))) \
return COSTS_N_INSNS (4); \
else if (GET_MODE (X) == DImode) \
return COSTS_N_INSNS (12); \
else \
return COSTS_N_INSNS (8); \
case PROCESSOR_EV6: \
if (FLOAT_MODE_P (GET_MODE (X))) \
return COSTS_N_INSNS (4); \
else \
return COSTS_N_INSNS (7); \
default: abort(); \
} \
case ASHIFT: \
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
&& INTVAL (XEXP (X, 1)) <= 3) \
break; \
/* ... fall through ... */ \
case ASHIFTRT: case LSHIFTRT: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
return COSTS_N_INSNS (2); \
case PROCESSOR_EV5: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (1); \
default: abort(); \
} \
case IF_THEN_ELSE: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (2); \
case PROCESSOR_EV5: \
return COSTS_N_INSNS (1); \
default: abort(); \
} \
case DIV: case UDIV: case MOD: case UMOD: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
if (GET_MODE (X) == SFmode) \
return COSTS_N_INSNS (34); \
else if (GET_MODE (X) == DFmode) \
return COSTS_N_INSNS (63); \
else \
return COSTS_N_INSNS (70); \
case PROCESSOR_EV5: \
if (GET_MODE (X) == SFmode) \
return COSTS_N_INSNS (15); \
else if (GET_MODE (X) == DFmode) \
return COSTS_N_INSNS (22); \
else \
return COSTS_N_INSNS (70); /* ??? */ \
case PROCESSOR_EV6: \
if (GET_MODE (X) == SFmode) \
return COSTS_N_INSNS (12); \
else if (GET_MODE (X) == DFmode) \
return COSTS_N_INSNS (15); \
else \
return COSTS_N_INSNS (70); /* ??? */ \
default: abort(); \
} \
case MEM: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (3); \
case PROCESSOR_EV5: \
return COSTS_N_INSNS (2); \
default: abort(); \
} \
case NEG: case ABS: \
if (! FLOAT_MODE_P (GET_MODE (X))) \
break; \
/* ... fall through ... */ \
case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \
case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
switch (alpha_cpu) \
{ \
case PROCESSOR_EV4: \
return COSTS_N_INSNS (6); \
case PROCESSOR_EV5: \
case PROCESSOR_EV6: \
return COSTS_N_INSNS (4); \
default: abort(); \
}
/* Control the assembler format that we output. */
@ -1759,18 +1492,12 @@ do { \
#define USER_LABEL_PREFIX ""
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
fprintf (FILE, "$%s%d:\n", PREFIX, NUM)
/* This is how to output a label for a jump table. Arguments are the same as
for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@ -1824,22 +1551,6 @@ do { \
} \
while (0)
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
fprintf (FILE, "\tsubq $30,8,$30\n\tst%s $%s%d,0($30)\n", \
(REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
(REGNO) & 31);
/* This is how to output an insn to pop a register from the stack.
It need not be very fast code. */
#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
fprintf (FILE, "\tld%s $%s%d,0($30)\n\taddq $30,8,$30\n", \
(REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
(REGNO) & 31);
/* This is how to output an element of a case-vector that is absolute.
(Alpha does not use such vectors, but we must define this macro anyway.) */
@ -1862,7 +1573,7 @@ do { \
/* This is how to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
fprintf (FILE, "\t.space %d\n", (SIZE))
fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@ -1870,7 +1581,7 @@ do { \
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs ("\t.comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%d\n", (SIZE)))
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* This says how to output an assembler line
to define a local common symbol. */
@ -1878,15 +1589,7 @@ do { \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \
( fputs ("\t.lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%d\n", (SIZE)))
/* Store in OUTPUT a string (made with alloca) containing
an assembler-name for a local static variable named NAME.
LABELNO is an integer which is different for each call. */
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* Print operand X (an rtx) in assembler syntax to file FILE.
@ -1908,11 +1611,14 @@ do { \
- Generates double precision suffix for floating point
instructions (t for IEEE, g for VAX)
+ Generates a nop instruction after a noreturn call at the very end
of the function
*/
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
|| (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
|| (CODE) == '#' || (CODE) == '*' || (CODE) == '&' || (CODE) == '+')
/* Print a memory address as an operand to reference that memory location. */
@ -1943,8 +1649,9 @@ do { \
{"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
{"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \
{"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \
{"fix_operator", {FIX, UNSIGNED_FIX}}, \
{"const0_operand", {CONST_INT, CONST_DOUBLE, CONST_VECTOR}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"samegp_function_operand", {SYMBOL_REF}}, \
{"direct_call_operand", {SYMBOL_REF}}, \
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
@ -1965,6 +1672,7 @@ do { \
{"unaligned_memory_operand", {MEM}}, \
{"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \
{"any_memory_operand", {MEM}}, \
{"normal_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}}, \
{"hard_int_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
@ -1974,10 +1682,6 @@ do { \
{"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
UNSPEC_VOLATILE}},
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \
(VALIST) = alpha_build_va_list ()
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
alpha_va_start (valist, nextarg)
@ -2024,7 +1728,7 @@ extern long alpha_auto_offset;
#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_offset)
#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \
#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE, COUNTER) \
alpha_output_lineno (STREAM, LINE)
#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV4.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
;; This file is part of GNU CC.
;; This file is part of GCC.
;;
;; GNU CC is free software; you can redistribute it and/or modify
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GNU CC is distributed in the hope that it will be useful,
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

View File

@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV5.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
;; This file is part of GNU CC.
;; This file is part of GCC.
;;
;; GNU CC is free software; you can redistribute it and/or modify
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GNU CC is distributed in the hope that it will be useful,
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

View File

@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV6.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
;; This file is part of GNU CC.
;; This file is part of GCC.
;;
;; GNU CC is free software; you can redistribute it and/or modify
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;;
;; GNU CC is distributed in the hope that it will be useful,
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING. If not, write to
;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

View File

@ -6,12 +6,8 @@
#undef TARGET_OS_CPP_BUILTINS /* config.gcc includes alpha/linux.h. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define ("__GNU__"); \
builtin_define ("__ELF__"); \
builtin_define ("__gnu_hurd__"); \
HURD_TARGET_OS_CPP_BUILTINS(); \
builtin_define ("_LONGLONG"); \
builtin_define_std ("unix"); \
builtin_assert ("system=gnu"); \
} while (0)
#undef ELF_DYNAMIC_LINKER

View File

@ -307,7 +307,7 @@ $46:
conventions. */
#if TYPE == UNSIGNED && SIZE == 32
/* This could be avoided by adding some CPP hair to the divide loop.
It is probably not worth the added complexity. */
It is probably not worth the added complexity. */
addl RETREG,0,RETREG
#endif

View File

@ -3,20 +3,20 @@
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Henderson.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -27,11 +27,7 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_EXTRA_SPECS \
{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
#ifdef USE_GNULIBC_1
#define ELF_DYNAMIC_LINKER "/lib/ld.so.1"
#else
#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2"
#endif
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
%{O*:-O3} %{!O*:-O1} \
@ -42,8 +38,8 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} \
%{static:-static}}"
#ifndef USE_GNULIBC_1
#undef LIB_SPEC
#define LIB_SPEC \
"%{pthread:-lpthread }%{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
#endif
"%{pthread:-lpthread} %{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack

View File

@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Henderson.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -30,8 +30,10 @@ Boston, MA 02111-1307, USA. */
builtin_define_std ("linux"); \
builtin_define_std ("unix"); \
builtin_assert ("system=linux"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=posix"); \
/* The GNU C++ standard library requires this. */ \
if (c_language == clk_cplusplus) \
if (c_dialect_cxx ()) \
builtin_define ("_GNU_SOURCE"); \
} while (0)
@ -59,6 +61,10 @@ Boston, MA 02111-1307, USA. */
/* Define this so that all GNU/Linux targets handle the same pragmas. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
/* Determine whether the the entire c99 runtime is present in the
runtime library. */
#define TARGET_C99_FUNCTIONS 1
#define TARGET_HAS_F_SETLKW
#define LINK_GCC_C_SEQUENCE_SPEC \

View File

@ -1,21 +1,21 @@
/* Definitions of target machine for GNU compiler,
for Alpha NetBSD systems.
Copyright (C) 1998, 2002 Free Software Foundation, Inc.
Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
NETBSD_OS_CPP_BUILTINS_ELF(); \
NETBSD_OS_CPP_BUILTINS_LP64(); \
} while (0)
@ -77,7 +76,7 @@ Boston, MA 02111-1307, USA. */
/* Attempt to enable execute permissions on the stack. */
#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#undef TARGET_VERSION

View File

@ -1,36 +1,26 @@
/* Configuration file for an alpha OpenBSD target.
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* We settle for little endian for now. */
#define TARGET_ENDIAN_DEFAULT 0
#define OBSD_NO_DYNAMIC_LIBRARIES
#define OBSD_HAS_DECLARE_FUNCTION_NAME
#define OBSD_HAS_DECLARE_FUNCTION_SIZE
#define OBSD_HAS_DECLARE_OBJECT
/* alpha ecoff supports only weak aliases, see below. */
#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
#include <openbsd.h>
/* Controlling the compilation driver. */
/* alpha needs __start. */
@ -82,38 +72,18 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
dwarf unwind information. egcs doesn't try too hard to check internal
configuration files... */
dwarf unwind information. */
#ifdef INCOMING_RETURN_ADDR_RTX
#undef DWARF2_UNWIND_INFO
#define DWARF2_UNWIND_INFO 0
#endif
/* Assembler format: file framework. */
/* Taken from alpha/osf.h. This used to be common to all alpha
configurations, but elf has departed from it.
Check alpha/alpha.h, alpha/osf.h for it when egcs is upgraded. */
#ifndef ASM_FILE_START
#define ASM_FILE_START(FILE) \
{ \
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
fprintf (FILE, "\t.set noat\n"); \
if (TARGET_SUPPORT_ARCH) \
fprintf (FILE, "\t.arch %s\n", \
TARGET_CPU_EV6 ? "ev6" \
: (TARGET_CPU_EV5 \
? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
: "ev4")); \
\
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
#endif
/* Assembler format: label output. */
/* alpha ecoff supports only weak aliases. */
#undef ASM_WEAKEN_LABEL
#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
#define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE) \
do { \
fputs ("\t.weakext\t", FILE); \

View File

@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003,
2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -49,6 +49,13 @@ Boston, MA 02111-1307, USA. */
to be defined for <math.h>. */ \
if (LONG_DOUBLE_TYPE_SIZE == 128) \
builtin_define ("__X_FLOAT"); \
\
/* Tru64 UNIX V4/V5 provide several ISO C94 \
features protected by the corresponding \
__STDC_VERSION__ macro. libstdc++ v3 \
needs them as well. */ \
if (c_dialect_cxx ()) \
builtin_define ("__STDC_VERSION__=199409L"); \
} while (0)
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
@ -84,22 +91,6 @@ Boston, MA 02111-1307, USA. */
#define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/"
#define ASM_FILE_START(FILE) \
{ \
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
fprintf (FILE, "\t.set noat\n"); \
if (TARGET_SUPPORT_ARCH) \
fprintf (FILE, "\t.arch %s\n", \
TARGET_CPU_EV6 ? "ev6" \
: (TARGET_CPU_EV5 \
? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
: "ev4")); \
\
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
/* Tru64 UNIX V5.1 requires a special as flag. Empty by default. */
#define ASM_OLDAS_SPEC ""
@ -154,14 +145,11 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on access permissions for the stack. */
#define TRANSFER_FROM_TRAMPOLINE \
extern void __enable_execute_stack PARAMS ((void *)); \
\
#define ENABLE_EXECUTE_STACK \
void \
__enable_execute_stack (addr) \
void *addr; \
__enable_execute_stack (void *addr) \
{ \
extern int mprotect PARAMS ((const void *, size_t, int)); \
extern int mprotect (const void *, size_t, int); \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
@ -181,6 +169,10 @@ __enable_execute_stack (addr) \
#define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini"
/* The linker needs a space after "-o". This allows -oldstyle_liblookup to
be passed to ld. */
#define SWITCHES_NEED_SPACES "o"
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.

View File

@ -1,29 +1,26 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Tru64 5.1 uses IEEE QUAD format. */
/* ??? However, since there is no support for VAX H_floating, we must
drop back to a 64-bit long double to avoid a crash looking for the
format associated with TFmode. */
#undef LONG_DOUBLE_TYPE_SIZE
#define LONG_DOUBLE_TYPE_SIZE (TARGET_FLOAT_VAX ? 64 : 128)
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_FP | MASK_FPREGS | MASK_LONG_DOUBLE_128
/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
(/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
@ -49,3 +46,8 @@
linked. */
#undef TARGET_LD_BUGGY_LDGP
#define TARGET_LD_BUGGY_LDGP 1
/* Tru64 v5.1 has the float and long double forms of math functions. */
#undef TARGET_C99_FUNCTIONS
#define TARGET_C99_FUNCTIONS 1

View File

@ -0,0 +1,5 @@
# Provide dummy POSIX threads functions
LIB2FUNCS_EXTRA += $(srcdir)/gthr-posix.c
# Compile libgcc2 with POSIX threads supports
TARGET_LIBGCC2_CFLAGS=-pthread

View File

@ -10,7 +10,11 @@ SHLIB_NAME = @shlib_base_name@.so
SHLIB_SONAME = @shlib_base_name@.so.1
SHLIB_OBJS = @shlib_objs@
# Hide all POSIX threads related symbols provided by gthr-posix.c. This
# only has an effect if t-osf-pthread is in use.
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-Wl,-hidden_symbol,pthread\* -Wl,-hidden_symbol,__pthread\* \
-Wl,-hidden_symbol,sched_get_\* -Wl,-hidden_symbol,sched_yield \
-Wl,-msym -Wl,-set_version,gcc.1 -Wl,-soname,$(SHLIB_SONAME) \
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
rm -f $(SHLIB_SONAME) && \

View File

@ -4,20 +4,20 @@
Free Software Foundation, Inc.
Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -102,8 +102,6 @@ Boston, MA 02111-1307, USA. */
other its replacement, at the start of a routine. This is somewhat
complicated on the T3E which is why we use a function. */
extern int unicosmk_initial_elimination_offset PARAMS ((int, int));
#undef INITIAL_ELIMINATION_OFFSET
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \
@ -178,7 +176,7 @@ typedef struct {
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
do { (CUM).num_args = 0; \
(CUM).num_arg_words = 0; \
(CUM).num_reg_words = 0; \
@ -220,41 +218,11 @@ do { \
++(CUM).num_args; \
} while(0)
/* We want the default definition for this.
??? In fact, we should delete the definition from alpha.h as it
corresponds to the default definition for little-endian machines. */
#undef FUNCTION_ARG_PADDING
/* An argument is passed either entirely in registers or entirely on stack. */
#undef FUNCTION_ARG_PARTIAL_NREGS
/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
arguments on the stack. Unfortunately, it doesn't always store the first
one (i.e. the one that arrives in $16 or $f16). This is not a problem
with stdargs as we always have at least one named argument there. */
#undef SETUP_INCOMING_VARARGS
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if ((CUM).num_reg_words < 6) \
{ \
if (! (NO_RTL)) \
{ \
int start = (CUM).num_reg_words + 1; \
\
emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
emit_insn (gen_arg_home_umk ()); \
} \
\
PRETEND_SIZE = 0; \
} \
}
/* This ensures that $15 increments/decrements in leaf functions won't get
eliminated. */
@ -319,43 +287,33 @@ do { fprintf (FILE, "\tbr $1,0\n"); \
COMMON_SECTION \
SSIB_SECTION
extern void common_section PARAMS ((void));
extern void common_section (void);
#define COMMON_SECTION \
void \
common_section () \
common_section (void) \
{ \
in_section = in_common; \
}
extern void ssib_section PARAMS ((void));
extern void ssib_section (void);
#define SSIB_SECTION \
void \
ssib_section () \
ssib_section (void) \
{ \
in_section = in_ssib; \
}
/* This outputs text to go at the start of an assembler file. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
/* This outputs text to go at the end of an assembler file. */
#undef ASM_FILE_END
#define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
/* We take care of that in ASM_FILE_START. */
/* We take care of this in unicosmk_file_start. */
#undef ASM_OUTPUT_SOURCE_FILENAME
/* This is how to output a label for a jump table. Arguments are the same as
for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
/* CAM has some restrictions with respect to string literals. It won't
accept lines with more that 256 characters which means that we have
@ -453,7 +411,8 @@ ssib_section () \
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM,SIZE) \
fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
(SIZE));
/* This says how to output an assembler line to define a global common
symbol. We need the alignment information because it has to be supplied
@ -470,7 +429,7 @@ ssib_section () \
do { data_section (); \
fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
} while (0)
/* CAM does not allow us to declare a symbol as external first and then
@ -521,28 +480,9 @@ ssib_section () \
#undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
#undef DWARF2_UNWIND_INFO
#undef INCOMING_RETURN_ADDR_RTX
/* We use the functions provided by the system library for integer
division. */
#undef UDIVDI3_LIBCALL
#undef DIVDI3_LIBCALL
#define UDIVDI3_LIBCALL "$uldiv"
#define DIVDI3_LIBCALL "$sldiv"
/* This is necessary to prevent gcc from generating calls to __divsi3. */
#define INIT_TARGET_OPTABS \
do { \
sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
} while (0)
#undef ASM_OUTPUT_SOURCE_LINE
/* We don't need a start file. */
@ -555,7 +495,6 @@ ssib_section () \
#undef LIB_SPEC
#define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
#undef BUILD_VA_LIST_TYPE
#undef EXPAND_BUILTIN_VA_START
#undef EXPAND_BUILTIN_VA_ARG

View File

@ -1,21 +1,21 @@
/* VMS DEC C wrapper.
Copyright (C) 2001 Free Software Foundation, Inc.
Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -25,6 +25,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#undef PATH_SEPARATOR
#undef PATH_SEPARATOR_STR
@ -32,50 +34,47 @@ Boston, MA 02111-1307, USA. */
#define PATH_SEPARATOR_STR ","
/* These can be set by command line arguments */
int verbose = 0;
int save_temps = 0;
static int verbose = 0;
static int save_temps = 0;
int comp_arg_max = -1;
const char **comp_args = 0;
int comp_arg_index = -1;
char *objfilename = 0;
static int comp_arg_max = -1;
static const char **comp_args = 0;
static int comp_arg_index = -1;
static char *objfilename = 0;
char *system_search_dirs = (char *) "";
char *search_dirs;
static char *system_search_dirs = (char *) "";
static char *search_dirs;
char *default_defines = (char *) "";
char *defines;
static char *default_defines = (char *) "";
static char *defines;
/* Translate a Unix syntax directory specification into VMS syntax.
If indicators of VMS syntax found, return input string. */
static char *to_host_dir_spec PARAMS ((char *));
If indicators of VMS syntax found, return input string. */
static char *to_host_dir_spec (char *);
/* Translate a Unix syntax file specification into VMS syntax.
If indicators of VMS syntax found, return input string. */
static char *to_host_file_spec PARAMS ((char *));
If indicators of VMS syntax found, return input string. */
static char *to_host_file_spec (char *);
/* Add a translated arg to the list to be passed to DEC CC */
static void addarg PARAMS ((const char *));
/* Add a translated arg to the list to be passed to DEC CC. */
static void addarg (const char *);
/* Preprocess the number of args in P_ARGC and contained in ARGV.
Look for special flags, etc. that must be handled first. */
static void preprocess_args PARAMS ((int *, char **));
Look for special flags, etc. that must be handled first. */
static void preprocess_args (int *, char **);
/* Process the number of args in P_ARGC and contained in ARGV. Look
for special flags, etc. that must be handled for the VMS compiler. */
static void process_args PARAMS ((int *, char **));
for special flags, etc. that must be handled for the VMS compiler. */
static void process_args (int *, char **);
/* Action routine called by decc$to_vms */
static int translate_unix PARAMS ((char *, int));
int main PARAMS ((int, char **));
static int translate_unix (char *, int);
/* Add the argument contained in STR to the list of arguments to pass to the
compiler. */
static void
addarg (str)
const char *str;
addarg (const char *str)
{
int i;
@ -98,9 +97,7 @@ addarg (str)
}
static void
preprocess_args (p_argc, argv)
int *p_argc;
char *argv[];
preprocess_args (int *p_argc, char *argv[])
{
int i;
@ -120,9 +117,7 @@ preprocess_args (p_argc, argv)
}
static void
process_args (p_argc, argv)
int *p_argc;
char *argv[];
process_args (int *p_argc, char *argv[])
{
int i;
@ -183,9 +178,7 @@ process_args (p_argc, argv)
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
int
main (argc, argv)
int argc;
char **argv;
main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@ -318,17 +311,14 @@ static char new_host_dirspec [255];
static char filename_buff [256];
static int
translate_unix (name, type)
char *name;
int type ATTRIBUTE_UNUSED;
translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
to_host_dir_spec (dirspec)
char *dirspec;
to_host_dir_spec (char *dirspec)
{
int len = strlen (dirspec);
@ -351,8 +341,7 @@ to_host_dir_spec (dirspec)
}
static char *
to_host_file_spec (filespec)
char *filespec;
to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))

View File

@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -77,7 +77,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
/* Reallocate argv with 64 bit pointers. */
/* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)

View File

@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
lib$establish. */
lib$establish. */
#include <stdlib.h>
#include <string.h>

View File

@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

View File

@ -2,9 +2,9 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */

View File

@ -1,22 +1,22 @@
/* VMS linker wrapper.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
@ -42,7 +44,7 @@ static char *vmsdwarf2spec = 0;
/* File specification for vms-dwarf2eh.o. */
static char *vmsdwarf2ehspec = 0;
/* verbose = 1 if -v passed. */
/* verbose = 1 if -v passed. */
static int verbose = 0;
/* save_temps = 1 if -save-temps passed. */
@ -87,39 +89,38 @@ static char *search_dirs;
/* Add STR to the list of arguments to pass to the linker. Expand the list as
necessary to accommodate. */
static void addarg PARAMS ((const char *));
static void addarg (const char *);
/* Check to see if NAME is a regular file, i.e. not a directory */
static int is_regular_file PARAMS ((char *));
static int is_regular_file (char *);
/* Translate a Unix syntax file specification FILESPEC into VMS syntax.
If indicators of VMS syntax found, return input string. */
static char *to_host_file_spec PARAMS ((char *));
If indicators of VMS syntax found, return input string. */
static char *to_host_file_spec (char *);
/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
static char *locate_lib PARAMS ((char *, char *));
/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
static char *locate_lib (char *, char *);
/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
libfoo.a in the set of directories we are allowed to search in. */
static const char *expand_lib PARAMS ((char *));
static const char *expand_lib (char *);
/* Preprocess the number of args P_ARGC in ARGV.
Look for special flags, etc. that must be handled first. */
static void preprocess_args PARAMS ((int *, char **));
Look for special flags, etc. that must be handled first. */
static void preprocess_args (int *, char **);
/* Preprocess the number of args P_ARGC in ARGV. Look for
special flags, etc. that must be handled for the VMS linker. */
static void process_args PARAMS ((int *, char **));
special flags, etc. that must be handled for the VMS linker. */
static void process_args (int *, char **);
/* Action routine called by decc$to_vms. NAME is a file name or
directory name. TYPE is unused. */
static int translate_unix PARAMS ((char *, int));
directory name. TYPE is unused. */
static int translate_unix (char *, int);
int main PARAMS ((int, char **));
int main (int, char **);
static void
addarg (str)
const char *str;
addarg (const char *str)
{
int i;
@ -142,9 +143,7 @@ addarg (str)
}
static char *
locate_lib (lib_name, path_val)
char *lib_name;
char *path_val;
locate_lib (char *lib_name, char *path_val)
{
int lib_len = strlen (lib_name);
char *eptr, *sptr;
@ -204,8 +203,7 @@ locate_lib (lib_name, path_val)
}
static const char *
expand_lib (name)
char *name;
expand_lib (char *name)
{
char *lib, *lib_path;
@ -238,8 +236,7 @@ expand_lib (name)
}
static int
is_regular_file (name)
char *name;
is_regular_file (char *name)
{
int ret;
struct stat statbuf;
@ -249,9 +246,7 @@ is_regular_file (name)
}
static void
preprocess_args (p_argc, argv)
int *p_argc;
char **argv;
preprocess_args (int *p_argc, char **argv)
{
int i;
@ -303,9 +298,7 @@ preprocess_args (p_argc, argv)
}
static void
process_args (p_argc, argv)
int *p_argc;
char **argv;
process_args (int *p_argc, char **argv)
{
int i;
@ -379,9 +372,7 @@ process_args (p_argc, argv)
and args to be what the VMS linker wants. */
int
main (argc, argv)
int argc;
char **argv;
main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@ -751,17 +742,14 @@ static char new_host_filespec [255];
static char filename_buff [256];
static int
translate_unix (name, type)
char *name;
int type ATTRIBUTE_UNUSED;
translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
to_host_file_spec (filespec)
char *filespec;
to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))

View File

@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -79,7 +79,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
/* Reallocate argv with 64 bit pointers. */
/* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)

View File

@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
lib$establish. */
lib$establish. */
#include <stdlib.h>
#include <string.h>

View File

@ -1,21 +1,21 @@
/* Output variables, constants and external declarations, for GNU compiler.
Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002
Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
This file is part of GNU CC.
This file is part of GCC.
GNU CC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@ -41,9 +41,6 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__IEEE_FLOAT"); \
} while (0)
/* By default, allow $ to be part of an identifier. */
#define DOLLARS_IN_IDENTIFIERS 2
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS)
#undef TARGET_ABI_OPEN_VMS
@ -54,9 +51,6 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
/* The structure return address arrives as an "argument" on VMS. */
#undef STRUCT_VALUE_REGNUM
#define STRUCT_VALUE 0
#undef PCC_STATIC_STRUCT_RETURN
/* "long" is 32 bits, but 64 bits for Ada. */
@ -178,7 +172,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(CUM).num_args = 0; \
(CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
(CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
@ -205,61 +199,10 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
+ ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM).num_args : 0)
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
CUM is as for INIT_CUMULATIVE_ARGS.
MODE and TYPE are the mode and type of the current parameter.
PRETEND_SIZE is a variable that should be set to the amount of stack
that must be pushed by the prolog to pretend that our caller pushed
it.
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed.
For VMS, we allocate space for all 6 arg registers plus a count.
However, if NO registers need to be saved, don't allocate any space.
This is not only because we won't need the space, but because AP includes
the current_pretend_args_size and we don't want to mess up any
ap-relative addresses already made. */
#undef SETUP_INCOMING_VARARGS
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if ((CUM).num_args < 6) \
{ \
if (! (NO_RTL)) \
{ \
emit_move_insn (gen_rtx_REG (DImode, 1), \
virtual_incoming_args_rtx); \
emit_insn (gen_arg_home ()); \
} \
\
PRETEND_SIZE = 7 * UNITS_PER_WORD; \
} \
}
/* ABI has stack checking, but it's broken. */
#undef STACK_CHECK_BUILTIN
#define STACK_CHECK_BUILTIN 0
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) \
{ \
alpha_write_verstamp (FILE); \
fprintf (FILE, "\t.set noreorder\n"); \
fprintf (FILE, "\t.set volatile\n"); \
if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
{ \
fprintf (FILE, "\t.arch %s\n", \
(TARGET_CPU_EV6 ? "ev6" \
: TARGET_MAX ? "pca56" : "ev56")); \
} \
ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
}
#define LINK_SECTION_ASM_OP "\t.link"
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
#define LITERALS_SECTION_ASM_OP "\t.literals"
@ -272,7 +215,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
void \
link_section () \
link_section (void) \
{ \
if (in_section != in_link) \
{ \
@ -281,7 +224,7 @@ link_section () \
} \
} \
void \
literals_section () \
literals_section (void) \
{ \
if (in_section != in_literals) \
{ \
@ -290,8 +233,8 @@ literals_section () \
} \
}
extern void link_section PARAMS ((void));
extern void literals_section PARAMS ((void));
extern void link_section (void);
extern void literals_section (void);
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
@ -306,7 +249,7 @@ extern void literals_section PARAMS ((void));
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
{ ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
{ ASM_OUTPUT_ALIGN (FILE, 3); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
@ -318,7 +261,7 @@ extern void literals_section PARAMS ((void));
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
@ -448,10 +391,7 @@ do { \
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE VMS_AND_DWARF2_DEBUG
#undef ASM_FORMAT_PRIVATE_NAME
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \
sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
#define ASM_PN_FORMAT "%s___%lu"
/* ??? VMS uses different linkage. */
#undef TARGET_ASM_OUTPUT_MI_THUNK
@ -479,7 +419,7 @@ do { \
}
/* Link with vms-dwarf2.o if -g (except -g0). This causes the
VMS link to pull all the dwarf2 debug sections together. */
VMS link to pull all the dwarf2 debug sections together. */
#undef LINK_SPEC
#define LINK_SPEC "%{g:-g vms-dwarf2.o%s} %{g0} %{g1:-g1 vms-dwarf2.o%s} \
%{g2:-g2 vms-dwarf2.o%s} %{g3:-g3 vms-dwarf2.o%s} %{shared} %{v} %{map}"
@ -491,16 +431,6 @@ do { \
#undef LIB_SPEC
#define LIB_SPEC "-lc"
/* Define the names of the division and modulus functions. */
#define DIVSI3_LIBCALL "OTS$DIV_I"
#define DIVDI3_LIBCALL "OTS$DIV_L"
#define UDIVSI3_LIBCALL "OTS$DIV_UI"
#define UDIVDI3_LIBCALL "OTS$DIV_UL"
#define MODSI3_LIBCALL "OTS$REM_I"
#define MODDI3_LIBCALL "OTS$REM_L"
#define UMODSI3_LIBCALL "OTS$REM_UI"
#define UMODDI3_LIBCALL "OTS$REM_UL"
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain

Some files were not shown because too many files have changed in this diff Show More