Richard Kenner <kenner@vlsi1.ultra.nyu.edu>:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Dec 1998 11:36:22 +0000 (11:36 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 29 Dec 1998 11:36:22 +0000 (11:36 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24439 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cse.c
gcc/expr.c
gcc/extend.texi
gcc/regclass.c
gcc/rtl.def

index 2d74239..cb230d9 100644 (file)
@@ -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.
index 2ef26a5..9ca2931 100644 (file)
--- a/gcc/cse.c
+++ b/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;
index e943e53..09a7eb1 100644 (file)
@@ -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 (! 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));
-           }
+         /* 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;
 
-         return const0_rtx;
+         /* 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.  */
+
+         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:
index cde383c..4389bee 100644 (file)
@@ -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
index b442cc2..489f824 100644 (file)
@@ -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:
index 5273fdf..8f47d40 100644 (file)
@@ -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')
 
 /*