xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/epiphany/mode-switch-use.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
1 /* Insert USEs in instructions that require mode switching.
2    This should probably be merged into mode-switching.c .
3    Copyright (C) 2011-2020 Free Software Foundation, Inc.
4    Contributed by Embecosm on behalf of Adapteva, Inc.
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12 
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #define IN_TARGET_CODE 1
23 
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "backend.h"
28 #include "rtl.h"
29 #include "df.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "emit-rtl.h"
33 #include "tree-pass.h"
34 #include "insn-attr.h"
35 
36 #ifndef TARGET_INSERT_MODE_SWITCH_USE
37 #define TARGET_INSERT_MODE_SWITCH_USE NULL
38 #endif
39 
40 static unsigned int
insert_uses(void)41 insert_uses (void)
42 {
43   static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
44 #define N_ENTITIES ARRAY_SIZE (num_modes)
45   int e;
46   void (*target_insert_mode_switch_use) (rtx_insn *insn, int, int)
47     = TARGET_INSERT_MODE_SWITCH_USE;
48 
49   for (e = N_ENTITIES - 1; e >= 0; e--)
50     {
51       int no_mode = num_modes[e];
52       rtx_insn *insn;
53       int mode;
54 
55       if (!OPTIMIZE_MODE_SWITCHING (e))
56 	continue;
57       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
58 	{
59 	  if (!INSN_P (insn))
60 	    continue;
61 	  mode = epiphany_mode_needed (e, insn);
62 	  if (mode == no_mode)
63 	    continue;
64 	  if (target_insert_mode_switch_use)
65 	    {
66 	      target_insert_mode_switch_use (insn, e, mode);
67 	      df_insn_rescan (insn);
68 	    }
69 	}
70     }
71   return 0;
72 }
73 
74 namespace {
75 
76 const pass_data pass_data_mode_switch_use =
77 {
78   RTL_PASS, /* type */
79   "mode_switch_use", /* name */
80   OPTGROUP_NONE, /* optinfo_flags */
81   TV_NONE, /* tv_id */
82   0, /* properties_required */
83   0, /* properties_provided */
84   0, /* properties_destroyed */
85   0, /* todo_flags_start */
86   0, /* todo_flags_finish */
87 };
88 
89 class pass_mode_switch_use : public rtl_opt_pass
90 {
91 public:
pass_mode_switch_use(gcc::context * ctxt)92   pass_mode_switch_use(gcc::context *ctxt)
93     : rtl_opt_pass(pass_data_mode_switch_use, ctxt)
94   {}
95 
96   /* opt_pass methods: */
execute(function *)97   virtual unsigned int execute (function *) { return insert_uses (); }
98 
99 }; // class pass_mode_switch_use
100 
101 } // anon namespace
102 
103 rtl_opt_pass *
make_pass_mode_switch_use(gcc::context * ctxt)104 make_pass_mode_switch_use (gcc::context *ctxt)
105 {
106   return new pass_mode_switch_use (ctxt);
107 }
108