tm.texi (TARGET_ADDR_SPACE_POINTER_MODE): Document.
[platform/upstream/gcc.git] / gcc / combine.c
index 60c4059..2311755 100644 (file)
@@ -321,7 +321,7 @@ static rtx *uid_log_links;
 
 static int label_tick;
 
-/* Reset to label_tick for each label.  */
+/* Reset to label_tick for each extended basic block in scanning order.  */
 
 static int label_tick_ebb_start;
 
@@ -1010,9 +1010,6 @@ clear_log_links (void)
     if (INSN_P (insn))
       free_INSN_LIST_list (&LOG_LINKS (insn));
 }
-
-
-
 \f
 /* Main entry point for combiner.  F is the first insn of the function.
    NREGS is the first unused pseudo-reg number.
@@ -1028,6 +1025,7 @@ combine_instructions (rtx f, unsigned int nregs)
 #endif
   rtx links, nextlinks;
   rtx first;
+  basic_block last_bb;
 
   int new_direct_jump_p = 0;
 
@@ -1058,6 +1056,7 @@ combine_instructions (rtx f, unsigned int nregs)
      problems when, for example, we have j <<= 1 in a loop.  */
 
   nonzero_sign_valid = 0;
+  label_tick = label_tick_ebb_start = 1;
 
   /* Scan all SETs and see if we can deduce anything about what
      bits are known to be zero for some registers and how many copies
@@ -1067,18 +1066,23 @@ combine_instructions (rtx f, unsigned int nregs)
      for what bits are known to be set.  */
 
   setup_incoming_promotions (first);
+  /* Allow the entry block and the first block to fall into the same EBB.
+     Conceptually the incoming promotions are assigned to the entry block.  */
+  last_bb = ENTRY_BLOCK_PTR;
 
   create_log_links ();
-  label_tick_ebb_start = ENTRY_BLOCK_PTR->index;
   FOR_EACH_BB (this_basic_block)
     {
       optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
       last_call_luid = 0;
       mem_last_set = -1;
-      label_tick = this_basic_block->index;
+
+      label_tick++;
       if (!single_pred_p (this_basic_block)
-         || single_pred (this_basic_block)->index != label_tick - 1)
+         || single_pred (this_basic_block) != last_bb)
        label_tick_ebb_start = label_tick;
+      last_bb = this_basic_block;
+
       FOR_BB_INSNS (this_basic_block, insn)
         if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
          {
@@ -1109,20 +1113,23 @@ combine_instructions (rtx f, unsigned int nregs)
   nonzero_sign_valid = 1;
 
   /* Now scan all the insns in forward order.  */
-
-  label_tick_ebb_start = ENTRY_BLOCK_PTR->index;
+  label_tick = label_tick_ebb_start = 1;
   init_reg_last ();
   setup_incoming_promotions (first);
+  last_bb = ENTRY_BLOCK_PTR;
 
   FOR_EACH_BB (this_basic_block)
     {
       optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
       last_call_luid = 0;
       mem_last_set = -1;
-      label_tick = this_basic_block->index;
+
+      label_tick++;
       if (!single_pred_p (this_basic_block)
-         || single_pred (this_basic_block)->index != label_tick - 1)
+         || single_pred (this_basic_block) != last_bb)
        label_tick_ebb_start = label_tick;
+      last_bb = this_basic_block;
+
       rtl_profile_for_bb (this_basic_block);
       for (insn = BB_HEAD (this_basic_block);
           insn != NEXT_INSN (BB_END (this_basic_block));
@@ -2257,68 +2264,33 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode)
 
   return x;
 }
-#endif
 
 /* Auxiliary data structure for propagate_for_debug_stmt.  */
 
 struct rtx_subst_pair
 {
-  rtx from, to;
-  bool changed;
-#ifdef AUTO_INC_DEC
+  rtx to;
   bool adjusted;
   bool after;
-#endif
 };
 
-/* Clean up any auto-updates in PAIR->to the first time it is called
-   for a PAIR.  PAIR->adjusted is used to tell whether we've cleaned
-   up before.  */
+/* DATA points to an rtx_subst_pair.  Return the value that should be
+   substituted.  */
 
