Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 341743
Collapse All | Expand All

(-)rtlanal.c (+27 lines)
Lines 1941-1946 remove_reg_equal_equiv_notes (rtx insn) Link Here
1941
    }
1941
    }
1942
}
1942
}
1943
1943
1944
/* Remove all REG_EQUAL and REG_EQUIV notes referring to REGNO.  */
1945
1946
void
1947
remove_reg_equal_equiv_notes_for_regno (unsigned int regno)
1948
{
1949
  df_ref eq_use;
1950
1951
  if (!df)
1952
    return;
1953
1954
  /* This loop is a little tricky.  We cannot just go down the chain because
1955
     it is being modified by some actions in the loop.  So we just iterate
1956
     over the head.  We plan to drain the list anyway.  */
1957
  while ((eq_use = DF_REG_EQ_USE_CHAIN (regno)) != NULL)
1958
    {
1959
      rtx insn = DF_REF_INSN (eq_use);
1960
      rtx note = find_reg_equal_equiv_note (insn);
1961
1962
      /* This assert is generally triggered when someone deletes a REG_EQUAL
1963
        or REG_EQUIV note by hacking the list manually rather than calling
1964
        remove_note.  */
1965
      gcc_assert (note);
1966
1967
      remove_note (insn, note);
1968
    }
1969
}
1970
1944
/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
1971
/* Search LISTP (an EXPR_LIST) for an entry whose first operand is NODE and
1945
   return 1 if it is found.  A simple equality test is used to determine if
1972
   return 1 if it is found.  A simple equality test is used to determine if
1946
   NODE matches.  */
1973
   NODE matches.  */
(-)df-scan.c (-3 / +5 lines)
Lines 445-451 df_scan_start_dump (FILE *file ATTRIBUTE Link Here
445
         }
445
         }
446
       if (DF_REG_EQ_USE_COUNT (i))
446
       if (DF_REG_EQ_USE_COUNT (i))
447
         {
447
         {
448
           fprintf (file, "%s%dd", sep, DF_REG_EQ_USE_COUNT (i));
448
           fprintf (file, "%s%de", sep, DF_REG_EQ_USE_COUNT (i));
449
           ecount += DF_REG_EQ_USE_COUNT (i);
449
           ecount += DF_REG_EQ_USE_COUNT (i);
450
         }
450
         }
451
       fprintf (file, "} ");
451
       fprintf (file, "} ");
Lines 461-468 df_scan_start_dump (FILE *file ATTRIBUTE Link Here
461
           icount++;
461
           icount++;
462
       }
462
       }
463
463
464
  fprintf (file, "\n;;    total ref usage %d{%dd,%du,%de} in %d{%d regular + %d call} insns.\n",
464
  fprintf (file, "\n;;    total ref usage %d{%dd,%du,%de}"
465
          dcount + ucount + ecount, dcount, ucount, ecount, icount + ccount, icount, ccount);
465
                " in %d{%d regular + %d call} insns.\n",
466
                dcount + ucount + ecount, dcount, ucount, ecount,
467
                icount + ccount, icount, ccount);
