2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief architecture dependent IR operations
34 #include "irgraph_t.h"
39 #include "firm_common_t.h"
41 #include "iropt_dbg.h"
44 /* when we need verifying */
46 # define IRN_VRFY_IRG(res, irg)
48 # define IRN_VRFY_IRG(res, irg) irn_vrfy_irg(res, irg)
51 /** current settings */
52 static arch_ops_info settings;
54 /** default settings */
55 static const arch_ops_info default_settings = {
60 /** The Min operation */
63 /** The Max operation */
66 ir_op *get_op_Min(void) { return op_Min; }
67 ir_op *get_op_Max(void) { return op_Max; }
70 * construct a Min: Min(a,b) = a < b ? a : b
73 new_rd_Min(dbg_info *db, ir_graph *irg, ir_node *block,
74 ir_node *op1, ir_node *op2, ir_mode *mode)
86 res = new_ir_node(db, irg, block, op_Min, mode, 2, in);
87 res = optimize_node(res);
88 IRN_VRFY_IRG(res, irg);
93 * construct a Max: Max(a,b) = a > b ? a : b
96 new_rd_Max(dbg_info *db, ir_graph *irg, ir_node *block,
97 ir_node *op1, ir_node *op2, ir_mode *mode)
109 res = new_ir_node(db, irg, block, op_Max, mode, 2, in);
110 res = optimize_node(res);
111 IRN_VRFY_IRG(res, irg);
116 new_r_Min(ir_graph *irg, ir_node *block,
117 ir_node *op1, ir_node *op2, ir_mode *mode) {
118 return new_rd_Min(NULL, irg, block, op1, op2, mode);
122 new_r_Max(ir_graph *irg, ir_node *block,
123 ir_node *op1, ir_node *op2, ir_mode *mode) {
124 return new_rd_Max(NULL, irg, block, op1, op2, mode);
128 new_d_Min(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
129 return new_rd_Min(db, current_ir_graph, current_ir_graph->current_block,
134 new_d_Max(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {
135 return new_rd_Max(db, current_ir_graph, current_ir_graph->current_block,
140 new_Min(ir_node *op1, ir_node *op2, ir_mode *mode) {
141 return new_d_Min(NULL, op1, op2, mode);
145 new_Max(ir_node *op1, ir_node *op2, ir_mode *mode) {
146 return new_d_Max(NULL, op1, op2, mode);
152 * return the value of a Min
154 static tarval *computed_value_Min(const ir_node *n) {
155 ir_node *a = get_binop_left(n);
156 ir_node *b = get_binop_right(n);
158 tarval *ta = value_of(a);
159 tarval *tb = value_of(b);
161 if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
162 pn_Cmp res = tarval_cmp(ta, tb);
164 /* beware: there might be Unordered tarvals here, in that
165 * case let the backend decide, do NOT optimize */
166 if (res == pn_Cmp_Lt)
168 if (res == pn_Cmp_Gt || res == pn_Cmp_Eq)
175 * return the value of a Max
177 static tarval *computed_value_Max(const ir_node *n) {
178 ir_node *a = get_binop_left(n);
179 ir_node *b = get_binop_right(n);
181 tarval *tb = value_of(b);
182 tarval *ta = value_of(a);
184 if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
185 pn_Cmp res = tarval_cmp(ta, tb);
187 /* beware: there might be Unordered tarvals here, in that
188 * case let the backend decide, do NOT optimize */
189 if (res == pn_Cmp_Gt)
191 if (res == pn_Cmp_Lt || res == pn_Cmp_Eq)
198 * Returns an equivalent node for a Min/Max node.
199 * We do not allow Exceptions in our Min/Max, so there will be always
201 * The problem is Min(NaN, NaN) == NaN ???.
203 static ir_node *equivalent_node_MinMax(ir_node *n)
209 if (settings.minmax_handle_NaN == 0 && mode_is_float(get_irn_mode(n)))
212 a = get_binop_left(n);
213 b = get_binop_right(n);
216 DBG_OPT_ALGSIM0(n, a, FS_OPT_MIN_MAX_EQ);
220 mode = get_irn_mode(n);
221 tv = n->op == op_Max ? get_mode_min(mode) : get_mode_max(mode);
223 if (value_of(b) == tv) {
224 DBG_OPT_ALGSIM0(n, a, FS_OPT_MIN_MAX_EQ);
227 if (value_of(a) == tv) {
228 DBG_OPT_ALGSIM0(n, b, FS_OPT_MIN_MAX_EQ);
235 #define equivalent_node_Min equivalent_node_MinMax
236 #define equivalent_node_Max equivalent_node_MinMax
239 * Create Min and Max from Mux nodes
241 ir_node *arch_transform_node_Mux(ir_node *n)
243 if (settings.enabled_ops & ARCH_OPS_MINMAX) {
244 ir_node *oldn = n, *cmp, *proj = get_Mux_sel(n);
247 if (get_irn_op(proj) != op_Proj)
250 cmp = get_Proj_pred(proj);
251 if (get_irn_op(cmp) == op_Cmp) {
252 ir_node *a = get_Cmp_left(cmp);
253 ir_node *b = get_Cmp_right(cmp);
254 ir_node *t = get_Mux_true(n);
255 ir_node *f = get_Mux_false(n);
257 proj_nr = get_Proj_proj(proj);
259 if (proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Le) {
260 if (a == t && b == f) {
261 /* a </<= b ? a : b ==> Min(a,b) */
262 n = new_rd_Min(get_irn_dbg_info(n),
268 DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MIN);
271 else if (a == f && b == t) {
272 /* a </<= b ? b : a ==> Max(a,b) */
273 n = new_rd_Max(get_irn_dbg_info(n),
279 DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MAX);
283 else if (proj_nr == pn_Cmp_Gt || proj_nr == pn_Cmp_Ge) {
284 if (a == t && b == f) {
285 /* a >/>= b ? a : b ==> Max(a,b) */
286 n = new_rd_Max(get_irn_dbg_info(n),
292 DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MAX);
295 else if (a == f && b == t) {
296 /* a >/>= b ? b : a ==> Min(a,b) */
297 n = new_rd_Min(get_irn_dbg_info(n),
303 DBG_OPT_ALGSIM1(oldn, cmp, proj, n, FS_OPT_MUX_TO_MIN);
313 * verify a MinMax node
315 static int verify_node_MinMax(ir_node *n, ir_graph *irg) {
316 ir_mode *mymode = get_irn_mode(n);
317 ir_mode *op1mode = get_irn_mode(get_binop_left(n));
318 ir_mode *op2mode = get_irn_mode(get_binop_right(n));
322 /* MinMax: BB x numP x numP --> numP */
325 mode_is_data(mymode),
332 * initialize the ops.
334 void firm_archops_init(const arch_ops_info *info)
339 info = &default_settings;
341 memcpy(&settings, info, sizeof(settings));
343 if (info->enabled_ops & ARCH_OPS_MINMAX) {
344 memset(&ops, 0, sizeof(ops));
346 ops.computed_value = computed_value_Min;
347 ops.equivalent_node = equivalent_node_Min;
348 ops.verify_node = verify_node_MinMax;
350 op_Min = new_ir_op(iro_Min, "Min", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0, &ops);
352 ops.computed_value = computed_value_Max;
353 ops.equivalent_node = equivalent_node_Max;
354 ops.verify_node = verify_node_MinMax;
356 op_Max = new_ir_op(iro_Max, "Max", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0, &ops);