152284Sobrien/* Insert USEs in instructions that require mode switching.
2169689Skan   This should probably be merged into mode-switching.cc .
3117395Skan   Copyright (C) 2011-2022 Free Software Foundation, Inc.
452284Sobrien   Contributed by Embecosm on behalf of Adapteva, Inc.
5132718Skan
652284SobrienThis file is part of GCC.
7132718Skan
852284SobrienGCC is free software; you can redistribute it and/or modify
952284Sobrienit under the terms of the GNU General Public License as published by
1052284Sobrienthe Free Software Foundation; either version 3, or (at your option)
1152284Sobrienany later version.
12132718Skan
1352284SobrienGCC is distributed in the hope that it will be useful,
1452284Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1552284SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1652284SobrienGNU General Public License for more details.
1752284Sobrien
18132718SkanYou should have received a copy of the GNU General Public License
19169689Skanalong with GCC; see the file COPYING3.  If not see
20169689Skan<http://www.gnu.org/licenses/>.  */
2152284Sobrien
2290075Sobrien#define IN_TARGET_CODE 1
23117395Skan
2490075Sobrien#include "config.h"
2590075Sobrien#include "system.h"
2652284Sobrien#include "coretypes.h"
2752284Sobrien#include "backend.h"
28117395Skan#include "rtl.h"
2952284Sobrien#include "df.h"
3052284Sobrien#include "memmodel.h"
3152284Sobrien#include "tm_p.h"
3252284Sobrien#include "emit-rtl.h"
3390075Sobrien#include "tree-pass.h"
3490075Sobrien#include "insn-attr.h"
3590075Sobrien
3690075Sobrien#ifndef TARGET_INSERT_MODE_SWITCH_USE
3790075Sobrien#define TARGET_INSERT_MODE_SWITCH_USE NULL
3890075Sobrien#endif
3990075Sobrien
4090075Sobrienstatic unsigned int
4190075Sobrieninsert_uses (void)
4290075Sobrien{
4390075Sobrien  static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
4490075Sobrien#define N_ENTITIES ARRAY_SIZE (num_modes)
4590075Sobrien  int e;
4690075Sobrien  void (*target_insert_mode_switch_use) (rtx_insn *insn, int, int)
4790075Sobrien    = TARGET_INSERT_MODE_SWITCH_USE;
4890075Sobrien
4990075Sobrien  for (e = N_ENTITIES - 1; e >= 0; e--)
5090075Sobrien    {
5152284Sobrien      int no_mode = num_modes[e];
5252284Sobrien      rtx_insn *insn;
5390075Sobrien      int mode;
5452284Sobrien
5552284Sobrien      if (!OPTIMIZE_MODE_SWITCHING (e))
5690075Sobrien	continue;
5790075Sobrien      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
5890075Sobrien	{
5952284Sobrien	  if (!INSN_P (insn))
60132718Skan	    continue;
6190075Sobrien	  mode = epiphany_mode_needed (e, insn);
62132718Skan	  if (mode == no_mode)
6390075Sobrien	    continue;
6490075Sobrien	  if (target_insert_mode_switch_use)
6590075Sobrien	    {
6690075Sobrien	      target_insert_mode_switch_use (insn, e, mode);
6790075Sobrien	      df_insn_rescan (insn);
6890075Sobrien	    }
6990075Sobrien	}
7090075Sobrien    }
7190075Sobrien  return 0;
7290075Sobrien}
7390075Sobrien
7490075Sobriennamespace {
7590075Sobrien
7652284Sobrienconst pass_data pass_data_mode_switch_use =
7752284Sobrien{
7852284Sobrien  RTL_PASS, /* type */
7952284Sobrien  "mode_switch_use", /* name */
8052284Sobrien  OPTGROUP_NONE, /* optinfo_flags */
81117395Skan  TV_NONE, /* tv_id */
82117395Skan  0, /* properties_required */
83117395Skan  0, /* properties_provided */
84117395Skan  0, /* properties_destroyed */
85117395Skan  0, /* todo_flags_start */
86117395Skan  0, /* todo_flags_finish */
87117395Skan};
88117395Skan
8952284Sobrienclass pass_mode_switch_use : public rtl_opt_pass
9090075Sobrien{
9190075Sobrienpublic:
92117395Skan  pass_mode_switch_use(gcc::context *ctxt)
9390075Sobrien    : rtl_opt_pass(pass_data_mode_switch_use, ctxt)
9490075Sobrien  {}
9552284Sobrien
9652284Sobrien  /* opt_pass methods: */
9752284Sobrien  virtual unsigned int execute (function *) { return insert_uses (); }
9852284Sobrien
9952284Sobrien}; // class pass_mode_switch_use
10052284Sobrien
10152284Sobrien} // anon namespace
10252284Sobrien
10352284Sobrienrtl_opt_pass *
10452284Sobrienmake_pass_mode_switch_use (gcc::context *ctxt)
10552284Sobrien{
10652284Sobrien  return new pass_mode_switch_use (ctxt);
10752284Sobrien}
10852284Sobrien