+2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ * df-problems.c: Include regs.h and function-abi.h.
+ (df_rd_problem_data): Rename sparse_invalidated_by_call to
+ sparse_invalidated_by_eh and dense_invalidated_by_call to
+ dense_invalidated_by_eh.
+ (df_print_bb_index): Update accordingly.
+ (df_rd_alloc, df_rd_start_dump, df_rd_confluence_n): Likewise.
+ (df_lr_confluence_n): Use eh_edge_abi to get the set of registers
+ that are clobbered by an EH edge. Clobber partially-clobbered
+ registers as well as fully-clobbered ones.
+ (df_md_confluence_n): Likewise.
+ (df_rd_local_compute): Likewise. Update for changes to
+ df_rd_problem_data.
+ * df-scan.c (df_scan_start_dump): Use eh_edge_abi to get the set
+ of registers that are clobbered by an EH edge. Includde partially-
+ clobbered registers as well as fully-clobbered ones.
+
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
* cselib.c (cselib_process_insn): If we know what mode a
#include "valtrack.h"
#include "dumpfile.h"
#include "rtl-iter.h"
+#include "regs.h"
+#include "function-abi.h"
/* Note that turning REG_DEAD_DEBUGGING on will cause
gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints
these along with the bitmap_clear_range call to remove ranges of
bits without actually generating a knockout vector.
- The kill and sparse_kill and the dense_invalidated_by_call and
- sparse_invalidated_by_call both play this game. */
+ The kill and sparse_kill and the dense_invalidated_by_eh and
+ sparse_invalidated_by_eh both play this game. */
/* Private data used to compute the solution for this problem. These
data structures are not accessible outside of this module. */
class df_rd_problem_data
{
public:
- /* The set of defs to regs invalidated by call. */
- bitmap_head sparse_invalidated_by_call;
- /* The set of defs to regs invalidate by call for rd. */
- bitmap_head dense_invalidated_by_call;
+ /* The set of defs to regs invalidated by EH edges. */
+ bitmap_head sparse_invalidated_by_eh;
+ bitmap_head dense_invalidated_by_eh;
/* An obstack for the bitmaps we need for this problem. */
bitmap_obstack rd_bitmaps;
};
if (df_rd->problem_data)
{
problem_data = (class df_rd_problem_data *) df_rd->problem_data;
- bitmap_clear (&problem_data->sparse_invalidated_by_call);
- bitmap_clear (&problem_data->dense_invalidated_by_call);
+ bitmap_clear (&problem_data->sparse_invalidated_by_eh);
+ bitmap_clear (&problem_data->dense_invalidated_by_eh);
}
else
{
df_rd->problem_data = problem_data;
bitmap_obstack_initialize (&problem_data->rd_bitmaps);
- bitmap_initialize (&problem_data->sparse_invalidated_by_call,
+ bitmap_initialize (&problem_data->sparse_invalidated_by_eh,
&problem_data->rd_bitmaps);
- bitmap_initialize (&problem_data->dense_invalidated_by_call,
+ bitmap_initialize (&problem_data->dense_invalidated_by_eh,
&problem_data->rd_bitmaps);
}
bitmap_iterator bi;
class df_rd_problem_data *problem_data
= (class df_rd_problem_data *) df_rd->problem_data;
- bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
- bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
+ bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_eh;
+ bitmap dense_invalidated = &problem_data->dense_invalidated_by_eh;
bitmap_initialize (&seen_in_block, &df_bitmap_obstack);
bitmap_initialize (&seen_in_insn, &df_bitmap_obstack);
df_rd_bb_local_compute (bb_index);
}
- /* Set up the knockout bit vectors to be applied across EH_EDGES. */
+ /* Set up the knockout bit vectors to be applied across EH_EDGES.
+ Conservatively treat partially-clobbered registers as surviving
+ across the EH edge, i.e. assume that definitions before the edge
+ is taken *might* reach uses after it has been taken. */
if (!(df->changeable_flags & DF_NO_HARD_REGS))
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
- if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+ if (eh_edge_abi.clobbers_full_reg_p (regno))
{
if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
bitmap_set_bit (sparse_invalidated, regno);
{
class df_rd_problem_data *problem_data
= (class df_rd_problem_data *) df_rd->problem_data;
- bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
- bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
+ bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_eh;
+ bitmap dense_invalidated = &problem_data->dense_invalidated_by_eh;
bitmap_iterator bi;
unsigned int regno;
fprintf (file, ";; Reaching defs:\n");
fprintf (file, ";; sparse invalidated \t");
- dump_bitmap (file, &problem_data->sparse_invalidated_by_call);
+ dump_bitmap (file, &problem_data->sparse_invalidated_by_eh);
fprintf (file, ";; dense invalidated \t");
- dump_bitmap (file, &problem_data->dense_invalidated_by_call);
+ dump_bitmap (file, &problem_data->dense_invalidated_by_eh);
fprintf (file, ";; reg->defs[] map:\t");
for (regno = 0; regno < m; regno++)
bitmap op2 = &df_lr_get_bb_info (e->dest->index)->in;
bool changed = false;
- /* Call-clobbered registers die across exception and call edges. */
+ /* Call-clobbered registers die across exception and call edges.
+ Conservatively treat partially-clobbered registers as surviving
+ across the edges; they might or might not, depending on what
+ mode they have. */
/* ??? Abnormal call edges ignored for the moment, as this gets
confused by sibling call edges, which crashes reg-stack. */
if (e->flags & EDGE_EH)
{
- bitmap_view<HARD_REG_SET> eh_kills (regs_invalidated_by_call);
+ bitmap_view<HARD_REG_SET> eh_kills (eh_edge_abi.full_reg_clobbers ());
changed = bitmap_ior_and_compl_into (op1, op2, eh_kills);
}
else
if (e->flags & EDGE_EH)
{
- bitmap_view<HARD_REG_SET> eh_kills (regs_invalidated_by_call);
+ /* Conservatively treat partially-clobbered registers as surviving
+ across the edge; they might or might not, depending on what mode
+ they have. */
+ bitmap_view<HARD_REG_SET> eh_kills (eh_edge_abi.full_reg_clobbers ());
return bitmap_ior_and_compl_into (op1, op2, eh_kills);
}
else