--- gcc/internals-2 2018/04/24 16:38:31 1.1.1.2 +++ gcc/internals-2 2018/04/24 16:40:30 1.1.1.4 @@ -1,31 +1,332 @@ -Info file internals, produced by Makeinfo, -*- Text -*- -from input file internals.texinfo. - - +Info file internals, produced by Makeinfo, -*- Text -*- from input +file internals.texinfo. This file documents the internals of the GNU compiler. Copyright (C) 1988 Free Software Foundation, Inc. -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. +Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + +Permission is granted to copy and distribute modified versions of +this manual under the conditions for verbatim copying, provided also +that the section entitled ``GNU CC General Public License'' is +included exactly as in the original, and provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that the section entitled ``GNU CC General Public +License'' and this permission notice may be included in translations +approved by the Free Software Foundation instead of in the original +English. + + + +File: internals, Node: Incompatibilities, Next: Extensions, Prev: Trouble, Up: Top + +Incompatibilities of GNU CC +*************************** + +There are several noteworthy incompatibilities between GNU C and most +existing (non-ANSI) versions of C. + +Ultimately our intention is that the `-traditional' option will +eliminate most of these incompatibilities by telling GNU C to behave +like the other C compilers. + + * GNU CC normally makes string constants read-only. If several + identical-looking string constants are used, GNU CC stores only + one copy of the string. + + One consequence is that you cannot call `mktemp' with a string + constant argument. The function `mktemp' always alters the + string its argument points to. + + Another consequence is that `sscanf' does not work on some + systems when passed a string constant as its format control + string. This is because `sscanf' incorrectly tries to write + into the string constant. + + The best solution to these problems is to change the program to + use `char'-array variables with initialization strings for these + purposes instead of string constants. But if this is not + possible, you can use the `-fwritable-strings' flag, which + directs GNU CC to handle string constants the same way most C + compilers do. + + * GNU CC does not substitute macro arguments when they appear + inside of string constants. For example, the following macro in + GNU CC + + #define foo(a) "a" + + will produce output `"a"' regardless of what the argument A is. + + The `-traditional' option directs GNU CC to handle such cases + (among others) in the old-fashioned (non-ANSI) fashion. + + * When you use `setjmp' and `longjmp', the only automatic + variables guaranteed to remain valid are those declared + `volatile'. This is a consequence of automatic register + allocation. Consider this function: + + jmp_buf j; + + foo () + { + int a, b; + + a = fun1 (); + if (setjmp (j)) + return a; + + a = fun2 (); + /* `longjmp (j)' may be occur in `fun3'. */ + return a + fun3 (); + } + + Here `a' may or may not be restored to its first value when the + `longjmp' occurs. If `a' is allocated in a register, then its + first value is restored; otherwise, it keeps the last value + stored in it. + + If you use the `-W' option with the `-O' option, you will get a + warning when GNU CC thinks such a problem might be possible. + + * Declarations of external variables and functions within a block + apply only to the block containing the declaration. In other + words, they have the same scope as any other declaration in the + same place. + + In some other C compilers, a `extern' declaration affects all + the rest of the file even if it happens within a block. + + The `-traditional' option directs GNU C to treat all `extern' + declarations as global, like traditional compilers. + + * In traditional C, you can combine `long', etc., with a typedef + name, as shown here: + + typedef int foo; + typedef long foo bar; + + In ANSI C, this is not allowed: `long' and other type modifiers + require an explicit `int'. Because this criterion is expressed + by Bison grammar rules rather than C code, the `-traditional' + flag cannot alter it. + + * PCC allows typedef names to be used as function parameters. The + difficulty described immediately above applies here too. + + * PCC allows whitespace in the middle of compound assignment + operators such as `+='. GNU CC, following the ANSI standard, + does not allow this. The difficulty described immediately above + applies here too. + + * When compiling functions that return `float', PCC converts it to + a double. GNU CC actually returns a `float'. If you are + concerned with PCC compatibility, you should declare your + functions to return `double'; you might as well say what you mean. + + * When compiling functions that return structures or unions, GNU + CC output code uses a method different from that used on most + versions of Unix. As a result, code compiled with GNU CC cannot + call a structure-returning function compiled with PCC, and vice + versa. + + The method used by GCC is as follows: a structure or union which + is 1, 2, 4 or 8 bytes long is returned like a scalar. A + structure or union with any other size is stored into an address + supplied by the caller in a special, fixed register. + + PCC usually handles all sizes of structures and unions by + returning the address of a block of static storage containing + the value. This method is not used in GCC because it is slower + and nonreentrant. + + On systems where PCC works this way, you may be able to make + GCC-compiled code call such functions that were compiled with + PCC by declaring them to return a pointer to the structure or + union instead of the structure or union itself. For example, + instead of this: + + struct foo nextfoo (); + + write this: + + struct foo *nextfoo (); + #define nextfoo *nextfoo + + (Note that this assumes you are using the GNU preprocessor and + not `-traditional', so that the ANSI antirecursion rules for + macro expansions are effective.) + + + +File: internals, Node: Extensions, Next: Bugs, Prev: Incompatibilities, Up: Top + +GNU Extensions to the C Language +******************************** + +GNU C provides several language features not found in ANSI standard C. +(The `-pedantic' option directs GNU CC to print a warning message if +any of these features is used.) To test for the availability of +these features in conditional compilation, check for a predefined +macro `__GNUC__', which is always defined under GNU CC. + +* Menu: + +* Statement Exprs:: Putting statements and declarations inside expressions. +* Naming Types:: Giving a name to the type of some expression. +* Typeof:: `typeof': referring to the type of an expression. +* Lvalues:: Using `?:', `,' and casts in lvalues. +* Conditionals:: Omitting the middle operand of a `?:' expression. +* Zero-Length:: Zero-length arrays. +* Variable-Length:: Arrays whose length is computed at run time. +* Subscripting:: Any array can be subscripted, even if not an lvalue. +* Pointer Arith:: Arithmetic on `void'-pointers and function pointers. +* Constructors:: Constructor expressions give structures, unions + or arrays as values. +* Dollar Signs:: Dollar sign is allowed in identifiers. +* Alignment:: Inquiring about the alignment of a type or variable. +* Inline:: Defining inline functions (as fast as macros). +* Extended Asm:: Assembler instructions with C expressions as operands. + (With them you can define ``built-in'' functions.) +* Asm Labels:: Specifying the assembler name to use for a C symbol. + + + +File: internals, Node: Statement Exprs, Next: Naming Types, Prev: Extensions, Up: Extensions + +Statements and Declarations inside of Expressions +================================================= + +A compound statement in parentheses may appear inside an expression +in GNU C. This allows you to declare variables within an expression. +For example: + + ({ int y = foo (); int z; + if (y > 0) z = y; + else z = - y; + z; }) + +is a valid (though slightly more complex than necessary) expression +for the absolute value of `foo ()'. + +This feature is especially useful in making macro definitions +``safe'' (so that they evaluate each operand exactly once). For +example, the ``maximum'' function is commonly defined as a macro in +standard C as follows: + + #define max(a,b) ((a) > (b) ? (a) : (b)) + +But this definition computes either A or B twice, with bad results if +the operand has side effects. In GNU C, if you know the type of the +operands (here let's assume `int'), you can define the macro safely +as follows: + + #define maxint(a,b) \ + ({int _a = (a), _b = (b); _a > _b ? _a : _b; }) + +Embedded statements are not allowed in constant expressions, such as +the value of an enumeration constant, the width of a bit field, or +the initial value of a static variable. + +If you don't know the type of the operand, you can still do this, but +you must use `typeof' (*note Typeof::.) or type naming (*note Naming +Types::.). + + + +File: internals, Node: Naming Types, Next: Typeof, Prev: Statement Exprs, Up: Extensions + +Naming an Expression's Type +=========================== + +You can give a name to the type of an expression using a `typedef' +declaration with an initializer. Here is how to define NAME as a +type name for the type of EXP: + + typedef NAME = EXP; + +This is useful in conjunction with the statements-within-expressions +feature. Here is how the two together can be used to define a safe +``maximum'' macro that operates on any arithmetic type: -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -section entitled ``GNU CC General Public License'' is included exactly as -in the original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this one. + #define max(a,b) \ + ({typedef _ta = (a), _tb = (b); \ + _ta _a = (a); _tb _b = (b); \ + _a > _b ? _a : _b; }) -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the section entitled ``GNU CC General Public License'' and -this permission notice may be included in translations approved by the -Free Software Foundation instead of in the original English. +The reason for using names that start with underscores for the local +variables is to avoid conflicts with variable names that occur within +the expressions that are substituted for `a' and `b'. Eventually we +hope to design a new form of declaration syntax that allows you to +declare variables whose scopes start only after their initializers; +this will be a more reliable way to prevent such conflicts. + +File: internals, Node: Typeof, Next: Lvalues, Prev: Naming Types, Up: Extensions + +Referring to a Type with `typeof' +================================= + +Another way to refer to the type of an expression is with `typeof'. +The syntax of using of this keyword looks like `sizeof', but the +construct acts semantically like a type name defined with `typedef'. + +There are two ways of writing the argument to `typeof': with an +expression or with a type. Here is an example with an expression: + + typeof (x[0](1)) + +This assumes that `x' is an array of functions; the type described is +that of the values of the functions. + +Here is an example with a typename as the argument: + + typeof (int *) + +Here the type described is that of pointers to `int'. + +A `typeof'-construct can be used anywhere a typedef name could be +used. For example, you can use it in a declaration, in a cast, or +inside of `sizeof' or `typeof'. + + * This declares `y' with the type of what `x' points to. + + typeof (*x) y; + + * This declares `y' as an array of such values. + + typeof (*x) y[4]; + + * This declares `y' as an array of pointers to characters: + + typeof (typeof (char *)[4]) y; + + It is equivalent to the following traditional C declaration: + + char *y[4]; + + To see the meaning of the declaration using `typeof', and why it + might be a useful way to write, let's rewrite it with these + macros: + + #define pointer(T) typeof(T *) + #define array(T, N) typeof(T [N]) + + Now the declaration can be rewritten this way: + + array (pointer (char), 4) y; + + Thus, `array (pointer (char), 4)' is the type of arrays of 4 + pointers to `char'. -  File: internals, Node: Lvalues, Next: Conditionals, Prev: Typeof, Up: Extensions @@ -33,9 +334,9 @@ File: internals, Node: Lvalues, Next: Generalized Lvalues =================== -Compound expressions, conditional expressions and casts are allowed as -lvalues provided their operands are lvalues. This means that you can take -their addresses or store values into them. +Compound expressions, conditional expressions and casts are allowed +as lvalues provided their operands are lvalues. This means that you +can take their addresses or store values into them. For example, a compound expression can be assigned, provided the last expression in the sequence is an lvalue. These two expressions are @@ -44,46 +345,42 @@ equivalent: (a, b) += 5 a, (b += 5) - -Similarly, the address of the compound expression can be taken. These two -expressions are equivalent: +Similarly, the address of the compound expression can be taken. +These two expressions are equivalent: &(a, b) a, &b - -A conditional expression is a valid lvalue if its type is not void and the -true and false branches are both valid lvalues. For example, these two -expressions are equivalent: +A conditional expression is a valid lvalue if its type is not void +and the true and false branches are both valid lvalues. For example, +these two expressions are equivalent: (a ? b : c) = 5 (a ? b = 5 : (c = 5)) - -A cast is a valid lvalue if its operand is valid. Taking the address of -the cast is the same as taking the address without a cast, except for the -type of the result. For example, these two expressions are equivalent (but -the second may be valid when the type of `a' does not permit a cast to `int -*'). +A cast is a valid lvalue if its operand is valid. Taking the address +of the cast is the same as taking the address without a cast, except +for the type of the result. For example, these two expressions are +equivalent (but the second may be valid when the type of `a' does not +permit a cast to `int *'). &(int *)a (int **)&a - -A simple assignment whose left-hand side is a cast works by converting the -right-hand side first to the specified type, then to the type of the inner -left-hand side expression. After this is stored, the value is converter -back to the specified type to become the value of the assignment. Thus, if -`a' has type `char *', the following two expressions are equivalent: +A simple assignment whose left-hand side is a cast works by +converting the right-hand side first to the specified type, then to +the type of the inner left-hand side expression. After this is +stored, the value is converter back to the specified type to become +the value of the assignment. Thus, if `a' has type `char *', the +following two expressions are equivalent: (int)a = 5 (int)(a = (char *)5) - -An assignment-with-arithmetic operation such as `+=' applied to a cast -performs the arithmetic using the type resulting from the cast, and then -continues as in the previous case. Therefore, these two expressions are -equivalent: +An assignment-with-arithmetic operation such as `+=' applied to a +cast performs the arithmetic using the type resulting from the cast, +and then continues as in the previous case. Therefore, these two +expressions are equivalent: (int)a += 5 (int)(a = (char *) ((int)a + 5)) @@ -95,28 +392,27 @@ File: internals, Node: Conditionals, N Conditional Expressions with Omitted Middle-Operands ==================================================== -The middle operand in a conditional expression may be omitted. Then if the -first operand is nonzero, its value is the value of the conditional -expression. +The middle operand in a conditional expression may be omitted. Then +if the first operand is nonzero, its value is the value of the +conditional expression. Therefore, the expression x ? : y - has the value of `x' if that is nonzero; otherwise, the value of `y'. This example is perfectly equivalent to x ? x : y - In this simple case, the ability to omit the middle operand is not -especially useful. When it becomes useful is when the first operand does, -or may (if it is a macro argument), contain a side effect. Then repeating -the operand in the middle would perform the side effect twice. Omitting -the middle operand uses the value already computed without the undesirable -effects of recomputing it. +especially useful. When it becomes useful is when the first operand +does, or may (if it is a macro argument), contain a side effect. +Then repeating the operand in the middle would perform the side +effect twice. Omitting the middle operand uses the value already +computed without the undesirable effects of recomputing it. +  File: internals, Node: Zero-Length, Next: Variable-Length, Prev: Conditionals, Up: Extensions @@ -124,8 +420,9 @@ File: internals, Node: Zero-Length, Ne Arrays of Length Zero ===================== -Zero-length arrays are allowed in GNU C. They are very useful as the last -element of a structure which is really a header for a variable-length object: +Zero-length arrays are allowed in GNU C. They are very useful as the +last element of a structure which is really a header for a +variable-length object: struct line { int length; @@ -135,12 +432,12 @@ element of a structure which is really a { struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); - thisline->length = thislength; + thisline->length = this_length; } +In standard C, you would have to give `contents' a length of 1, which +means either you waste space or complicate the argument to `malloc'. -In standard C, you would have to give `contents' a length of 1, which means -either you waste space or complicate the argument to `malloc'.  File: internals, Node: Variable-Length, Next: Subscripting, Prev: Zero-Length, Up: Extensions @@ -148,10 +445,10 @@ File: internals, Node: Variable-Length, Arrays of Variable Length ========================= -Variable-length automatic arrays are allowed in GNU C. These arrays are -declared like any other automatic arrays, but with a length that is not a -constant expression. The storage is allocated at that time and deallocated -when the brace-level is exited. For example: +Variable-length automatic arrays are allowed in GNU C. These arrays +are declared like any other automatic arrays, but with a length that +is not a constant expression. The storage is allocated at that time +and deallocated when the brace-level is exited. For example: FILE *concat_fopen (char *s1, char *s2, char *mode) { @@ -161,9 +458,9 @@ when the brace-level is exited. For exa return fopen (str, mode); } - -You can also define structure types containing variable-length arrays, and -use them even for arguments or function values, as shown here: +You can also define structure types containing variable-length +arrays, and use them even for arguments or function values, as shown +here: int foo; @@ -182,29 +479,30 @@ use them even for arguments or function return new; } - (Eventually there will be a way to say that the size of the array is another member of the same structure.) -The length of an array is computed on entry to the brace-level where the -array is declared and is remembered for the scope of the array in case you -access it with `sizeof'. - -Jumping or breaking out of the scope of the array name will also deallocate -the storage. Jumping into the scope is not allowed; you will get an error -message for it. +The length of an array is computed on entry to the brace-level where +the array is declared and is remembered for the scope of the array in +case you access it with `sizeof'. + +Jumping or breaking out of the scope of the array name will also +deallocate the storage. Jumping into the scope is not allowed; you +will get an error message for it. You can use the function `alloca' to get an effect much like -variable-length arrays. The function `alloca' is available in many other C -implementations (but not in all). On the other hand, variable-length -arrays are more elegant. - -There are other differences between these two methods. Space allocated -with `alloca' exists until the containing *function* returns. The space -for a variable-length array is deallocated as soon as the array name's -scope ends. (If you use both variable-length arrays and `alloca' in the -same function, deallocation of a variable-length array will also deallocate -anything more recently allocated with `alloca'.) +variable-length arrays. The function `alloca' is available in many +other C implementations (but not in all). On the other hand, +variable-length arrays are more elegant. + +There are other differences between these two methods. Space +allocated with `alloca' exists until the containing *function* returns. +The space for a variable-length array is deallocated as soon as the +array name's scope ends. (If you use both variable-length arrays and +`alloca' in the same function, deallocation of a variable-length +array will also deallocate anything more recently allocated with +`alloca'.) +  File: internals, Node: Subscripting, Next: Pointer Arith, Prev: Variable-Length, Up: Extensions @@ -212,9 +510,9 @@ File: internals, Node: Subscripting, N Non-Lvalue Arrays May Have Subscripts ===================================== -Subscripting is allowed on arrays that are not lvalues, even though the -unary `&' operator is not. For example, this is valid in GNU C though not -valid in other C dialects: +Subscripting is allowed on arrays that are not lvalues, even though +the unary `&' operator is not. For example, this is valid in GNU C +though not valid in other C dialects: struct foo {int a[4];}; @@ -232,12 +530,13 @@ File: internals, Node: Pointer Arith, Arithmetic on `void'-Pointers and Function Pointers =================================================== -In GNU C, addition and subtraction operations are supported on pointers to -`void' and on pointers to functions. This is done by treating the size of -a `void' or of a function as 1. +In GNU C, addition and subtraction operations are supported on +pointers to `void' and on pointers to functions. This is done by +treating the size of a `void' or of a function as 1. + +A consequence of this is that `sizeof' is also allowed on `void' and +on function types, and returns 1. -A consequence of this is that `sizeof' is also allowed on `void' and on -function types, and returns 1.  File: internals, Node: Initializers, Next: Constructors, Prev: Pointer Arith, Up: Extensions @@ -245,9 +544,9 @@ File: internals, Node: Initializers, N Non-Constant Initializers ========================= -The elements of an aggregate initializer are not required to be constant -expressions in GNU C. Here is an example of an initializer with run-time -varying elements: +The elements of an aggregate initializer are not required to be +constant expressions in GNU C. Here is an example of an initializer +with run-time varying elements: foo (float f, float g) { @@ -262,21 +561,19 @@ File: internals, Node: Constructors, N Constructor Expressions ======================= -GNU C supports constructor expressions. A constructor looks like a cast -containing an initializer. Its value is an object of the type specified in -the cast, containing the elements specified in the initializer. The type -must be a structure, union or array type. +GNU C supports constructor expressions. A constructor looks like a +cast containing an initializer. Its value is an object of the type +specified in the cast, containing the elements specified in the +initializer. The type must be a structure, union or array type. Assume that `struct foo' and `structure' are declared as shown: struct foo {int a; char b[2];} structure; - Here is an example of constructing a `struct foo' with a constructor: structure = ((struct foo) {x + y, 'a', 0}); - This is equivalent to writing the following: { @@ -284,20 +581,19 @@ This is equivalent to writing the follow structure = temp; } - -You can also construct an array. If all the elements of the constructor -are (made up of) simple constant expressions, suitable for use in -initializers, then the constructor is an lvalue and can be coerced to a -pointer to its first element, as shown here: +You can also construct an array. If all the elements of the +constructor are (made up of) simple constant expressions, suitable +for use in initializers, then the constructor is an lvalue and can be +coerced to a pointer to its first element, as shown here: char **foo = (char *[]) { "x", "y", "z" }; - -Array constructors whose elements are not simple constants are not very -useful, because the constructor is not an lvalue. There are only two valid -ways to use it: to subscript it, or initialize an array variable with it. -The former is probably slower than a `switch' statement, while the latter -does the same thing an ordinary C initializer would do. +Array constructors whose elements are not simple constants are not +very useful, because the constructor is not an lvalue. There are +only two valid ways to use it: to subscript it, or initialize an +array variable with it. The former is probably slower than a +`switch' statement, while the latter does the same thing an ordinary +C initializer would do. output = ((int[]) { 2, x, 28 }) [input]; @@ -308,8 +604,9 @@ File: internals, Node: Dollar Signs, N Dollar Signs in Identifier Names ================================ -In GNU C, you may use dollar signs in identifier names. This is because -many traditional C implementations allow such identifiers. +In GNU C, you may use dollar signs in identifier names. This is +because many traditional C implementations allow such identifiers. +  File: internals, Node: Alignment, Next: Inline, Prev: Dollar Signs, Up: Extensions @@ -318,30 +615,30 @@ Inquiring about the Alignment of a Type =================================================== The keyword `__alignof' allows you to inquire about how an object is -aligned, or the minimum alignment usually required by a type. Its syntax -is just like `sizeof'. +aligned, or the minimum alignment usually required by a type. Its +syntax is just like `sizeof'. -For example, if the target machine requires a `double' value to be aligned -on an 8-byte boundary, then `__alignof (double)' is 8. This is true on -many RISC machines. On more traditional machine designs, `__alignof -(double)' is 4 or even 2. - -Some machines never actually require alignment; they allow reference to any -data type even at an odd addresses. For these machines, `__alignof' -reports the *recommended* alignment of a type. - -When the operand of `__alignof' is an lvalue rather than a type, the value -is the largest alignment that the lvalue is known to have. It may have -this alignment as a result of its data type, or because it is part of a -structure and inherits alignment from that structure. For example, after -this declaration: +For example, if the target machine requires a `double' value to be +aligned on an 8-byte boundary, then `__alignof (double)' is 8. This +is true on many RISC machines. On more traditional machine designs, +`__alignof (double)' is 4 or even 2. + +Some machines never actually require alignment; they allow reference +to any data type even at an odd addresses. For these machines, +`__alignof' reports the *recommended* alignment of a type. + +When the operand of `__alignof' is an lvalue rather than a type, the +value is the largest alignment that the lvalue is known to have. It +may have this alignment as a result of its data type, or because it +is part of a structure and inherits alignment from that structure. +For example, after this declaration: struct foo { int x; char y; } foo1; - the value of `__alignof (foo1.y)' is probably 2 or 4, the same as -`__alignof (int)', even though the data type of `foo1.y' does not itself -demand any alignment. +`__alignof (int)', even though the data type of `foo1.y' does not +itself demand any alignment. +  File: internals, Node: Inline, Next: Extended Asm, Prev: Alignment, Up: Extensions @@ -349,15 +646,15 @@ File: internals, Node: Inline, Next: E An Inline Function is As Fast As a Macro ======================================== -By declaring a function `inline', you can direct GNU CC to integrate that -function's code into the code for its callers. This makes execution faster -by eliminating the function-call overhead; in addition, if any of the -actual argument values are constant, their known values may permit -simplifications at compile time so that not all of the inline function's -code needs to be included. +By declaring a function `inline', you can direct GNU CC to integrate +that function's code into the code for its callers. This makes +execution faster by eliminating the function-call overhead; in +addition, if any of the actual argument values are constant, their +known values may permit simplifications at compile time so that not +all of the inline function's code needs to be included. -To declare a function inline, use the `inline' keyword in its declaration, -like this: +To declare a function inline, use the `inline' keyword in its +declaration, like this: inline int inc (int *a) @@ -365,27 +662,27 @@ like this: (*a)++; } +You can also make all ``simple enough'' functions inline with the +option `-finline-functions'. Note that certain usages in a function +definition can make it unsuitable for inline substitution. + +When a function is both inline and `static', if all calls to the +function are integrated into the caller, then the function's own +assembler code is never referenced. In this case, GNU CC does not +actually output assembler code for the function, unless you specify +the option `-fkeep-inline-functions'. Some calls cannot be +integrated for various reasons (in particular, calls that precede the +function's definition cannot be integrated, and neither can recursive +calls within the definition). If there is a nonintegrated call, then +the function is compiled to assembler code as usual. + +When an inline function is not `static', then the compiler must +assume that there may be calls from other source files; since a +global symbol can be defined only once in any program, the function +must not be defined in the other source files, so the calls therein +cannot be integrated. Therefore, a non-`static' inline function is +always compiled on its own in the usual fashion. -You can also make all ``simple enough'' functions inline with the option -`-finline-functions'. Note that certain usages in a function definition -can make it unsuitable for inline substitution. - -When a function is both inline and `static', if all calls to the function -are integrated into the caller, then the function's own assembler code is -never referenced. In this case, GNU CC does not actually output assembler -code for the function, unless you specify the option -`-fkeep-inline-functions'. Some calls cannot be integrated for various -reasons (in particular, calls that precede the function's definition cannot -be integrated, and neither can recursive calls within the definition). If -there is a nonintegrated call, then the function is compiled to assembler -code as usual. - -When an inline function is not `static', then the compiler must assume that -there may be calls from other source files; since a global symbol can be -defined only once in any program, the function must not be defined in the -other source files, so the calls therein cannot be integrated. Therefore, -a non-`static' inline function is always compiled on its own in the usual -fashion.  File: internals, Node: Extended Asm, Next: Asm Labels, Prev: Inline, Up: Extensions @@ -393,53 +690,98 @@ File: internals, Node: Extended Asm, N Assembler Instructions with C Expression Operands ================================================= -In an assembler instruction using `asm', you can now specify the operands -of the instruction using C expressions. This means no more guessing which -registers or memory locations will contain the data you want to use. - -You must specify an assembler instruction template much like what appears -in a machine description, plus an operand constraint string for each operand. +In an assembler instruction using `asm', you can now specify the +operands of the instruction using C expressions. This means no more +guessing which registers or memory locations will contain the data +you want to use. + +You must specify an assembler instruction template much like what +appears in a machine description, plus an operand constraint string +for each operand. For example, here is how to use the 68881's `fsinx' instruction: asm ("fsinx %1,%0" : "=f" (result) : "f" (angle)); - -Here `angle' is the C expression for the input operand while `result' is -that of the output operand. Each has `"f"' as its operand constraint, -saying that a floating-point register is required. The constraints use the -same language used in the machine description (*Note Constraints::.). - -Each operand is described by an operand-constraint string followed by the C -expression in parentheses. A colon separates the assembler template from -the first output operand, and another separates the last output operand -from the first input, if any. Commas separate output operands and separate -inputs. The number of operands is limited to the maximum number of -operands in any instruction pattern in the machine description. - -Output operand expressions must be lvalues, and there must be at least one -of them. The compiler can check this. The input operands need not be -lvalues, and there need not be any. The compiler cannot check whether the -operands have data types that are reasonable for the instruction being -executed. - -The output operands must be write-only; GNU CC will assume that the values -in these operands before the instruction are dead and need not be -generated. For an operand that is read-write, you must logically split its -function into two separate operands, one input operand and one write-only -output operand. The connection between them is expressed by constraints -which say they need to be in the same location when the instruction -executes. You can use the same C expression for both operands, or -different expressions. For example, here we write the (fictitious) -`combine' instruction with `bar' as its read-only source operand and `foo' -as its read-write destination: +Here `angle' is the C expression for the input operand while `result' +is that of the output operand. Each has `"f"' as its operand +constraint, saying that a floating-point register is required. The +constraints use the same language used in the machine description +(*note Constraints::.). + +Each operand is described by an operand-constraint string followed by +the C expression in parentheses. A colon separates the assembler +template from the first output operand, and another separates the +last output operand from the first input, if any. Commas separate +output operands and separate inputs. The number of operands is +limited to the maximum number of operands in any instruction pattern +in the machine description. + +Output operand expressions must be lvalues; the compiler can check +this. The input operands need not be lvalues. The compiler cannot +check whether the operands have data types that are reasonable for +the instruction being executed. It does not parse the assembler +instruction template and does not know what it means, or whether it +is valid assembler input. The extended `asm' feature is most often +used for machine instructions that the compiler itself does not know +exist. + +If there are no output operands, and there are input operands, then +you should write two colons in a row where the output operands would +go. + +The output operands must be write-only; GNU CC will assume that the +values in these operands before the instruction are dead and need not +be generated. For an operand that is read-write, or in which not all +bits are written and the other bits contain useful information, you +must logically split its function into two separate operands, one +input operand and one write-only output operand. The connection +between them is expressed by constraints which say they need to be in +the same location when the instruction executes. You can use the +same C expression for both operands, or different expressions. For +example, here we write the (fictitious) `combine' instruction with +`bar' as its read-only source operand and `foo' as its read-write +destination: asm ("combine %2,%0" : "=r" (foo) : "0" (foo), "g" (bar)); - The constraint `"0"' for operand 1 says that it must occupy the same -location as operand 0. Therefore it is not necessary to substitute operand -1 into the assembler code output. +location as operand 0. + +Only a digit in the constraint can guarantee that one operand will be +in the same place as another. The mere fact that `foo' is the value +of both operands is not enough to guarantee that they will be in the +same place in the generated assembler code. The following would not +work: + + asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar)); + +Various optimizations or reloading could cause operands 0 and 1 to be +in different registers; GNU CC knows no reason not to do so. For +example, the compiler might find a copy of the value of `foo' in one +register and use it for operand 1, but generate the output operand 0 +in a different register (copying it afterward to `foo''s own +address). Of course, since the register for operand 1 is not even +mentioned in the assembler code, the result will not work, but GNU CC +can't tell that. + +Unless an output operand has the `&' constraint modifier, GNU CC may +allocate it in the same register as an unrelated input operand, on +the assumption that the inputs are consumed before the outputs are +produced. This assumption may be false if the assembler code +actually consists of more than one instruction. In such a case, use +`&' for each output operand that may not overlap an input. *Note +Modifiers::. + +Some instructions clobber specific hard registers. To describe this, +write a third colon after the input operands, followed by the names +of the clobbered hard registers (given as strings). For example, on +the vax, + + asm volatile ("movc3 %0,%1,%2" + : /* no outputs */ + : "g" (from), "g" (to), "g" (count) + : "r0", "r1", "r2", "r3", "r4", "r5"); Usually the most convenient way to use these `asm' instructions is to encapsulate them in macros that look like functions. For example, @@ -449,46 +791,48 @@ encapsulate them in macros that look lik asm ("fsinx %1,%0": "=f" (__value): "f" (__arg)); \ __value; }) - Here the variable `__arg' is used to make sure that the instruction -operates on a proper `double' value, and to accept only those arguments `x' -which can convert automatically to a `double'. - -Another way to make sure the instruction operates on the correct data type -is to use a cast in the `asm'. This is different from using a variable -`__arg' in that it converts more different types. For example, if the -desired type were `int', casting the argument to `int' would accept a -pointer with no complaint, while assigning the argument to an `int' -variable named `__arg' would warn about using a pointer unless the caller -explicitly casts it. - -GNU CC assumes for optimization purposes that these instructions have no -side effects except to change the output operands. This does not mean that -instructions with a side effect cannot be used, but you must be careful, -because the compiler may eliminate them if the output operands aren't used, -or move them out of loops, or replace two with one if they constitute a -common subexpression. Also, if your instruction does have a side effect on -a variable that otherwise appears not to change, the old value of the -variable may be reused later if it happens to be found in a register. +operates on a proper `double' value, and to accept only those +arguments `x' which can convert automatically to a `double'. -You can prevent an `asm' instruction from being deleted, moved or combined -by writing the keyword `volatile' after the `asm'. For example: +Another way to make sure the instruction operates on the correct data +type is to use a cast in the `asm'. This is different from using a +variable `__arg' in that it converts more different types. For +example, if the desired type were `int', casting the argument to +`int' would accept a pointer with no complaint, while assigning the +argument to an `int' variable named `__arg' would warn about using a +pointer unless the caller explicitly casts it. + +GNU CC assumes for optimization purposes that these instructions have +no side effects except to change the output operands. This does not +mean that instructions with a side effect cannot be used, but you +must be careful, because the compiler may eliminate them if the +output operands aren't used, or move them out of loops, or replace +two with one if they constitute a common subexpression. Also, if +your instruction does have a side effect on a variable that otherwise +appears not to change, the old value of the variable may be reused +later if it happens to be found in a register. + +You can prevent an `asm' instruction from being deleted, moved or +combined by writing the keyword `volatile' after the `asm'. For +example: #define set_priority(x) \ asm volatile ("set_priority %1": \ "=m" (*(char *)0): "g" (x)) +Note that we have supplied an output operand which is not actually +used in the instruction. This is because `asm' requires at least one +output operand. This requirement exists for internal implementation +reasons and we might be able to relax it in the future. + +In this case output operand has the additional benefit effect of +giving the appearance of writing in memory. As a result, GNU CC will +assume that data previously fetched from memory must be fetched again +if needed again later. This may be desirable if you have not +employed the `volatile' keyword on all the variable declarations that +ought to have it. -Note that we have supplied an output operand which is not actually used in -the instruction. This is because `asm' requires at least one output -operand. This requirement exists for internal implementation reasons and -we might be able to relax it in the future. - -In this case output operand has the additional benefit effect of giving the -appearance of writing in memory. As a result, GNU CC will assume that data -previously fetched from memory must be fetched again if needed again later. - This may be desirable if you have not employed the `volatile' keyword on -all the variable declarations that ought to have it.  File: internals, Node: Asm Labels, Prev: Extended Asm, Up: Extensions @@ -496,22 +840,22 @@ File: internals, Node: Asm Labels, Pre Controlling Names Used in Assembler Code ======================================== -You can specify the name to be used in the assembler code for a C function -or variable by writing the `asm' keyword after the declarator as follows: +You can specify the name to be used in the assembler code for a C +function or variable by writing the `asm' keyword after the +declarator as follows: int foo asm ("myfoo") = 2; - This specifies that the name to be used for the variable `foo' in the assembler code should be `myfoo' rather than the usual `_foo'. -On systems where an underscore is normally prepended to the name of a C -function or variable, this feature allows you to define names for the -linker that do not start with an underscore. - -You cannot use `asm' in this way in a function *definition*; but you can -get the same effect by writing a declaration for the function before its -definition and putting `asm' there, like this: +On systems where an underscore is normally prepended to the name of a +C function or variable, this feature allows you to define names for +the linker that do not start with an underscore. + +You cannot use `asm' in this way in a function *definition*; but you +can get the same effect by writing a declaration for the function +before its definition and putting `asm' there, like this: extern func () asm ("FUNC"); @@ -519,12 +863,12 @@ definition and putting `asm' there, like int x, y; ... + It is up to you to make sure that the assembler names you choose do +not conflict with any other assembler symbols. Also, you must not +use a register name; that would produce completely invalid assembler +code. GNU CC does not as yet have the ability to store static +variables in registers. Perhaps that will be added. - It is up to you to make sure that the assembler names you choose do not -conflict with any other assembler symbols. Also, you must not use a -register name; that would produce completely invalid assembler code. GNU -CC does not as yet have the ability to store static variables in registers. - Perhaps that will be added.  File: internals, Node: Bugs, Next: Portability, Prev: Extensions, Up: Top @@ -534,68 +878,71 @@ Reporting Bugs Your bug reports play an essential role in making GNU CC reliable. -Reporting a bug may help you by bringing a solution to your problem, or it -may not. But in any case the important function of a bug report is to help -the entire community by making the next version of GNU CC work better. Bug -reports are your contribution to the maintenance of GNU CC. +Reporting a bug may help you by bringing a solution to your problem, +or it may not. But in any case the important function of a bug +report is to help the entire community by making the next version of +GNU CC work better. Bug reports are your contribution to the +maintenance of GNU CC. In order for a bug report to serve its purpose, you must include the information that makes for fixing the bug. - * Menu: * Criteria: Bug Criteria. Have you really found a bug? * Reporting: Bug Reporting. How to report a bug effectively. - +  File: internals, Node: Bug Criteria, Next: Bug Reporting, Prev: Bugs, Up: Bugs Have You Found a Bug? ===================== -If you are not sure whether you have found a bug, here are some guidelines: +If you are not sure whether you have found a bug, here are some +guidelines: - * If the compiler gets a fatal signal, for any input whatever, that is a - compiler bug. Reliable compilers never crash. + * If the compiler gets a fatal signal, for any input whatever, + that is a compiler bug. Reliable compilers never crash. - * If the compiler produces invalid assembly code, for any input whatever - (except an `asm' statement), that is a compiler bug, unless the - compiler reports errors (not just warnings) which would ordinarily - prevent the assembler from being run. - - * If the compiler produces valid assembly code that does not correctly - execute the input source code, that is a compiler bug. - - However, you must double-check to make sure, because you may have run - into an incompatibility between GNU C and traditional C (*Note - Incompatibilities::.). These incompatibilities might be considered - bugs, but they are inescapable consequences of features valuable - features. - - Or you may have a program whose behavior is undefined, which happened - by chance to give the desired results with another C compiler. - - For example, in many nonoptimizing compilers, you can write `x;' at - the end of a function instead of `return x;', with the same results. - But the value of the function is undefined if `return' is omitted; it - is not a bug when GNU CC produces different results. - - Problems often result from expressions with two increment operators, - as in `f (*p++, *p++)'. Your previous compiler might have interpreted - that expression the way you intended; GNU CC might interpret it - another way; neither compiler is wrong. - - After you have localized the error to a single source line, it should - be easy to check for these things. If your program is correct and - well defined, you have found a compiler bug. + * If the compiler produces invalid assembly code, for any input + whatever (except an `asm' statement), that is a compiler bug, + unless the compiler reports errors (not just warnings) which + would ordinarily prevent the assembler from being run. + + * If the compiler produces valid assembly code that does not + correctly execute the input source code, that is a compiler bug. + + However, you must double-check to make sure, because you may + have run into an incompatibility between GNU C and traditional C + (*note Incompatibilities::.). These incompatibilities might be + considered bugs, but they are inescapable consequences of + valuable features. + + Or you may have a program whose behavior is undefined, which + happened by chance to give the desired results with another C + compiler. + + For example, in many nonoptimizing compilers, you can write `x;' + at the end of a function instead of `return x;', with the same + results. But the value of the function is undefined if `return' + is omitted; it is not a bug when GNU CC produces different + results. + + Problems often result from expressions with two increment + operators, as in `f (*p++, *p++)'. Your previous compiler might + have interpreted that expression the way you intended; GNU CC + might interpret it another way; neither compiler is wrong. + + After you have localized the error to a single source line, it + should be easy to check for these things. If your program is + correct and well defined, you have found a compiler bug. - * If the compiler produces an error message for valid input, that is a - compiler bug. + * If the compiler produces an error message for valid input, that + is a compiler bug. - Note that the following is not valid input, and the error message for - it is not a bug: + Note that the following is not valid input, and the error + message for it is not a bug: int foo (char); @@ -604,18 +951,18 @@ If you are not sure whether you have fou char x; { ... } + The prototype says to pass a `char', while the definition says + to pass an `int' and treat the value as a `char'. This is what + the ANSI standard says, and it makes sense. + + * If the compiler does not produce an error message for invalid + input, that is a compiler bug. However, you should note that + your idea of ``invalid input'' might be my idea of ``an + extension'' or ``support for traditional practice''. - The prototype says to pass a `char', while the definition says to pass - an `int' and treat the value as a `char'. This is what the ANSI - standard says, and it makes sense. - - * If the compiler does not produce an error message for invalid input, - that is a compiler bug. However, you should note that your idea of - ``invalid input'' might be my idea of ``an extension'' or ``support - for traditional practice''. + * If you are an experienced user of C compilers, your suggestions + for improvement of GNU CC are welcome in any case. - * If you are an experienced user of C compilers, your suggestions for - improvement of GNU CC are welcome in any case.  File: internals, Node: Bug Reporting, Prev: Bug Criteria, Up: Bugs @@ -628,135 +975,148 @@ Send bug reports for GNU C to one of the bug-gcc@prep.ai.mit.edu {ucbvax|mit-eddie|uunet}!prep.ai.mit.edu!bug-gcc - As a last resort, snail them to: GNU Compiler Bugs 545 Tech Sq Cambridge, MA 02139 - -The fundamental principle of reporting bugs usefully is this: *report all -the facts*. If you are not sure whether to mention a fact or leave it out, -mention it! +The fundamental principle of reporting bugs usefully is this: *report +all the facts*. If you are not sure whether to mention a fact or +leave it out, mention it! Often people omit facts because they think they know what causes the -problem and they conclude that some details don't matter. Thus, you might -assume that the name of the variable you use in an example does not matter. - Well, probably it doesn't, but one cannot be sure. Perhaps the bug is a -stray memory reference which happens to fetch from the location where that -name is stored in memory; perhaps, if the name were different, the contents -of that location would fool the compiler into doing the right thing despite -the bug. Play it safe and give an exact example. - -If you want to enable me to fix the bug, you should include all these things: - - * The version of GNU CC. You can get this by running it with the `-v' - option. - - Without this, I won't know whether there is any point in looking for - the bug in the current version of GNU CC. - - * A complete input file that will reproduce the bug. If the bug is in - the C preprocessor, send me a source file and any header files that it - requires. If the bug is in the compiler proper (`cc1'), run your - source file through the C preprocessor by doing `gcc -E SOURCEFILE > - OUTFILE', then include the contents of OUTFILE in the bug report. - (Any `-I', `-D' or `-U' options that you used in actual compilation - should also be used when doing this.) - - A single statement is not enough of an example. In order to compile - it, it must be embedded in a function definition; and the bug might - depend on the details of how this is done. - - Without a real example I can compile, all I can do about your bug - report is wish you luck. It would be futile to try to guess how to - provoke the bug. For example, bugs in register allocation and - reloading frequently depend on every little detail of the function - they happen in. - - * The command arguments you gave GNU CC to compile that example and - observe the bug. For example, did you use `-O'? To guarantee you - won't omit something important, list them all. +problem and they conclude that some details don't matter. Thus, you +might assume that the name of the variable you use in an example does +not matter. Well, probably it doesn't, but one cannot be sure. +Perhaps the bug is a stray memory reference which happens to fetch +from the location where that name is stored in memory; perhaps, if +the name were different, the contents of that location would fool the +compiler into doing the right thing despite the bug. Play it safe +and give an exact example. + +If you want to enable me to fix the bug, you should include all these +things: + + * The version of GNU CC. You can get this by running it with the + `-v' option. + + Without this, I won't know whether there is any point in looking + for the bug in the current version of GNU CC. + + * A complete input file that will reproduce the bug. If the bug + is in the C preprocessor, send me a source file and any header + files that it requires. If the bug is in the compiler proper + (`cc1'), run your source file through the C preprocessor by + doing `gcc -E SOURCEFILE > OUTFILE', then include the contents + of OUTFILE in the bug report. (Any `-I', `-D' or `-U' options + that you used in actual compilation should also be used when + doing this.) + + A single statement is not enough of an example. In order to + compile it, it must be embedded in a function definition; and + the bug might depend on the details of how this is done. + + Without a real example I can compile, all I can do about your + bug report is wish you luck. It would be futile to try to guess + how to provoke the bug. For example, bugs in register + allocation and reloading frequently depend on every little + detail of the function they happen in. + + * The command arguments you gave GNU CC to compile that example + and observe the bug. For example, did you use `-O'? To + guarantee you won't omit something important, list them all. - If I were to try to guess the arguments, I would probably guess wrong - and then I would not encounter the bug. + If I were to try to guess the arguments, I would probably guess + wrong and then I would not encounter the bug. - * The names of the files that you used for `tm.h' and `md' when you - installed the compiler. + * The names of the files that you used for `tm.h' and `md' when + you installed the compiler. - * The type of machine you are using, and the operating system name and - version number. + * The type of machine you are using, and the operating system name + and version number. * A description of what behavior you observe that you believe is - incorrect. For example, ``It gets a fatal signal,'' or, ``There is an - incorrect assembler instruction in the output.'' + incorrect. For example, ``It gets a fatal signal,'' or, ``There + is an incorrect assembler instruction in the output.'' - Of course, if the bug is that the compiler gets a fatal signal, then I - will certainly notice it. But if the bug is incorrect output, I might - not notice unless it is glaringly wrong. I won't study all the - assembler code from a 50-line C program just on the off chance that it - might be wrong. - - Even if the problem you experience is a fatal signal, you should still - say so explicitly. Suppose something strange is going on, such as, - your copy of the compiler is out of synch, or you have encountered a - bug in the C library on your system. (This has happened!) Your copy - might crash and mine would not. If you told me to expect a crash, - then when mine fails to crash, I would know that the bug was not - happening for me. If you had not told me to expect a crash, then I - would not be able to draw any conclusion from my observations. - - In cases where GNU CC generates incorrect code, if you send me a small - complete sample program I will find the error myself by running the - program under a debugger. If you send me a large example or a part of - a larger program, I cannot do this; you must debug the compiled - program and narrow the problem down to one source line. Tell me which - source line it is, and what you believe is incorrect about the code - generated for that line. - - * If you send me examples of output from GNU CC, please use `-g' when - you make them. The debugging information includes source line numbers - which are essential for correlating the output with the input. + Of course, if the bug is that the compiler gets a fatal signal, + then I will certainly notice it. But if the bug is incorrect + output, I might not notice unless it is glaringly wrong. I + won't study all the assembler code from a 50-line C program just + on the off chance that it might be wrong. + + Even if the problem you experience is a fatal signal, you should + still say so explicitly. Suppose something strange is going on, + such as, your copy of the compiler is out of synch, or you have + encountered a bug in the C library on your system. (This has + happened!) Your copy might crash and mine would not. If you + told me to expect a crash, then when mine fails to crash, I + would know that the bug was not happening for me. If you had + not told me to expect a crash, then I would not be able to draw + any conclusion from my observations. + + In cases where GNU CC generates incorrect code, if you send me a + small complete sample program I will find the error myself by + running the program under a debugger. If you send me a large + example or a part of a larger program, I cannot do this; you + must debug the compiled program and narrow the problem down to + one source line. Tell me which source line it is, and what you + believe is incorrect about the code generated for that line. + + * If you send me examples of output from GNU CC, please use `-g' + when you make them. The debugging information includes source + line numbers which are essential for correlating the output with + the input. + + * If you wish to suggest changes to the GNU CC source, send me + context diffs. If you even discuss something in the GNU CC + source, refer to it by context, not by line number. + + The line numbers in my development sources don't match those in + your sources. They won't tell me anything. Here are some things that are not necessary: * A description of the envelope of the bug. - Often people who encounter a bug spend a lot of time investigating - which changes to the input file will make the bug go away and which - changes will not affect it. - - This is often time consuming and not very useful, because the way I - will find the bug is by running a single example under the debugger - with breakpoints, not by pure deduction from a series of examples. + Often people who encounter a bug spend a lot of time + investigating which changes to the input file will make the bug + go away and which changes will not affect it. + + This is often time consuming and not very useful, because the + way I will find the bug is by running a single example under the + debugger with breakpoints, not by pure deduction from a series + of examples. Of course, it can't hurt if you can find a simpler example that - triggers the same bug. Errors in the output will be easier to spot, - running under the debugger will take less time, etc. An easy way to - simplify an example is to delete all the function definitions except - the one where the bug occurs. Those earlier in the file may be - replaced by external declarations. + triggers the same bug. Errors in the output will be easier to + spot, running under the debugger will take less time, etc. An + easy way to simplify an example is to delete all the function + definitions except the one where the bug occurs. Those earlier + in the file may be replaced by external declarations. - However, simplification is not necessary; if you don't want to do - this, report the bug anyway. + However, simplification is not necessary; if you don't want to + do this, report the bug anyway. * A patch for the bug. - A patch for the bug does help me if it is a good one. But don't omit - the necessary information, such as the test case, because I might see - problems with your patch and decide to fix the problem another way. - - Sometimes with a program as complicated as GNU CC it is very hard to - construct an example that will make the program go through a certain - point in the code. If you don't send me the example, I won't be able - to verify that the bug is fixed. + A patch for the bug does help me if it is a good one. But don't + omit the necessary information, such as the test case, because I + might see problems with your patch and decide to fix the problem + another way. + + Sometimes with a program as complicated as GNU CC it is very + hard to construct an example that will make the program go + through a certain point in the code. If you don't send me the + example, I won't be able to verify that the bug is fixed. * A guess about what the bug is or what it depends on. - Such guesses are usually wrong. Even I can't guess right about such - things without using the debugger to find the facts. They also don't - serve a useful purpose. + Such guesses are usually wrong. Even I can't guess right about + such things without using the debugger to find the facts. They + also don't serve a useful purpose. +  File: internals, Node: Portability, Next: Interface, Prev: Bugs, Up: Top @@ -764,31 +1124,34 @@ File: internals, Node: Portability, Ne GNU CC and Portability ********************** -The main goal of GNU CC was to make a good, fast compiler for machines in -the class that the GNU system aims to run on: 32-bit machines that address -8-bit bytes and have several general registers. Elegance, theoretical -power and simplicity are only secondary. - -GNU CC gets most of the information about the target machine from a machine -description which gives an algebraic formula for each of the machine's -instructions. This is a very clean way to describe the target. But when -the compiler needs information that is difficult to express in this -fashion, I have not hesitated to define an ad-hoc parameter to the machine -description. The purpose of portability is to reduce the total work needed -on the compiler; it was not of interest for its own sake. - -GNU CC does not contain machine dependent code, but it does contain code -that depends on machine parameters such as endianness (whether the most -significant byte has the highest or lowest address of the bytes in a word) -and the availability of autoincrement addressing. In the RTL-generation -pass, it is often necessary to have multiple strategies for generating code -for a particular kind of syntax tree, strategies that are usable for -different combinations of parameters. Often I have not tried to address -all possible cases, but only the common ones or only the ones that I have -encountered. As a result, a new target may require additional strategies. -You will know if this happens because the compiler will call `abort'. -Fortunately, the new strategies can be added in a machine-independent -fashion, and will affect only the target machines that need them. +The main goal of GNU CC was to make a good, fast compiler for +machines in the class that the GNU system aims to run on: 32-bit +machines that address 8-bit bytes and have several general registers. +Elegance, theoretical power and simplicity are only secondary. + +GNU CC gets most of the information about the target machine from a +machine description which gives an algebraic formula for each of the +machine's instructions. This is a very clean way to describe the +target. But when the compiler needs information that is difficult to +express in this fashion, I have not hesitated to define an ad-hoc +parameter to the machine description. The purpose of portability is +to reduce the total work needed on the compiler; it was not of +interest for its own sake. + +GNU CC does not contain machine dependent code, but it does contain +code that depends on machine parameters such as endianness (whether +the most significant byte has the highest or lowest address of the +bytes in a word) and the availability of autoincrement addressing. +In the RTL-generation pass, it is often necessary to have multiple +strategies for generating code for a particular kind of syntax tree, +strategies that are usable for different combinations of parameters. +Often I have not tried to address all possible cases, but only the +common ones or only the ones that I have encountered. As a result, a +new target may require additional strategies. You will know if this +happens because the compiler will call `abort'. Fortunately, the new +strategies can be added in a machine-independent fashion, and will +affect only the target machines that need them. +  File: internals, Node: Interface, Next: Passes, Prev: Portability, Up: Top @@ -796,41 +1159,45 @@ File: internals, Node: Interface, Next Interfacing to GNU CC Output **************************** -GNU CC is normally configured to use the same function calling convention -normally in use on the target system. This is done with the -machine-description macros described (*Note Machine Macros::.). - -However, returning of structure and union values is done differently. As a -result, functions compiled with PCC returning such types cannot be called -from code compiled with GNU CC, and vice versa. This usually does not -cause trouble because the Unix library routines don't return structures and -unions. - -Structures and unions that are 1, 2, 4 or 8 bytes long are returned in the -same registers used for `int' or `double' return values. (GNU CC typically -allocates variables of such types in registers also.) Structures and -unions of other sizes are returned by storing them into an address passed -by the caller in a register. This method is faster than the one normally -used by PCC and is also reentrant. The register used for passing the -address is specified by the machine-description macro `STRUCT_VALUE_REGNUM'. - -GNU CC always passes arguments on the stack. At some point it will be -extended to pass arguments in registers, for machines which use that as the -standard calling convention. This will make it possible to use such a -convention on other machines as well. However, that would render it -completely incompatible with PCC. We will probably do this once we have a -complete GNU system so we can compile the libraries with GNU CC. - -If you use `longjmp', beware of automatic variables. ANSI C says that -automatic variables that are not declared `volatile' have undefined values -after a `longjmp'. And this is all GNU CC promises to do, because it is -very difficult to restore register variables correctly, and one of GNU CC's -features is that it can put variables in registers without your asking it to. - -If you want a variable to be unaltered by `longjmp', and you don't want to -write `volatile' because old C compilers don't accept it, just take the -address of the variable. If a variable's address is ever taken, even if -just to compute it and ignore it, then the variable cannot go in a register: +GNU CC is normally configured to use the same function calling +convention normally in use on the target system. This is done with +the machine-description macros described (*note Machine Macros::.). + +However, returning of structure and union values is done differently. +As a result, functions compiled with PCC returning such types cannot +be called from code compiled with GNU CC, and vice versa. This +usually does not cause trouble because the Unix library routines +don't return structures and unions. + +Structures and unions that are 1, 2, 4 or 8 bytes long are returned +in the same registers used for `int' or `double' return values. (GNU +CC typically allocates variables of such types in registers also.) +Structures and unions of other sizes are returned by storing them +into an address passed by the caller in a register. This method is +faster than the one normally used by PCC and is also reentrant. The +register used for passing the address is specified by the +machine-description macro `STRUCT_VALUE'. + +GNU CC always passes arguments on the stack. At some point it will +be extended to pass arguments in registers, for machines which use +that as the standard calling convention. This will make it possible +to use such a convention on other machines as well. However, that +would render it completely incompatible with PCC. We will probably +do this once we have a complete GNU system so we can compile the +libraries with GNU CC. + +If you use `longjmp', beware of automatic variables. ANSI C says +that automatic variables that are not declared `volatile' have +undefined values after a `longjmp'. And this is all GNU CC promises +to do, because it is very difficult to restore register variables +correctly, and one of GNU CC's features is that it can put variables +in registers without your asking it to. + +If you want a variable to be unaltered by `longjmp', and you don't +want to write `volatile' because old C compilers don't accept it, +just take the address of the variable. If a variable's address is +ever taken, even if just to compute it and ignore it, then the +variable cannot go in a register: { int careful; @@ -838,356 +1205,12 @@ just to compute it and ignore it, then t ... } +Code compiled with GNU CC may call certain library routines. The +routines needed on the Vax and 68000 are in the file `gnulib.c'. You +must compile this file with the standard C compiler, not with GNU CC, +and then link it with each program you compile with GNU CC. (In +actuality, many programs will not need it.) The usual function call +interface is used for calling the library routines. Some standard +parts of the C library, such as `bcopy', are also called automatically. -Code compiled with GNU CC may call certain library routines. The routines -needed on the Vax and 68000 are in the file `gnulib.c'. You must compile -this file with the standard C compiler, not with GNU CC, and then link it -with each program you compile with GNU CC. (In actuality, many programs -will not need it.) The usual function call interface is used for calling -the library routines. Some standard parts of the C library, such as -`bcopy', are also called automatically. - - -File: internals, Node: Passes, Next: RTL, Prev: Interface, Up: Top -Passes and Files of the Compiler -******************************** - -The overall control structure of the compiler is in `toplev.c'. This file -is responsible for initialization, decoding arguments, opening and closing -files, and sequencing the passes. - -The parsing pass is invoked only once, to parse the entire input. The RTL -intermediate code for a function is generated as the function is parsed, a -statement at a time. Each statement is read in as a syntax tree and then -converted to RTL; then the storage for the tree for the statement is -reclaimed. Storage for types (and the expressions for their sizes), -declarations, and a representation of the binding contours and how they -nest, remains until the function is finished being compiled; these are all -needed to output the debugging information. - -Each time the parsing pass reads a complete function definition or -top-level declaration, it calls the function `rest_of_compilation' or -`rest_of_decl_compilation' in `toplev.c', which are responsible for all -further processing necessary, ending with output of the assembler language. - All other compiler passes run, in sequence, within `rest_of_compilation'. -When that function returns from compiling a function definition, the -storage used for that function definition's compilation is entirely freed, -unless it is an inline function (*Note Inline::.). - -Here is a list of all the passes of the compiler and their source files. -Also included is a description of where debugging dumps can be requested -with `-d' options. - - * Parsing. This pass reads the entire text of a function definition, - constructing partial syntax trees. This and RTL generation are no - longer truly separate passes (formerly they were), but it is easier to - think of them as separate. - - The tree representation does not entirely follow C syntax, because it - is intended to support other languages as well. - - C data type analysis is also done in this pass, and every tree node - that represents an expression has a data type attached. Variables are - represented as declaration nodes. - - Constant folding and associative-law simplifications are also done - during this pass. - - The source files for parsing are `parse.y', `decl.c', `typecheck.c', - `stor-layout.c', `fold-const.c', and `tree.c'. The last three are - intended to be language-independent. There are also header files - `parse.h', `c-tree.h', `tree.h' and `tree.def'. The last two define - the format of the tree representation. - - * RTL generation. This is the conversion of syntax tree into RTL code. - It is actually done statement-by-statement during parsing, but for - most purposes it can be thought of as a separate pass. - - This is where the bulk of target-parameter-dependent code is found, - since often it is necessary for strategies to apply only when certain - standard kinds of instructions are available. The purpose of named - instruction patterns is to provide this information to the RTL - generation pass. - - Optimization is done in this pass for `if'-conditions that are - comparisons, boolean operations or conditional expressions. Tail - recursion is detected at this time also. Decisions are made about how - best to arrange loops and how to output `switch' statements. - - The source files for RTL generation are `stmt.c', `expr.c', - `explow.c', `expmed.c', `optabs.c' and `emit-rtl.c'. Also, the file - `insn-emit.c', generated from the machine description by the program - `genemit', is used in this pass. The header files `expr.h' is used - for communication within this pass. - - The header files `insn-flags.h' and `insn-codes.h', generated from the - machine description by the programs `genflags' and `gencodes', tell - this pass which standard names are available for use and which - patterns correspond to them. - - Aside from debugging information output, none of the following passes - refers to the tree structure representation of the function (only part - of which is saved). - - The decision of whether the function can and should be expanded inline - in its subsequent callers is made at the end of rtl generation. The - function must meet certain criteria, currently related to the size of - the function and the types and number of parameters it has. Note that - this function may contain loops, recursive calls to itself - (tail-recursive functions can be inlined!), gotos, in short, all - constructs supported by GNU CC. - - The option `-dr' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.rtl' to the input - file name. - - * Jump optimization. This pass simplifies jumps to the following - instruction, jumps across jumps, and jumps to jumps. It deletes - unreferenced labels and unreachable code, except that unreachable code - that contains a loop is not recognized as unreachable in this pass. - (Such loops are deleted later in the basic block analysis.) - - Jump optimization is performed two or three times. The first time is - immediately following RTL generation. The second time is after CSE, - but only if CSE says repeated jump optimization is needed. The last - time is right before the final pass. That time, cross-jumping and - deletion of no-op move instructions are done together with the - optimizations described above. - - The source file of this pass is `jump.c'. - - The option `-dj' causes a debugging dump of the RTL code after this - pass is run for the first time. This dump file's name is made by - appending `.jump' to the input file name. - - * Register scan. This pass finds the first and last use of each - register, as a guide for common subexpression elimination. Its source - is in `regclass.c'. - - * Common subexpression elimination. This pass also does constant - propagation. Its source file is `cse.c'. If constant propagation - causes conditional jumps to become unconditional or to become no-ops, - jump optimization is run again when CSE is finished. - - The option `-ds' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.cse' to the input - file name. - - * Loop optimization. This pass moves constant expressions out of loops. - Its source file is `loop.c'. - - The option `-dL' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.loop' to the input - file name. - - * Stupid register allocation is performed at this point in a - nonoptimizing compilation. It does a little data flow analysis as - well. When stupid register allocation is in use, the next pass - executed is the reloading pass; the others in between are skipped. - The source file is `stupid.c'. - - * Data flow analysis (`flow.c'). This pass divides the program into - basic blocks (and in the process deletes unreachable loops); then it - computes which pseudo-registers are live at each point in the program, - and makes the first instruction that uses a value point at the - instruction that computed the value. - - This pass also deletes computations whose results are never used, and - combines memory references with add or subtract instructions to make - autoincrement or autodecrement addressing. - - The option `-df' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.flow' to the input - file name. If stupid register allocation is in use, this dump file - reflects the full results of such allocation. - - * Instruction combination (`combine.c'). This pass attempts to combine - groups of two or three instructions that are related by data flow into - single instructions. It combines the RTL expressions for the - instructions by substitution, simplifies the result using algebra, and - then attempts to match the result against the machine description. - - The option `-dc' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.combine' to the - input file name. - - * Register class preferencing. The RTL code is scanned to find out - which register class is best for each pseudo register. The source - file is `regclass.c'. - - * Local register allocation (`local-alloc.c'). This pass allocates hard - registers to pseudo registers that are used only within one basic - block. Because the basic block is linear, it can use fast and - powerful techniques to do a very good job. - - The option `-dl' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.lreg' to the input - file name. - - * Global register allocation (`global-alloc.c'). This pass allocates - hard registers for the remaining pseudo registers (those whose life - spans are not contained in one basic block). - - * Reloading. This pass renumbers pseudo registers with the hardware - registers numbers they were allocated. Pseudo registers that did not - get hard registers are replaced with stack slots. Then it finds - instructions that are invalid because a value has failed to end up in - a register, or has ended up in a register of the wrong kind. It fixes - up these instructions by reloading the problematical values - temporarily into registers. Additional instructions are generated to - do the copying. - - Source files are `reload.c' and `reload1.c', plus the header - `reload.h' used for communication between them. - - The option `-dg' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.greg' to the input - file name. - - * Jump optimization is repeated, this time including cross-jumping and - deletion of no-op move instructions. Machine-specific peephole - optimizations are performed at the same time. - - The option `-dJ' causes a debugging dump of the RTL code after this - pass. This dump file's name is made by appending `.jump2' to the - input file name. - - * Final. This pass outputs the assembler code for the function. It is - also responsible for identifying spurious test and compare - instructions. The function entry and exit sequences are generated - directly as assembler code in this pass; they never exist as RTL. - - The source files are `final.c' plus `insn-output.c'; the latter is - generated automatically from the machine description by the tool - `genoutput'. The header file `conditions.h' is used for communication - between these files. - - * Debugging information output. This is run after final because it must - output the stack slot offsets for pseudo registers that did not get - hard registers. Source files are `dbxout.c' for DBX symbol table - format and `symout.c' for GDB's own symbol table format. - -Some additional files are used by all or many passes: - - * Every pass uses `machmode.def', which defines the machine modes. - - * All the passes that work with RTL use the header files `rtl.h' and - `rtl.def', and subroutines in file `rtl.c'. The tools `gen*' also use - these files to read and work with the machine description RTL. - - * Several passes refer to the header file `insn-config.h' which contains - a few parameters (C macro definitions) generated automatically from - the machine description RTL by the tool `genconfig'. - - * Several passes use the instruction recognizer, which consists of - `recog.c' and `recog.h', plus the files `insn-recog.c' and - `insn-extract.c' that are generated automatically from the machine - description by the tools `genrecog' and `genextract'. - - * Several passes use the header files `regs.h' which defines the - information recorded about pseudo register usage, and `basic-block.h' - which defines the information recorded about basic blocks. - - * `hard-reg-set.h' defines the type `HARD_REG_SET', a bit-vector with a - bit for each hard register, and some macros to manipulate it. This - type is just `int' if the machine has few enough hard registers; - otherwise it is an array of `int' and some of the macros expand into - loops. - - -File: internals, Node: RTL, Next: Machine Desc, Prev: Passes, Up: Top - -RTL Representation -****************** - -Most of the work of the compiler is done on an intermediate representation -called register transfer language. In this language, the instructions to -be output are described, pretty much one by one, in an algebraic form that -describes what the instruction does. - -RTL is inspired by Lisp lists. It has both an internal form, made up of -structures that point at other structures, and a textual form that is used -in the machine description and in printed debugging dumps. The textual -form uses nested parentheses to indicate the pointers in the internal form. - - -* Menu: - -* RTL Objects:: Expressions vs vectors vs strings vs integers. -* Accessors:: Macros to access expression operands or vector elts. -* Flags:: Other flags in an RTL expression. -* Machine Modes:: Describing the size and format of a datum. -* Constants:: Expressions with constant values. -* Regs and Memory:: Expressions representing register contents or memory. -* Arithmetic:: Expressions representing arithmetic on other expressions. -* Comparisons:: Expressions representing comparison of expressions. -* Bit Fields:: Expressions representing bit-fields in memory or reg. -* Conversions:: Extending, truncating, floating or fixing. -* RTL Declarations:: Declaring volatility, constancy, etc. -* Side Effects:: Expressions for storing in registers, etc. -* Incdec:: Embedded side-effects for autoincrement addressing. -* Assembler:: Representing `asm' with operands. -* Insns:: Expression types for entire insns. -* Calls:: RTL representation of function call insns. -* Sharing:: Some expressions are unique; others *must* be copied. - - - -File: internals, Node: RTL Objects, Next: Accessors, Prev: RTL, Up: RTL - -RTL Object Types -================ - -RTL uses four kinds of objects: expressions, integers, strings and vectors. - Expressions are the most important ones. An RTL expression (``RTX'', for -short) is a C structure, but it is usually referred to with a pointer; a -type that is given the typedef name `rtx'. - -An integer is simply an `int', and a string is a `char *'. Within RTL -code, strings appear only inside `symbol_ref' expressions, but they appear -in other contexts in the RTL expressions that make up machine descriptions. - Their written form uses decimal digits. - -A string is a sequence of characters. In core it is represented as a `char -*' in usual C fashion, and it is written in C syntax as well. However, -strings in RTL may never be null. If you write an empty string in a -machine description, it is represented in core as a null pointer rather -than as a pointer to a null character. In certain contexts, these null -pointers instead of strings are valid. - -A vector contains an arbitrary, specified number of pointers to -expressions. The number of elements in the vector is explicitly present in -the vector. The written form of a vector consists of square brackets -(`[...]') surrounding the elements, in sequence and with whitespace -separating them. Vectors of length zero are not created; null pointers are -used instead. - -Expressions are classified by "expression codes" (also called RTX codes). -The expression code is a name defined in `rtl.def', which is also (in upper -case) a C enumeration constant. The possible expression codes and their -meanings are machine-independent. The code of an RTX can be extracted with -the macro `GET_CODE (X)' and altered with `PUT_CODE (X, NEWCODE)'. - -The expression code determines how many operands the expression contains, -and what kinds of objects they are. In RTL, unlike Lisp, you cannot tell -by looking at an operand what kind of object it is. Instead, you must know -from its context---from the expression code of the containing expression. -For example, in an expression of code `subreg', the first operand is to be -regarded as an expression and the second operand as an integer. In an -expression of code `plus', there are two operands, both of which are to be -regarded as expressions. In a `symbol_ref' expression, there is one -operand, which is to be regarded as a string. - -Expressions are written as parentheses containing the name of the -expression type, its flags and machine mode if any, and then the operands -of the expression (separated by spaces). - -Expression code names in the `md' file are written in lower case, but when -they appear in C code they are written in upper case. In this manual, they -are shown as follows: `const_int'. - -In a few contexts a null pointer is valid where an expression is normally -wanted. The written form of this is `(nil)'. - -