2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-04-13 11:41:12 +08:00

Richard Kenner <kenner@vlsi1.ultra.nyu.edu>:

* rtl.def (CONSTANT_P_RTX): Clarify commentary.
        * expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Rework to
        consider constant CONSTRUCTOR constant and to defer some cases
        to cse.
        * cse.c (fold_rtx, case CONST): Add handling for CONSTANT_P_RTX.
        * regclass.c (reg_scan_mark_refs, case CONST): Likewise.
Richard Henderson  <rth@cygnus.com>
        * expr.c (init_expr_once): Kill can_handle_constant_p recognition.
        * cse.c (fold_rtx, case 'x'): Remove standalone CONSTANT_P_RTX code.

From-SVN: r24439
This commit is contained in:
Richard Henderson 1998-12-29 03:36:22 -08:00
parent eb8da8684c
commit 185ebd6c71
6 changed files with 124 additions and 45 deletions

@ -1,3 +1,23 @@
Tue Dec 29 11:32:54 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>:
* rtl.def (CONSTANT_P_RTX): Clarify commentary.
* expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Rework to
consider constant CONSTRUCTOR constant and to defer some cases
to cse.
* cse.c (fold_rtx, case CONST): Add handling for CONSTANT_P_RTX.
* regclass.c (reg_scan_mark_refs, case CONST): Likewise.
Tue Dec 29 11:30:10 1998 Richard Henderson <rth@cygnus.com>
* expr.c (init_expr_once): Kill can_handle_constant_p recognition.
* cse.c (fold_rtx, case 'x'): Remove standalone CONSTANT_P_RTX code.
* alpha.c (reg_or_6bit_operand): Remove CONSTANT_P_RTX handling.
(reg_or_8bit_operand, cint8_operand, add_operand): Likewise.
(sext_add_operand, and_operand, or_operand): Likewise.
(reg_or_cint_operand, some_operand, input_operand): Likewise.
* alpha.h (PREDICATE_CODES): Likewise.
Sat Dec 26 23:26:26 PST 1998 Jeff Law (law@cygnus.com)
* version.c: Bump for snapshot.

@ -4931,6 +4931,21 @@ fold_rtx (x, insn)
switch (code)
{
case CONST:
/* If the operand is a CONSTANT_P_RTX, see if what's inside it
is known to be constant and replace the whole thing with a
CONST_INT of either zero or one. Note that this code assumes
that an insn that recognizes a CONST will also recognize a
CONST_INT, but that seems to be a safe assumption. */
if (GET_CODE (XEXP (x, 0)) == CONSTANT_P_RTX)
{
x = equiv_constant (fold_rtx (XEXP (XEXP (x, 0), 0), 0));
return (x != 0 && (GET_CODE (x) == CONST_INT
|| GET_CODE (x) == CONST_DOUBLE)
? const1_rtx : const0_rtx);
}
/* ... fall through ... */
case CONST_INT:
case CONST_DOUBLE:
case SYMBOL_REF:
@ -5850,12 +5865,6 @@ fold_rtx (x, insn)
const_arg1 ? const_arg1 : folded_arg1,
const_arg2 ? const_arg2 : XEXP (x, 2));
break;
case 'x':
/* Always eliminate CONSTANT_P_RTX at this stage. */
if (code == CONSTANT_P_RTX)
return (const_arg0 ? const1_rtx : const0_rtx);
break;
}
return new ? new : x;

@ -101,11 +101,6 @@ static rtx saveregs_value;
/* Similarly for __builtin_apply_args. */
static rtx apply_args_value;
/* Nonzero if the machine description has been fixed to accept
CONSTANT_P_RTX patterns. We will emit a warning and continue
if we find we must actually use such a beast. */
static int can_handle_constant_p;
/* Don't check memory usage, since code is being emitted to check a memory
usage. Used when current_function_check_memory_usage is true, to avoid
infinite recursion. */
@ -309,14 +304,6 @@ init_expr_once ()
}
}
/* Find out if CONSTANT_P_RTX is accepted. */
SET_DEST (pat) = gen_rtx_REG (TYPE_MODE (integer_type_node),
FIRST_PSEUDO_REGISTER);
SET_SRC (pat) = gen_rtx_CONSTANT_P_RTX (TYPE_MODE (integer_type_node),
SET_DEST (pat));
if (recog (pat, insn, &num_clobbers) >= 0)
can_handle_constant_p = 1;
end_sequence ();
obfree (free_point);
}
@ -9010,36 +8997,42 @@ expand_builtin (exp, target, subtarget, mode, ignore)
else
{
tree arg = TREE_VALUE (arglist);
rtx tmp;
/* We return 1 for a numeric type that's known to be a constant
value at compile-time or for an aggregate type that's a
literal constant. */
STRIP_NOPS (arg);
if (really_constant_p (arg)
/* If we know this is a constant, emit the constant of one. */
if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'c'
|| (TREE_CODE (arg) == CONSTRUCTOR
&& TREE_CONSTANT (arg))
|| (TREE_CODE (arg) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST))
return const1_rtx;
/* Only emit CONSTANT_P_RTX if CSE will be run.
Moreover, we don't want to expand trees that have side effects,
as the original __builtin_constant_p did not evaluate its
argument at all, and we would break existing usage by changing
this. This quirk was generally useful, eliminating a bit of hair
in the writing of the macros that use this function. Now the
same thing can be better accomplished in an inline function. */
/* If we aren't going to be running CSE or this expression
has side effects, show we don't know it to be a constant.
Likewise if it's a pointer or aggregate type since in those
case we only want literals, since those are only optimized
when generating RTL, not later. */
if (TREE_SIDE_EFFECTS (arg) || cse_not_expected
|| AGGREGATE_TYPE_P (TREE_TYPE (arg))
|| POINTER_TYPE_P (TREE_TYPE (arg)))
return const0_rtx;
if (! cse_not_expected && ! TREE_SIDE_EFFECTS (arg))
{
/* Lazy fixup of old code: issue a warning and fail the test. */
if (! can_handle_constant_p)
{
warning ("Delayed evaluation of __builtin_constant_p not supported on this target.");
warning ("Please report this as a bug to egcs-bugs@cygnus.com.");
return const0_rtx;
}
return gen_rtx_CONSTANT_P_RTX (TYPE_MODE (integer_type_node),
expand_expr (arg, NULL_RTX,
VOIDmode, 0));
}
/* Otherwise, emit (const (constant_p_rtx (ARG))) and let CSE
get a chance to see if it can deduce whether ARG is constant. */
/* ??? We always generate the CONST in ptr_mode since that's
certain to be valid on this machine, then convert it to
whatever we need. */
return const0_rtx;
tmp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
tmp = gen_rtx_CONSTANT_P_RTX (ptr_mode, tmp);
tmp = gen_rtx_CONST (ptr_mode, tmp);
tmp = convert_to_mode (mode, tmp, 0);
return tmp;
}
case BUILT_IN_FRAME_ADDRESS:

