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:
commit
4609cf73ba
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132719
22319
contrib/gcc/ChangeLog
22319
contrib/gcc/ChangeLog
File diff suppressed because it is too large
Load Diff
@ -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
16352
contrib/gcc/ChangeLog.10
Normal file
File diff suppressed because it is too large
Load Diff
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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
14448
contrib/gcc/ChangeLog.8
Normal file
File diff suppressed because it is too large
Load Diff
21488
contrib/gcc/ChangeLog.9
Normal file
21488
contrib/gcc/ChangeLog.9
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
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
367
contrib/gcc/alloc-pool.c
Normal 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
55
contrib/gcc/alloc-pool.h
Normal 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
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
1377
contrib/gcc/bt-load.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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
591
contrib/gcc/c-cppbuiltin.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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
364
contrib/gcc/c-incpath.c
Normal 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
23
contrib/gcc/c-incpath.h
Normal 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 };
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
1650
contrib/gcc/c-opts.c
1650
contrib/gcc/c-opts.c
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
433
contrib/gcc/c-pch.c
Normal 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
415
contrib/gcc/c-ppoutput.c
Normal 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;
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
825
contrib/gcc/c.opt
Normal 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.
|
@ -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;
|
||||
|
1774
contrib/gcc/calls.c
1774
contrib/gcc/calls.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
48
contrib/gcc/cfghooks.c
Normal 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
83
contrib/gcc/cfghooks.h
Normal 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
@ -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);
|
||||
|
@ -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
341
contrib/gcc/cfgloop.h
Normal 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
1482
contrib/gcc/cfgloopanal.c
Normal file
File diff suppressed because it is too large
Load Diff
1244
contrib/gcc/cfgloopmanip.c
Normal file
1244
contrib/gcc/cfgloopmanip.c
Normal file
File diff suppressed because it is too large
Load Diff
1433
contrib/gcc/cfgrtl.c
1433
contrib/gcc/cfgrtl.c
File diff suppressed because it is too large
Load Diff
644
contrib/gcc/cgraph.c
Normal file
644
contrib/gcc/cgraph.c
Normal 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
192
contrib/gcc/cgraph.h
Normal 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
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
@ -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
808
contrib/gcc/common.opt
Normal 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
123
contrib/gcc/config.build
Normal 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
155
contrib/gcc/config.host
Normal 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
23
contrib/gcc/config/alpha/alpha-modes.def
Normal file
23
contrib/gcc/config/alpha/alpha-modes.def
Normal 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);
|
@ -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
|
||||
|
@ -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
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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); \
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
5
contrib/gcc/config/alpha/t-osf-pthread
Normal file
5
contrib/gcc/config/alpha/t-osf-pthread
Normal 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
|
@ -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) && \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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, ':'))
|
||||
|
@ -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++)
|
||||
|
@ -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>
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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, ':'))
|
||||
|
@ -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++)
|
||||
|
@ -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>
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user