re PR target/65697 (__atomic memory barriers not strong enough for __sync builtins)
[gcc.git] / gcc / cse.c
index 2a33827a61c9f3d28afde01296c1161b3463805a..100c9c83e769faf920d15c98bb614c35b80e8b5d 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -26,11 +26,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "hard-reg-set.h"
 #include "regs.h"
 #include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
-#include "input.h"
 #include "function.h"
 #include "dominance.h"
 #include "cfg.h"
@@ -42,13 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-config.h"
 #include "recog.h"
 #include "symtab.h"
-#include "statistics.h"
-#include "double-int.h"
-#include "real.h"
-#include "fixed-value.h"
 #include "alias.h"
-#include "wide-int.h"
-#include "inchash.h"
 #include "tree.h"
 #include "expmed.h"
 #include "dojump.h"
@@ -60,7 +49,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "expr.h"
 #include "diagnostic-core.h"
 #include "toplev.h"
-#include "ggc.h"
 #include "except.h"
 #include "target.h"
 #include "params.h"
@@ -281,7 +269,6 @@ struct qty_table_elem
 /* The table of all qtys, indexed by qty number.  */
 static struct qty_table_elem *qty_table;
 
-#ifdef HAVE_cc0
 /* For machines that have a CC0, we do not record its value in the hash
    table since its use is guaranteed to be the insn immediately following
    its definition and any other insn is presumed to invalidate it.
@@ -293,7 +280,6 @@ static struct qty_table_elem *qty_table;
 
 static rtx this_insn_cc0, prev_insn_cc0;
 static machine_mode this_insn_cc0_mode, prev_insn_cc0_mode;
-#endif
 
 /* Insn being scanned.  */
 
@@ -884,9 +870,7 @@ new_basic_block (void)
        }
     }
 
-#ifdef HAVE_cc0
   prev_insn_cc0 = 0;
-#endif
 }
 
 /* Say that register REG contains a quantity in mode MODE not in any
@@ -1898,7 +1882,7 @@ invalidate (rtx x, machine_mode full_mode)
          {
            HOST_WIDE_INT in_table
              = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
-           unsigned int endregno = END_HARD_REGNO (x);
+           unsigned int endregno = END_REGNO (x);
            unsigned int tregno, tendregno, rn;
            struct table_elt *p, *next;
 
@@ -1924,7 +1908,7 @@ invalidate (rtx x, machine_mode full_mode)
                      continue;
 
                    tregno = REGNO (p->exp);
-                   tendregno = END_HARD_REGNO (p->exp);
+                   tendregno = END_REGNO (p->exp);
                    if (tendregno > regno && tregno < endregno)
                      remove_from_table (p, hash);
                  }
@@ -2143,7 +2127,7 @@ invalidate_for_call (void)
            continue;
 
          regno = REGNO (p->exp);
-         endregno = END_HARD_REGNO (p->exp);
+         endregno = END_REGNO (p->exp);
 
          for (i = regno; i < endregno; i++)
            if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
@@ -3150,6 +3134,15 @@ fold_rtx (rtx x, rtx_insn *insn)
     {
     case MEM:
     case SUBREG:
+    /* The first operand of a SIGN/ZERO_EXTRACT has a different meaning
+       than it would in other contexts.  Basically its mode does not
+       signify the size of the object read.  That information is carried
+       by size operand.    If we happen to have a MEM of the appropriate
+       mode in our tables with a constant value we could simplify the
+       extraction incorrectly if we allowed substitution of that value
+       for the MEM.   */
+    case ZERO_EXTRACT:
+    case SIGN_EXTRACT:
       if ((new_rtx = equiv_constant (x)) != NULL_RTX)
         return new_rtx;
       return x;
@@ -3166,10 +3159,8 @@ fold_rtx (rtx x, rtx_insn *insn)
     case EXPR_LIST:
       return x;
 
-#ifdef HAVE_cc0
     case CC0:
       return prev_insn_cc0;
-#endif
 
     case ASM_OPERANDS:
       if (insn)
@@ -3180,12 +3171,10 @@ fold_rtx (rtx x, rtx_insn *insn)
        }
       return x;
 
-#ifdef NO_FUNCTION_CSE
     case CALL:
