OSDN Git Service

PR debug/43051
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 16 Mar 2010 10:50:42 +0000 (10:50 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:12:44 +0000 (14:12 +0900)
PR debug/43092
* cselib.c (cselib_preserve_constants,
cfa_base_preserved_val): New static variables.
(preserve_only_constants): New function.
(cselib_reset_table): If cfa_base_preserved_val is non-NULL, don't
clear its REG_VALUES.  If cselib_preserve_constants, don't
empty the whole hash table, but preserve there VALUEs with constants,
cfa_base_preserved_val and cfa_base_preserved_val plus constant.
(cselib_preserve_cfa_base_value): New function.
(cselib_invalidate_regno): Don't invalidate cfa_base_preserved_val.
(cselib_init): Change argument to int bitfield.  Set
cselib_preserve_constants to whether CSELIB_PRESERVE_CONSTANTS
is in it.
(cselib_finish): Clear cselib_preserve_constants and
cfa_base_preserved_val.
* cselib.h (enum cselib_record_what): New enum.
(cselib_init): Change argument to int.
(cselib_preserve_cfa_base_value): New prototype.
* postreload.c (reload_cse_regs_1): Adjust cselib_init caller.
* dse.c (dse_step1): Likewise.
* cfgcleanup.c (thread_jump): Likewise.
* sched-deps.c (sched_analyze): Likewise.
* gcse.c (local_cprop_pass): Likewise.
* simplify-rtx.c (simplify_replace_fn_rtx): Add argument to callback.
If FN is non-NULL, call the callback always and whenever it returns
non-NULL just return that.  Only do rtx_equal_p if FN is NULL.
* rtl.h (simplify_replace_fn_rtx): Add argument to callback.
* combine.c (propagate_for_debug_subst): Add old_rtx argument,
compare from with old_rtx and if it isn't rtx_equal_p, return NULL.
* Makefile.in (var-tracking.o): Depend on $(RECOG_H).
* var-tracking.c: Include recog.h.
(bb_stack_adjust_offset): Remove.
(vt_stack_adjustments): Don't call it, instead just gather the
adjustments using insn_stack_adjust_offset_pre_post on each bb insn.
(adjust_stack_reference): Remove.
(compute_cfa_pointer): New function.
(hard_frame_pointer_adjustment, cfa_base_rtx): New static variables.
(struct adjust_mem_data): New type.
(adjust_mems, adjust_mem_uses, adjust_mem_stores, adjust_insn): New
functions.
(get_address_mode): New function.
(replace_expr_with_values): Use it.
(use_type): Don't do cselib_lookup for VAR_LOC_UNKNOWN_P.
Use get_address_mode.  For cfa_base_rtx return MO_CLOBBER.
(adjust_sets): Remove.
(add_uses): Don't add extra MO_VAL_USE for cfa_base_rtx plus constant.
Use get_address_mode.
(get_adjusted_src): Remove.
(add_stores): Don't call it.  Never reuse expr SET.  Don't add extra
MO_VAL_USE for cfa_base_rtx plus constant.  Use get_address_mode.
(add_with_sets): Don't call adjust_sets.
(fp_setter, vt_init_cfa_base): New functions.
(vt_initialize): Change return type to bool.  Move most of pool etc.
initialization to the beginning of the function from end.  Pass
CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS to cselib_init.
If !frame_pointer_needed, call vt_stack_adjustment before mos
vector is filled, call vt_init_cfa_base if argp/framep has been
eliminated to sp.  If frame_pointer_needed and argp/framep has
been eliminated to hard frame pointer, set
hard_frame_pointer_adjustment and call vt_init_cfa_base after
encountering fp setter in the prologue.  For MO_ADJUST, call
log_op_type before pusing the op into mos vector, not afterwards.
Call adjust_insn before cselib_process_insn/add_with_sets,
call cancel_changes (0) afterwards.
(variable_tracking_main_1): Adjust for vt_initialize calling
vt_stack_adjustments and returning whether it succeeded or not.

* gcc.dg/guality/pr43051-1.c: New test.

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

gcc/ChangeLog
gcc/cselib.c
gcc/cselib.h
gcc/testsuite/ChangeLog
gcc/var-tracking.c

index 718af29..9f2d070 100644 (file)
@@ -1,3 +1,73 @@
+2010-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/43051
+       PR debug/43092
+       * cselib.c (cselib_preserve_constants,
+       cfa_base_preserved_val): New static variables.
+       (preserve_only_constants): New function.
+       (cselib_reset_table): If cfa_base_preserved_val is non-NULL, don't
+       clear its REG_VALUES.  If cselib_preserve_constants, don't 
+       empty the whole hash table, but preserve there VALUEs with constants,
+       cfa_base_preserved_val and cfa_base_preserved_val plus constant.
+       (cselib_preserve_cfa_base_value): New function.
+       (cselib_invalidate_regno): Don't invalidate cfa_base_preserved_val.
+       (cselib_init): Change argument to int bitfield.  Set
+       cselib_preserve_constants to whether CSELIB_PRESERVE_CONSTANTS
+       is in it.
+       (cselib_finish): Clear cselib_preserve_constants and
+       cfa_base_preserved_val.
+       * cselib.h (enum cselib_record_what): New enum.
+       (cselib_init): Change argument to int.
+       (cselib_preserve_cfa_base_value): New prototype.
+       * postreload.c (reload_cse_regs_1): Adjust cselib_init caller.
+       * dse.c (dse_step1): Likewise.
+       * cfgcleanup.c (thread_jump): Likewise.
+       * sched-deps.c (sched_analyze): Likewise.
+       * gcse.c (local_cprop_pass): Likewise.
+       * simplify-rtx.c (simplify_replace_fn_rtx): Add argument to callback.
+       If FN is non-NULL, call the callback always and whenever it returns
+       non-NULL just return that.  Only do rtx_equal_p if FN is NULL.
+       * rtl.h (simplify_replace_fn_rtx): Add argument to callback.
+       * combine.c (propagate_for_debug_subst): Add old_rtx argument,
+       compare from with old_rtx and if it isn't rtx_equal_p, return NULL.
+       * Makefile.in (var-tracking.o): Depend on $(RECOG_H).
+       * var-tracking.c: Include recog.h.
+       (bb_stack_adjust_offset): Remove.
+       (vt_stack_adjustments): Don't call it, instead just gather the
+       adjustments using insn_stack_adjust_offset_pre_post on each bb insn.
+       (adjust_stack_reference): Remove.
+       (compute_cfa_pointer): New function.
+       (hard_frame_pointer_adjustment, cfa_base_rtx): New static variables.
+       (struct adjust_mem_data): New type.
+       (adjust_mems, adjust_mem_uses, adjust_mem_stores, adjust_insn): New
+       functions.
+       (get_address_mode): New function.
+       (replace_expr_with_values): Use it.
+       (use_type): Don't do cselib_lookup for VAR_LOC_UNKNOWN_P.
+       Use get_address_mode.  For cfa_base_rtx return MO_CLOBBER.
+       (adjust_sets): Remove.
+       (add_uses): Don't add extra MO_VAL_USE for cfa_base_rtx plus constant.
+       Use get_address_mode.
+       (get_adjusted_src): Remove.
+       (add_stores): Don't call it.  Never reuse expr SET.  Don't add extra
+       MO_VAL_USE for cfa_base_rtx plus constant.  Use get_address_mode.
+       (add_with_sets): Don't call adjust_sets.
+       (fp_setter, vt_init_cfa_base): New functions.
+       (vt_initialize): Change return type to bool.  Move most of pool etc.
+       initialization to the beginning of the function from end.  Pass
+       CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS to cselib_init.
+       If !frame_pointer_needed, call vt_stack_adjustment before mos
+       vector is filled, call vt_init_cfa_base if argp/framep has been
+       eliminated to sp.  If frame_pointer_needed and argp/framep has
+       been eliminated to hard frame pointer, set
+       hard_frame_pointer_adjustment and call vt_init_cfa_base after
+       encountering fp setter in the prologue.  For MO_ADJUST, call
+       log_op_type before pusing the op into mos vector, not afterwards.
+       Call adjust_insn before cselib_process_insn/add_with_sets,
+       call cancel_changes (0) afterwards.
+       (variable_tracking_main_1): Adjust for vt_initialize calling
+       vt_stack_adjustments and returning whether it succeeded or not.
+
 2010-03-15  Aldy Hernandez  <aldyh@redhat.com>
 
        * graphite-sese-to-poly.c (rewrite_cross_bb_scalar_deps): Skip
index b5750a0..f46c5ec 100644 (file)
@@ -567,6 +567,18 @@ cselib_preserved_value_p (cselib_val *v)
   return PRESERVED_VALUE_P (v->val_rtx);
 }
 
