Commit 2a8f6b90 by Jan Hubicka Committed by Jan Hubicka

alias.c (nonlocal_reference_p): Take a care for CALL_INSNS's fusage field.

	* alias.c (nonlocal_reference_p): Take a care for
	CALL_INSNS's fusage field.
	* calls.c (ECF_PURE): New flag.
	(emit_call_1): Handle ECF_PURE calls.
	(initialize_argument_information): Unset ECF_PURE flag too.
	(precompute_arguments): Precompute for ECF_PURE too.
	(expand_call): Handle ECF_PURE calls too.
	(emit_library_call_value_1): Rename no_queue argument to
	fn_type, accept value of 2 as pure function.
	(emit_library_call_value, emit_library_call): Rename no_queue argument
	to fn_type.
	* optabs.c (prepare_cmp_insn): Pass fn_type 2 to memcmp call.

	* tree.h (DECL_IS_PURE): New macro.
	(struct tree_decl): Add pure_flag.
	* c-common.c (enum attrs): Add attribute "pure".
	(init_attributes): Initialize attribute "pure"
	(decl_attributes): Handle attribute "pure".
	* extend.texi (Attribute "pure"): Document.
	* calls.c (expand_call): Add (mem:BLK (scratch)) to "equal from"
	in pure function.
	(flags_from_decl_or_type): Support attribute "pure".

