OSDN Git Service

* c-decl.c (c_init_decl_processing): Clear input_file_name
[pf3gnuchains/gcc-fork.git] / gcc / optabs.c
index fc00b18..c693e80 100644 (file)
@@ -700,8 +700,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
 
   if (flag_force_mem)
     {
-      op0 = force_not_mem (op0);
-      op1 = force_not_mem (op1);
+      /* Load duplicate non-volatile operands once.  */
+      if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
+       {
+         op0 = force_not_mem (op0);
+         op1 = op0;
+       }
+      else
+       {
+         op0 = force_not_mem (op0);
+         op1 = force_not_mem (op1);
+       }
     }
 
   /* If subtracting an integer constant, convert this into an addition of
@@ -1299,7 +1308,8 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
 
       if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
        {
-         if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
+         if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
+             || ! rtx_equal_p (target, xtarget))
            {
              rtx temp = emit_move_insn (target, xtarget);
 
@@ -1637,8 +1647,13 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
              temp1 = expand_binop (submode, binoptab, real0, imag1,
                                    NULL_RTX, unsignedp, methods);
 
-             temp2 = expand_binop (submode, binoptab, real1, imag0,
-                                   NULL_RTX, unsignedp, methods);
+             /* Avoid expanding redundant multiplication for the common
+                case of squaring a complex number.  */
+             if (rtx_equal_p (real0, real1) && rtx_equal_p (imag0, imag1))
+               temp2 = temp1;
+             else
+               temp2 = expand_binop (submode, binoptab, real1, imag0,
+                                     NULL_RTX, unsignedp, methods);
 
              if (temp1 == 0 || temp2 == 0)
                break;
@@ -2772,14 +2787,13 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
  */
 
 rtx
-expand_abs (mode, op0, target, result_unsignedp, safe)
+expand_abs_nojump (mode, op0, target, result_unsignedp)
      enum machine_mode mode;
      rtx op0;
      rtx target;
      int result_unsignedp;
-     int safe;
 {
-  rtx temp, op1;
+  rtx temp;
 
   if (! flag_trapv)
     result_unsignedp = 1;
@@ -2867,6 +2881,23 @@ expand_abs (mode, op0, target, result_unsignedp, safe)
        return temp;
     }
 
+  return NULL_RTX;
+}
+
+rtx
+expand_abs (mode, op0, target, result_unsignedp, safe)
+     enum machine_mode mode;
+     rtx op0;
+     rtx target;
+     int result_unsignedp;
+     int safe;
+{
+  rtx temp, op1;
+
+  temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
+  if (temp != 0)
+    return temp;
+
   /* If that does not win, use conditional jump and negate.  */
 
   /* It is safe to use the target if it is the same
@@ -3570,8 +3601,17 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
 
   if (mode != BLKmode && flag_force_mem)
     {
-      x = force_not_mem (x);
-      y = force_not_mem (y);
+      /* Load duplicate non-volatile operands once.  */
+      if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
+       {
+         x = force_not_mem (x);
+         y = x;
+       }
+      else
+       {
+         x = force_not_mem (x);
+         y = force_not_mem (y);
+       }
     }
 
   /* If we are inside an appropriately-short loop and one operand is an
@@ -5381,6 +5421,8 @@ rtx
 init_one_libfunc (name)
      const char *name;
 {
+  rtx symbol;
+
   /* Create a FUNCTION_DECL that can be passed to
      targetm.encode_section_info.  */
   /* ??? We don't have any type information except for this is
@@ -5391,8 +5433,13 @@ init_one_libfunc (name)
   DECL_EXTERNAL (decl) = 1;
   TREE_PUBLIC (decl) = 1;
 
-  /* Return the symbol_ref from the mem rtx.  */
-  return XEXP (DECL_RTL (decl), 0);
+  symbol = XEXP (DECL_RTL (decl), 0);
+
+  /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
+     are the flags assigned by targetm.encode_section_info.  */
+  SYMBOL_REF_DECL (symbol) = 0;
+
+  return symbol;
 }
 
 /* Call this once to initialize the contents of the optabs