summaryrefslogtreecommitdiff
path: root/gcc/mode-switching.c
diff options
context:
space:
mode:
authorChristian Bruel <christian.bruel@st.com>2014-05-13 10:50:51 +0200
committerChristian Bruel <chrbr@gcc.gnu.org>2014-05-13 10:50:51 +0200
commit06b906021422980e8b9b7aea0509d24e94777a19 (patch)
tree2492f596015f55629c1fed3420c824e3fc566559 /gcc/mode-switching.c
parent455464ab334ad9fad4a1d2513581ecd21fd92c2b (diff)
target.def (mode_switching): New hook vector.
2014-05-13 Christian Bruel <christian.bruel@st.com> * target.def (mode_switching): New hook vector. (mode_emit, mode_needed, mode_after, mode_entry): New hooks. (mode_exit, modepriority_to_mode): Likewise. * mode-switching.c (MODE_NEEDED, MODE_AFTER, MODE_ENTRY): Hookify. (MODE_EXIT, MODE_PRIORITY_TO_MODE, EMIT_MODE_SET): Likewise. (default_priority_to_mode): Define. * targhooks.h (default_priority_to_mode): Declare. * target.h: Include tm.h and hard-reg-set.h. * doc/tm.texi.in (EMIT_MODE_SET, MODE_NEEDED, MODE_AFTER, MODE_ENTRY) (MODE_EXIT, MODE_PRIORITY_TO_MODE): Delete and hookify. * doc/tm.texi Regenerate. * config/sh/sh.h (MODE_NEEDED, MODE_AFTER, MODE_ENTRY): Delete (MODE_EXIT, MODE_PRIORITY_TO_MODE, EMIT_MODE_SET): Likewise. * config/sh/sh.c (sh_emit_mode_set, sh_mode_priority): Hookify. (sh_mode_needed, sh_mode_after, sh_mode_entry, sh_mode_exit): Likewise. * config/i386/i386.h (MODE_NEEDED, MODE_AFTER, MODE_ENTRY): Delete (MODE_EXIT, MODE_PRIORITY_TO_MODE, EMIT_MODE_SET): Likewise. * config/i386/i386-protos.h (ix86_mode_needed, ix86_mode_after) (ix86_mode_entrym, ix86_emit_mode_set): Remove external declaration. * config/i386/i386.c (ix86_mode_needed, ix86_mode_after, ix86_mode_exit, (ix86_mode_entry, ix86_mode_priority, ix86_emit_mode_set): Hookify. * config/epiphany/epiphany.h (MODE_NEEDED, MODE_AFTER, MODE_ENTRY): Delete (MODE_EXIT, MODE_PRIORITY_TO_MODE, EMIT_MODE_SET): Likewise. * config/sh/sh.h (MODE_NEEDED, MODE_AFTER, MODE_ENTRY): Delete (MODE_EXIT, MODE_PRIORITY_TO_MODE, EMIT_MODE_SET): Likewise. * config/sh/sh.c (sh4_emit_mode_set, sh4_mode_needed): Hookify. (sh4_mode_after, sh4_mode_entry, sh4_mode_exit): Likewise. * config/epiphany/epiphany-protos.h (epiphany_mode_needed) (emit_set_fp_mode, epiphany_mode_entry_exit, epiphany_mode_after) (epiphany_mode_priority_to_mode): Remove declaration. * config/epiphany/epiphany.c (emit_set_fp_mode): Hookify. (epiphany_mode_needed, epiphany_mode_priority_to_mode): Likewise. (epiphany_mode_entry, epiphany_mode_exit, epiphany_mode_after): Likewise. (epiphany_mode_priority_to_mode): Change priority type. Hookify. (epiphany_mode_needed, epiphany_mode_entry_exit): Hookify. (epiphany_mode_after, epiphany_mode_entry, emit_set_fp_mode): Hookify. From-SVN: r210354
Diffstat (limited to 'gcc/mode-switching.c')
-rw-r--r--gcc/mode-switching.c112
1 files changed, 57 insertions, 55 deletions
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index 1ae8120ee4d..b70b2e59581 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -195,13 +195,6 @@ reg_becomes_live (rtx reg, const_rtx setter ATTRIBUTE_UNUSED, void *live)
add_to_hard_reg_set ((HARD_REG_SET *) live, GET_MODE (reg), regno);
}
-/* Make sure if MODE_ENTRY is defined the MODE_EXIT is defined
- and vice versa. */
-#if defined (MODE_ENTRY) != defined (MODE_EXIT)
- #error "Both MODE_ENTRY and MODE_EXIT must be defined"
-#endif
-
-#if defined (MODE_ENTRY) && defined (MODE_EXIT)
/* Split the fallthrough edge to the exit block, so that we can note
that there NORMAL_MODE is required. Return the new block if it's
inserted before the exit block. Otherwise return null. */
@@ -349,9 +342,11 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
for (j = n_entities - 1; j >= 0; j--)
{
int e = entity_map[j];
- int mode = MODE_NEEDED (e, return_copy);
+ int mode =
+ targetm.mode_switching.needed (e, return_copy);
- if (mode != num_modes[e] && mode != MODE_EXIT (e))
+ if (mode != num_modes[e]
+ && mode != targetm.mode_switching.exit (e))
break;
}
if (j >= 0)
@@ -450,7 +445,6 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
return pre_exit;
}
-#endif
/* Find all insns that need a particular mode setting, and insert the
necessary mode switches. Return true if we did work. */
@@ -472,7 +466,8 @@ optimize_mode_switching (void)
int n_entities;
int max_num_modes = 0;
bool emitted ATTRIBUTE_UNUSED = false;
- basic_block post_entry ATTRIBUTE_UNUSED, pre_exit ATTRIBUTE_UNUSED;
+ basic_block post_entry = 0;
+ basic_block pre_exit = 0;
for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
if (OPTIMIZE_MODE_SWITCHING (e))
@@ -482,9 +477,9 @@ optimize_mode_switching (void)
/* Create the list of segments within each basic block.
If NORMAL_MODE is defined, allow for two extra
blocks split from the entry and exit block. */
-#if defined (MODE_ENTRY) && defined (MODE_EXIT)
- entry_exit_extra = 3;
-#endif
+ if (targetm.mode_switching.entry && targetm.mode_switching.exit)
+ entry_exit_extra = 3;
+
bb_info[n_entities]
= XCNEWVEC (struct bb_info,
last_basic_block_for_fn (cfun) + entry_exit_extra);
@@ -496,12 +491,17 @@ optimize_mode_switching (void)
if (! n_entities)
return 0;
-#if defined (MODE_ENTRY) && defined (MODE_EXIT)
- /* Split the edge from the entry block, so that we can note that
- there NORMAL_MODE is supplied. */
- post_entry = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
- pre_exit = create_pre_exit (n_entities, entity_map, num_modes);
-#endif
+ /* Make sure if MODE_ENTRY is defined the MODE_EXIT is defined and vice versa. */
+ gcc_assert ((targetm.mode_switching.entry && targetm.mode_switching.exit)
+ || (!targetm.mode_switching.entry && !targetm.mode_switching.exit));
+
+ if (targetm.mode_switching.entry && targetm.mode_switching.exit)
+ {
+ /* Split the edge from the entry block, so that we can note that
+ there NORMAL_MODE is supplied. */
+ post_entry = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+ pre_exit = create_pre_exit (n_entities, entity_map, num_modes);
+ }
df_analyze ();
@@ -556,7 +556,7 @@ optimize_mode_switching (void)
{
if (INSN_P (insn))
{
- int mode = MODE_NEEDED (e, insn);
+ int mode = targetm.mode_switching.needed (e, insn);
rtx link;
if (mode != no_mode && mode != last_mode)
@@ -567,9 +567,10 @@ optimize_mode_switching (void)
add_seginfo (info + bb->index, ptr);
bitmap_clear_bit (transp[bb->index], j);
}
-#ifdef MODE_AFTER
- last_mode = MODE_AFTER (e, last_mode, insn);
-#endif
+
+ if (targetm.mode_switching.after)
+ last_mode = targetm.mode_switching.after (e, last_mode, insn);
+
/* Update LIVE_NOW. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -595,30 +596,30 @@ optimize_mode_switching (void)
bitmap_clear_bit (transp[bb->index], j);
}
}
-#if defined (MODE_ENTRY) && defined (MODE_EXIT)
- {
- int mode = MODE_ENTRY (e);
-
- if (mode != no_mode)
- {
- bb = post_entry;
-
- /* By always making this nontransparent, we save
- an extra check in make_preds_opaque. We also
- need this to avoid confusing pre_edge_lcm when
- antic is cleared but transp and comp are set. */
- bitmap_clear_bit (transp[bb->index], j);
-
- /* Insert a fake computing definition of MODE into entry
- blocks which compute no mode. This represents the mode on
- entry. */
- info[bb->index].computing = mode;
+ if (targetm.mode_switching.entry && targetm.mode_switching.exit)
+ {
+ int mode = targetm.mode_switching.entry (e);
- if (pre_exit)
- info[pre_exit->index].seginfo->mode = MODE_EXIT (e);
- }
- }
-#endif /* NORMAL_MODE */
+ if (mode != no_mode)
+ {
+ bb = post_entry;
+
+ /* By always making this nontransparent, we save
+ an extra check in make_preds_opaque. We also
+ need this to avoid confusing pre_edge_lcm when
+ antic is cleared but transp and comp are set. */
+ bitmap_clear_bit (transp[bb->index], j);
+
+ /* Insert a fake computing definition of MODE into entry
+ blocks which compute no mode. This represents the mode on
+ entry. */
+ info[bb->index].computing = mode;
+
+ if (pre_exit)
+ info[pre_exit->index].seginfo->mode =
+ targetm.mode_switching.exit (e);
+ }
+ }
}
kill = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_entities);
@@ -633,7 +634,8 @@ optimize_mode_switching (void)
bitmap_vector_clear (comp, last_basic_block_for_fn (cfun));
for (j = n_entities - 1; j >= 0; j--)
{
- int m = current_mode[j] = MODE_PRIORITY_TO_MODE (entity_map[j], i);
+ int m = current_mode[j] =
+ targetm.mode_switching.priority (entity_map[j], i);
struct bb_info *info = bb_info[j];
FOR_EACH_BB_FN (bb, cfun)
@@ -688,7 +690,7 @@ optimize_mode_switching (void)
rtl_profile_for_edge (eg);
start_sequence ();
- EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
+ targetm.mode_switching.emit (entity_map[j], mode, live_at_edge);
mode_set = get_insns ();
end_sequence ();
default_rtl_profile ();
@@ -736,7 +738,9 @@ optimize_mode_switching (void)
rtl_profile_for_bb (bb);
start_sequence ();
- EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
+ targetm.mode_switching.emit (entity_map[j],
+ ptr->mode,
+ ptr->regs_live);
mode_set = get_insns ();
end_sequence ();
@@ -777,12 +781,10 @@ optimize_mode_switching (void)
if (need_commit)
commit_edge_insertions ();
-#if defined (MODE_ENTRY) && defined (MODE_EXIT)
- cleanup_cfg (CLEANUP_NO_INSN_DEL);
-#else
- if (!need_commit && !emitted)
+ if (targetm.mode_switching.entry && targetm.mode_switching.exit)
+ cleanup_cfg (CLEANUP_NO_INSN_DEL);
+ else if (!need_commit && !emitted)
return 0;
-#endif
return 1;
}