-static void
-auto_adjust_pair (struct rtx_subst_pair *pair ATTRIBUTE_UNUSED)
+static rtx
+propagate_for_debug_subst (rtx from ATTRIBUTE_UNUSED, void *data)
 {
-#ifdef AUTO_INC_DEC
+  struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
+
   if (!pair->adjusted)
     {
       pair->adjusted = true;
       pair->to = cleanup_auto_inc_dec (pair->to, pair->after, VOIDmode);
+      return pair->to;
     }
-#endif
-}
-
-/* If *LOC is the same as FROM in the struct rtx_subst_pair passed as
-   DATA, replace it with a copy of TO.  Handle SUBREGs of *LOC as
-   well.  */
-
-static int
-propagate_for_debug_subst (rtx *loc, void *data)
-{
-  struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
-  rtx from = pair->from, to = pair->to;
-  rtx x = *loc, s = x;
-
-  if (rtx_equal_p (x, from)
-      || (GET_CODE (x) == SUBREG && rtx_equal_p ((s = SUBREG_REG (x)), from)))
-    {
-      auto_adjust_pair (pair);
-      if (pair->to != to)
-       to = pair->to;
-      else
-       to = copy_rtx (to);
-      if (s != x)
-       {
-         gcc_assert (GET_CODE (x) == SUBREG && SUBREG_REG (x) == s);
-         to = simplify_gen_subreg (GET_MODE (x), to,
-                                   GET_MODE (from), SUBREG_BYTE (x));
-       }
-      *loc = wrap_constant (GET_MODE (x), to);
-      pair->changed = true;
-      return -1;
-    }
-
-  return 0;
+  return copy_rtx (pair->to);
 }
+#endif
 
 /* Replace occurrences of DEST with SRC in DEBUG_INSNs between INSN
    and LAST.  If MOVE holds, debug insns must also be moved past
@@ -2327,14 +2299,11 @@ propagate_for_debug_subst (rtx *loc, void *data)
 static void
 propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
 {
-  struct rtx_subst_pair p;
-  rtx next, move_pos = move ? last : NULL_RTX;
-
-  p.from = dest;
-  p.to = src;
-  p.changed = false;
+  rtx next, move_pos = move ? last : NULL_RTX, loc;
 
 #ifdef AUTO_INC_DEC
+  struct rtx_subst_pair p;
+  p.to = src;
   p.adjusted = false;
   p.after = move;
 #endif
@@ -2346,11 +2315,15 @@ propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
       next = NEXT_INSN (insn);
       if (DEBUG_INSN_P (insn))
        {
-         for_each_rtx (&INSN_VAR_LOCATION_LOC (insn),
-                       propagate_for_debug_subst, &p);
-         if (!p.changed)
+#ifdef AUTO_INC_DEC
+         loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
+                                        dest, propagate_for_debug_subst, &p);
+#else
+         loc = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn), dest, src);
+#endif
+         if (loc == INSN_VAR_LOCATION_LOC (insn))
            continue;
-         p.changed = false;
+         INSN_VAR_LOCATION_LOC (insn) = loc;
          if (move_pos)
            {
              remove_insn (insn);
@@ -4186,9 +4159,12 @@ find_split_point (rtx *loc, rtx insn)
       if (GET_CODE (XEXP (x, 0)) == CONST
          || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
        {
+         enum machine_mode address_mode
+           = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
+
          SUBST (XEXP (x, 0),
-                gen_rtx_LO_SUM (Pmode,
-                                gen_rtx_HIGH (Pmode, XEXP (x, 0)),
+                gen_rtx_LO_SUM (address_mode,
+                                gen_rtx_HIGH (address_mode, XEXP (x, 0)),
                                 XEXP (x, 0)));
          return &XEXP (XEXP (x, 0), 0);
        }
@@ -4201,7 +4177,8 @@ find_split_point (rtx *loc, rtx insn)
         it will not remain in the result.  */
       if (GET_CODE (XEXP (x, 0)) == PLUS
          && CONST_INT_P (XEXP (XEXP (x, 0), 1))
-         && ! memory_address_p (GET_MODE (x), XEXP (x, 0)))
+         && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
+                                           MEM_ADDR_SPACE (x)))
        {
          rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
          rtx seq = combine_split_insns (gen_rtx_SET (VOIDmode, reg,
@@ -4224,8 +4201,9 @@ find_split_point (rtx *loc, rtx insn)
              && NONJUMP_INSN_P (NEXT_INSN (seq))
              && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
              && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
-             && memory_address_p (GET_MODE (x),
-                                  SET_SRC (PATTERN (NEXT_INSN (seq)))))
+             && memory_address_addr_space_p
+                  (GET_MODE (x), SET_SRC (PATTERN (NEXT_INSN (seq))),
+                   MEM_ADDR_SPACE (x)))
            {
              rtx src1 = SET_SRC (PATTERN (seq));
              rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));
@@ -4264,7 +4242,8 @@ find_split_point (rtx *loc, rtx insn)
       /* If we have a PLUS whose first operand is complex, try computing it
          separately by making a split there.  */
       if (GET_CODE (XEXP (x, 0)) == PLUS
-          && ! memory_address_p (GET_MODE (x), XEXP (x, 0))
+          && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
+                                           MEM_ADDR_SPACE (x))
           && ! OBJECT_P (XEXP (XEXP (x, 0), 0))
           && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
                 && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))