@ -64,6 +64,7 @@ C++ Language}, for extensions that apply @emph{only} to C++.
* Function Names:: Printable strings which are the name of the current
function.
* Return Address:: Getting the return or frame address of a function.
* Other Builtins:: Other built-in functions.
@end menu
@end ifset
@ifclear INTERNALS
@ -2904,6 +2905,7 @@ These functions may be used to get information about the callers of a
function.
@table @code
@findex __builtin_return_address
@item __builtin_return_address (@var{level})
This function returns the return address of the current function, or of
one of its callers. The @var{level} argument is number of frames to
@ -2920,6 +2922,7 @@ of the stack has been reached, this function will return @code{0}.
This function should only be used with a non-zero argument for debugging
purposes.
@findex __builtin_frame_address
@item __builtin_frame_address (@var{level})
This function is similar to @code{__builtin_return_address}, but it
returns the address of the function frame rather than the return address
@ -2940,6 +2943,55 @@ The caveats that apply to @code{__builtin_return_address} apply to this
function as well.
@end table
@node Other Builtins
@section Other built-in functions provided by GNU CC
GNU CC provides a large number of built-in functions other than the ones
mentioned above. Some of these are for internal use in the processing
of exceptions or variable-length argument lists and will not be
documented here because they may change from time to time; we do not
recommend general use of these functions.
The remaining functions are provided for optimization purposes.
GNU CC includes builtin versions of many of the functions in the
standard C library. These will always be treated as having the same
meaning as the C library function even if you specify the
@samp{-fno-builtin} (@pxref{C Dialect Options}) option. These functions
correspond to the C library functions @code{alloca}, @code{ffs},
@code{abs}, @code{fabsf}, @code{fabs}, @code{fabsl}, @code{labs},
@code{memcpy}, @code{memcmp}, @code{strcmp}, @code{strcpy},
@code{strlen}, @code{sqrtf}, @code{sqrt}, @code{sqrtl}, @code{sinf},
@code{sin}, @code{sinl}, @code{cosf}, @code{cos}, and @code{cosl}.
@findex __builtin_constant_p
You can use the builtin function @code{__builtin_constant_p} to
determine if a value is known to be constant at compile-time and hence
that GNU CC can perform constant-folding on expressions involving that
value. The argument of the function is the value to test. The function
returns the integer 1 if the argument is known to be a compile-time
constant and 0 if it is not known to be a compile-time constant. A
return of 0 does not indicate that the value is @emph{not} a constant,
but merely that GNU CC cannot prove it is a constant with the specified
value of the @samp{-O} option.
You would typically use this function in an embedded application where
memory was a critical resource. If you have some complex calculation,
you may want it to be folded if it involves constants, but need to call
a function if it does not. For example:
#define Scale_Value(X) \
(__builtin_constant_p (X) ? ((X) * SCALE + OFFSET) : Scale (X))
@end smallexample
You may use this builtin function in either a macro or an inline
function. However, if you use it in an inlined function and pass an
argument of the function as the argument to the builtin, GNU CC will
never return 1 when you call the inline function with a string constant
or constructor expression (@pxref{Constructors}) and will not return 1
when you pass a constant numeric value to the inline function unless you
specify the @samp{-O} option.
@node C++ Extensions
@chapter Extensions to the C++ Language
@cindex extensions, C++ language

@ -2032,8 +2032,12 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
code = GET_CODE (x);
switch (code)
{
case CONST_INT:
case CONST:
if (GET_CODE (XEXP (x, 0)) == CONSTANT_P_RTX)
reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn, note_flag, min_regno);
return;
case CONST_INT:
case CONST_DOUBLE:
case CC0:
case PC:

@ -850,9 +850,10 @@ DEF_RTL_EXPR(RANGE_VAR, "range_var", "eti", 'x')
0 is the live bitmap. Operand 1 is the original block number. */
DEF_RTL_EXPR(RANGE_LIVE, "range_live", "bi", 'x')
/* A unary `__builtin_constant_p' expression. These are only emitted
during RTL generation, and then only if optimize > 0. They are
eliminated by the first CSE pass. */
/* A unary `__builtin_constant_p' expression. This RTL code may only be used
as an operand of a CONST. This pattern is only emitted during RTL
generation and then only if optimize > 0. It is converted by the first
CSE pass into the appropriate CONST_INT. */
DEF_RTL_EXPR(CONSTANT_P_RTX, "constant_p_rtx", "e", 'x')
/*