You should have received a copy of the GNU General Public License
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. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
#include "output.h"
#include "tm_p.h"
#include "function.h"
+#include "tree-pass.h"
+#include "timevar.h"
/* We want target macros for the mode switching code to be able to refer
to instruction attribute values. */
new_seginfo (int mode, rtx insn, int bb, HARD_REG_SET regs_live)
{
struct seginfo *ptr;
- ptr = xmalloc (sizeof (struct seginfo));
+ ptr = XNEW (struct seginfo);
ptr->mode = mode;
ptr->insn_ptr = insn;
ptr->bbnum = bb;
/* Find all insns that need a particular mode setting, and insert the
necessary mode switches. Return true if we did work. */
-int
-optimize_mode_switching (FILE *file)
+static int
+optimize_mode_switching (void)
{
rtx insn;
int e;
entry_exit_extra = 3;
#endif
bb_info[n_entities]
- = xcalloc (last_basic_block + entry_exit_extra, sizeof **bb_info);
+ = XCNEWVEC (struct bb_info, last_basic_block + entry_exit_extra);
entity_map[n_entities++] = e;
if (num_modes[e] > max_num_modes)
max_num_modes = num_modes[e];
REG_SET_TO_HARD_REG_SET (live_now,
bb->il.rtl->global_live_at_start);
+
+ /* Pretend the mode is clobbered across abnormal edges. */
+ {
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->flags & EDGE_COMPLEX)
+ break;
+ if (e)
+ RESET_BIT (transp[bb->index], j);
+ }
+
for (insn = BB_HEAD (bb);
insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
FOR_EACH_BB (bb)
sbitmap_not (kill[bb->index], transp[bb->index]);
- edge_list = pre_edge_lcm (file, n_entities, transp, comp, antic,
+ edge_list = pre_edge_lcm (n_entities, transp, comp, antic,
kill, &insert, &delete);
for (j = n_entities - 1; j >= 0; j--)
return 1;
}
+
+#endif /* OPTIMIZE_MODE_SWITCHING */
+\f
+static bool
+gate_mode_switching (void)
+{
+#ifdef OPTIMIZE_MODE_SWITCHING
+ return true;
+#else
+ return false;
+#endif
+}
+
+static unsigned int
+rest_of_handle_mode_switching (void)
+{
+#ifdef OPTIMIZE_MODE_SWITCHING
+ no_new_pseudos = 0;
+ optimize_mode_switching ();
+ no_new_pseudos = 1;
#endif /* OPTIMIZE_MODE_SWITCHING */
+ return 0;
+}
+
+
+struct tree_opt_pass pass_mode_switching =
+{
+ "mode-sw", /* name */
+ gate_mode_switching, /* gate */
+ rest_of_handle_mode_switching, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_MODE_SWITCH, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func, /* todo_flags_finish */
+ 0 /* letter */
+};