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:
parent
eb8da8684c
commit
185ebd6c71
@ -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.
|
||||
|
21
gcc/cse.c
21
gcc/cse.c
@ -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;
|
||||
|
63
gcc/expr.c
63
gcc/expr.c
@ -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')
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user