From 06b906021422980e8b9b7aea0509d24e94777a19 Mon Sep 17 00:00:00 2001 From: Christian Bruel Date: Tue, 13 May 2014 10:50:51 +0200 Subject: target.def (mode_switching): New hook vector. 2014-05-13 Christian Bruel * 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 --- gcc/mode-switching.c | 112 ++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 55 deletions(-) (limited to 'gcc/mode-switching.c') 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; } -- cgit v1.2.3