]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/epiphany/resolve-sw-modes.c
remove has_execute
[thirdparty/gcc.git] / gcc / config / epiphany / resolve-sw-modes.c
CommitLineData
d19f5793 1/* Mode switching cleanup pass for the EPIPHANY cpu.
3aea1f79 2 Copyright (C) 2000-2014 Free Software Foundation, Inc.
d19f5793 3 Contributed by Embecosm on behalf of Adapteva, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "machmode.h"
25#include "tm.h"
26#include "hard-reg-set.h"
27#include "tm_p.h"
28#include "vec.h"
29#include "sbitmap.h"
30#include "basic-block.h"
31#include "df.h"
32#include "rtl.h"
33#include "insn-config.h"
34#include "insn-codes.h"
35#include "emit-rtl.h"
36#include "recog.h"
37#include "function.h"
38#include "insn-attr-common.h"
39#include "tree-pass.h"
40
65b0537f 41namespace {
42
43const pass_data pass_data_resolve_sw_modes =
44{
45 RTL_PASS, /* type */
46 "resolve_sw_modes", /* name */
47 OPTGROUP_NONE, /* optinfo_flags */
65b0537f 48 TV_MODE_SWITCH, /* tv_id */
49 0, /* properties_required */
50 0, /* properties_provided */
51 0, /* properties_destroyed */
52 0, /* todo_flags_start */
8b88439e 53 TODO_df_finish, /* todo_flags_finish */
65b0537f 54};
55
56class pass_resolve_sw_modes : public rtl_opt_pass
57{
58public:
59 pass_resolve_sw_modes(gcc::context *ctxt)
60 : rtl_opt_pass(pass_data_resolve_sw_modes, ctxt)
61 {}
62
63 /* opt_pass methods: */
64 virtual bool gate (function *) { return optimize; }
65 virtual unsigned int execute (function *);
66
67}; // class pass_resolve_sw_modes
68
d19f5793 69/* Clean-up after mode switching:
70 Check for mode setting insns that have FP_MODE_ROUND_UNKNOWN.
71 If only one rounding mode is required, select that one.
72 Else we have to choose one to use in this mode setting insn and
73 insert new mode setting insns on the edges where the other mode
74 becomes unambigous. */
75
65b0537f 76unsigned
77pass_resolve_sw_modes::execute (function *fun)
d19f5793 78{
79 basic_block bb;
80 rtx insn, src;
f1f41a6c 81 vec<basic_block> todo;
d19f5793 82 sbitmap pushed;
83 bool need_commit = false;
84 bool finalize_fp_sets = (MACHINE_FUNCTION (cfun)->unknown_mode_sets == 0);
85
65b0537f 86 todo.create (last_basic_block_for_fn (fun));
87 pushed = sbitmap_alloc (last_basic_block_for_fn (fun));
53c5d9d4 88 bitmap_clear (pushed);
d19f5793 89 if (!finalize_fp_sets)
90 {
91 df_note_add_problem ();
92 df_analyze ();
93 }
65b0537f 94 FOR_EACH_BB_FN (bb, fun)
d19f5793 95 FOR_BB_INSNS (bb, insn)
96 {
97 enum attr_fp_mode selected_mode;
98
99 if (!NONJUMP_INSN_P (insn)
100 || recog_memoized (insn) != CODE_FOR_set_fp_mode)
101 continue;
102 src = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
103 if (finalize_fp_sets)
104 {
105 SET_SRC (XVECEXP (PATTERN (insn), 0, 2)) = copy_rtx (src);
106 if (REG_P (src))
107 df_insn_rescan (insn);
108 continue;
109 }
110 if (REG_P (src)
111 || XINT (XVECEXP (XEXP (src, 0), 0, 0), 0) != FP_MODE_ROUND_UNKNOWN)
112 continue;
113 if (find_regno_note (insn, REG_UNUSED, FP_TRUNCATE_REGNUM))
114 selected_mode = FP_MODE_ROUND_NEAREST;
115 else if (find_regno_note (insn, REG_UNUSED, FP_NEAREST_REGNUM))
116 selected_mode = FP_MODE_ROUND_TRUNC;
117 else
118 {
119 /* We could get more fancy in the selection of the mode by
120 checking the total frequency of the affected edges. */
121 selected_mode = (enum attr_fp_mode) epiphany_normal_fp_rounding;
122
f1f41a6c 123 todo.quick_push (bb);
08b7917c 124 bitmap_set_bit (pushed, bb->index);
d19f5793 125 }
126 XVECEXP (XEXP (src, 0), 0, 0) = GEN_INT (selected_mode);
127 SET_SRC (XVECEXP (PATTERN (insn), 0, 1)) = copy_rtx (src);
128 SET_SRC (XVECEXP (PATTERN (insn), 0, 2)) = copy_rtx (src);
129 df_insn_rescan (insn);
130 }
f1f41a6c 131 while (todo.length ())
d19f5793 132 {
f1f41a6c 133 basic_block bb = todo.pop ();
d19f5793 134 int selected_reg, jilted_reg;
135 enum attr_fp_mode jilted_mode;
136 edge e;
137 edge_iterator ei;
138
08b7917c 139 bitmap_set_bit (pushed, bb->index);
140 bitmap_set_bit (pushed, bb->index);
d19f5793 141
142 if (epiphany_normal_fp_rounding == FP_MODE_ROUND_NEAREST)
143 {
144 selected_reg = FP_NEAREST_REGNUM;
145 jilted_reg = FP_TRUNCATE_REGNUM;
146 jilted_mode = FP_MODE_ROUND_TRUNC;
147 }
148 else
149 {
150 selected_reg = FP_TRUNCATE_REGNUM;
151 jilted_reg = FP_NEAREST_REGNUM;
152 jilted_mode = FP_MODE_ROUND_NEAREST;
153 }
154
155 FOR_EACH_EDGE (e, ei, bb->succs)
156 {
157 basic_block succ = e->dest;
158 rtx seq;
159
160 if (!REGNO_REG_SET_P (DF_LIVE_IN (succ), jilted_reg))
161 continue;
162 if (REGNO_REG_SET_P (DF_LIVE_IN (succ), selected_reg))
163 {
08b7917c 164 if (bitmap_bit_p (pushed, succ->index))
d19f5793 165 continue;
f1f41a6c 166 todo.quick_push (succ);
08b7917c 167 bitmap_set_bit (pushed, bb->index);
d19f5793 168 continue;
169 }
170 start_sequence ();
171 emit_set_fp_mode (EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN,
7fc0df2f 172 jilted_mode, FP_MODE_NONE, NULL);
d19f5793 173 seq = get_insns ();
174 end_sequence ();
175 need_commit = true;
176 insert_insn_on_edge (seq, e);
177 }
178 }
f1f41a6c 179 todo.release ();
d19f5793 180 sbitmap_free (pushed);
181 if (need_commit)
182 commit_edge_insertions ();
183 return 0;
184}
185
cbe8bda8 186} // anon namespace
187
188rtl_opt_pass *
189make_pass_resolve_sw_modes (gcc::context *ctxt)
190{
191 return new pass_resolve_sw_modes (ctxt);
192}