+/* Arrange for a REG value to be assumed constant through the whole function,
+   never invalidated and preserved across cselib_reset_table calls.  */
+
+void
+cselib_preserve_cfa_base_value (cselib_val *v)
+{
+  if (cselib_preserve_constants
+      && v->locs
+      && REG_P (v->locs->loc))
+    cfa_base_preserved_val = v;
+}
+
 /* Clean all non-constant expressions in the hash table, but retain
    their values.  */
 
index ce0bd2b..015d628 100644 (file)
@@ -77,7 +77,6 @@ extern void (*cselib_record_sets_hook) (rtx insn, struct cselib_set *sets,
                                        int n_sets);
 
 extern cselib_val *cselib_lookup (rtx, enum machine_mode, int);
-extern cselib_val *cselib_lookup_from_insn (rtx, enum machine_mode, int, rtx);
 extern void cselib_init (int);
 extern void cselib_clear_table (void);
 extern void cselib_finish (void);
@@ -99,5 +98,6 @@ extern unsigned int cselib_get_next_uid (void);
 extern void cselib_preserve_value (cselib_val *);
 extern bool cselib_preserved_value_p (cselib_val *);
 extern void cselib_preserve_only_values (void);
+extern void cselib_preserve_cfa_base_value (cselib_val *);
 
 extern void dump_cselib_table (FILE *);