From-SVN: r33138
parent c966901c
Thu Apr 13 15:55:08 MET DST 2000 Jan Hubicka <jh@suse.cz>
* alias.c (nonlocal_reference_p): Take a care for
CALL_INSNS's fusage field.
* calls.c (ECF_PURE): New flag.
(emit_call_1): Handle ECF_PURE calls.
(initialize_argument_information): Unset ECF_PURE flag too.
(precompute_arguments): Precompute for ECF_PURE too.
(expand_call): Handle ECF_PURE calls too.
(emit_library_call_value_1): Rename no_queue argument to
fn_type, accept value of 2 as pure function.
(emit_library_call_value, emit_library_call): Rename no_queue argument
to fn_type.
* optabs.c (prepare_cmp_insn): Pass fn_type 2 to memcmp call.
* tree.h (DECL_IS_PURE): New macro.
(struct tree_decl): Add pure_flag.
* c-common.c (enum attrs): Add attribute "pure".
(init_attributes): Initialize attribute "pure"
(decl_attributes): Handle attribute "pure".
* extend.texi (Attribute "pure"): Document.
* calls.c (expand_call): Add (mem:BLK (scratch)) to "equal from"
in pure function.
(flags_from_decl_or_type): Support attribute "pure".
2000-04-13 Jason Merrill <jason@casey.cygnus.com> 2000-04-13 Jason Merrill <jason@casey.cygnus.com>
* cpplex.c (_cpp_lex_token): Handle digraphs. Don't null-terminate * cpplex.c (_cpp_lex_token): Handle digraphs. Don't null-terminate
......
...@@ -1424,10 +1424,15 @@ nonlocal_reference_p (x) ...@@ -1424,10 +1424,15 @@ nonlocal_reference_p (x)
if (GET_RTX_CLASS (code) == 'i') if (GET_RTX_CLASS (code) == 'i')
{ {
/* Constant functions are constant. */ /* Constant functions can be constant if they don't use
scratch memory used to mark function w/o side effects. */
if (code == CALL_INSN && CONST_CALL_P (x)) if (code == CALL_INSN && CONST_CALL_P (x))
return 0; {
x = PATTERN (x); x = CALL_INSN_FUNCTION_USAGE (x);
if (!x) return 0;
}
else
x = PATTERN (x);
code = GET_CODE (x); code = GET_CODE (x);
} }
...@@ -1520,7 +1525,7 @@ nonlocal_reference_p (x) ...@@ -1520,7 +1525,7 @@ nonlocal_reference_p (x)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
if (fmt[i] == 'e') if (fmt[i] == 'e' && XEXP (x, i))
{ {
if (nonlocal_reference_p (XEXP (x, i))) if (nonlocal_reference_p (XEXP (x, i)))
return 1; return 1;
......
...@@ -145,7 +145,7 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION, ...@@ -145,7 +145,7 @@ enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION,
A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION, A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION,
A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED, A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, A_MALLOC, A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS, A_MALLOC,
A_NO_LIMIT_STACK}; A_NO_LIMIT_STACK, A_PURE};
enum format_type { printf_format_type, scanf_format_type, enum format_type { printf_format_type, scanf_format_type,
strftime_format_type }; strftime_format_type };
...@@ -457,6 +457,7 @@ init_attributes () ...@@ -457,6 +457,7 @@ init_attributes ()
add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1); add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1);
add_attribute (A_MALLOC, "malloc", 0, 0, 1); add_attribute (A_MALLOC, "malloc", 0, 0, 1);
add_attribute (A_NO_LIMIT_STACK, "no_stack_limit", 0, 0, 1); add_attribute (A_NO_LIMIT_STACK, "no_stack_limit", 0, 0, 1);
add_attribute (A_PURE, "pure", 0, 0, 1);
} }
/* Default implementation of valid_lang_attribute, below. By default, there /* Default implementation of valid_lang_attribute, below. By default, there
...@@ -596,6 +597,7 @@ decl_attributes (node, attributes, prefix_attributes) ...@@ -596,6 +597,7 @@ decl_attributes (node, attributes, prefix_attributes)
case A_MALLOC: case A_MALLOC:
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_IS_MALLOC (decl) = 1; DECL_IS_MALLOC (decl) = 1;
/* ??? TODO: Support types. */
else else
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
break; break;
...@@ -625,6 +627,15 @@ decl_attributes (node, attributes, prefix_attributes) ...@@ -625,6 +627,15 @@ decl_attributes (node, attributes, prefix_attributes)
warning ( "`%s' attribute ignored", IDENTIFIER_POINTER (name)); warning ( "`%s' attribute ignored", IDENTIFIER_POINTER (name));
break; break;
case A_PURE:
if (TREE_CODE (decl) == FUNCTION_DECL)
DECL_IS_PURE (decl) = 1;
/* ??? TODO: Support types. */
else
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
break;
case A_T_UNION: case A_T_UNION:
if (is_type if (is_type
&& TREE_CODE (type) == UNION_TYPE && TREE_CODE (type) == UNION_TYPE
......
...@@ -1379,22 +1379,44 @@ typedef void voidfn (); ...@@ -1379,22 +1379,44 @@ typedef void voidfn ();
volatile voidfn fatal; volatile voidfn fatal;
@end smallexample @end smallexample
@cindex @code{const} function attribute @cindex @code{pure} function attribute
@item const @item pure
Many functions do not examine any values except their arguments, and Many functions have no effects except the return value and their
have no effects except the return value. Such a function can be subject return value and depends only on the parameters and/or global variables.
Such a function can be subject
to common subexpression elimination and loop optimization just as an to common subexpression elimination and loop optimization just as an
arithmetic operator would be. These functions should be declared arithmetic operator would be. These functions should be declared
with the attribute @code{const}. For example, with the attribute @code{pure}. For example,
@smallexample @smallexample
int square (int) __attribute__ ((const)); int square (int) __attribute__ ((pure));
@end smallexample @end smallexample
@noindent @noindent
says that the hypothetical function @code{square} is safe to call says that the hypothetical function @code{square} is safe to call
fewer times than the program says. fewer times than the program says.
Some of common examples of pure functions are @code{strlen} or @code{memcmp}.
Interesting non-pure functions are functions with infinite loops or those
depending on volatile memory or other system resource, that may change between
two consetuctive calls (such as @code{feof} in multithreding environment).
The attribute @code{pure} is not implemented in GNU C versions earlier
than 2.96.
@cindex @code{const} function attribute
@item const
Many functions do not examine any values except their arguments, and
have no effects except the return value. Basically this is just slightly
more strict class than the "pure" attribute above, since function is not
alloved to read global memory.
@cindex pointer arguments
Note that a function that has pointer arguments and examines the data
pointed to must @emph{not} be declared @code{const}. Likewise, a
function that calls a non-@code{const} function usually must not be
@code{const}. It does not make sense for a @code{const} function to
return @code{void}.
The attribute @code{const} is not implemented in GNU C versions earlier The attribute @code{const} is not implemented in GNU C versions earlier
than 2.5. An alternative way to declare that a function has no side than 2.5. An alternative way to declare that a function has no side
effects, which works in the current version and in some older versions, effects, which works in the current version and in some older versions,
...@@ -1409,12 +1431,6 @@ extern const intfn square; ...@@ -1409,12 +1431,6 @@ extern const intfn square;
This approach does not work in GNU C++ from 2.6.0 on, since the language This approach does not work in GNU C++ from 2.6.0 on, since the language
specifies that the @samp{const} must be attached to the return value. specifies that the @samp{const} must be attached to the return value.
@cindex pointer arguments
Note that a function that has pointer arguments and examines the data
pointed to must @emph{not} be declared @code{const}. Likewise, a
function that calls a non-@code{const} function usually must not be
@code{const}. It does not make sense for a @code{const} function to
return @code{void}.
@item format (@var{archetype}, @var{string-index}, @var{first-to-check}) @item format (@var{archetype}, @var{string-index}, @var{first-to-check})
@cindex @code{format} function attribute @cindex @code{format} function attribute
......
...@@ -3020,14 +3020,14 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align, ...@@ -3020,14 +3020,14 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
#endif #endif
{ {
#ifdef TARGET_MEM_FUNCTIONS #ifdef TARGET_MEM_FUNCTIONS
emit_library_call (memcmp_libfunc, 0, emit_library_call (memcmp_libfunc, 2,
TYPE_MODE (integer_type_node), 3, TYPE_MODE (integer_type_node), 3,
XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
convert_to_mode (TYPE_MODE (sizetype), size, convert_to_mode (TYPE_MODE (sizetype), size,
TREE_UNSIGNED (sizetype)), TREE_UNSIGNED (sizetype)),
TYPE_MODE (sizetype)); TYPE_MODE (sizetype));
#else #else
emit_library_call (bcmp_libfunc, 0, emit_library_call (bcmp_libfunc, 2,
TYPE_MODE (integer_type_node), 3, TYPE_MODE (integer_type_node), 3,
XEXP (x, 0), Pmode, XEXP (y, 0), Pmode, XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
convert_to_mode (TYPE_MODE (integer_type_node), convert_to_mode (TYPE_MODE (integer_type_node),
......
...@@ -1253,6 +1253,10 @@ struct tree_type ...@@ -1253,6 +1253,10 @@ struct tree_type
not an alias. */ not an alias. */
#define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag) #define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag)
/* Nonzero in a FUNCTION_DECL means this function should be treated
as "pure" function (like const function, but may read global memory). */
#define DECL_IS_PURE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.pure_flag)
/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */ specially. */
#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag) #define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag)
...@@ -1392,6 +1396,7 @@ struct tree_decl ...@@ -1392,6 +1396,7 @@ struct tree_decl
unsigned comdat_flag : 1; unsigned comdat_flag : 1;
unsigned malloc_flag : 1; unsigned malloc_flag : 1;
unsigned no_limit_stack : 1; unsigned no_limit_stack : 1;
unsigned pure_flag : 1;
#ifdef ONLY_INT_FIELDS #ifdef ONLY_INT_FIELDS
unsigned int built_in_class : 2; unsigned int built_in_class : 2;
#else #else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment