re PR debug/47624 (FAIL: gcc.dg/guality/pr43077-1.c -O1 line 42 c == 3)
authorAlexandre Oliva <aoliva@redhat.com>
Wed, 13 Jun 2012 21:43:19 +0000 (21:43 +0000)
committerAlexandre Oliva <aoliva@gcc.gnu.org>
Wed, 13 Jun 2012 21:43:19 +0000 (21:43 +0000)
PR debug/47624
* var-tracking.c (loc_exp_dep_pool): New.
(vt_emit_notes): Create and release the pool.
(compute_bb_dataflow): Use value-based locations in MO_VAL_SET.
(emit_notes_in_bb): Likewise.
(loc_exp_dep_insert): Deal with NOT_ONEPART vars.
(notify_dependents_of_changed_value): Likewise.
(notify_dependents_of_resolved_value): Check that NOT_ONEPART
variables don't have a VAR_LOC_DEP_LST.
(emit_note_insn_var_location): Expand NOT_ONEPART locs that are
VALUEs or MEMs of VALUEs.

From-SVN: r188530

gcc/ChangeLog
gcc/var-tracking.c

index c17e7ad511ee6b7643e7a0e5cfb18cedcf9b3961..d07a9008f176eb7118a33a666c44fb427377f8c8 100644 (file)
@@ -1,3 +1,17 @@
+2012-06-13  Alexandre Oliva  <aoliva@redhat.com>
+
+       PR debug/47624
+       * var-tracking.c (loc_exp_dep_pool): New.
+       (vt_emit_notes): Create and release the pool.
+       (compute_bb_dataflow): Use value-based locations in MO_VAL_SET.
+       (emit_notes_in_bb): Likewise.
+       (loc_exp_dep_insert): Deal with NOT_ONEPART vars.
+       (notify_dependents_of_changed_value): Likewise.
+       (notify_dependents_of_resolved_value): Check that NOT_ONEPART
+       variables don't have a VAR_LOC_DEP_LST.
+       (emit_note_insn_var_location): Expand NOT_ONEPART locs that are
+       VALUEs or MEMs of VALUEs.
+
 2012-06-13  Alexandre Oliva  <aoliva@redhat.com>
 
        PR debug/52983
index 07cabe7930520ec30bac7820efaf4cb08a87483a..e001df0ab4d5bbf92644da01ed3344cc5a6d3417 100644 (file)
@@ -473,6 +473,9 @@ static alloc_pool loc_chain_pool;
 /* Alloc pool for struct shared_hash_def.  */
 static alloc_pool shared_hash_pool;
 
+/* Alloc pool for struct loc_exp_dep_s for NOT_ONEPART variables.  */
+static alloc_pool loc_exp_dep_pool;
+
 /* Changed variables, notes will be emitted for them.  */
 static htab_t changed_variables;
 
@@ -6273,29 +6276,41 @@ compute_bb_dataflow (basic_block bb)
            {
              rtx loc = mo->u.loc;
              rtx val, vloc, uloc;
+             rtx dstv, srcv;
 
              vloc = loc;
              uloc = XEXP (vloc, 1);
              val = XEXP (vloc, 0);
              vloc = uloc;
 
+             if (GET_CODE (uloc) == SET)
+               {
+                 dstv = SET_DEST (uloc);
+                 srcv = SET_SRC (uloc);
+               }
+             else
+               {
+                 dstv = uloc;
+                 srcv = NULL;
+               }
+
              if (GET_CODE (val) == CONCAT)
                {
-                 vloc = XEXP (val, 1);
+                 dstv = vloc = XEXP (val, 1);
                  val = XEXP (val, 0);
                }
 
              if (GET_CODE (vloc) == SET)
                {
-                 rtx vsrc = SET_SRC (vloc);
+                 srcv = SET_SRC (vloc);
 
-                 gcc_assert (val != vsrc);
+                 gcc_assert (val != srcv);
                  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
 
-                 vloc = SET_DEST (vloc);
+                 dstv = vloc = SET_DEST (vloc);
 
                  if (VAL_NEEDS_RESOLUTION (loc))
-                   val_resolve (out, val, vsrc, insn);
+                   val_resolve (out, val, srcv, insn);
                }
              else if (VAL_NEEDS_RESOLUTION (loc))
                {
@@ -6311,45 +6326,53 @@ compute_bb_dataflow (basic_block bb)
                      if (REG_P (uloc))
                        var_reg_delete (out, uloc, true);
                      else if (MEM_P (uloc))
-                       var_mem_delete (out, uloc, true);
+                       {
+                         gcc_assert (MEM_P (dstv));
+                         gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
+                         var_mem_delete (out, dstv, true);
+                       }
                    }
                  else
                    {
                      bool copied_p = VAL_EXPR_IS_COPIED (loc);
-                     rtx set_src = NULL;
+                     rtx src = NULL, dst = uloc;
                      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
 
                      if (GET_CODE (uloc) == SET)
                        {
-                         set_src = SET_SRC (uloc);
-                         uloc = SET_DEST (uloc);
+                         src = SET_SRC (uloc);
+                         dst = SET_DEST (uloc);
                        }
 
                      if (copied_p)
                        {
                          if (flag_var_tracking_uninit)
                            {
-                             status = find_src_status (in, set_src);
+                             status = find_src_status (in, src);
 
                              if (status == VAR_INIT_STATUS_UNKNOWN)
-                               status = find_src_status (out, set_src);
+                               status = find_src_status (out, src);
                            }
 
-                         set_src = find_src_set_src (in, set_src);
+                         src = find_src_set_src (in, src);
                        }
 
-                     if (REG_P (uloc))
-                       var_reg_delete_and_set (out, uloc, !copied_p,
-                                               status, set_src);
-                     else if (MEM_P (uloc))
-                       var_mem_delete_and_set (out, uloc, !copied_p,
-                                               status, set_src);
+                     if (REG_P (dst))
+                       var_reg_delete_and_set (out, dst, !copied_p,
+                                               status, srcv);
+                     else if (MEM_P (dst))
+                       {
+                         gcc_assert (MEM_P (dstv));
+                         gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
+                         var_mem_delete_and_set (out, dstv, !copied_p,
+                                                 status, srcv);
+                       }
                    }
                }
              else if (REG_P (uloc))
                var_regno_delete (out, REGNO (uloc));
 
-             val_store (out, val, vloc, insn, true);
+             val_store (out, val, dstv, insn, true);
            }
            break;
 
@@ -7591,8 +7614,13 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars)
   if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
     return;
 
-  VEC_quick_push (loc_exp_dep, VAR_LOC_DEP_VEC (var), NULL);
-  led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
+  if (var->onepart == NOT_ONEPART)
+    led = (loc_exp_dep *) pool_alloc (loc_exp_dep_pool);
+  else
+    {
+      VEC_quick_push (loc_exp_dep, VAR_LOC_DEP_VEC (var), NULL);
+      led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
+    }
   led->dv = var->dv;
   led->value = x;
 
@@ -7668,8 +7696,12 @@ notify_dependents_of_resolved_value (variable ivar, htab_t vars)
 
          gcc_checking_assert (dv_changed_p (dv));
        }
-      else if (!dv_changed_p (dv))
-       continue;
+      else
+       {
+         gcc_checking_assert (dv_onepart_p (dv) != NOT_ONEPART);
+         if (!dv_changed_p (dv))
+           continue;
+      }
 
       var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
 
@@ -8124,11 +8156,23 @@ emit_note_insn_var_location (void **varp, void *data)
          else if (last_limit > VAR_PART_OFFSET (var, i))
            continue;
          offset = VAR_PART_OFFSET (var, i);
-         if (!var->var_part[i].cur_loc)
+         loc2 = var->var_part[i].cur_loc;
+         if (loc2 && GET_CODE (loc2) == MEM
+             && GET_CODE (XEXP (loc2, 0)) == VALUE)
+           {
+             rtx depval = XEXP (loc2, 0);
+
+             loc2 = vt_expand_loc (loc2, vars);
+
+             if (loc2)
+               loc_exp_insert_dep (var, depval, vars);
+           }
+         if (!loc2)
            {
              complete = false;
              continue;
            }
+         gcc_checking_assert (GET_CODE (loc2) != VALUE);
          for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
            if (var->var_part[i].cur_loc == lc->loc)
              {
@@ -8136,7 +8180,6 @@ emit_note_insn_var_location (void **varp, void *data)
                break;
              }
          gcc_assert (lc);
-         loc2 = var->var_part[i].cur_loc;
        }
 
       offsets[n_var_parts] = offset;
