/* Standard problems for dataflow support routines.
- Copyright (C) 1999-2014 Free Software Foundation, Inc.
+ Copyright (C) 1999-2015 Free Software Foundation, Inc.
Originally contributed by Michael P. Hayes
(m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
#include "tm_p.h"
#include "insn-config.h"
#include "recog.h"
+#include "hard-reg-set.h"
#include "function.h"
#include "regs.h"
#include "alloc-pool.h"
#include "flags.h"
-#include "hard-reg-set.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfganal.h"
#include "basic-block.h"
#include "sbitmap.h"
#include "bitmap.h"
#include "dce.h"
#include "valtrack.h"
#include "dumpfile.h"
+#include "rtl-iter.h"
/* Note that turning REG_DEAD_DEBUGGING on will cause
gcc.c-torture/unsorted/dump-noaddr.c to fail because it prints
LOCAL_RD. */
void
-df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn,
+df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
bitmap local_rd)
{
df_ref def;
reference of the frame pointer. */
bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM);
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
/* Pseudos with argument area equivalences may require
reloading via the argument pointer. */
- if (fixed_regs[ARG_POINTER_REGNUM])
+ if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ && fixed_regs[ARG_POINTER_REGNUM])
bitmap_set_bit (&df->hardware_regs_used, ARG_POINTER_REGNUM);
-#endif
/* Any constant, or pseudo with constant equivalences, may
require reloading from memory using the pic register. */
df_chain_create (df_ref src, df_ref dst)
{
struct df_link *head = DF_REF_CHAIN (src);
- struct df_link *link = (struct df_link *) pool_alloc (df_chain->block_pool);
+ struct df_link *link = df_chain->block_pool->allocate ();
DF_REF_CHAIN (src) = link;
link->next = head;
prev->next = chain->next;
else
DF_REF_CHAIN (ref) = chain->next;
- pool_free (df_chain->block_pool, chain);
+ df_chain->block_pool->remove (chain);
return;
}
prev = chain;
struct df_link *next = chain->next;
/* Delete the other side if it exists. */
df_chain_unlink_1 (chain->ref, ref);
- pool_free (df_chain->block_pool, chain);
+ df_chain->block_pool->remove (chain);
chain = next;
}
DF_REF_CHAIN (ref) = NULL;
/* Wholesale destruction of the old chains. */
if (df_chain->block_pool)
- free_alloc_pool (df_chain->block_pool);
+ delete df_chain->block_pool;
EXECUTE_IF_SET_IN_BITMAP (df_chain->out_of_date_transfer_functions, 0, bb_index, bi)
{
df_chain_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
{
df_chain_remove_problem ();
- df_chain->block_pool = create_alloc_pool ("df_chain_block pool",
- sizeof (struct df_link), 50);
+ df_chain->block_pool = new pool_allocator<df_link> ("df_chain_block pool",
+ 50);
df_chain->optional_p = true;
}
static void
df_chain_free (void)
{
- free_alloc_pool (df_chain->block_pool);
+ delete df_chain->block_pool;
BITMAP_FREE (df_chain->out_of_date_transfer_functions);
free (df_chain);
}
}
static void
-df_chain_insn_top_dump (const_rtx insn, FILE *file)
+df_chain_insn_top_dump (const rtx_insn *insn, FILE *file)
{
if (df_chain_problem_p (DF_UD_CHAIN) && INSN_P (insn))
{
}
static void
-df_chain_insn_bottom_dump (const_rtx insn, FILE *file)
+df_chain_insn_bottom_dump (const rtx_insn *insn, FILE *file)
{
if (df_chain_problem_p (DF_DU_CHAIN) && INSN_P (insn))
{
{
rtx orig_reg = DF_REF_REG (ref);
rtx reg = orig_reg;
- enum machine_mode reg_mode;
+ machine_mode reg_mode;
unsigned regno;
/* Left at -1 for whole accesses. */
int which_subword = -1;
an insn. */
bool
-df_word_lr_simulate_defs (rtx insn, bitmap live)
+df_word_lr_simulate_defs (rtx_insn *insn, bitmap live)
{
bool changed = false;
df_ref def;
/* Simulate the effects of the uses of INSN on LIVE. */
void
-df_word_lr_simulate_uses (rtx insn, bitmap live)
+df_word_lr_simulate_uses (rtx_insn *insn, bitmap live)
{
df_ref use;
/* This is only used if REG_DEAD_DEBUGGING is in effect. */
static void
-df_print_note (const char *prefix, rtx insn, rtx note)
+df_print_note (const char *prefix, rtx_insn *insn, rtx note)
{
if (dump_file)
{
/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN. */
static void
-df_remove_dead_and_unused_notes (rtx insn)
+df_remove_dead_and_unused_notes (rtx_insn *insn)
{
rtx *pprev = ®_NOTES (insn);
rtx link = *pprev;
/* Set a NOTE_TYPE note for REG in INSN. */
static inline void
-df_set_note (enum reg_note note_type, rtx insn, rtx reg)
+df_set_note (enum reg_note note_type, rtx_insn *insn, rtx reg)
{
gcc_checking_assert (!DEBUG_INSN_P (insn));
add_reg_note (insn, note_type, reg);
*/
static void
-df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+df_set_unused_notes_for_mw (rtx_insn *insn, struct df_mw_hardreg *mws,
bitmap live, bitmap do_not_gen,
bitmap artificial_uses,
struct dead_debug_local *debug)
register. */
static void
-df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+df_set_dead_notes_for_mw (rtx_insn *insn, struct df_mw_hardreg *mws,
bitmap live, bitmap do_not_gen,
bitmap artificial_uses, bool *added_notes_p)
{
LIVE. Do not generate notes for registers in ARTIFICIAL_USES. */
static void
-df_create_unused_note (rtx insn, df_ref def,
+df_create_unused_note (rtx_insn *insn, df_ref def,
bitmap live, bitmap artificial_uses,
struct dead_debug_local *debug)
{
/* Find the set of DEFs for INSN. */
void
-df_simulate_find_defs (rtx insn, bitmap defs)
+df_simulate_find_defs (rtx_insn *insn, bitmap defs)
{
df_ref def;
/* Find the set of uses for INSN. This includes partial defs. */
static void
-df_simulate_find_uses (rtx insn, bitmap uses)
+df_simulate_find_uses (rtx_insn *insn, bitmap uses)
{
df_ref def, use;
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
/* Find the set of real DEFs, which are not clobbers, for INSN. */
void
-df_simulate_find_noclobber_defs (rtx insn, bitmap defs)
+df_simulate_find_noclobber_defs (rtx_insn *insn, bitmap defs)
{
df_ref def;
/* Simulate the effects of the defs of INSN on LIVE. */
void
-df_simulate_defs (rtx insn, bitmap live)
+df_simulate_defs (rtx_insn *insn, bitmap live)
{
df_ref def;
/* Simulate the effects of the uses of INSN on LIVE. */
void
-df_simulate_uses (rtx insn, bitmap live)
+df_simulate_uses (rtx_insn *insn, bitmap live)
{
df_ref use;
/* Simulate the backwards effects of INSN on the bitmap LIVE. */
void
-df_simulate_one_insn_backwards (basic_block bb, rtx insn, bitmap live)
+df_simulate_one_insn_backwards (basic_block bb, rtx_insn *insn, bitmap live)
{
if (!NONDEBUG_INSN_P (insn))
return;
/* Simulate the forwards effects of INSN on the bitmap LIVE. */
void
-df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
+df_simulate_one_insn_forwards (basic_block bb, rtx_insn *insn, bitmap live)
{
rtx link;
if (! INSN_P (insn))
case REG_UNUSED:
{
rtx reg = XEXP (link, 0);
- int regno = REGNO (reg);
- if (HARD_REGISTER_NUM_P (regno))
- bitmap_clear_range (live, regno,
- hard_regno_nregs[regno][GET_MODE (reg)]);
- else
- bitmap_clear_bit (live, regno);
+ bitmap_clear_range (live, REGNO (reg), REG_NREGS (reg));
}
break;
default:
#define MEMREF_NORMAL 1
#define MEMREF_VOLATILE 2
-/* A subroutine of can_move_insns_across_p called through for_each_rtx.
- Return either MEMREF_NORMAL or MEMREF_VOLATILE if a memory is found. */
+/* Return an OR of MEMREF_NORMAL or MEMREF_VOLATILE for the MEMs in X. */
static int
-find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
+find_memory (rtx_insn *insn)
{
- rtx x = *px;
-
- if (GET_CODE (x) == ASM_OPERANDS && MEM_VOLATILE_P (x))
- return MEMREF_VOLATILE;
-
- if (!MEM_P (x))
- return 0;
- if (MEM_VOLATILE_P (x))
- return MEMREF_VOLATILE;
- if (MEM_READONLY_P (x))
- return 0;
-
- return MEMREF_NORMAL;
+ int flags = 0;
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+ {
+ const_rtx x = *iter;
+ if (GET_CODE (x) == ASM_OPERANDS && MEM_VOLATILE_P (x))
+ flags |= MEMREF_VOLATILE;
+ else if (MEM_P (x))
+ {
+ if (MEM_VOLATILE_P (x))
+ flags |= MEMREF_VOLATILE;
+ else if (!MEM_READONLY_P (x))
+ flags |= MEMREF_NORMAL;
+ }
+ }
+ return flags;
}
/* A subroutine of can_move_insns_across_p called through note_stores.
{
if (volatile_insn_p (PATTERN (insn)))
return false;
- memrefs_in_across |= for_each_rtx (&PATTERN (insn), find_memory,
- NULL);
+ memrefs_in_across |= find_memory (insn);
note_stores (PATTERN (insn), find_memory_stores,
&mem_sets_in_across);
/* This is used just to find sets of the stack pointer. */
int mem_ref_flags = 0;
int mem_set_flags = 0;
note_stores (PATTERN (insn), find_memory_stores, &mem_set_flags);
- mem_ref_flags = for_each_rtx (&PATTERN (insn), find_memory,
- NULL);
+ mem_ref_flags = find_memory (insn);
/* Catch sets of the stack pointer. */
mem_ref_flags |= mem_set_flags;
if (bitmap_intersect_p (merge_set, test_use)
|| bitmap_intersect_p (merge_use, test_set))
break;
-#ifdef HAVE_cc0
- if (!sets_cc0_p (insn))
-#endif
+ if (!HAVE_cc0 || !sets_cc0_p (insn))
max_to = insn;
}
next = NEXT_INSN (insn);
if (NONDEBUG_INSN_P (insn))
{
if (!bitmap_intersect_p (test_set, local_merge_live)
-#ifdef HAVE_cc0
- && !sets_cc0_p (insn)
-#endif
- )
+ && (!HAVE_cc0 || !sets_cc0_p (insn)))
{
max_to = insn;
break;
LOCAL_MD. */
void
-df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx insn,
+df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
bitmap local_md)
{
df_ref def;