Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz,
mhayes@redhat.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
OVERVIEW:
static void df_bb_refs_record PARAMS((struct df *, basic_block));
static void df_refs_record PARAMS((struct df *, bitmap));
-static int df_visit_next PARAMS ((struct df *, sbitmap));
+static int df_visit_next_rc PARAMS ((struct df *, sbitmap));
+static int df_visit_next_rts PARAMS ((struct df *, sbitmap));
static void df_bb_reg_def_chain_create PARAMS((struct df *, basic_block));
static void df_reg_def_chain_create PARAMS((struct df *, bitmap));
static void df_bb_reg_use_chain_create PARAMS((struct df *, basic_block));
for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
df_uses_record (df, &ASM_OPERANDS_INPUT (x, j),
DF_REF_REG_USE, bb, insn);
+ return;
}
break;
}
/* Catch the def of the register being modified. */
df_ref_record (df, XEXP (x, 0), &XEXP (x, 0), bb, insn, DF_REF_REG_DEF);
- /* ... Fall through to handle uses ... */
+ /* ... Fall through to handle uses ... */
default:
break;
if (df->flags & DF_HARD_REGS)
{
- /* Each call clobbers all call-clobbered regs that are not
- global or fixed and have not been explicitly defined
- in the call pattern. */
+ /* Kill all registers invalidated by a call. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i]
- && ! global_regs[i]
- && ! fixed_regs[i]
- && ! df_insn_regno_def_p (df, bb, insn, i))
+ if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
{
rtx reg_clob = df_reg_clobber_gen (i);
df_defs_record (df, reg_clob, bb, insn);
}
\f
-/* Use depth first order, and the worklist, to figure out what block
- to look at next. */
+/* Use reverse completion order, and the worklist, to figure out what block
+ to look at next. */
static int
-df_visit_next (df, blocks)
+df_visit_next_rc (df, blocks)
struct df *df ATTRIBUTE_UNUSED;
sbitmap blocks;
{
return sbitmap_first_set_bit (blocks);
}
+/* Use reverse topsort order, and the worklist, to figure out what block
+ to look at next. */
+
+static int
+df_visit_next_rts (df, blocks)
+ struct df *df ATTRIBUTE_UNUSED;
+ sbitmap blocks;
+{
+ int i=0;
+ for (i = 0; i < n_basic_blocks; i++)
+ if (TEST_BIT (blocks, df->rts_order[i]))
+ return df->rts_order[i];
+ return sbitmap_first_set_bit (blocks);
+}
+
+
/* Calculate reaching defs for each basic block in BLOCKS, i.e., the
defs that are live at the start of a basic block. */
static void
bitmap_copy (bb_info->rd_out, bb_info->rd_gen);
});
- while ((i = df_visit_next (df, worklist)) >= 0)
+ while ((i = df_visit_next_rc (df, worklist)) >= 0)
{
struct bb_info *bb_info;
edge e;
if (e->dest == EXIT_BLOCK_PTR)
continue;
- SET_BIT (worklist, i);
+ SET_BIT (worklist, e->dest->index);
}
}
}
});
- while ((i = df_visit_next (df, worklist)) >= 0)
+ while ((i = df_visit_next_rts (df, worklist)) >= 0)
{
struct bb_info *bb_info;
edge e;
if (e->src == ENTRY_BLOCK_PTR)
continue;
- SET_BIT (worklist, i);
+ SET_BIT (worklist, e->src->index);
}
}
}
df->dfs_order = xmalloc (sizeof(int) * n_basic_blocks);
df->rc_order = xmalloc (sizeof(int) * n_basic_blocks);
+ df->rts_order = xmalloc (sizeof(int) * n_basic_blocks);
flow_depth_first_order_compute (df->dfs_order, df->rc_order);
-
+ flow_reverse_top_sort_order_compute (df->rts_order);
if (aflags & DF_RD)
{
/* Compute the sets of gens and kills for the defs of each bb. */
}
free (df->dfs_order);
free (df->rc_order);
+ free (df->rts_order);
}
uid = INSN_UID (insn);
+ if (uid >= df->insn_size)
+ df_insn_table_realloc (df, 0);
+
bitmap_set_bit (df->bbs_modified, bb->index);
bitmap_set_bit (df->insns_modified, uid);
it does, we need to create a new basic block. Ouch. The
same applies for a label. */
if ((GET_CODE (insn) == CALL_INSN
- && ! CONST_CALL_P (insn))
+ && ! CONST_OR_PURE_CALL_P (insn))
|| GET_CODE (insn) == CODE_LABEL)
abort ();