index 1003554..db71435 100644 (file)
@@ -1,3 +1,8 @@
+2010-03-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/43051
+       * gcc.dg/guality/pr43051-1.c: New test.
+
 2010-03-15  Janis Johnson  <janis187@us.ibm.com>
 
        PR testsuite/43363
index 5e261d6..cec6a80 100644 (file)
@@ -614,29 +614,6 @@ insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
     }
 }
 
-/* Compute stack adjustment in basic block BB.  */
-
-static void
-bb_stack_adjust_offset (basic_block bb)
-{
-  HOST_WIDE_INT offset;
-  unsigned int i;
-  micro_operation *mo;
-
-  offset = VTI (bb)->in.stack_adjust;
-  for (i = 0; VEC_iterate (micro_operation, VTI (bb)->mos, i, mo); i++)
-    {
-      if (mo->type == MO_ADJUST)
-       offset += mo->u.adjust;
-      else if (mo->type != MO_CALL)
-       {
-         if (MEM_P (mo->u.loc))
-           mo->u.loc = adjust_stack_reference (mo->u.loc, -offset);
-       }
-    }
-  VTI (bb)->out.stack_adjust = offset;
-}
-
 /* Compute stack adjustments for all blocks by traversing DFS tree.
    Return true when the adjustments on all incoming edges are consistent.
    Heavily borrowed from pre_and_rev_post_order_compute.  */
@@ -749,65 +726,6 @@ struct adjust_mem_data
   rtx side_effects;
 };
 
-/* Helper for adjust_mems.  Return 1 if *loc is unsuitable for
-   transformation of wider mode arithmetics to narrower mode,
-   -1 if it is suitable and subexpressions shouldn't be
-   traversed and 0 if it is suitable and subexpressions should
-   be traversed.  Called through for_each_rtx.  */
-
-static int
-use_narrower_mode_test (rtx *loc, void *data)
-{
-  rtx subreg = (rtx) data;
-
-  if (CONSTANT_P (*loc))
-    return -1;
-  switch (GET_CODE (*loc))
-    {
-    case REG:
-      if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0))
-       return 1;
-      return -1;
-    case PLUS:
-    case MINUS:
-    case MULT:
-      return 0;
-    case ASHIFT:
-      if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data))
-       return 1;
-      else
-       return -1;
-    default:
-      return 1;
-    }
-}
-
-/* Transform X into narrower mode MODE from wider mode WMODE.  */
-
-static rtx
-use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
-{
-  rtx op0, op1;
-  if (CONSTANT_P (x))
-    return lowpart_subreg (mode, x, wmode);
-  switch (GET_CODE (x))
-    {
-    case REG:
-      return lowpart_subreg (mode, x, wmode);
-    case PLUS:
-    case MINUS:
-    case MULT:
-      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
-      op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
-      return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
-    case ASHIFT:
-      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
-      return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
-    default:
-      gcc_unreachable ();
-    }
-}
-
 /* Helper function for adjusting used MEMs.  */
 
 static rtx
@@ -883,7 +801,7 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
     case POST_MODIFY:
       if (addr == loc)
        addr = XEXP (loc, 0);