@@ -8350,7 +8393,6 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
   while ((led = VAR_LOC_DEP_LST (var)))
     {
       decl_or_value ldv = led->dv;
-      void **islot;
       variable ivar;
 
       /* Deactivate and remove the backlink, as it was “used up”.  It
@@ -8375,13 +8417,34 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
          VEC_safe_push (rtx, stack, *changed_values_stack, dv_as_rtx (ldv));
          break;
 
-       default:
-         islot = htab_find_slot_with_hash (htab, ldv, dv_htab_hash (ldv),
-                                           NO_INSERT);
-         ivar = (variable) *islot;
+       case ONEPART_VDECL:
+         ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
          gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
          variable_was_changed (ivar, NULL);
          break;
+
+       case NOT_ONEPART:
+         pool_free (loc_exp_dep_pool, led);
+         ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
+         if (ivar)
+           {
+             int i = ivar->n_var_parts;
+             while (i--)
+               {
+                 rtx loc = ivar->var_part[i].cur_loc;
+
+                 if (loc && GET_CODE (loc) == MEM
+                     && XEXP (loc, 0) == val)
+                   {
+                     variable_was_changed (ivar, NULL);
+                     break;
+                   }
+               }
+           }
+         break;
+
+       default:
+         gcc_unreachable ();
        }
     }
 }
@@ -8718,29 +8781,41 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
            {
              rtx loc = mo->u.loc;
              rtx val, vloc, uloc;
+             rtx dstv, srcv;
 
              vloc = loc;
              uloc = XEXP (vloc, 1);
              val = XEXP (vloc, 0);
              vloc = uloc;
 
+             if (GET_CODE (uloc) == SET)
+               {
+                 dstv = SET_DEST (uloc);
+                 srcv = SET_SRC (uloc);
+               }
+             else
+               {
+                 dstv = uloc;
+                 srcv = NULL;
+               }
+
              if (GET_CODE (val) == CONCAT)
                {
-                 vloc = XEXP (val, 1);
+                 dstv = vloc = XEXP (val, 1);
                  val = XEXP (val, 0);
                }
 
              if (GET_CODE (vloc) == SET)
                {
-                 rtx vsrc = SET_SRC (vloc);
+                 srcv = SET_SRC (vloc);
 
-                 gcc_assert (val != vsrc);
+                 gcc_assert (val != srcv);
                  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
 
-                 vloc = SET_DEST (vloc);
+                 dstv = vloc = SET_DEST (vloc);
 
                  if (VAL_NEEDS_RESOLUTION (loc))
-                   val_resolve (set, val, vsrc, insn);
+                   val_resolve (set, val, srcv, insn);
                }
              else if (VAL_NEEDS_RESOLUTION (loc))
                {
@@ -8756,39 +8831,47 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
                      if (REG_P (uloc))
                        var_reg_delete (set, uloc, true);
                      else if (MEM_P (uloc))
-                       var_mem_delete (set, uloc, true);
+                       {
+                         gcc_assert (MEM_P (dstv));
+                         gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (uloc));
+                         var_mem_delete (set, dstv, true);
+                       }
                    }
                  else
                    {
                      bool copied_p = VAL_EXPR_IS_COPIED (loc);
-                     rtx set_src = NULL;
+                     rtx src = NULL, dst = uloc;
                      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
 
                      if (GET_CODE (uloc) == SET)
                        {
-                         set_src = SET_SRC (uloc);
-                         uloc = SET_DEST (uloc);
+                         src = SET_SRC (uloc);
+                         dst = SET_DEST (uloc);
                        }
 
                      if (copied_p)
                        {
-                         status = find_src_status (set, set_src);
+                         status = find_src_status (set, src);
 
-                         set_src = find_src_set_src (set, set_src);
+                         src = find_src_set_src (set, src);
                        }
 
-                     if (REG_P (uloc))
-                       var_reg_delete_and_set (set, uloc, !copied_p,
-                                               status, set_src);
-                     else if (MEM_P (uloc))
-                       var_mem_delete_and_set (set, uloc, !copied_p,
-                                               status, set_src);
+                     if (REG_P (dst))
+                       var_reg_delete_and_set (set, dst, !copied_p,
+                                               status, srcv);
+                     else if (MEM_P (dst))
+                       {
+                         gcc_assert (MEM_P (dstv));
+                         gcc_assert (MEM_ATTRS (dstv) == MEM_ATTRS (dst));
+                         var_mem_delete_and_set (set, dstv, !copied_p,
+                                                 status, srcv);
+                       }
                    }
                }
              else if (REG_P (uloc))
                var_regno_delete (set, REGNO (uloc));
 
-             val_store (set, val, vloc, insn, true);
+             val_store (set, val, dstv, insn, true);
 
              emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
                                      set->vars);
@@ -8897,9 +8980,13 @@ vt_emit_notes (void)
   emit_notes = true;
 
   if (MAY_HAVE_DEBUG_INSNS)
-    dropped_values = htab_create (cselib_get_next_uid () * 2,
-                                 variable_htab_hash, variable_htab_eq,
-                                 variable_htab_free);
+    {
+      dropped_values = htab_create (cselib_get_next_uid () * 2,
+                                   variable_htab_hash, variable_htab_eq,
+                                   variable_htab_free);
+      loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool",
+                                           sizeof (loc_exp_dep), 64);
+    }
 
   dataflow_set_init (&cur);
 
@@ -8924,7 +9011,11 @@ vt_emit_notes (void)
   dataflow_set_destroy (&cur);
 
   if (MAY_HAVE_DEBUG_INSNS)
-    htab_delete (dropped_values);
+    {
+      free_alloc_pool (loc_exp_dep_pool);
+      loc_exp_dep_pool = NULL;
+      htab_delete (dropped_values);
+    }
 
   emit_notes = false;
 }