466
}
468
}
467
469
468
/* Dump the bb_info for a given basic block. */
470
/* Dump the bb_info for a given basic block. */
(-)df-core.c (-8 / +13 lines)
Lines 2051-2056 df_dump_bottom (basic_block bb, FILE *fi Link Here
2051
}
2051
}
2052
2052
2053
2053
2054
static void
2055
df_ref_dump (df_ref ref, FILE *file)
2056
{
2057
  fprintf (file, "%c%d(%d)",
2058
          DF_REF_REG_DEF_P (ref)
2059
          ? 'd'
2060
          : (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
2061
          DF_REF_ID (ref),
2062
          DF_REF_REGNO (ref));
2063
}
2064
2054
void
2065
void
2055
df_refs_chain_dump (df_ref *ref_rec, bool follow_chain, FILE *file)
2066
df_refs_chain_dump (df_ref *ref_rec, bool follow_chain, FILE *file)
2056
{
2067
{
Lines 2058-2067 df_refs_chain_dump (df_ref *ref_rec, boo Link Here
2058
  while (*ref_rec)
2069
  while (*ref_rec)
2059
    {
2070
    {
2060
      df_ref ref = *ref_rec;
2071
      df_ref ref = *ref_rec;
2061
      fprintf (file, "%c%d(%d)",
2072
      df_ref_dump (ref, file);
2062
              DF_REF_REG_DEF_P (ref) ? 'd' : (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
2063
              DF_REF_ID (ref),
2064
              DF_REF_REGNO (ref));
2065
      if (follow_chain)
2073
      if (follow_chain)
2066
       df_chain_dump (DF_REF_CHAIN (ref), file);
2074
       df_chain_dump (DF_REF_CHAIN (ref), file);
2067
      ref_rec++;
2075
      ref_rec++;
Lines 2078-2087 df_regs_chain_dump (df_ref ref, FILE *f Link Here
2078
  fprintf (file, "{ ");
2086
  fprintf (file, "{ ");
2079
  while (ref)
2087
  while (ref)
2080
    {
2088
    {
2081
      fprintf (file, "%c%d(%d) ",
2089
      df_ref_dump (ref, file);
2082
              DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
2083
              DF_REF_ID (ref),
2084
              DF_REF_REGNO (ref));
2085
      ref = DF_REF_NEXT_REG (ref);
2090
      ref = DF_REF_NEXT_REG (ref);
2086
    }
2091
    }
2087
  fprintf (file, "}");
2092
  fprintf (file, "}");
(-)ifcvt.c (-19 / +38 lines)
Lines 3998-4003 dead_or_predicable (basic_block test_bb, Link Here
3998
                   basic_block other_bb, basic_block new_dest, int reversep)
3998
                   basic_block other_bb, basic_block new_dest, int reversep)
3999
{
3999
{
4000
  rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
4000
  rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
4001
  bitmap merge_set = NULL, merge_set_noclobber = NULL;
4001
  /* Number of pending changes.  */
4002
  /* Number of pending changes.  */
4002
  int n_validated_changes = 0;
4003
  int n_validated_changes = 0;
4003
4004
Lines 4086-4091 dead_or_predicable (basic_block test_bb, Link Here
4086
      earliest = jump;
4087
      earliest = jump;
4087
    }
4088
    }
4088
#endif
4089
#endif
4090
4089
  /* Try the NCE path if the CE path did not result in any changes.  */
4091
  /* Try the NCE path if the CE path did not result in any changes.  */
4090
  if (n_validated_changes == 0)
4092
  if (n_validated_changes == 0)
4091
    {
4093
    {
Lines 4094-4102 dead_or_predicable (basic_block test_bb, Link Here
4094
        that any registers modified are dead at the branch site.  */
4096
        that any registers modified are dead at the branch site.  */
4095
4097
4096
      rtx insn, cond, prev;
4098
      rtx insn, cond, prev;
4097
      bitmap merge_set, merge_set_noclobber, test_live, test_set;
4099
      bitmap test_live, test_set;
4098
      unsigned i, fail = 0;
4100
      bool intersect = false;
4099
      bitmap_iterator bi;
4100
4101
4101
      /* Check for no calls or trapping operations.  */
4102
      /* Check for no calls or trapping operations.  */
4102
      for (insn = head; ; insn = NEXT_INSN (insn))
4103
      for (insn = head; ; insn = NEXT_INSN (insn))
Lines 4138-4149 dead_or_predicable (basic_block test_bb, Link Here
4138
4139
4139
      merge_set = BITMAP_ALLOC (&reg_obstack);
4140
      merge_set = BITMAP_ALLOC (&reg_obstack);
4140
      merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
4141
      merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
4141
      test_live = BITMAP_ALLOC (&reg_obstack);
4142
      test_set = BITMAP_ALLOC (&reg_obstack);
4143
4142
4144
      /* ??? bb->local_set is only valid during calculate_global_regs_live,
4145
        so we must recompute usage for MERGE_BB.  Not so bad, I suppose,
4146
         since we've already asserted that MERGE_BB is small.  */
4147
      /* If we allocated new pseudos (e.g. in the conditional move
4143
      /* If we allocated new pseudos (e.g. in the conditional move
4148
        expander called from noce_emit_cmove), we must resize the
4144
        expander called from noce_emit_cmove), we must resize the
4149
        array first.  */
4145
        array first.  */
Lines 4164-4180 dead_or_predicable (basic_block test_bb, Link Here
4164
      if (! reload_completed
4160
      if (! reload_completed
4165
         && targetm.small_register_classes_for_mode_p (VOIDmode))
4161
         && targetm.small_register_classes_for_mode_p (VOIDmode))
4166
       {
4162
       {
4163
         unsigned i;
4164
         bitmap_iterator bi;
4165
4167
          EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
4166
          EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
4168
           {
4167
           {
4169
             if (i < FIRST_PSEUDO_REGISTER
4168
             if (i < FIRST_PSEUDO_REGISTER
4170
                 && ! fixed_regs[i]
4169
                 && ! fixed_regs[i]
4171
                 && ! global_regs[i])
4170
                 && ! global_regs[i])
4172
               fail = 1;
4171
               goto fail;
4173
           }
4172
           }
4174
       }
4173
       }
4175
4174
4176
      /* For TEST, we're interested in a range of insns, not a whole block.
4175
      /* For TEST, we're interested in a range of insns, not a whole block.
4177
        Moreover, we're interested in the insns live from OTHER_BB.  */
4176
        Moreover, we're interested in the insns live from OTHER_BB.  */
4177
      test_live = BITMAP_ALLOC (&reg_obstack);
4178
      test_set = BITMAP_ALLOC (&reg_obstack);
4178
4179
4179
      /* The loop below takes the set of live registers
4180
      /* The loop below takes the set of live registers
4180
         after JUMP, and calculates the live set before EARLIEST. */
4181
         after JUMP, and calculates the live set before EARLIEST. */
Lines 4195-4217 dead_or_predicable (basic_block test_bb, Link Here
4195
      /* We can perform the transformation if
4196
      /* We can perform the transformation if
4196
          MERGE_SET_NOCLOBBER & TEST_SET
4197
          MERGE_SET_NOCLOBBER & TEST_SET
4197
        and
4198
        and
4198
          MERGE_SET & TEST_LIVE)
4199
          MERGE_SET & TEST_LIVE
4199
        and
4200
        and
4200
          TEST_SET & DF_LIVE_IN (merge_bb)
4201
          TEST_SET & DF_LIVE_IN (merge_bb)
4201
        are empty.  */
4202
        are empty.  */
4202
4203
4203
      if (bitmap_intersect_p (test_set, merge_set_noclobber)
4204
      if (bitmap_intersect_p (merge_set_noclobber, test_set)
4204
         || bitmap_intersect_p (test_live, merge_set)
4205
         || bitmap_intersect_p (merge_set, test_live)
4205
         || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
4206
         || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
4206
       fail = 1;
4207
       intersect = true;
4207
4208
4208
      BITMAP_FREE (merge_set_noclobber);
4209
      BITMAP_FREE (merge_set);
4210
      BITMAP_FREE (test_live);
4209
      BITMAP_FREE (test_live);
4211
      BITMAP_FREE (test_set);
4210
      BITMAP_FREE (test_set);
4212
4211
4213
      if (fail)
4212
      if (intersect)
4214
       return FALSE;
4213
       goto fail;
4215
    }
4214
    }
4216
4215
4217
 no_body:
4216
 no_body:
Lines 4261-4268 dead_or_predicable (basic_block test_bb, Link Here
4261
      if (end == BB_END (merge_bb))
4260
      if (end == BB_END (merge_bb))
4262
       BB_END (merge_bb) = PREV_INSN (head);
4261
       BB_END (merge_bb) = PREV_INSN (head);
4263
4262
4264
      /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
4263
      /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
4265
        notes might become invalid.  */
4264
        notes being moved might become invalid.  */
4266
      insn = head;
4265
      insn = head;
4267
      do
4266
      do
4268
       {
4267
       {
Lines 4279-4284 dead_or_predicable (basic_block test_bb, Link Here
4279
           remove_note (insn, note);
4278
           remove_note (insn, note);
4280
       } while (insn != end && (insn = NEXT_INSN (insn)));
4279
       } while (insn != end && (insn = NEXT_INSN (insn)));
4281
4280
4281
      /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
4282
        notes referring to the registers being set might become invalid.  */
4283
      if (merge_set)
4284
       {
4285
         unsigned i;
4286
         bitmap_iterator bi;
4287
4288
         EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
4289
           remove_reg_equal_equiv_notes_for_regno (i);
4290
4291
         BITMAP_FREE (merge_set);
4292
         BITMAP_FREE (merge_set_noclobber);
4293
       }
4294
4282
      reorder_insns (head, end, PREV_INSN (earliest));
4295
      reorder_insns (head, end, PREV_INSN (earliest));
4283
    }
4296
    }
4284
4297
Lines 4295-4300 dead_or_predicable (basic_block test_bb, Link Here
4295
4308
4296
 cancel:
4309
 cancel:
4297
  cancel_changes (0);
4310
  cancel_changes (0);
4311
 fail:
4312
  if (merge_set)
4313
    {
4314
      BITMAP_FREE (merge_set);
4315
      BITMAP_FREE (merge_set_noclobber);
4316
    }
4298
  return FALSE;
4317
  return FALSE;
4299
}
4318
}
4300
4319
(-)rtl.h (+1 lines)
Lines 1892-1897 extern rtx alloc_reg_note (enum reg_note Link Here
1892
extern void add_reg_note (rtx, enum reg_note, rtx);
1892
extern void add_reg_note (rtx, enum reg_note, rtx);
1893
extern void remove_note (rtx, const_rtx);
1893
extern void remove_note (rtx, const_rtx);
1894
extern void remove_reg_equal_equiv_notes (rtx);
1894
extern void remove_reg_equal_equiv_notes (rtx);
1895
extern void remove_reg_equal_equiv_notes_for_regno (unsigned int);
1895
extern int side_effects_p (const_rtx);
1896
extern int side_effects_p (const_rtx);
1896
extern int volatile_refs_p (const_rtx);
1897
extern int volatile_refs_p (const_rtx);
1897
extern int volatile_insn_p (const_rtx);
1898
extern int volatile_insn_p (const_rtx);
(-)df-problems.c (-2 / +5 lines)
Lines 109-118 df_chain_dump (struct df_link *link, FIL Link Here
109
  for (; link; link = link->next)
109
  for (; link; link = link->next)
110
    {
110
    {
111
      fprintf (file, "%c%d(bb %d insn %d) ",
111
      fprintf (file, "%c%d(bb %d insn %d) ",
112
              DF_REF_REG_DEF_P (link->ref) ? 'd' : 'u',
112
              DF_REF_REG_DEF_P (link->ref)
113
              ? 'd'
114
              : (DF_REF_FLAGS (link->ref) & DF_REF_IN_NOTE) ? 'e' : 'u',
113
              DF_REF_ID (link->ref),
115
              DF_REF_ID (link->ref),
114
              DF_REF_BBNO (link->ref),
116
              DF_REF_BBNO (link->ref),
115
              DF_REF_IS_ARTIFICIAL (link->ref) ? -1 : DF_REF_INSN_UID (link->ref));
117
              DF_REF_IS_ARTIFICIAL (link->ref)
118
              ? -1 : DF_REF_INSN_UID (link->ref));
116
    }
119
    }
117
  fprintf (file, "}");
120
  fprintf (file, "}");
118
}
121
}
(-)dce.c (-27 / +7 lines)
Lines 466-501 find_call_stack_args (rtx call_insn, boo Link Here
466
}
466
}
467
467
468
468
469
/* Delete all REG_EQUAL notes of the registers INSN writes, to prevent
469
/* Remove all REG_EQUAL and REG_EQUIV notes referring to the registers INSN
470
   bad dangling REG_EQUAL notes. */
470
   writes to.  */
471
471
472
static void
472
static void
473
delete_corresponding_reg_eq_notes (rtx insn)
473
remove_reg_equal_equiv_notes_for_defs (rtx insn)
474
{
474
{
475
  df_ref *def_rec;
475
  df_ref *def_rec;
476
476
  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
477
  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
477
    {
478
    remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (*def_rec));
478
      df_ref def = *def_rec;
479
      unsigned int regno = DF_REF_REGNO (def);
480
      /* This loop is a little tricky.  We cannot just go down the
481
        chain because it is being modified by the actions in the
482
        loop.  So we just get the head.  We plan to drain the list
483
        anyway.  */
484
      while (DF_REG_EQ_USE_CHAIN (regno))
485
       {
486
         df_ref eq_use = DF_REG_EQ_USE_CHAIN (regno);
487
         rtx noted_insn = DF_REF_INSN (eq_use);
488
         rtx note = find_reg_note (noted_insn, REG_EQUAL, NULL_RTX);
489
         if (!note)
490
           note = find_reg_note (noted_insn, REG_EQUIV, NULL_RTX);
491
492
         /* This assert is generally triggered when someone deletes a
493
            REG_EQUAL or REG_EQUIV note by hacking the list manually
494
            rather than calling remove_note.  */
495
         gcc_assert (note);
496
         remove_note (noted_insn, note);
497
       }
498
    }
499
}
479
}
500
480
501
481
Lines 544-552 delete_unmarked_insns (void) Link Here
544
         if (dump_file)
524
         if (dump_file)
545
           fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
525
           fprintf (dump_file, "DCE: Deleting insn %d\n", INSN_UID (insn));
546
526
547
         /* Before we delete the insn we have to delete REG_EQUAL notes
527
         /* Before we delete the insn we have to remove the REG_EQUAL notes
548
            for the destination regs in order to avoid dangling notes.  */
528
            for the destination regs in order to avoid dangling notes.  */
549
         delete_corresponding_reg_eq_notes (insn);
529
         remove_reg_equal_equiv_notes_for_defs (insn);
550
530
551
         /* If a pure or const call is deleted, this may make the cfg
531
         /* If a pure or const call is deleted, this may make the cfg
552
            have unreachable blocks.  We rememeber this and call
532
            have unreachable blocks.  We rememeber this and call
553
 int n = 0;
533
 int n = 0;
554
 char const *lim = s + digits;
534
 char const *lim = s + digits;
555
 while (s < lim)
535
 while (s < lim)
556
   {
536
   {
557
     unsigned d = *s++ - '0';
537
     unsigned d = *s++ - '0';
558
     if (9 < d)
538
     if (9 < d)
559
       return 0;
539
       return 0;
560
     n = 10 * n + d;
540
     n = 10 * n + d;
561
   }
541
   }
562
 return s && 0 <= n && n <= 59 ? s : 0;
542
 return s && 0 <= n && n <= 59 ? s : 0;
563
 const char *s = "10092240";
543
 const char *s = "10092240";
564
 s = parse_ranged (s, 2);
544
 s = parse_ranged (s, 2);
565
 s = parse_ranged (s, 2);
545
 s = parse_ranged (s, 2);
566
 s = parse_ranged (s, 2);
546
 s = parse_ranged (s, 2);
567
 s = parse_ranged (s, 2);
547
 s = parse_ranged (s, 2);
568
 if (!s || *s != '\0')
548
 if (!s || *s != '\0')
569
   abort();
549
   abort();
570
 return 0;
550
 return 0;

Return to bug 341743