aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <sayle@gcc.gnu.org>2003-06-04 12:07:52 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-06-04 12:07:52 +0000
commit8c6a82695b85f8ed74cdc67f2cf74c5a62d0d91d (patch)
tree3db65d6f6c47477a6b251f457addfa72eb727e45
parente2d8bb2946c433461b613996567250b72b87cd24 (diff)
downloadgcc-8c6a82695b85f8ed74cdc67f2cf74c5a62d0d91d.zip
gcc-8c6a82695b85f8ed74cdc67f2cf74c5a62d0d91d.tar.gz
gcc-8c6a82695b85f8ed74cdc67f2cf74c5a62d0d91d.tar.bz2
calls.c (expand_call): Avoid calling pure or const functions when the result is ignored (or void) and...
* calls.c (expand_call): Avoid calling pure or const functions when the result is ignored (or void) and none of the arguments are volatile. Move warning diagnostic earlier in function. From-SVN: r67436
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/calls.c36
2 files changed, 39 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8be4202..4199b50 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-06-04 Roger Sayle <roger@eyesopen.com>
+
+ * calls.c (expand_call): Avoid calling pure or const functions
+ when the result is ignored (or void) and none of the arguments
+ are volatile. Move warning diagnostic earlier in function.
+
2003-06-04 Andreas Jaeger <aj@suse.de>
* system.h: Do not poison TDESC_SECTION_ASM_OP,
@@ -15,7 +21,8 @@
* cse.c: Include params.h.
(PATHLENGTH): Removed.
(struct cse_basic_block_data): Make path array dynamic.
- (cse_end_of_basic_block): Use PARAM_MAX_CSE_PATH_LENGTH instead of PATHLENGTH.
+ (cse_end_of_basic_block): Use PARAM_MAX_CSE_PATH_LENGTH instead
+ of PATHLENGTH.
(cse_main, cse_basic_block): Allocate path array.
* params.def (PARAM_MAX_CSE_PATH_LENGTH): New.
diff --git a/gcc/calls.c b/gcc/calls.c
index 4e95735..db6b884 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2211,6 +2211,37 @@ expand_call (exp, target, ignore)
else
flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
+ /* Warn if this value is an aggregate type,
+ regardless of which calling convention we are using for it. */
+ if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ warning ("function call has aggregate value");
+
+ /* If the result of a pure or const function call is ignored (or void),
+ and none of its arguments are volatile, we can avoid expanding the
+ call and just evaluate the arguments for side-effects. */
+ if ((flags & (ECF_CONST | ECF_PURE))
+ && (ignore || target == const0_rtx
+ || TYPE_MODE (TREE_TYPE (exp)) == VOIDmode))
+ {
+ bool volatilep = false;
+ tree arg;
+
+ for (arg = actparms; arg; arg = TREE_CHAIN (arg))
+ if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
+ {
+ volatilep = true;
+ break;
+ }
+
+ if (! volatilep)
+ {
+ for (arg = actparms; arg; arg = TREE_CHAIN (arg))
+ expand_expr (TREE_VALUE (arg), const0_rtx,
+ VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+ }
+
#ifdef REG_PARM_STACK_SPACE
#ifdef MAYBE_REG_PARM_STACK_SPACE
reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
@@ -2224,11 +2255,6 @@ expand_call (exp, target, ignore)
must_preallocate = 1;
#endif
- /* Warn if this value is an aggregate type,
- regardless of which calling convention we are using for it. */
- if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
- warning ("function call has aggregate value");
-
/* Set up a place to return a structure. */
/* Cater to broken compilers. */