+ NULL, /* Incremental solution verify end. */
+ &problem_LR, /* Dependent problem. */
+ TV_DF_NOTE, /* Timing variable. */
+ false /* Reset blocks on dropping out of blocks_to_analyze. */
+};
+
+
+/* Create a new DATAFLOW instance and add it to an existing instance
+ of DF. The returned structure is what is used to get at the
+ solution. */
+
+void
+df_note_add_problem (void)
+{
+ df_add_problem (&problem_NOTE);
+}
+
+
+
+\f
+/*----------------------------------------------------------------------------
+ Functions for simulating the effects of single insns.
+
+ You can either simulate in the forwards direction, starting from
+ the top of a block or the backwards direction from the end of the
+ block. If you go backwards, defs are examined first to clear bits,
+ then uses are examined to set bits. If you go forwards, defs are
+ examined first to set bits, then REG_DEAD and REG_UNUSED notes
+ are examined to clear bits. In either case, the result of examining
+ a def can be undone (respectively by a use or a REG_UNUSED note).
+
+ If you start at the top of the block, use one of DF_LIVE_IN or
+ DF_LR_IN. If you start at the bottom of the block use one of
+ DF_LIVE_OUT or DF_LR_OUT. BE SURE TO PASS A COPY OF THESE SETS,
+ THEY WILL BE DESTROYED.
+----------------------------------------------------------------------------*/
+
+
+/* Find the set of DEFs for INSN. */
+
+void
+df_simulate_find_defs (rtx insn, bitmap defs)
+{
+ df_ref *def_rec;
+ unsigned int uid = INSN_UID (insn);
+
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ bitmap_set_bit (defs, DF_REF_REGNO (def));
+ }
+}
+
+/* Find the set of real DEFs, which are not clobbers, for INSN. */
+
+void
+df_simulate_find_noclobber_defs (rtx insn, bitmap defs)
+{
+ df_ref *def_rec;
+ unsigned int uid = INSN_UID (insn);
+
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
+ bitmap_set_bit (defs, DF_REF_REGNO (def));
+ }
+}
+
+
+/* Simulate the effects of the defs of INSN on LIVE. */
+
+void
+df_simulate_defs (rtx insn, bitmap live)
+{
+ df_ref *def_rec;
+ unsigned int uid = INSN_UID (insn);
+
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ unsigned int dregno = DF_REF_REGNO (def);
+
+ /* If the def is to only part of the reg, it does
+ not kill the other defs that reach here. */
+ if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+ bitmap_clear_bit (live, dregno);
+ }
+}
+
+
+/* Simulate the effects of the uses of INSN on LIVE. */
+
+void
+df_simulate_uses (rtx insn, bitmap live)
+{
+ df_ref *use_rec;
+ unsigned int uid = INSN_UID (insn);
+
+ if (DEBUG_INSN_P (insn))
+ return;
+
+ for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
+ {
+ df_ref use = *use_rec;
+ /* Add use to set of uses in this BB. */
+ bitmap_set_bit (live, DF_REF_REGNO (use));
+ }
+}
+
+
+/* Add back the always live regs in BB to LIVE. */
+
+static inline void
+df_simulate_fixup_sets (basic_block bb, bitmap live)
+{
+ /* These regs are considered always live so if they end up dying
+ because of some def, we need to bring the back again. */
+ if (bb_has_eh_pred (bb))
+ bitmap_ior_into (live, df->eh_block_artificial_uses);
+ else
+ bitmap_ior_into (live, df->regular_block_artificial_uses);
+}
+
+
+/*----------------------------------------------------------------------------
+ The following three functions are used only for BACKWARDS scanning:
+ i.e. they process the defs before the uses.
+
+ df_simulate_initialize_backwards should be called first with a
+ bitvector copyied from the DF_LIVE_OUT or DF_LR_OUT. Then
+ df_simulate_one_insn_backwards should be called for each insn in
+ the block, starting with the last one. Finally,
+ df_simulate_finalize_backwards can be called to get a new value
+ of the sets at the top of the block (this is rarely used).
+ ----------------------------------------------------------------------------*/
+
+/* Apply the artificial uses and defs at the end of BB in a backwards
+ direction. */
+
+void
+df_simulate_initialize_backwards (basic_block bb, bitmap live)
+{
+ df_ref *def_rec;
+ df_ref *use_rec;
+ int bb_index = bb->index;
+
+ for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+ bitmap_clear_bit (live, DF_REF_REGNO (def));
+ }
+
+ for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
+ {
+ df_ref use = *use_rec;
+ if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
+ bitmap_set_bit (live, DF_REF_REGNO (use));
+ }
+}
+
+
+/* Simulate the backwards effects of INSN on the bitmap LIVE. */
+
+void
+df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live)
+{
+ if (!NONDEBUG_INSN_P (insn))
+ return;
+
+ df_simulate_defs (insn, live);
+ df_simulate_uses (insn, live);
+ df_simulate_fixup_sets (bb, live);
+}
+
+
+/* Apply the artificial uses and defs at the top of BB in a backwards
+ direction. */
+
+void
+df_simulate_finalize_backwards (basic_block bb, bitmap live)
+{
+ df_ref *def_rec;
+#ifdef EH_USES
+ df_ref *use_rec;
+#endif
+ int bb_index = bb->index;
+
+ for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ bitmap_clear_bit (live, DF_REF_REGNO (def));
+ }
+
+#ifdef EH_USES
+ for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
+ {
+ df_ref use = *use_rec;
+ if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
+ bitmap_set_bit (live, DF_REF_REGNO (use));
+ }
+#endif
+}
+/*----------------------------------------------------------------------------
+ The following three functions are used only for FORWARDS scanning:
+ i.e. they process the defs and the REG_DEAD and REG_UNUSED notes.
+ Thus it is important to add the DF_NOTES problem to the stack of
+ problems computed before using these functions.
+
+ df_simulate_initialize_forwards should be called first with a
+ bitvector copyied from the DF_LIVE_IN or DF_LR_IN. Then
+ df_simulate_one_insn_forwards should be called for each insn in
+ the block, starting with the first one.
+ ----------------------------------------------------------------------------*/
+
+/* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or
+ DF_LR_IN for basic block BB, for forward scanning by marking artificial
+ defs live. */
+
+void
+df_simulate_initialize_forwards (basic_block bb, bitmap live)
+{
+ df_ref *def_rec;
+ int bb_index = bb->index;
+
+ for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ bitmap_set_bit (live, DF_REF_REGNO (def));
+ }
+}
+
+/* Simulate the forwards effects of INSN on the bitmap LIVE. */
+
+void
+df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
+{
+ rtx link;
+ if (! INSN_P (insn))
+ return;
+
+ /* Make sure that DF_NOTE really is an active df problem. */
+ gcc_assert (df_note);
+
+ /* Note that this is the opposite as how the problem is defined, because
+ in the LR problem defs _kill_ liveness. However, they do so backwards,
+ while here the scan is performed forwards! So, first assume that the
+ def is live, and if this is not true REG_UNUSED notes will rectify the
+ situation. */
+ df_simulate_find_noclobber_defs (insn, live);
+
+ /* Clear all of the registers that go dead. */
+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+ {
+ switch (REG_NOTE_KIND (link))
+ {
+ case REG_DEAD:
+ case REG_UNUSED:
+ {
+ rtx reg = XEXP (link, 0);
+ int regno = REGNO (reg);
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = hard_regno_nregs[regno][GET_MODE (reg)];
+ while (--n >= 0)
+ bitmap_clear_bit (live, regno + n);
+ }
+ else
+ bitmap_clear_bit (live, regno);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ df_simulate_fixup_sets (bb, live);
+}
+
+
+\f
+/*----------------------------------------------------------------------------
+ MULTIPLE DEFINITIONS
+
+ Find the locations in the function reached by multiple definition sites
+ for a live pseudo. In and out bitvectors are built for each basic
+ block. They are restricted for efficiency to live registers.
+
+ The gen and kill sets for the problem are obvious. Together they
+ include all defined registers in a basic block; the gen set includes
+ registers where a partial or conditional or may-clobber definition is
+ last in the BB, while the kill set includes registers with a complete
+ definition coming last. However, the computation of the dataflow
+ itself is interesting.
+
+ The idea behind it comes from SSA form's iterated dominance frontier
+ criterion for inserting PHI functions. Just like in that case, we can use
+ the dominance frontier to find places where multiple definitions meet;
+ a register X defined in a basic block BB1 has multiple definitions in
+ basic blocks in BB1's dominance frontier.
+
+ So, the in-set of a basic block BB2 is not just the union of the
+ out-sets of BB2's predecessors, but includes some more bits that come
+ from the basic blocks of whose dominance frontier BB2 is part (BB1 in
+ the previous paragraph). I called this set the init-set of BB2.
+
+ (Note: I actually use the kill-set only to build the init-set.
+ gen bits are anyway propagated from BB1 to BB2 by dataflow).
+
+ For example, if you have