-      if (CONSTANT_P (XEXP (XEXP (x, 0), 0)))
+      if (NO_FUNCTION_CSE && CONSTANT_P (XEXP (XEXP (x, 0), 0)))
        return x;
       break;
-#endif
 
     /* Anything else goes through the loop below.  */
     default:
@@ -3223,7 +3212,6 @@ fold_rtx (rtx x, rtx_insn *insn)
            const_arg = folded_arg;
            break;
 
-#ifdef HAVE_cc0
          case CC0:
            /* The cc0-user and cc0-setter may be in different blocks if
               the cc0-setter potentially traps.  In that case PREV_INSN_CC0
@@ -3247,7 +3235,6 @@ fold_rtx (rtx x, rtx_insn *insn)
                const_arg = equiv_constant (folded_arg);
              }
            break;
-#endif
 
          default:
            folded_arg = fold_rtx (folded_arg, insn);
@@ -4522,11 +4509,9 @@ cse_insn (rtx_insn *insn)
     sets = XALLOCAVEC (struct set, XVECLEN (x, 0));
 
   this_insn = insn;
-#ifdef HAVE_cc0
   /* Records what this insn does to set CC0.  */
   this_insn_cc0 = 0;
   this_insn_cc0_mode = VOIDmode;
-#endif
 
   /* Find all regs explicitly clobbered in this insn,
      to ensure they are not replaced with any other regs
@@ -5495,7 +5480,7 @@ cse_insn (rtx_insn *insn)
             and hope for the best.  */
          if (n_sets == 1)
            {
-             rtx_insn *new_rtx;
+             rtx_jump_insn *new_rtx;
              rtx note;
 
              new_rtx = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
@@ -5541,7 +5526,6 @@ cse_insn (rtx_insn *insn)
            }
        }
 
-#ifdef HAVE_cc0
       /* If setting CC0, record what it was set to, or a constant, if it
         is equivalent to a constant.  If it is being set to a floating-point
         value, make a COMPARE with the appropriate constant of 0.  If we
@@ -5556,7 +5540,6 @@ cse_insn (rtx_insn *insn)
            this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
                                             CONST0_RTX (mode));
        }
-#endif
     }
 
   /* Now enter all non-volatile source expressions in the hash table
@@ -6527,8 +6510,7 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
                  && check_for_label_ref (insn))
                recorded_label_ref = true;
 
-#ifdef HAVE_cc0
-             if (NONDEBUG_INSN_P (insn))
+             if (HAVE_cc0 && NONDEBUG_INSN_P (insn))
                {
                  /* If the previous insn sets CC0 and this insn no
                     longer references CC0, delete the previous insn.
@@ -6555,7 +6537,6 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
                      prev_insn_cc0_mode = this_insn_cc0_mode;
                    }
                }
-#endif
            }
        }
 
@@ -6604,11 +6585,9 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
          record_jump_equiv (insn, taken);
        }
 
-#ifdef HAVE_cc0
       /* Clear the CC0-tracking related insns, they can't provide
         useful information across basic block boundaries.  */
       prev_insn_cc0 = 0;
-#endif
     }
 
   gcc_assert (next_qty <= max_qty);
@@ -6859,21 +6838,17 @@ static bool
 set_live_p (rtx set, rtx_insn *insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0.  */
            int *counts)
 {
-#ifdef HAVE_cc0
-  rtx tem;
-#endif
+  rtx_insn *tem;
 
   if (set_noop_p (set))
     ;
 
-#ifdef HAVE_cc0
   else if (GET_CODE (SET_DEST (set)) == CC0
           && !side_effects_p (SET_SRC (set))
           && ((tem = next_nonnote_nondebug_insn (insn)) == NULL_RTX
               || !INSN_P (tem)
               || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
     return false;
-#endif
   else if (!is_dead_reg (SET_DEST (set), counts)
           || side_effects_p (SET_SRC (set)))
     return true;
@@ -7144,7 +7119,7 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
 
 static void
 cse_change_cc_mode (subrtx_ptr_iterator::array_type &array,
-                   rtx *loc, rtx insn, rtx newreg)
+                   rtx *loc, rtx_insn *insn, rtx newreg)
 {
   FOR_EACH_SUBRTX_PTR (iter, array, loc, NONCONST)
     {