-      gcc_assert (amd->mem_mode != VOIDmode);
+      gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
       addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
       amd->side_effects = alloc_EXPR_LIST (0,
                                           gen_rtx_SET (VOIDmode,
@@ -901,36 +819,18 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data)
       amd->store = store_save;
       mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
       if (mem == SUBREG_REG (loc))
-       {
-         tem = loc;
-         goto finish_subreg;
-       }
+       return loc;
       tem = simplify_gen_subreg (GET_MODE (loc), mem,
                                 GET_MODE (SUBREG_REG (loc)),
                                 SUBREG_BYTE (loc));
       if (tem)
-       goto finish_subreg;
+       return tem;
       tem = simplify_gen_subreg (GET_MODE (loc), addr,
                                 GET_MODE (SUBREG_REG (loc)),
                                 SUBREG_BYTE (loc));
-      if (tem == NULL_RTX)
-       tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
-    finish_subreg:
-      if (MAY_HAVE_DEBUG_INSNS
-         && GET_CODE (tem) == SUBREG
-         && (GET_CODE (SUBREG_REG (tem)) == PLUS
-             || GET_CODE (SUBREG_REG (tem)) == MINUS
-             || GET_CODE (SUBREG_REG (tem)) == MULT
-             || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
-         && GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
-         && GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
-         && GET_MODE_SIZE (GET_MODE (tem))
-            < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem)))
-         && subreg_lowpart_p (tem)
-         && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem))
-       return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
-                                 GET_MODE (SUBREG_REG (tem)));
-      return tem;
+      if (tem)
+       return tem;
+      return gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
     default:
       break;
     }
@@ -4874,30 +4774,6 @@ log_op_type (rtx x, basic_block bb, rtx insn,
   fputc ('\n', out);
 }
 
-/* Adjust sets if needed.  Currently this optimizes read-only MEM loads
-   if REG_EQUAL/REG_EQUIV note is present.  */
-
-static void
-adjust_sets (rtx insn, struct cselib_set *sets, int n_sets)
-{
-  if (n_sets == 1 && MEM_P (sets[0].src) && MEM_READONLY_P (sets[0].src))
-    {
-      /* For read-only MEMs containing some constant, prefer those
-        constants.  */
-      rtx note = find_reg_equal_equiv_note (insn), src;
-
-      if (note && CONSTANT_P (XEXP (note, 0)))
-       {
-         sets[0].src = src = XEXP (note, 0);
-         if (GET_CODE (PATTERN (insn)) == COND_EXEC)
-           src = gen_rtx_IF_THEN_ELSE (GET_MODE (sets[0].dest),
-                                       COND_EXEC_TEST (PATTERN (insn)),
-                                       src, sets[0].dest);
-         sets[0].src_elt = cselib_lookup (src, GET_MODE (sets[0].dest), 1);
-       }
-    }
-}
-
 /* Tell whether the CONCAT used to holds a VALUE and its location
    needs value resolution, i.e., an attempt of mapping the location
    back to other incoming values.  */
@@ -5260,6 +5136,7 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
 
   if (REG_P (loc))
     {
+      gcc_assert (loc != cfa_base_rtx);
       if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
          || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
          || GET_CODE (expr) == CLOBBER)
@@ -8138,19 +8015,13 @@ vt_init_cfa_base (void)
 #else
   cfa_base_rtx = arg_pointer_rtx;
 #endif
-  if (cfa_base_rtx == hard_frame_pointer_rtx
-      || !fixed_regs[REGNO (cfa_base_rtx)])
-    {
-      cfa_base_rtx = NULL_RTX;
-      return;
-    }
   if (!MAY_HAVE_DEBUG_INSNS)
     return;
 
-  val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
-                                get_insns ());
+  val = cselib_lookup (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1);
   preserve_value (val);
   cselib_preserve_cfa_base_value (val);
+  val->locs->setting_insn = get_insns ();
   var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx,
                    VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx),
                    0, NULL_RTX, INSERT);
@@ -8298,6 +8169,8 @@ vt_initialize (void)
       /* Add the micro-operations to the vector.  */
       FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
        {
+         HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
+         VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
          for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
               insn = NEXT_INSN (insn))
            {
@@ -8312,9 +8185,6 @@ vt_initialize (void)
                          mo.type = MO_ADJUST;
                          mo.u.adjust = pre;
                          mo.insn = insn;
-                         VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
-                                        &mo);
-
                          if (dump_file && (dump_flags & TDF_DETAILS))
                            log_op_type (PATTERN (insn), bb, insn,
                                         MO_ADJUST, dump_file);
@@ -8345,9 +8215,6 @@ vt_initialize (void)
                      mo.type = MO_ADJUST;
                      mo.u.adjust = post;
                      mo.insn = insn;
-                     VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
-                                    &mo);
-
                      if (dump_file && (dump_flags & TDF_DETAILS))
                        log_op_type (PATTERN (insn), bb, insn,
                                     MO_ADJUST, dump_file);
@@ -8366,6 +8233,7 @@ vt_initialize (void)
                    }
                }
            }
+         gcc_assert (offset == VTI (bb)->out.stack_adjust);
        }
 
       bb = last_bb;