+ max_regno = max_reg_num ();
+ allocate_reg_info (max_regno, FALSE, FALSE);
+
+ /* Reset all the data we'll collect. */
+ for (i = 0; i < max_regno; i++)
+ {
+ REG_N_SETS (i) = DF_REG_DEF_COUNT (df, i);
+ REG_N_REFS (i) = DF_REG_USE_COUNT (df, i) + REG_N_SETS (i);
+ REG_N_DEATHS (i) = 0;
+ REG_N_CALLS_CROSSED (i) = 0;
+ REG_N_THROWING_CALLS_CROSSED (i) = 0;
+ REG_LIVE_LENGTH (i) = 0;
+ REG_FREQ (i) = 0;
+ REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
+ }
+ }
+}
+
+
+/* After reg-stack, the x86 floating point stack regs are difficult to
+ analyze because of all of the pushes, pops and rotations. Thus, we
+ just leave the notes alone. */
+
+static inline bool
+df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
+{
+#ifdef STACK_REGS
+ return (regstack_completed
+ && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
+#else
+ return false;
+#endif
+}
+
+
+/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN. */
+
+static void
+df_kill_notes (rtx insn, int flags)
+{
+ rtx *pprev = ®_NOTES (insn);
+ rtx link = *pprev;
+
+ while (link)
+ {
+ switch (REG_NOTE_KIND (link))
+ {
+ case REG_DEAD:
+ if (flags & DF_RI_LIFE)
+ if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+ REG_N_DEATHS (REGNO (XEXP (link, 0)))++;
+
+ /* Fallthru */
+ case REG_UNUSED:
+ if (!df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+ {
+ rtx next = XEXP (link, 1);
+#ifdef REG_DEAD_DEBUGGING
+ print_note ("deleting: ", insn, link);
+#endif
+ free_EXPR_LIST_node (link);
+ *pprev = link = next;
+ }
+ break;
+
+ default:
+ pprev = &XEXP (link, 1);
+ link = *pprev;
+ break;
+ }
+ }
+}
+
+
+/* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
+ based on the bits in LIVE. Do not generate notes for registers in
+ artificial uses. DO_NOT_GEN is updated so that REG_DEAD notes are
+ not generated if the reg is both read and written by the
+ instruction.
+*/
+
+static void
+df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+ bitmap live, bitmap do_not_gen,
+ bitmap artificial_uses, int flags)
+{
+ bool all_dead = true;
+ struct df_link *regs = mws->regs;
+ unsigned int regno = DF_REF_REGNO (regs->ref);
+
+#ifdef REG_DEAD_DEBUGGING
+ fprintf (stderr, "mw unused looking at %d\n", DF_REF_REGNO (regs->ref));
+ df_ref_debug (regs->ref, stderr);
+#endif
+ while (regs)
+ {
+ unsigned int regno = DF_REF_REGNO (regs->ref);
+ if ((bitmap_bit_p (live, regno))
+ || bitmap_bit_p (artificial_uses, regno))
+ {
+ all_dead = false;
+ break;
+ }
+ regs = regs->next;
+ }
+
+ if (all_dead)
+ {
+ struct df_link *regs = mws->regs;
+ rtx note = alloc_EXPR_LIST (REG_UNUSED, *DF_REF_LOC (regs->ref),
+ REG_NOTES (insn));
+ REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+ print_note ("adding 1: ", insn, note);
+#endif
+ bitmap_set_bit (do_not_gen, regno);
+ /* Only do this if the value is totally dead. */
+ if (flags & DF_RI_LIFE)
+ {
+ REG_N_DEATHS (regno) ++;
+ REG_LIVE_LENGTH (regno)++;
+ }
+ }
+ else
+ {
+ struct df_link *regs = mws->regs;
+ while (regs)
+ {
+ struct df_ref *ref = regs->ref;
+
+ regno = DF_REF_REGNO (ref);
+ if ((!bitmap_bit_p (live, regno))
+ && (!bitmap_bit_p (artificial_uses, regno)))
+ {
+ rtx note = alloc_EXPR_LIST (REG_UNUSED, regno_reg_rtx[regno],
+ REG_NOTES (insn));
+ REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+ print_note ("adding 2: ", insn, note);
+#endif
+ }
+ bitmap_set_bit (do_not_gen, regno);
+ regs = regs->next;
+ }
+ }
+}
+
+
+/* Set the REG_DEAD notes for the multiword hardreg use in INSN based
+ on the bits in LIVE. DO_NOT_GEN is used to keep REG_DEAD notes
+ from being set if the instruction both reads and writes the
+ register. */
+
+static void
+df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+ bitmap live, bitmap do_not_gen,
+ bitmap artificial_uses, int flags)
+{
+ bool all_dead = true;
+ struct df_link *regs = mws->regs;
+ unsigned int regno = DF_REF_REGNO (regs->ref);
+
+#ifdef REG_DEAD_DEBUGGING
+ fprintf (stderr, "mw looking at %d\n", DF_REF_REGNO (regs->ref));
+ df_ref_debug (regs->ref, stderr);
+#endif
+ while (regs)
+ {
+ unsigned int regno = DF_REF_REGNO (regs->ref);
+ if ((bitmap_bit_p (live, regno))
+ || bitmap_bit_p (artificial_uses, regno))
+ {
+ all_dead = false;
+ break;
+ }
+ regs = regs->next;
+ }
+
+ if (all_dead)
+ {
+ if (!bitmap_bit_p (do_not_gen, regno))
+ {
+ /* Add a dead note for the entire multi word register. */
+ struct df_link *regs = mws->regs;
+ rtx note = alloc_EXPR_LIST (REG_DEAD, *DF_REF_LOC (regs->ref),
+ REG_NOTES (insn));
+ REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+ print_note ("adding 1: ", insn, note);
+#endif
+
+ if (flags & DF_RI_LIFE)
+ {
+ struct df_link *regs = mws->regs;
+ while (regs)
+ {
+ struct df_ref *ref = regs->ref;
+ regno = DF_REF_REGNO (ref);
+ REG_N_DEATHS (regno)++;
+ regs = regs->next;
+ }
+ }
+ }
+ }
+ else
+ {
+ struct df_link *regs = mws->regs;
+ while (regs)
+ {
+ struct df_ref *ref = regs->ref;
+
+ regno = DF_REF_REGNO (ref);
+ if ((!bitmap_bit_p (live, regno))
+ && (!bitmap_bit_p (artificial_uses, regno))
+ && (!bitmap_bit_p (do_not_gen, regno)))
+ {
+ rtx note = alloc_EXPR_LIST (REG_DEAD, regno_reg_rtx[regno],
+ REG_NOTES (insn));
+ REG_NOTES (insn) = note;
+ if (flags & DF_RI_LIFE)
+ REG_N_DEATHS (regno)++;
+#ifdef REG_DEAD_DEBUGGING
+ print_note ("adding 2: ", insn, note);
+#endif
+ }
+
+ regs = regs->next;
+ }