1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
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.
10  *
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.
14  *
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
17  * PURPOSE.
18  */
19 
20 /**
21  * @file
22  * @brief   iropt --- optimizations intertwined with IR construction.
23  * @author  Christian Schaefer, Goetz Lindenmaier, Michael Beck
24  */
25 #include "config.h"
26 
27 #include <string.h>
28 #include <stdbool.h>
29 
30 #include "irnode_t.h"
31 #include "irgraph_t.h"
32 #include "iredges_t.h"
33 #include "irmode_t.h"
34 #include "iropt_t.h"
35 #include "ircons_t.h"
36 #include "irgmod.h"
37 #include "irverify.h"
38 #include "iroptimize.h"
39 #include "tv_t.h"
40 #include "dbginfo_t.h"
41 #include "iropt_dbg.h"
42 #include "irflag_t.h"
43 #include "irhooks.h"
44 #include "irarch.h"
45 #include "hashptr.h"
46 #include "irtools.h"
47 #include "irhooks.h"
48 #include "array_t.h"
49 #include "vrp.h"
50 #include "firm_types.h"
51 #include "bitfiddle.h"
52 #include "be.h"
53 #include "error.h"
54 
55 #include "entity_t.h"
56 
is_Or_Eor_Add(const ir_node * node)57 static bool is_Or_Eor_Add(const ir_node *node)
58 {
59 	if (is_Or(node) || is_Eor(node) || is_Add(node)) {
60 		ir_node  *left      = get_binop_left(node);
61 		ir_node  *right     = get_binop_right(node);
62 		vrp_attr *vrp_left  = vrp_get_info(left);
63 		vrp_attr *vrp_right = vrp_get_info(right);
64 		if (vrp_left != NULL && vrp_right != NULL) {
65 			ir_tarval *vrp_val
66 				= tarval_and(vrp_left->bits_not_set, vrp_right->bits_not_set);
67 			return tarval_is_null(vrp_val);
68 		}
69 	}
70 	return false;
71 }
72 
73 /**
74  * Returns the tarval of a Const node or tarval_bad for all other nodes.
75  */
default_value_of(const ir_node * n)76 static ir_tarval *default_value_of(const ir_node *n)
77 {
78 	if (is_Const(n))
79 		return get_Const_tarval(n); /* might return tarval_bad */
80 	else
81 		return tarval_bad;
82 }
83 
84 value_of_func value_of_ptr = default_value_of;
85 
set_value_of_func(value_of_func func)86 void set_value_of_func(value_of_func func)
87 {
88 	if (func != NULL)
89 		value_of_ptr = func;
90 	else
91 		value_of_ptr = default_value_of;
92 }
93 
94 /**
95  * Return the value of a Constant.
96  */
computed_value_Const(const ir_node * n)97 static ir_tarval *computed_value_Const(const ir_node *n)
98 {
99 	return get_Const_tarval(n);
100 }
101 
102 /**
103  * Return the value of a 'sizeof', 'alignof' or 'offsetof' SymConst.
104  */
computed_value_SymConst(const ir_node * n)105 static ir_tarval *computed_value_SymConst(const ir_node *n)
106 {
107 	ir_type   *type;
108 	ir_entity *ent;
109 
110 	switch (get_SymConst_kind(n)) {
111 	case symconst_type_size:
112 		type = get_SymConst_type(n);
113 		if (get_type_state(type) == layout_fixed)
114 			return new_tarval_from_long(get_type_size_bytes(type), get_irn_mode(n));
115 		break;
116 	case symconst_type_align:
117 		type = get_SymConst_type(n);
118 		if (get_type_state(type) == layout_fixed)
119 			return new_tarval_from_long(get_type_alignment_bytes(type), get_irn_mode(n));
120 		break;
121 	case symconst_ofs_ent:
122 		ent  = get_SymConst_entity(n);
123 		type = get_entity_owner(ent);
124 		if (get_type_state(type) == layout_fixed)
125 			return new_tarval_from_long(get_entity_offset(ent), get_irn_mode(n));
126 		break;
127 	default:
128 		break;
129 	}
130 	return tarval_bad;
131 }
132 
133 /**
134  * Return the value of an Add.
135  */
computed_value_Add(const ir_node * n)136 static ir_tarval *computed_value_Add(const ir_node *n)
137 {
138 	ir_node *a = get_Add_left(n);
139 	ir_node *b = get_Add_right(n);
140 
141 	ir_tarval *ta = value_of(a);
142 	ir_tarval *tb = value_of(b);
143 
144 	if ((ta != tarval_bad) && (tb != tarval_bad))
145 		return tarval_add(ta, tb);
146 
147 	/* x+~x => -1 */
148 	if ((is_Not(a) && get_Not_op(a) == b)
149 	    || (is_Not(b) && get_Not_op(b) == a)) {
150 		return get_mode_all_one(get_irn_mode(n));
151 	}
152 
153 	return tarval_bad;
154 }
155 
156 /**
157  * Return the value of a Sub.
158  * Special case: a - a
159  */
computed_value_Sub(const ir_node * n)160 static ir_tarval *computed_value_Sub(const ir_node *n)
161 {
162 	ir_mode   *mode = get_irn_mode(n);
163 	ir_node   *a    = get_Sub_left(n);
164 	ir_node   *b    = get_Sub_right(n);
165 	ir_tarval *ta;
166 	ir_tarval *tb;
167 
168 	/* NaN - NaN != 0 */
169 	if (! mode_is_float(mode)) {
170 		/* a - a = 0 */
171 		if (a == b)
172 			return get_mode_null(mode);
173 	}
174 
175 	ta = value_of(a);
176 	tb = value_of(b);
177 
178 	if ((ta != tarval_bad) && (tb != tarval_bad))
179 		return tarval_sub(ta, tb, mode);
180 
181 	return tarval_bad;
182 }
183 
184 /**
185  * Return the value of a Carry.
186  * Special : a op 0, 0 op b
187  */
computed_value_Carry(const ir_node * n)188 static ir_tarval *computed_value_Carry(const ir_node *n)
189 {
190 	ir_node   *a  = get_binop_left(n);
191 	ir_node   *b  = get_binop_right(n);
192 	ir_mode   *m  = get_irn_mode(n);
193 	ir_tarval *ta = value_of(a);
194 	ir_tarval *tb = value_of(b);
195 
196 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
197 		tarval_add(ta, tb);
198 		return tarval_carry() ? get_mode_one(m) : get_mode_null(m);
199 	} else {
200 		if (tarval_is_null(ta) || tarval_is_null(tb))
201 			return get_mode_null(m);
202 	}
203 	return tarval_bad;
204 }
205 
206 /**
207  * Return the value of a Borrow.
208  * Special : a op 0
209  */
computed_value_Borrow(const ir_node * n)210 static ir_tarval *computed_value_Borrow(const ir_node *n)
211 {
212 	ir_node   *a  = get_binop_left(n);
213 	ir_node   *b  = get_binop_right(n);
214 	ir_mode   *m  = get_irn_mode(n);
215 	ir_tarval *ta = value_of(a);
216 	ir_tarval *tb = value_of(b);
217 
218 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
219 		return tarval_cmp(ta, tb) == ir_relation_less ? get_mode_one(m) : get_mode_null(m);
220 	} else if (tarval_is_null(ta)) {
221 		return get_mode_null(m);
222 	}
223 	return tarval_bad;
224 }
225 
226 /**
227  * Return the value of an unary Minus.
228  */
computed_value_Minus(const ir_node * n)229 static ir_tarval *computed_value_Minus(const ir_node *n)
230 {
231 	ir_node   *a  = get_Minus_op(n);
232 	ir_tarval *ta = value_of(a);
233 
234 	if (ta != tarval_bad)
235 		return tarval_neg(ta);
236 
237 	return tarval_bad;
238 }
239 
240 /**
241  * Return the value of a Mul.
242  */
computed_value_Mul(const ir_node * n)243 static ir_tarval *computed_value_Mul(const ir_node *n)
244 {
245 	ir_node   *a  = get_Mul_left(n);
246 	ir_node   *b  = get_Mul_right(n);
247 	ir_tarval *ta = value_of(a);
248 	ir_tarval *tb = value_of(b);
249 	ir_mode   *mode;
250 
251 	mode = get_irn_mode(n);
252 	if (mode != get_irn_mode(a)) {
253 		/* n * n = 2n bit multiplication */
254 		ta = tarval_convert_to(ta, mode);
255 		tb = tarval_convert_to(tb, mode);
256 	}
257 
258 	if (ta != tarval_bad && tb != tarval_bad) {
259 		return tarval_mul(ta, tb);
260 	} else {
261 		/* a * 0 != 0 if a == NaN or a == Inf */
262 		if (!mode_is_float(mode)) {
263 			/* a*0 = 0 or 0*b = 0 */
264 			if (ta == get_mode_null(mode))
265 				return ta;
266 			if (tb == get_mode_null(mode))
267 				return tb;
268 		}
269 	}
270 	return tarval_bad;
271 }
272 
273 /**
274  * Return the value of an And.
275  * Special case: a & 0, 0 & b
276  */
computed_value_And(const ir_node * n)277 static ir_tarval *computed_value_And(const ir_node *n)
278 {
279 	ir_node   *a  = get_And_left(n);
280 	ir_node   *b  = get_And_right(n);
281 	ir_tarval *ta = value_of(a);
282 	ir_tarval *tb = value_of(b);
283 
284 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
285 		return tarval_and (ta, tb);
286 	}
287 
288 	if (tarval_is_null(ta)) return ta;
289 	if (tarval_is_null(tb)) return tb;
290 
291 	/* x&~x => 0 */
292 	if ((is_Not(a) && get_Not_op(a) == b)
293 	    || (is_Not(b) && get_Not_op(b) == a)) {
294 		return get_mode_null(get_irn_mode(n));
295 	}
296 
297 	return tarval_bad;
298 }
299 
300 /**
301  * Return the value of an Or.
302  * Special case: a | 1...1, 1...1 | b
303  */
computed_value_Or(const ir_node * n)304 static ir_tarval *computed_value_Or(const ir_node *n)
305 {
306 	ir_node   *a  = get_Or_left(n);
307 	ir_node   *b  = get_Or_right(n);
308 	ir_tarval *ta = value_of(a);
309 	ir_tarval *tb = value_of(b);
310 
311 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
312 		return tarval_or (ta, tb);
313 	}
314 
315 	if (tarval_is_all_one(ta)) return ta;
316 	if (tarval_is_all_one(tb)) return tb;
317 
318 	/* x|~x => -1 */
319 	if ((is_Not(a) && get_Not_op(a) == b)
320 	    || (is_Not(b) && get_Not_op(b) == a)) {
321 		return get_mode_all_one(get_irn_mode(n));
322 	}
323 	return tarval_bad;
324 }
325 
326 /**
327  * Return the value of an Eor.
328  */
computed_value_Eor(const ir_node * n)329 static ir_tarval *computed_value_Eor(const ir_node *n)
330 {
331 	ir_node *a = get_Eor_left(n);
332 	ir_node *b = get_Eor_right(n);
333 
334 	ir_tarval *ta, *tb;
335 
336 	if (a == b)
337 		return get_mode_null(get_irn_mode(n));
338 	/* x^~x => -1 */
339 	if ((is_Not(a) && get_Not_op(a) == b)
340 	    || (is_Not(b) && get_Not_op(b) == a)) {
341 		return get_mode_all_one(get_irn_mode(n));
342 	}
343 
344 	ta = value_of(a);
345 	tb = value_of(b);
346 
347 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
348 		return tarval_eor(ta, tb);
349 	}
350 	return tarval_bad;
351 }
352 
353 /**
354  * Return the value of a Not.
355  */
computed_value_Not(const ir_node * n)356 static ir_tarval *computed_value_Not(const ir_node *n)
357 {
358 	ir_node   *a  = get_Not_op(n);
359 	ir_tarval *ta = value_of(a);
360 
361 	if (ta != tarval_bad)
362 		return tarval_not(ta);
363 
364 	return tarval_bad;
365 }
366 
367 /**
368  * Tests whether a shift shifts more bits than available in the mode
369  */
is_oversize_shift(const ir_node * n)370 static bool is_oversize_shift(const ir_node *n)
371 {
372 	ir_node   *count = get_binop_right(n);
373 	ir_mode   *mode  = get_irn_mode(n);
374 	ir_tarval *tv    = value_of(count);
375 	long       modulo_shift;
376 	long       shiftval;
377 	if (tv == tarval_bad)
378 		return false;
379 	if (!tarval_is_long(tv))
380 		return false;
381 	shiftval     = get_tarval_long(tv);
382 	modulo_shift = get_mode_modulo_shift(mode);
383 	if (shiftval < 0 || (modulo_shift > 0 && shiftval >= modulo_shift))
384 		return false;
385 
386 	return shiftval >= (long)get_mode_size_bits(mode);
387 }
388 
389 /**
390  * Return the value of a Shl.
391  */
computed_value_Shl(const ir_node * n)392 static ir_tarval *computed_value_Shl(const ir_node *n)
393 {
394 	ir_node *a = get_Shl_left(n);
395 	ir_node *b = get_Shl_right(n);
396 
397 	ir_tarval *ta = value_of(a);
398 	ir_tarval *tb = value_of(b);
399 
400 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
401 		return tarval_shl(ta, tb);
402 	}
403 
404 	if (is_oversize_shift(n))
405 		return get_mode_null(get_irn_mode(n));
406 
407 	return tarval_bad;
408 }
409 
410 /**
411  * Return the value of a Shr.
412  */
computed_value_Shr(const ir_node * n)413 static ir_tarval *computed_value_Shr(const ir_node *n)
414 {
415 	ir_node *a = get_Shr_left(n);
416 	ir_node *b = get_Shr_right(n);
417 
418 	ir_tarval *ta = value_of(a);
419 	ir_tarval *tb = value_of(b);
420 
421 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
422 		return tarval_shr(ta, tb);
423 	}
424 	if (is_oversize_shift(n))
425 		return get_mode_null(get_irn_mode(n));
426 
427 	return tarval_bad;
428 }
429 
430 /**
431  * Return the value of a Shrs.
432  */
computed_value_Shrs(const ir_node * n)433 static ir_tarval *computed_value_Shrs(const ir_node *n)
434 {
435 	ir_node *a = get_Shrs_left(n);
436 	ir_node *b = get_Shrs_right(n);
437 
438 	ir_tarval *ta = value_of(a);
439 	ir_tarval *tb = value_of(b);
440 
441 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
442 		return tarval_shrs(ta, tb);
443 	}
444 	return tarval_bad;
445 }
446 
447 /**
448  * Return the value of a Rotl.
449  */
computed_value_Rotl(const ir_node * n)450 static ir_tarval *computed_value_Rotl(const ir_node *n)
451 {
452 	ir_node *a = get_Rotl_left(n);
453 	ir_node *b = get_Rotl_right(n);
454 
455 	ir_tarval *ta = value_of(a);
456 	ir_tarval *tb = value_of(b);
457 
458 	if ((ta != tarval_bad) && (tb != tarval_bad)) {
459 		return tarval_rotl(ta, tb);
460 	}
461 	return tarval_bad;
462 }
463 
ir_zero_when_converted(const ir_node * node,ir_mode * dest_mode)464 bool ir_zero_when_converted(const ir_node *node, ir_mode *dest_mode)
465 {
466 	ir_mode *mode = get_irn_mode(node);
467 	if (get_mode_arithmetic(mode) != irma_twos_complement
468 	    || get_mode_arithmetic(dest_mode) != irma_twos_complement)
469 	    return false;
470 
471 	if (is_Shl(node)) {
472 		ir_node *count = get_Shl_right(node);
473 		if (is_Const(count)) {
474 			ir_tarval *tv = get_Const_tarval(count);
475 			if (tarval_is_long(tv)) {
476 				long shiftval = get_tarval_long(tv);
477 				long destbits = get_mode_size_bits(dest_mode);
478 				if (shiftval >= destbits
479 				    && shiftval < (long)get_mode_modulo_shift(mode))
480 					return true;
481 			}
482 		}
483 	}
484 	if (is_And(node)) {
485 		ir_node *right = get_And_right(node);
486 		if (is_Const(right)) {
487 			ir_tarval *tv     = get_Const_tarval(right);
488 			ir_tarval *conved = tarval_convert_to(tv, dest_mode);
489 			return tarval_is_null(conved);
490 		}
491 	}
492 	return false;
493 }
494 
495 /**
496  * Return the value of a Conv.
497  */
computed_value_Conv(const ir_node * n)498 static ir_tarval *computed_value_Conv(const ir_node *n)
499 {
500 	ir_node   *a    = get_Conv_op(n);
501 	ir_tarval *ta   = value_of(a);
502 	ir_mode   *mode = get_irn_mode(n);
503 
504 	if (ta != tarval_bad)
505 		return tarval_convert_to(ta, get_irn_mode(n));
506 
507 	if (ir_zero_when_converted(a, mode))
508 		return get_mode_null(mode);
509 
510 	return tarval_bad;
511 }
512 
513 /**
514  * Calculate the value of a Mux: can be evaluated, if the
515  * sel and the right input are known.
516  */
computed_value_Mux(const ir_node * n)517 static ir_tarval *computed_value_Mux(const ir_node *n)
518 {
519 	ir_node *sel = get_Mux_sel(n);
520 	ir_tarval *ts = value_of(sel);
521 
522 	if (ts == get_tarval_b_true()) {
523 		ir_node *v = get_Mux_true(n);
524 		return value_of(v);
525 	}
526 	else if (ts == get_tarval_b_false()) {
527 		ir_node *v = get_Mux_false(n);
528 		return value_of(v);
529 	}
530 	return tarval_bad;
531 }
532 
533 /**
534  * Calculate the value of a Confirm: can be evaluated,
535  * if it has the form Confirm(x, '=', Const).
536  */
computed_value_Confirm(const ir_node * n)537 static ir_tarval *computed_value_Confirm(const ir_node *n)
538 {
539 	if (get_Confirm_relation(n) == ir_relation_equal) {
540 		ir_tarval *tv = value_of(get_Confirm_bound(n));
541 		if (tv != tarval_bad)
542 			return tv;
543 	}
544 	return value_of(get_Confirm_value(n));
545 }
546 
547 /**
548  * gives a (conservative) estimation of possible relation when comparing
549  * left+right
550  */
ir_get_possible_cmp_relations(const ir_node * left,const ir_node * right)551 ir_relation ir_get_possible_cmp_relations(const ir_node *left,
552                                           const ir_node *right)
553 {
554 	ir_relation possible = ir_relation_true;
555 	ir_tarval  *tv_l     = value_of(left);
556 	ir_tarval  *tv_r     = value_of(right);
557 	ir_mode    *mode     = get_irn_mode(left);
558 	ir_tarval  *min      = mode == mode_b ? tarval_b_false : get_mode_min(mode);
559 	ir_tarval  *max      = mode == mode_b ? tarval_b_true  : get_mode_max(mode);
560 
561 	/* both values known - evaluate them */
562 	if ((tv_l != tarval_bad) && (tv_r != tarval_bad)) {
563 		possible = tarval_cmp(tv_l, tv_r);
564 		/* we can return now, won't get any better */
565 		return possible;
566 	}
567 	/* a == a is never less or greater (but might be equal or unordered) */
568 	if (left == right)
569 		possible &= ~ir_relation_less_greater;
570 	/* unordered results only happen for float compares */
571 	if (!mode_is_float(mode))
572 		possible &= ~ir_relation_unordered;
573 	/* values can never be less than the least representable number or
574 	 * greater than the greatest representable number */
575 	if (tv_l == min)
576 		possible &= ~ir_relation_greater;
577 	if (tv_l == max)
578 		possible &= ~ir_relation_less;
579 	if (tv_r == max)
580 		possible &= ~ir_relation_greater;
581 	if (tv_r == min)
582 		possible &= ~ir_relation_less;
583 	/* maybe vrp can tell us more */
584 	possible &= vrp_cmp(left, right);
585 	/* Alloc nodes never return null (but throw an exception) */
586 	if (is_Alloc(left) && tarval_is_null(tv_r))
587 		possible &= ~ir_relation_equal;
588 	/* stuff known through confirm nodes */
589 	if (is_Confirm(left) && get_Confirm_bound(left) == right) {
590 		possible &= get_Confirm_relation(left);
591 	}
592 	if (is_Confirm(right) && get_Confirm_bound(right) == left) {
593 		ir_relation relation = get_Confirm_relation(right);
594 		relation = get_inversed_relation(relation);
595 		possible &= relation;
596 	}
597 
598 	return possible;
599 }
600 
compute_cmp(const ir_node * cmp)601 static ir_tarval *compute_cmp(const ir_node *cmp)
602 {
603 	ir_node    *left     = get_Cmp_left(cmp);
604 	ir_node    *right    = get_Cmp_right(cmp);
605 	ir_relation possible = ir_get_possible_cmp_relations(left, right);
606 	ir_relation relation = get_Cmp_relation(cmp);
607 
608 	/* if none of the requested relations is possible, return false */
609 	if ((possible & relation) == ir_relation_false)
610 		return tarval_b_false;
611 	/* if possible relations are a subset of the requested ones return true */
612 	if ((possible & ~relation) == ir_relation_false)
613 		return tarval_b_true;
614 
615 	return computed_value_Cmp_Confirm(cmp, left, right, relation);
616 }
617 
618 /**
619  * some people want to call compute_cmp directly, in this case we have to
620  * test the constant folding flag again
621  */
compute_cmp_ext(const ir_node * cmp)622 static ir_tarval *compute_cmp_ext(const ir_node *cmp)
623 {
624 	if (!get_opt_constant_folding())
625 		return tarval_bad;
626 	return compute_cmp(cmp);
627 }
628 
629 /**
630  * Return the value of a Cmp.
631  *
632  * The basic idea here is to determine which relations are possible and which
633  * one are definitely impossible.
634  */
computed_value_Cmp(const ir_node * cmp)635 static ir_tarval *computed_value_Cmp(const ir_node *cmp)
636 {
637 	/* we can't construct Constb after lowering mode_b nodes */
638 	if (irg_is_constrained(get_irn_irg(cmp), IR_GRAPH_CONSTRAINT_MODEB_LOWERED))
639 		return tarval_bad;
640 
641 	return compute_cmp(cmp);
642 }
643 
644 /**
645  * Calculate the value of an integer Div.
646  * Special case: 0 / b
647  */
do_computed_value_Div(const ir_node * div)648 static ir_tarval *do_computed_value_Div(const ir_node *div)
649 {
650 	const ir_node *a    = get_Div_left(div);
651 	const ir_node *b    = get_Div_right(div);
652 	const ir_mode *mode = get_Div_resmode(div);
653 	ir_tarval     *ta   = value_of(a);
654 	ir_tarval     *tb;
655 	const ir_node *dummy;
656 
657 	/* cannot optimize 0 / b = 0 because of NaN */
658 	if (!mode_is_float(mode)) {
659 		if (tarval_is_null(ta) && value_not_zero(b, &dummy))
660 			return ta;  /* 0 / b == 0 if b != 0 */
661 	}
662 	tb = value_of(b);
663 	if (ta != tarval_bad && tb != tarval_bad)
664 		return tarval_div(ta, tb);
665 	return tarval_bad;
666 }
667 
668 /**
669  * Calculate the value of an integer Mod of two nodes.
670  * Special case: a % 1
671  */
do_computed_value_Mod(const ir_node * a,const ir_node * b)672 static ir_tarval *do_computed_value_Mod(const ir_node *a, const ir_node *b)
673 {
674 	ir_tarval *ta = value_of(a);
675 	ir_tarval *tb = value_of(b);
676 
677 	/* Compute a % 1 or c1 % c2 */
678 	if (tarval_is_one(tb))
679 		return get_mode_null(get_irn_mode(a));
680 	if (ta != tarval_bad && tb != tarval_bad)
681 		return tarval_mod(ta, tb);
682 	return tarval_bad;
683 }
684 
685 /**
686  * Return the value of a Proj(Div).
687  */
computed_value_Proj_Div(const ir_node * n)688 static ir_tarval *computed_value_Proj_Div(const ir_node *n)
689 {
690 	long proj_nr = get_Proj_proj(n);
691 	if (proj_nr != pn_Div_res)
692 		return tarval_bad;
693 
694 	return do_computed_value_Div(get_Proj_pred(n));
695 }
696 
697 /**
698  * Return the value of a Proj(Mod).
699  */
computed_value_Proj_Mod(const ir_node * n)700 static ir_tarval *computed_value_Proj_Mod(const ir_node *n)
701 {
702 	long proj_nr = get_Proj_proj(n);
703 
704 	if (proj_nr == pn_Mod_res) {
705 		const ir_node *mod = get_Proj_pred(n);
706 		return do_computed_value_Mod(get_Mod_left(mod), get_Mod_right(mod));
707 	}
708 	return tarval_bad;
709 }
710 
711 /**
712  * Return the value of a Proj.
713  */
computed_value_Proj(const ir_node * proj)714 static ir_tarval *computed_value_Proj(const ir_node *proj)
715 {
716 	ir_node *n = get_Proj_pred(proj);
717 
718 	if (n->op->ops.computed_value_Proj != NULL)
719 		return n->op->ops.computed_value_Proj(proj);
720 	return tarval_bad;
721 }
722 
723 /**
724  * If the parameter n can be computed, return its value, else tarval_bad.
725  * Performs constant folding.
726  *
727  * @param n  The node this should be evaluated
728  */
computed_value(const ir_node * n)729 ir_tarval *computed_value(const ir_node *n)
730 {
731 	vrp_attr *vrp = vrp_get_info(n);
732 	if (vrp != NULL && vrp->bits_set == vrp->bits_not_set)
733 		return vrp->bits_set;
734 
735 	if (n->op->ops.computed_value)
736 		return n->op->ops.computed_value(n);
737 	return tarval_bad;
738 }
739 
740 /**
741  * Optimize operations that are commutative and have neutral 0,
742  * so a op 0 = 0 op a = a.
743  */
equivalent_node_neutral_zero(ir_node * n)744 static ir_node *equivalent_node_neutral_zero(ir_node *n)
745 {
746 	ir_node *oldn = n;
747 
748 	ir_node *a = get_binop_left(n);
749 	ir_node *b = get_binop_right(n);
750 
751 	ir_tarval *tv;
752 	ir_node *on;
753 
754 	/* After running compute_node there is only one constant predecessor.
755 	   Find this predecessors value and remember the other node: */
756 	if ((tv = value_of(a)) != tarval_bad) {
757 		on = b;
758 	} else if ((tv = value_of(b)) != tarval_bad) {
759 		on = a;
760 	} else
761 		return n;
762 
763 	/* If this predecessors constant value is zero, the operation is
764 	 * unnecessary. Remove it.
765 	 *
766 	 * Beware: If n is a Add, the mode of on and n might be different
767 	 * which happens in this rare construction: NULL + 3.
768 	 * Then, a Conv would be needed which we cannot include here.
769 	 */
770 	if (tarval_is_null(tv) && get_irn_mode(on) == get_irn_mode(n)) {
771 		n = on;
772 
773 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
774 	}
775 
776 	return n;
777 }
778 
779 /**
780  * Eor is commutative and has neutral 0.
781  */
equivalent_node_Eor(ir_node * n)782 static ir_node *equivalent_node_Eor(ir_node *n)
783 {
784 	ir_node *oldn = n;
785 	ir_node *a;
786 	ir_node *b;
787 
788 	n = equivalent_node_neutral_zero(n);
789 	if (n != oldn) return n;
790 
791 	a = get_Eor_left(n);
792 	b = get_Eor_right(n);
793 
794 	if (is_Eor(a) || is_Or_Eor_Add(a)) {
795 		ir_node *aa = get_binop_left(a);
796 		ir_node *ab = get_binop_right(a);
797 
798 		if (aa == b) {
799 			/* (a ^ b) ^ a -> b */
800 			n = ab;
801 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
802 			return n;
803 		} else if (ab == b) {
804 			/* (a ^ b) ^ b -> a */
805 			n = aa;
806 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
807 			return n;
808 		}
809 	}
810 	if (is_Eor(b) || is_Or_Eor_Add(b)) {
811 		ir_node *ba = get_binop_left(b);
812 		ir_node *bb = get_binop_right(b);
813 
814 		if (ba == a) {
815 			/* a ^ (a ^ b) -> b */
816 			n = bb;
817 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
818 			return n;
819 		} else if (bb == a) {
820 			/* a ^ (b ^ a) -> b */
821 			n = ba;
822 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
823 			return n;
824 		}
825 	}
826 	return n;
827 }
828 
829 /*
830  * Optimize a - 0 and (a - x) + x (for modes with wrap-around).
831  *
832  * The second one looks strange, but this construct
833  * is used heavily in the LCC sources :-).
834  *
835  * Beware: The Mode of an Add may be different than the mode of its
836  * predecessors, so we could not return a predecessors in all cases.
837  */
equivalent_node_Add(ir_node * n)838 static ir_node *equivalent_node_Add(ir_node *n)
839 {
840 	ir_node *oldn = n;
841 	ir_node *left, *right;
842 	ir_mode *mode = get_irn_mode(n);
843 
844 	n = equivalent_node_neutral_zero(n);
845 	if (n != oldn)
846 		return n;
847 
848 	/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
849 	if (mode_is_float(mode)) {
850 		ir_graph *irg = get_irn_irg(n);
851 		if (get_irg_fp_model(irg) & fp_strict_algebraic)
852 			return n;
853 	}
854 
855 	left  = get_Add_left(n);
856 	right = get_Add_right(n);
857 
858 	if (is_Sub(left)) {
859 		if (get_Sub_right(left) == right) {
860 			/* (a - x) + x */
861 
862 			n = get_Sub_left(left);
863 			if (mode == get_irn_mode(n)) {
864 				DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB);
865 				return n;
866 			}
867 		}
868 	}
869 	if (is_Sub(right)) {
870 		if (get_Sub_right(right) == left) {
871 			/* x + (a - x) */
872 
873 			n = get_Sub_left(right);
874 			if (mode == get_irn_mode(n)) {
875 				DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB);
876 				return n;
877 			}
878 		}
879 	}
880 	return n;
881 }
882 
883 /**
884  * optimize operations that are not commutative but have neutral 0 on left,
885  * so a op 0 = a.
886  */
equivalent_node_left_zero(ir_node * n)887 static ir_node *equivalent_node_left_zero(ir_node *n)
888 {
889 	ir_node *oldn = n;
890 
891 	ir_node   *a  = get_binop_left(n);
892 	ir_node   *b  = get_binop_right(n);
893 	ir_tarval *tb = value_of(b);
894 
895 	if (tarval_is_null(tb)) {
896 		n = a;
897 
898 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
899 	}
900 	return n;
901 }
902 
903 /**
904  * Optimize a - 0 and (a + x) - x (for modes with wrap-around).
905  *
906  * The second one looks strange, but this construct
907  * is used heavily in the LCC sources :-).
908  *
909  * Beware: The Mode of a Sub may be different than the mode of its
910  * predecessors, so we could not return a predecessors in all cases.
911  */
equivalent_node_Sub(ir_node * n)912 static ir_node *equivalent_node_Sub(ir_node *n)
913 {
914 	ir_node   *oldn = n;
915 	ir_node   *b;
916 	ir_mode   *mode = get_irn_mode(n);
917 	ir_tarval *tb;
918 
919 	/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
920 	if (mode_is_float(mode)) {
921 		ir_graph *irg = get_irn_irg(n);
922 		if (get_irg_fp_model(irg) & fp_strict_algebraic)
923 			return n;
924 	}
925 
926 	b  = get_Sub_right(n);
927 	tb = value_of(b);
928 
929 	/* Beware: modes might be different */
930 	if (tarval_is_null(tb)) {
931 		ir_node *a = get_Sub_left(n);
932 		if (mode == get_irn_mode(a)) {
933 			n = a;
934 
935 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
936 		}
937 	}
938 	return n;
939 }
940 
941 
942 /**
943  * Optimize an "self-inverse unary op", i.e. op(op(n)) = n.
944  *
945  * @todo
946  *   -(-a) == a, but might overflow two times.
947  *   We handle it anyway here but the better way would be a
948  *   flag. This would be needed for Pascal for instance.
949  */
equivalent_node_involution(ir_node * n)950 static ir_node *equivalent_node_involution(ir_node *n)
951 {
952 	ir_node *oldn = n;
953 	ir_node *pred = get_unop_op(n);
954 	if (get_irn_op(pred) == get_irn_op(n)) {
955 		n = get_unop_op(pred);
956 		DBG_OPT_ALGSIM2(oldn, pred, n, FS_OPT_INVOLUTION);
957 	}
958 	return n;
959 }
960 
961 /**
962  * Optimize a * 1 = 1 * a = a.
963  */
equivalent_node_Mul(ir_node * n)964 static ir_node *equivalent_node_Mul(ir_node *n)
965 {
966 	ir_node *oldn = n;
967 	ir_node *a = get_Mul_left(n);
968 
969 	/* we can handle here only the n * n = n bit cases */
970 	if (get_irn_mode(n) == get_irn_mode(a)) {
971 		ir_node   *b = get_Mul_right(n);
972 		ir_tarval *tv;
973 
974 		/*
975 		 * Mul is commutative and has again an other neutral element.
976 		 * Constants are place right, so check this case first.
977 		 */
978 		tv = value_of(b);
979 		if (tarval_is_one(tv)) {
980 			n = a;
981 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
982 		} else {
983 			tv = value_of(a);
984 			if (tarval_is_one(tv)) {
985 				n = b;
986 				DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
987 			}
988 		}
989 	}
990 	return n;
991 }
992 
993 /**
994  * Use algebraic simplification a | a = a | 0 = 0 | a = a.
995  */
equivalent_node_Or(ir_node * n)996 static ir_node *equivalent_node_Or(ir_node *n)
997 {
998 	ir_node *oldn = n;
999 
1000 	ir_node   *a = get_Or_left(n);
1001 	ir_node   *b = get_Or_right(n);
1002 	ir_tarval *tv;
1003 
1004 	if (a == b) {
1005 		n = a;    /* idempotence */
1006 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_OR);
1007 		return n;
1008 	}
1009 	/* constants are normalized to right, check this side first */
1010 	tv = value_of(b);
1011 	if (tarval_is_null(tv)) {
1012 		n = a;
1013 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_OR);
1014 		return n;
1015 	}
1016 	tv = value_of(a);
1017 	if (tarval_is_null(tv)) {
1018 		n = b;
1019 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_OR);
1020 		return n;
1021 	}
1022 
1023 	return n;
1024 }
1025 
1026 /**
1027  * Optimize a & 0b1...1 = 0b1...1 & a = a & a = (a|X) & a = a.
1028  */
equivalent_node_And(ir_node * n)1029 static ir_node *equivalent_node_And(ir_node *n)
1030 {
1031 	ir_node *oldn = n;
1032 
1033 	ir_node   *a = get_And_left(n);
1034 	ir_node   *b = get_And_right(n);
1035 	ir_tarval *tv;
1036 
1037 	if (a == b) {
1038 		n = a;    /* idempotence */
1039 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_AND);
1040 		return n;
1041 	}
1042 	/* constants are normalized to right, check this side first */
1043 	tv = value_of(b);
1044 	if (tarval_is_all_one(tv)) {
1045 		n = a;
1046 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1047 		return n;
1048 	}
1049 	if (tv != get_tarval_bad()) {
1050 		ir_mode *mode = get_irn_mode(n);
1051 		if (!mode_is_signed(mode) && is_Conv(a)) {
1052 			ir_node *convop     = get_Conv_op(a);
1053 			ir_mode *convopmode = get_irn_mode(convop);
1054 			if (!mode_is_signed(convopmode)) {
1055 				/* Check Conv(all_one) & Const = all_one */
1056 				ir_tarval *one  = get_mode_all_one(convopmode);
1057 				ir_tarval *conv = tarval_convert_to(one, mode);
1058 				ir_tarval *tand = tarval_and(conv, tv);
1059 
1060 				if (tarval_is_all_one(tand)) {
1061 					/* Conv(X) & Const = X */
1062 					n = a;
1063 					DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1064 					return n;
1065 				}
1066 			}
1067 		}
1068 	}
1069 	tv = value_of(a);
1070 	if (tarval_is_all_one(tv)) {
1071 		n = b;
1072 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1073 		return n;
1074 	}
1075 	/* (a|X) & a => a*/
1076 	if ((is_Or(a) || is_Or_Eor_Add(a))
1077 	    && (b == get_binop_left(a) || b == get_binop_right(a))) {
1078 		n = b;
1079 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1080 		return n;
1081 	}
1082 	/* a & (a|X) => a*/
1083 	if ((is_Or(b) || is_Or_Eor_Add(b))
1084 	    && (a == get_binop_left(b) || a == get_binop_right(b))) {
1085 		n = a;
1086 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1087 		return n;
1088 	}
1089 	return n;
1090 }
1091 
1092 /**
1093  * Try to remove useless Conv's:
1094  */
equivalent_node_Conv(ir_node * n)1095 static ir_node *equivalent_node_Conv(ir_node *n)
1096 {
1097 	ir_node *oldn = n;
1098 	ir_node *a = get_Conv_op(n);
1099 
1100 	ir_mode *n_mode = get_irn_mode(n);
1101 	ir_mode *a_mode = get_irn_mode(a);
1102 
1103 	if (n_mode == a_mode) { /* No Conv necessary */
1104 		n = a;
1105 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
1106 		return n;
1107 	} else if (is_Conv(a)) { /* Conv(Conv(b)) */
1108 		ir_node *b      = get_Conv_op(a);
1109 		ir_mode *b_mode = get_irn_mode(b);
1110 
1111 		if (n_mode == b_mode && values_in_mode(b_mode, a_mode)) {
1112 			n = b;
1113 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
1114 			return n;
1115 		}
1116 	}
1117 	return n;
1118 }
1119 
1120 /**
1121  * - fold Phi-nodes, iff they have only one predecessor except
1122  *   themselves.
1123  */
equivalent_node_Phi(ir_node * n)1124 static ir_node *equivalent_node_Phi(ir_node *n)
1125 {
1126 	int i, n_preds;
1127 
1128 	ir_node *oldn = n;
1129 	ir_node *first_val = NULL; /* to shutup gcc */
1130 
1131 	if (!get_opt_optimize() &&
1132 	    !irg_is_constrained(get_irn_irg(n), IR_GRAPH_CONSTRAINT_CONSTRUCTION))
1133 		return n;
1134 
1135 	n_preds = get_Phi_n_preds(n);
1136 
1137 	/* Phi of dead Region without predecessors. */
1138 	if (n_preds == 0)
1139 		return n;
1140 
1141 	/* Find first non-self-referencing input */
1142 	for (i = 0; i < n_preds; ++i) {
1143 		first_val = get_Phi_pred(n, i);
1144 		/* not self pointer */
1145 		if (first_val != n) {
1146 			/* then found first value. */
1147 			break;
1148 		}
1149 	}
1150 
1151 	/* search for rest of inputs, determine if any of these
1152 	are non-self-referencing */
1153 	while (++i < n_preds) {
1154 		ir_node *scnd_val = get_Phi_pred(n, i);
1155 		if (scnd_val != n && scnd_val != first_val) {
1156 			break;
1157 		}
1158 	}
1159 
1160 	if (i >= n_preds && !is_Dummy(first_val)) {
1161 		/* Fold, if no multiple distinct non-self-referencing inputs */
1162 		n = first_val;
1163 		DBG_OPT_PHI(oldn, n);
1164 	}
1165 	return n;
1166 }
1167 
1168 /**
1169  * Optimize Proj(Tuple).
1170  */
equivalent_node_Proj_Tuple(ir_node * proj)1171 static ir_node *equivalent_node_Proj_Tuple(ir_node *proj)
1172 {
1173 	ir_node *oldn  = proj;
1174 	ir_node *tuple = get_Proj_pred(proj);
1175 
1176 	/* Remove the Tuple/Proj combination. */
1177 	proj = get_Tuple_pred(tuple, get_Proj_proj(proj));
1178 	DBG_OPT_TUPLE(oldn, tuple, proj);
1179 
1180 	return proj;
1181 }
1182 
1183 /**
1184  * Optimize a / 1 = a.
1185  */
equivalent_node_Proj_Div(ir_node * proj)1186 static ir_node *equivalent_node_Proj_Div(ir_node *proj)
1187 {
1188 	ir_node   *oldn = proj;
1189 	ir_node   *div  = get_Proj_pred(proj);
1190 	ir_node   *b    = get_Div_right(div);
1191 	ir_tarval *tb   = value_of(b);
1192 
1193 	/* Div is not commutative. */
1194 	if (tarval_is_one(tb)) { /* div(x, 1) == x */
1195 		switch (get_Proj_proj(proj)) {
1196 		case pn_Div_M:
1197 			proj = get_Div_mem(div);
1198 			DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1);
1199 			return proj;
1200 
1201 		case pn_Div_res:
1202 			proj = get_Div_left(div);
1203 			DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NEUTRAL_1);
1204 			return proj;
1205 
1206 		default:
1207 			/* we cannot replace the exception Proj's here, this is done in
1208 			   transform_node_Proj_Div() */
1209 			return proj;
1210 		}
1211 	}
1212 	return proj;
1213 }
1214 
1215 /**
1216  * Optimize CopyB(mem, x, x) into a Nop.
1217  */
equivalent_node_Proj_CopyB(ir_node * proj)1218 static ir_node *equivalent_node_Proj_CopyB(ir_node *proj)
1219 {
1220 	ir_node *oldn  = proj;
1221 	ir_node *copyb = get_Proj_pred(proj);
1222 	ir_node *a     = get_CopyB_dst(copyb);
1223 	ir_node *b     = get_CopyB_src(copyb);
1224 
1225 	if (a == b) {
1226 		/* Turn CopyB into a tuple (mem, jmp, bad, bad) */
1227 		switch (get_Proj_proj(proj)) {
1228 		case pn_CopyB_M:
1229 			proj = get_CopyB_mem(copyb);
1230 			DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NOP);
1231 			break;
1232 		}
1233 	}
1234 	return proj;
1235 }
1236 
1237 /**
1238  * Optimize Bounds(idx, idx, upper) into idx.
1239  */
equivalent_node_Proj_Bound(ir_node * proj)1240 static ir_node *equivalent_node_Proj_Bound(ir_node *proj)
1241 {
1242 	ir_node *oldn  = proj;
1243 	ir_node *bound = get_Proj_pred(proj);
1244 	ir_node *idx   = get_Bound_index(bound);
1245 	ir_node *pred  = skip_Proj(idx);
1246 	int ret_tuple  = 0;
1247 
1248 	if (idx == get_Bound_lower(bound))
1249 		ret_tuple = 1;
1250 	else if (is_Bound(pred)) {
1251 		/*
1252 		 * idx was Bounds checked previously, it is still valid if
1253 		 * lower <= pred_lower && pred_upper <= upper.
1254 		 */
1255 		ir_node *lower = get_Bound_lower(bound);
1256 		ir_node *upper = get_Bound_upper(bound);
1257 		if (get_Bound_lower(pred) == lower &&
1258 			get_Bound_upper(pred) == upper) {
1259 			/*
1260 			 * One could expect that we simply return the previous
1261 			 * Bound here. However, this would be wrong, as we could
1262 			 * add an exception Proj to a new location then.
1263 			 * So, we must turn in into a tuple.
1264 			 */
1265 			ret_tuple = 1;
1266 		}
1267 	}
1268 	if (ret_tuple) {
1269 		/* Turn Bound into a tuple (mem, jmp, bad, idx) */
1270 		switch (get_Proj_proj(proj)) {
1271 		case pn_Bound_M:
1272 			DBG_OPT_EXC_REM(proj);
1273 			proj = get_Bound_mem(bound);
1274 			break;
1275 		case pn_Bound_res:
1276 			proj = idx;
1277 			DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NOP);
1278 			break;
1279 		default:
1280 			/* cannot optimize pn_Bound_X_regular, handled in transform ... */
1281 			break;
1282 		}
1283 	}
1284 	return proj;
1285 }
1286 
1287 /**
1288  * Does all optimizations on nodes that must be done on its Projs
1289  * because of creating new nodes.
1290  */
equivalent_node_Proj(ir_node * proj)1291 static ir_node *equivalent_node_Proj(ir_node *proj)
1292 {
1293 	ir_node *n = get_Proj_pred(proj);
1294 	if (n->op->ops.equivalent_node_Proj)
1295 		return n->op->ops.equivalent_node_Proj(proj);
1296 	return proj;
1297 }
1298 
1299 /**
1300  * Remove Id's.
1301  */
equivalent_node_Id(ir_node * n)1302 static ir_node *equivalent_node_Id(ir_node *n)
1303 {
1304 	ir_node *oldn = n;
1305 
1306 	do {
1307 		n = get_Id_pred(n);
1308 	} while (is_Id(n));
1309 
1310 	DBG_OPT_ID(oldn, n);
1311 	return n;
1312 }
1313 
1314 /**
1315  * Optimize a Mux.
1316  */
equivalent_node_Mux(ir_node * n)1317 static ir_node *equivalent_node_Mux(ir_node *n)
1318 {
1319 	ir_node   *oldn = n, *sel = get_Mux_sel(n);
1320 	ir_node   *n_t, *n_f;
1321 	ir_tarval *ts = value_of(sel);
1322 
1323 	if (ts == tarval_bad && is_Cmp(sel)) {
1324 		/* try again with a direct call to compute_cmp, as we don't care
1325 		 * about the MODEB_LOWERED flag here */
1326 		ts = compute_cmp_ext(sel);
1327 	}
1328 
1329 	/* Mux(true, f, t) == t */
1330 	if (ts == tarval_b_true) {
1331 		n = get_Mux_true(n);
1332 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_C);
1333 		return n;
1334 	}
1335 	/* Mux(false, f, t) == f */
1336 	if (ts == tarval_b_false) {
1337 		n = get_Mux_false(n);
1338 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_C);
1339 		return n;
1340 	}
1341 	n_t = get_Mux_true(n);
1342 	n_f = get_Mux_false(n);
1343 
1344 	/* Mux(v, x, T) == x */
1345 	if (is_Unknown(n_f)) {
1346 		n = n_t;
1347 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_EQ);
1348 		return n;
1349 	}
1350 	/* Mux(v, T, x) == x */
1351 	if (is_Unknown(n_t)) {
1352 		n = n_f;
1353 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_EQ);
1354 		return n;
1355 	}
1356 
1357 	/* Mux(v, x, x) == x */
1358 	if (n_t == n_f) {
1359 		n = n_t;
1360 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_EQ);
1361 		return n;
1362 	}
1363 	if (is_Cmp(sel) && !mode_honor_signed_zeros(get_irn_mode(n))) {
1364 		ir_relation relation = get_Cmp_relation(sel);
1365 		ir_node    *f        = get_Mux_false(n);
1366 		ir_node    *t        = get_Mux_true(n);
1367 
1368 		/*
1369 		 * Note further that these optimization work even for floating point
1370 		 * with NaN's because -NaN == NaN.
1371 		 * However, if +0 and -0 is handled differently, we cannot use the first one.
1372 		 */
1373 		ir_node *const cmp_l = get_Cmp_left(sel);
1374 		ir_node *const cmp_r = get_Cmp_right(sel);
1375 
1376 		switch (relation) {
1377 		case ir_relation_equal:
1378 			if ((cmp_l == t && cmp_r == f) || /* Mux(t == f, t, f) -> f */
1379 					(cmp_l == f && cmp_r == t)) { /* Mux(f == t, t, f) -> f */
1380 				n = f;
1381 				DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1382 				return n;
1383 			}
1384 			break;
1385 
1386 		case ir_relation_less_greater:
1387 		case ir_relation_unordered_less_greater:
1388 			if ((cmp_l == t && cmp_r == f) || /* Mux(t != f, t, f) -> t */
1389 					(cmp_l == f && cmp_r == t)) { /* Mux(f != t, t, f) -> t */
1390 				n = t;
1391 				DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1392 				return n;
1393 			}
1394 			break;
1395 		default:
1396 			break;
1397 		}
1398 
1399 		/*
1400 		 * Note: normalization puts the constant on the right side,
1401 		 * so we check only one case.
1402 		 */
1403 		if (cmp_l == t && tarval_is_null(value_of(cmp_r))) {
1404 			/* Mux(t CMP 0, X, t) */
1405 			if (is_Minus(f) && get_Minus_op(f) == t) {
1406 				/* Mux(t CMP 0, -t, t) */
1407 				if (relation == ir_relation_equal) {
1408 					/* Mux(t == 0, -t, t)  ==>  -t */
1409 					n = f;
1410 					DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1411 				} else if (relation == ir_relation_less_greater || relation == ir_relation_unordered_less_greater) {
1412 					/* Mux(t != 0, -t, t)  ==> t */
1413 					n = t;
1414 					DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1415 				}
1416 			}
1417 		}
1418 	}
1419 
1420 	return n;
1421 }
1422 
1423 /**
1424  * Remove Confirm nodes if setting is on.
1425  * Replace Confirms(x, '=', Constlike) by Constlike.
1426  */
equivalent_node_Confirm(ir_node * n)1427 static ir_node *equivalent_node_Confirm(ir_node *n)
1428 {
1429 	ir_node    *pred     = get_Confirm_value(n);
1430 	ir_relation relation = get_Confirm_relation(n);
1431 
1432 	while (is_Confirm(pred) && relation == get_Confirm_relation(pred)) {
1433 		/*
1434 		 * rare case: two identical Confirms one after another,
1435 		 * replace the second one with the first.
1436 		 */
1437 		n    = pred;
1438 		pred = get_Confirm_value(n);
1439 	}
1440 	return n;
1441 }
1442 
1443 /**
1444  * equivalent_node() returns a node equivalent to input n. It skips all nodes that
1445  * perform no actual computation, as, e.g., the Id nodes.  It does not create
1446  * new nodes.  It is therefore safe to free n if the node returned is not n.
1447  * If a node returns a Tuple we can not just skip it.  If the size of the
1448  * in array fits, we transform n into a tuple (e.g., Div).
1449  */
equivalent_node(ir_node * n)1450 ir_node *equivalent_node(ir_node *n)
1451 {
1452 	if (n->op->ops.equivalent_node)
1453 		return n->op->ops.equivalent_node(n);
1454 	return n;
1455 }
1456 
1457 /**
1458  * Returns non-zero if a node is a Phi node
1459  * with all predecessors constant.
1460  */
is_const_Phi(ir_node * n)1461 static int is_const_Phi(ir_node *n)
1462 {
1463 	int i;
1464 
1465 	if (! is_Phi(n) || get_irn_arity(n) == 0)
1466 		return 0;
1467 	for (i = get_irn_arity(n) - 1; i >= 0; --i) {
1468 		if (! is_Const(get_irn_n(n, i)))
1469 			return 0;
1470 	}
1471 	return 1;
1472 }
1473 
1474 typedef ir_tarval *(*tarval_sub_type)(ir_tarval *a, ir_tarval *b, ir_mode *mode);
1475 typedef ir_tarval *(*tarval_binop_type)(ir_tarval *a, ir_tarval *b);
1476 
1477 /**
1478  * in reality eval_func should be tarval (*eval_func)() but incomplete
1479  * declarations are bad style and generate noisy warnings
1480  */
1481 typedef void (*eval_func)(void);
1482 
1483 /**
1484  * Wrapper for the tarval binop evaluation, tarval_sub has one more parameter.
1485  */
do_eval(eval_func eval,ir_tarval * a,ir_tarval * b,ir_mode * mode)1486 static ir_tarval *do_eval(eval_func eval, ir_tarval *a, ir_tarval *b, ir_mode *mode)
1487 {
1488 	if (eval == (eval_func) tarval_sub) {
1489 		tarval_sub_type func = (tarval_sub_type)eval;
1490 
1491 		return func(a, b, mode);
1492 	} else {
1493 		tarval_binop_type func = (tarval_binop_type)eval;
1494 
1495 		return func(a, b);
1496 	}
1497 }
1498 
1499 /**
1500  * Apply an evaluator on a binop with a constant operators (and one Phi).
1501  *
1502  * @param phi    the Phi node
1503  * @param other  the other operand
1504  * @param eval   an evaluator function
1505  * @param mode   the mode of the result, may be different from the mode of the Phi!
1506  * @param left   if non-zero, other is the left operand, else the right
1507  *
1508  * @return a new Phi node if the conversion was successful, NULL else
1509  */
apply_binop_on_phi(ir_node * phi,ir_tarval * other,eval_func eval,ir_mode * mode,int left)1510 static ir_node *apply_binop_on_phi(ir_node *phi, ir_tarval *other, eval_func eval, ir_mode *mode, int left)
1511 {
1512 	int         n   = get_irn_arity(phi);
1513 	ir_tarval **tvs = ALLOCAN(ir_tarval*, n);
1514 	if (left) {
1515 		for (int i = 0; i < n; ++i) {
1516 			ir_node   *pred = get_irn_n(phi, i);
1517 			ir_tarval *tv   = get_Const_tarval(pred);
1518 			tv = do_eval(eval, other, tv, mode);
1519 
1520 			if (tv == tarval_bad) {
1521 				/* folding failed, bad */
1522 				return NULL;
1523 			}
1524 			tvs[i] = tv;
1525 		}
1526 	} else {
1527 		for (int i = 0; i < n; ++i) {
1528 			ir_node   *pred = get_irn_n(phi, i);
1529 			ir_tarval *tv   = get_Const_tarval(pred);
1530 			tv = do_eval(eval, tv, other, mode);
1531 
1532 			if (tv == tarval_bad) {
1533 				/* folding failed, bad */
1534 				return 0;
1535 			}
1536 			tvs[i] = tv;
1537 		}
1538 	}
1539 	ir_graph *irg = get_irn_irg(phi);
1540 	ir_node **res = ALLOCAN(ir_node*, n);
1541 	for (int i = 0; i < n; ++i) {
1542 		res[i] = new_r_Const(irg, tvs[i]);
1543 	}
1544 	ir_node *block = get_nodes_block(phi);
1545 	return new_r_Phi(block, n, res, mode);
1546 }
1547 
1548 /**
1549  * Apply an evaluator on a binop with two constant Phi.
1550  *
1551  * @param a      the left Phi node
1552  * @param b      the right Phi node
1553  * @param eval   an evaluator function
1554  * @param mode   the mode of the result, may be different from the mode of the Phi!
1555  *
1556  * @return a new Phi node if the conversion was successful, NULL else
1557  */
apply_binop_on_2_phis(ir_node * a,ir_node * b,eval_func eval,ir_mode * mode)1558 static ir_node *apply_binop_on_2_phis(ir_node *a, ir_node *b, eval_func eval, ir_mode *mode)
1559 {
1560 	if (get_nodes_block(a) != get_nodes_block(b))
1561 		return NULL;
1562 
1563 	int         n   = get_irn_arity(a);
1564 	ir_tarval **tvs = ALLOCAN(ir_tarval*, n);
1565 	for (int i = 0; i < n; ++i) {
1566 		ir_node   *pred_a = get_irn_n(a, i);
1567 		ir_tarval *tv_l   = get_Const_tarval(pred_a);
1568 		ir_node   *pred_b = get_irn_n(b, i);
1569 		ir_tarval *tv_r   = get_Const_tarval(pred_b);
1570 		ir_tarval *tv     = do_eval(eval, tv_l, tv_r, mode);
1571 
1572 		if (tv == tarval_bad) {
1573 			/* folding failed, bad */
1574 			return NULL;
1575 		}
1576 		tvs[i] = tv;
1577 	}
1578 	ir_graph *irg = get_irn_irg(a);
1579 	ir_node **res = ALLOCAN(ir_node*, n);
1580 	for (int i = 0; i < n; ++i) {
1581 		res[i] = new_r_Const(irg, tvs[i]);
1582 	}
1583 	ir_node *block = get_nodes_block(a);
1584 	return new_r_Phi(block, n, res, mode);
1585 }
1586 
1587 /**
1588  * Apply an evaluator on a unop with a constant operator (a Phi).
1589  *
1590  * @param phi    the Phi node
1591  * @param eval   an evaluator function
1592  *
1593  * @return a new Phi node if the conversion was successful, NULL else
1594  */
apply_unop_on_phi(ir_node * phi,ir_tarval * (* eval)(ir_tarval *))1595 static ir_node *apply_unop_on_phi(ir_node *phi, ir_tarval *(*eval)(ir_tarval *))
1596 {
1597 	int         n   = get_irn_arity(phi);
1598 	ir_tarval **tvs = ALLOCAN(ir_tarval*, n);
1599 	for (int i = 0; i < n; ++i) {
1600 		ir_node   *pred = get_irn_n(phi, i);
1601 		ir_tarval *tv   = get_Const_tarval(pred);
1602 		tv = eval(tv);
1603 
1604 		if (tv == tarval_bad) {
1605 			/* folding failed, bad */
1606 			return 0;
1607 		}
1608 		tvs[i] = tv;
1609 	}
1610 	ir_graph *irg  = get_irn_irg(phi);
1611 	ir_node **res  = ALLOCAN(ir_node*, n);
1612 	for (int i = 0; i < n; ++i) {
1613 		res[i] = new_r_Const(irg, tvs[i]);
1614 	}
1615 	ir_node *block = get_nodes_block(phi);
1616 	ir_mode *mode  = get_irn_mode(phi);
1617 	return new_r_Phi(block, n, res, mode);
1618 }
1619 
1620 /**
1621  * Apply a conversion on a constant operator (a Phi).
1622  *
1623  * @param phi    the Phi node
1624  *
1625  * @return a new Phi node if the conversion was successful, NULL else
1626  */
apply_conv_on_phi(ir_node * phi,ir_mode * mode)1627 static ir_node *apply_conv_on_phi(ir_node *phi, ir_mode *mode)
1628 {
1629 	int         n   = get_irn_arity(phi);
1630 	ir_tarval **tvs = ALLOCAN(ir_tarval*, n);
1631 	for (int i = 0; i < n; ++i) {
1632 		ir_node   *pred = get_irn_n(phi, i);
1633 		ir_tarval *tv   = get_Const_tarval(pred);
1634 		tv = tarval_convert_to(tv, mode);
1635 
1636 		if (tv == tarval_bad) {
1637 			/* folding failed, bad */
1638 			return 0;
1639 		}
1640 		tvs[i] = tv;
1641 	}
1642 	ir_graph *irg = get_irn_irg(phi);
1643 	ir_node **res = ALLOCAN(ir_node*, n);
1644 	for (int i = 0; i < n; ++i) {
1645 		res[i] = new_r_Const(irg, tvs[i]);
1646 	}
1647 	ir_node *block = get_nodes_block(phi);
1648 	return new_r_Phi(block, n, res, mode);
1649 }
1650 
1651 /**
1652  * Transform AddP(P, ConvIs(Iu)), AddP(P, ConvIu(Is)) and
1653  * SubP(P, ConvIs(Iu)), SubP(P, ConvIu(Is)).
1654  * If possible, remove the Conv's.
1655  */
transform_node_AddSub(ir_node * n)1656 static ir_node *transform_node_AddSub(ir_node *n)
1657 {
1658 	ir_mode *mode = get_irn_mode(n);
1659 
1660 	if (mode_is_reference(mode)) {
1661 		ir_node *left     = get_binop_left(n);
1662 		ir_node *right    = get_binop_right(n);
1663 		unsigned ref_bits = get_mode_size_bits(mode);
1664 
1665 		if (is_Conv(left)) {
1666 			ir_mode *lmode = get_irn_mode(left);
1667 			unsigned bits = get_mode_size_bits(lmode);
1668 
1669 			if (ref_bits == bits &&
1670 			    mode_is_int(lmode) &&
1671 			    get_mode_arithmetic(lmode) == irma_twos_complement) {
1672 				ir_node *pre      = get_Conv_op(left);
1673 				ir_mode *pre_mode = get_irn_mode(pre);
1674 
1675 				if (mode_is_int(pre_mode) &&
1676 				    get_mode_size_bits(pre_mode) == bits &&
1677 				    get_mode_arithmetic(pre_mode) == irma_twos_complement) {
1678 					/* ok, this conv just changes to sign, moreover the calculation
1679 					 * is done with same number of bits as our address mode, so
1680 					 * we can ignore the conv as address calculation can be viewed
1681 					 * as either signed or unsigned
1682 					 */
1683 					set_binop_left(n, pre);
1684 				}
1685 			}
1686 		}
1687 
1688 		if (is_Conv(right)) {
1689 			ir_mode *rmode = get_irn_mode(right);
1690 			unsigned bits = get_mode_size_bits(rmode);
1691 
1692 			if (ref_bits == bits &&
1693 			    mode_is_int(rmode) &&
1694 			    get_mode_arithmetic(rmode) == irma_twos_complement) {
1695 				ir_node *pre      = get_Conv_op(right);
1696 				ir_mode *pre_mode = get_irn_mode(pre);
1697 
1698 				if (mode_is_int(pre_mode) &&
1699 				    get_mode_size_bits(pre_mode) == bits &&
1700 				    get_mode_arithmetic(pre_mode) == irma_twos_complement) {
1701 					/* ok, this conv just changes to sign, moreover the calculation
1702 					 * is done with same number of bits as our address mode, so
1703 					 * we can ignore the conv as address calculation can be viewed
1704 					 * as either signed or unsigned
1705 					 */
1706 					set_binop_right(n, pre);
1707 				}
1708 			}
1709 		}
1710 
1711 		/* let address arithmetic use unsigned modes */
1712 		if (is_Const(right)) {
1713 			ir_mode *rmode = get_irn_mode(right);
1714 
1715 			if (mode_is_signed(rmode) && get_mode_arithmetic(rmode) == irma_twos_complement) {
1716 				/* convert a AddP(P, *s) into AddP(P, *u) */
1717 				ir_mode *nm = get_reference_mode_unsigned_eq(mode);
1718 
1719 				ir_node *pre = new_r_Conv(get_nodes_block(n), right, nm);
1720 				set_binop_right(n, pre);
1721 			}
1722 		}
1723 	}
1724 
1725 	return n;
1726 }
1727 
1728 #define HANDLE_BINOP_PHI(eval, a, b, c, mode)                     \
1729   do {                                                            \
1730   c = NULL;                                                       \
1731   if (is_Const(b) && is_const_Phi(a)) {                           \
1732     /* check for Op(Phi, Const) */                                \
1733     c = apply_binop_on_phi(a, get_Const_tarval(b), eval, mode, 0);\
1734   }                                                               \
1735   else if (is_Const(a) && is_const_Phi(b)) {                      \
1736     /* check for Op(Const, Phi) */                                \
1737     c = apply_binop_on_phi(b, get_Const_tarval(a), eval, mode, 1);\
1738   }                                                               \
1739   else if (is_const_Phi(a) && is_const_Phi(b)) {                  \
1740     /* check for Op(Phi, Phi) */                                  \
1741     c = apply_binop_on_2_phis(a, b, eval, mode);                  \
1742   }                                                               \
1743   if (c) {                                                        \
1744     DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI);                   \
1745     return c;                                                     \
1746   }                                                               \
1747   } while(0)
1748 
1749 #define HANDLE_UNOP_PHI(eval, a, c)               \
1750   do {                                            \
1751   c = NULL;                                       \
1752   if (is_const_Phi(a)) {                          \
1753     /* check for Op(Phi) */                       \
1754     c = apply_unop_on_phi(a, eval);               \
1755     if (c) {                                      \
1756       DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI); \
1757       return c;                                   \
1758     }                                             \
1759   }                                               \
1760   } while(0)
1761 
1762 /**
1763  * Create a 0 constant of given mode.
1764  */
create_zero_const(ir_graph * irg,ir_mode * mode)1765 static ir_node *create_zero_const(ir_graph *irg, ir_mode *mode)
1766 {
1767 	ir_tarval *tv   = get_mode_null(mode);
1768 	ir_node   *cnst = new_r_Const(irg, tv);
1769 
1770 	return cnst;
1771 }
1772 
is_shiftop(const ir_node * n)1773 static bool is_shiftop(const ir_node *n)
1774 {
1775 	return is_Shl(n) || is_Shr(n) || is_Shrs(n) || is_Rotl(n);
1776 }
1777 
1778 /* the order of the values is important! */
1779 typedef enum const_class {
1780 	const_const = 0,
1781 	const_like  = 1,
1782 	const_other = 2
1783 } const_class;
1784 
classify_const(const ir_node * n)1785 static const_class classify_const(const ir_node* n)
1786 {
1787 	if (is_Const(n))         return const_const;
1788 	if (is_irn_constlike(n)) return const_like;
1789 	return const_other;
1790 }
1791 
1792 /**
1793  * Determines whether r is more constlike or has a larger index (in that order)
1794  * than l.
1795  */
operands_are_normalized(const ir_node * l,const ir_node * r)1796 static bool operands_are_normalized(const ir_node *l, const ir_node *r)
1797 {
1798 	const const_class l_order = classify_const(l);
1799 	const const_class r_order = classify_const(r);
1800 	return
1801 		l_order > r_order ||
1802 		(l_order == r_order && get_irn_idx(l) <= get_irn_idx(r));
1803 }
1804 
is_cmp_unequal(const ir_node * node)1805 static bool is_cmp_unequal(const ir_node *node)
1806 {
1807 	ir_relation relation = get_Cmp_relation(node);
1808 	ir_node    *left     = get_Cmp_left(node);
1809 	ir_node    *right    = get_Cmp_right(node);
1810 	ir_mode    *mode     = get_irn_mode(left);
1811 
1812 	if (relation == ir_relation_less_greater)
1813 		return true;
1814 
1815 	if (!mode_is_signed(mode) && is_Const(right) && is_Const_null(right))
1816 		return relation == ir_relation_greater;
1817 	return false;
1818 }
1819 
1820 /**
1821  * returns true for Cmp(x == 0) or Cmp(x != 0)
1822  */
is_cmp_equality_zero(const ir_node * node)1823 static bool is_cmp_equality_zero(const ir_node *node)
1824 {
1825 	ir_relation relation;
1826 	ir_node    *right    = get_Cmp_right(node);
1827 
1828 	if (!is_Const(right) || !is_Const_null(right))
1829 		return false;
1830 	relation = get_Cmp_relation(node);
1831 	return relation == ir_relation_equal
1832 		|| relation == ir_relation_less_greater
1833 		|| (!mode_is_signed(get_irn_mode(right))
1834 		    && relation == ir_relation_greater);
1835 }
1836 
1837 /**
1838  * Optimize a Or(And(Or(And(v,c4),c3),c2),c1) pattern if possible.
1839  * Such pattern may arise in bitfield stores.
1840  *
1841  * value  c4                  value      c4 & c2
1842  *    AND     c3                    AND           c1 | c3
1843  *        OR     c2      ===>               OR
1844  *           AND    c1
1845  *               OR
1846  *
1847  *
1848  * value  c2                 value  c1
1849  *     AND   c1    ===>           OR     if (c1 | c2) == 0x111..11
1850  *        OR
1851  */
transform_node_Or_bf_store(ir_node * irn_or)1852 static ir_node *transform_node_Or_bf_store(ir_node *irn_or)
1853 {
1854 	ir_node *irn_and, *c1;
1855 	ir_node *or_l, *c2;
1856 	ir_node *and_l, *c3;
1857 	ir_node *value, *c4;
1858 	ir_node *new_and, *new_const, *block;
1859 	ir_mode *mode = get_irn_mode(irn_or);
1860 
1861 	ir_tarval *tv1, *tv2, *tv3, *tv4, *tv;
1862 
1863 	for (;;) {
1864 		ir_graph *irg;
1865 		irn_and = get_binop_left(irn_or);
1866 		c1      = get_binop_right(irn_or);
1867 		if (!is_Const(c1) || !is_And(irn_and))
1868 			return irn_or;
1869 
1870 		or_l = get_binop_left(irn_and);
1871 		c2   = get_binop_right(irn_and);
1872 		if (!is_Const(c2))
1873 			return irn_or;
1874 
1875 		tv1 = get_Const_tarval(c1);
1876 		tv2 = get_Const_tarval(c2);
1877 
1878 		tv = tarval_or(tv1, tv2);
1879 		if (tarval_is_all_one(tv)) {
1880 			/* the AND does NOT clear a bit with isn't set by the OR */
1881 			set_binop_left(irn_or, or_l);
1882 			set_binop_right(irn_or, c1);
1883 
1884 			/* check for more */
1885 			continue;
1886 		}
1887 
1888 		if (!is_Or(or_l) && !is_Or_Eor_Add(or_l))
1889 			return irn_or;
1890 
1891 		and_l = get_binop_left(or_l);
1892 		c3    = get_binop_right(or_l);
1893 		if (!is_Const(c3) || !is_And(and_l))
1894 			return irn_or;
1895 
1896 		value = get_binop_left(and_l);
1897 		c4    = get_binop_right(and_l);
1898 		if (!is_Const(c4))
1899 			return irn_or;
1900 
1901 		/* ok, found the pattern, check for conditions */
1902 		assert(mode == get_irn_mode(irn_and));
1903 		assert(mode == get_irn_mode(or_l));
1904 		assert(mode == get_irn_mode(and_l));
1905 
1906 		tv3 = get_Const_tarval(c3);
1907 		tv4 = get_Const_tarval(c4);
1908 
1909 		tv = tarval_or(tv4, tv2);
1910 		if (!tarval_is_all_one(tv)) {
1911 			/* have at least one 0 at the same bit position */
1912 			return irn_or;
1913 		}
1914 
1915 		if (tv3 != tarval_andnot(tv3, tv4)) {
1916 			/* bit in the or_mask is outside the and_mask */
1917 			return irn_or;
1918 		}
1919 
1920 		if (tv1 != tarval_andnot(tv1, tv2)) {
1921 			/* bit in the or_mask is outside the and_mask */
1922 			return irn_or;
1923 		}
1924 
1925 		/* ok, all conditions met */
1926 		block = get_nodes_block(irn_or);
1927 		irg   = get_irn_irg(block);
1928 
1929 		new_and = new_r_And(block, value, new_r_Const(irg, tarval_and(tv4, tv2)), mode);
1930 
1931 		new_const = new_r_Const(irg, tarval_or(tv3, tv1));
1932 
1933 		set_binop_left(irn_or, new_and);
1934 		set_binop_right(irn_or, new_const);
1935 
1936 		/* check for more */
1937 	}
1938 }
1939 
1940 /**
1941  * Optimize an Or(shl(x, c), shr(x, bits - c)) into a Rotl
1942  */
transform_node_Or_Rotl(ir_node * irn_or)1943 static ir_node *transform_node_Or_Rotl(ir_node *irn_or)
1944 {
1945 	ir_mode *mode = get_irn_mode(irn_or);
1946 	ir_node *shl, *shr, *block;
1947 	ir_node *irn, *x, *c1, *c2, *n;
1948 	ir_tarval *tv1, *tv2;
1949 
1950 	/* some backends can't handle rotl */
1951 	if (!be_get_backend_param()->support_rotl)
1952 		return irn_or;
1953 
1954 	if (! mode_is_int(mode))
1955 		return irn_or;
1956 
1957 	shl = get_binop_left(irn_or);
1958 	shr = get_binop_right(irn_or);
1959 
1960 	if (is_Shr(shl)) {
1961 		if (!is_Shl(shr))
1962 			return irn_or;
1963 
1964 		irn = shl;
1965 		shl = shr;
1966 		shr = irn;
1967 	} else if (!is_Shl(shl)) {
1968 		return irn_or;
1969 	} else if (!is_Shr(shr)) {
1970 		return irn_or;
1971 	}
1972 	x = get_Shl_left(shl);
1973 	if (x != get_Shr_left(shr))
1974 		return irn_or;
1975 
1976 	c1 = get_Shl_right(shl);
1977 	c2 = get_Shr_right(shr);
1978 	if (is_Const(c1) && is_Const(c2)) {
1979 		tv1 = get_Const_tarval(c1);
1980 		if (! tarval_is_long(tv1))
1981 			return irn_or;
1982 
1983 		tv2 = get_Const_tarval(c2);
1984 		if (! tarval_is_long(tv2))
1985 			return irn_or;
1986 
1987 		if (get_tarval_long(tv1) + get_tarval_long(tv2)
1988 				!= (int) get_mode_size_bits(mode))
1989 			return irn_or;
1990 
1991 		/* yet, condition met */
1992 		block = get_nodes_block(irn_or);
1993 
1994 		n = new_r_Rotl(block, x, c1, mode);
1995 
1996 		DBG_OPT_ALGSIM1(irn_or, shl, shr, n, FS_OPT_OR_SHFT_TO_ROTL);
1997 		return n;
1998 	}
1999 
2000 	/* Note: the obvious rot formulation (a << x) | (a >> (32-x)) gets
2001 	 * transformed to (a << x) | (a >> -x) by transform_node_shift_modulo() */
2002 	if (!ir_is_negated_value(c1, c2)) {
2003 		return irn_or;
2004 	}
2005 
2006 	/* yet, condition met */
2007 	block = get_nodes_block(irn_or);
2008 	n = new_r_Rotl(block, x, c1, mode);
2009 	DBG_OPT_ALGSIM0(irn_or, n, FS_OPT_OR_SHFT_TO_ROTL);
2010 	return n;
2011 }
2012 
2013 /**
2014  * Prototype of a recursive transform function
2015  * for bitwise distributive transformations.
2016  */
2017 typedef ir_node* (*recursive_transform)(ir_node *n);
2018 
2019 /**
2020  * makes use of distributive laws for and, or, eor
2021  *     and(a OP c, b OP c) -> and(a, b) OP c
2022  * note, might return a different op than n
2023  */
transform_bitwise_distributive(ir_node * n,recursive_transform trans_func)2024 static ir_node *transform_bitwise_distributive(ir_node *n,
2025                                                recursive_transform trans_func)
2026 {
2027 	ir_node *oldn    = n;
2028 	ir_node *a       = get_binop_left(n);
2029 	ir_node *b       = get_binop_right(n);
2030 	ir_op   *op      = get_irn_op(a);
2031 	ir_op   *op_root = get_irn_op(n);
2032 
2033 	if (op != get_irn_op(b))
2034 		return n;
2035 
2036 	/* and(conv(a), conv(b)) -> conv(and(a,b)) */
2037 	if (op == op_Conv) {
2038 		ir_node *a_op   = get_Conv_op(a);
2039 		ir_node *b_op   = get_Conv_op(b);
2040 		ir_mode *a_mode = get_irn_mode(a_op);
2041 		ir_mode *b_mode = get_irn_mode(b_op);
2042 		if (a_mode == b_mode && (mode_is_int(a_mode) || a_mode == mode_b)) {
2043 			ir_node *blk = get_nodes_block(n);
2044 
2045 			n = exact_copy(n);
2046 			set_binop_left(n, a_op);
2047 			set_binop_right(n, b_op);
2048 			set_irn_mode(n, a_mode);
2049 			n = trans_func(n);
2050 			n = new_r_Conv(blk, n, get_irn_mode(oldn));
2051 
2052 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
2053 			return n;
2054 		}
2055 	}
2056 
2057 	if (op == op_Eor) {
2058 		/* nothing to gain here */
2059 		return n;
2060 	}
2061 
2062 	if (op == op_Shrs || op == op_Shr || op == op_Shl
2063 			|| op == op_And || op == op_Or || op == op_Eor) {
2064 		ir_node *a_left  = get_binop_left(a);
2065 		ir_node *a_right = get_binop_right(a);
2066 		ir_node *b_left  = get_binop_left(b);
2067 		ir_node *b_right = get_binop_right(b);
2068 		ir_node *c       = NULL;
2069 		ir_node *op1     = NULL;
2070 		ir_node *op2     = NULL;
2071 
2072 		if (is_op_commutative(op)) {
2073 			if (a_left == b_left) {
2074 				c   = a_left;
2075 				op1 = a_right;
2076 				op2 = b_right;
2077 			} else if (a_left == b_right) {
2078 				c   = a_left;
2079 				op1 = a_right;
2080 				op2 = b_left;
2081 			} else if (a_right == b_left) {
2082 				c   = a_right;
2083 				op1 = a_left;
2084 				op2 = b_right;
2085 			}
2086 		}
2087 		if (a_right == b_right) {
2088 			c   = a_right;
2089 			op1 = a_left;
2090 			op2 = b_left;
2091 		}
2092 
2093 		if (c != NULL) {
2094 			/* (a sop c) & (b sop c) => (a & b) sop c */
2095 			ir_node *blk = get_nodes_block(n);
2096 
2097 			ir_node *new_n = exact_copy(n);
2098 			set_binop_left(new_n, op1);
2099 			set_binop_right(new_n, op2);
2100 			new_n = trans_func(new_n);
2101 
2102 			if (op_root == op_Eor && op == op_Or) {
2103 				dbg_info  *dbgi = get_irn_dbg_info(n);
2104 				ir_mode   *mode = get_irn_mode(c);
2105 
2106 				c = new_rd_Not(dbgi, blk, c, mode);
2107 				n = new_rd_And(dbgi, blk, new_n, c, mode);
2108 			} else {
2109 				n = exact_copy(a);
2110 				set_nodes_block(n, blk);
2111 				set_binop_left(n, new_n);
2112 				set_binop_right(n, c);
2113 				add_identities(n);
2114 			}
2115 
2116 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_AND);
2117 			return n;
2118 		}
2119 	}
2120 
2121 	return n;
2122 }
2123 
2124 /**
2125  * normalisation: (x >> c1) & c2   to   (x & (c2<<c1)) >> c1
2126  *  (we can use:
2127  *    - and, or, xor          instead of &
2128  *    - Shl, Shr, Shrs, rotl  instead of >>
2129  *    (with a special case for Or/Xor + Shrs)
2130  *
2131  * This normalisation is usually good for the backend since << C can often be
2132  * matched as address-mode.
2133  */
transform_node_bitop_shift(ir_node * n)2134 static ir_node *transform_node_bitop_shift(ir_node *n)
2135 {
2136 	ir_graph  *irg   = get_irn_irg(n);
2137 	ir_node   *left  = get_binop_left(n);
2138 	ir_node   *right = get_binop_right(n);
2139 	ir_mode   *mode  = get_irn_mode(n);
2140 	ir_node   *shift_left;
2141 	ir_node   *shift_right;
2142 	ir_node   *block;
2143 	dbg_info  *dbg_bitop;
2144 	dbg_info  *dbg_shift;
2145 	ir_node   *new_bitop;
2146 	ir_node   *new_shift;
2147 	ir_node   *new_const;
2148 	ir_tarval *tv1;
2149 	ir_tarval *tv2;
2150 	ir_tarval *tv_bitop;
2151 
2152 	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_NORMALISATION2))
2153 		return n;
2154 
2155 	assert(is_And(n) || is_Or(n) || is_Eor(n) || is_Or_Eor_Add(n));
2156 	if (!is_Const(right) || !is_shiftop(left))
2157 		return n;
2158 
2159 	shift_left  = get_binop_left(left);
2160 	shift_right = get_binop_right(left);
2161 	if (!is_Const(shift_right))
2162 		return n;
2163 
2164 	/* doing it with Shrs is not legal if the Or/Eor affects the topmost bit */
2165 	if (is_Shrs(left)) {
2166 		/* TODO this could be improved */
2167 		return n;
2168 	}
2169 
2170 	irg       = get_irn_irg(n);
2171 	block     = get_nodes_block(n);
2172 	dbg_bitop = get_irn_dbg_info(n);
2173 	dbg_shift = get_irn_dbg_info(left);
2174 	tv1       = get_Const_tarval(shift_right);
2175 	tv2       = get_Const_tarval(right);
2176 	assert(get_tarval_mode(tv2) == mode);
2177 
2178 	if (is_Shl(left)) {
2179 		tv_bitop = tarval_shr(tv2, tv1);
2180 
2181 		/* Check whether we have lost some bits during the right shift. */
2182 		if (!is_And(n)) {
2183 			ir_tarval *tv_back_again = tarval_shl(tv_bitop, tv1);
2184 
2185 			if (tarval_cmp(tv_back_again, tv2) != ir_relation_equal)
2186 				return n;
2187 		}
2188 	} else if (is_Shr(left)) {
2189 		if (!is_And(n)) {
2190 			/*
2191 			 * TODO this can be improved by checking whether
2192 			 *      the left shift produces an overflow
2193 			 */
2194 			return n;
2195 		}
2196 		tv_bitop = tarval_shl(tv2, tv1);
2197 	} else {
2198 		assert(is_Rotl(left));
2199 		tv_bitop = tarval_rotl(tv2, tarval_neg(tv1));
2200 	}
2201 	new_const = new_r_Const(irg, tv_bitop);
2202 
2203 	if (is_And(n)) {
2204 		new_bitop = new_rd_And(dbg_bitop, block, shift_left, new_const, mode);
2205 	} else if (is_Or(n) || is_Or_Eor_Add(n)) {
2206 		new_bitop = new_rd_Or(dbg_bitop, block, shift_left, new_const, mode);
2207 	} else {
2208 		assert(is_Eor(n));
2209 		new_bitop = new_rd_Eor(dbg_bitop, block, shift_left, new_const, mode);
2210 	}
2211 
2212 	if (is_Shl(left)) {
2213 		new_shift = new_rd_Shl(dbg_shift, block, new_bitop, shift_right, mode);
2214 	} else if (is_Shr(left)) {
2215 		new_shift = new_rd_Shr(dbg_shift, block, new_bitop, shift_right, mode);
2216 	} else {
2217 		assert(is_Rotl(left));
2218 		new_shift = new_rd_Rotl(dbg_shift, block, new_bitop, shift_right, mode);
2219 	}
2220 
2221 	return new_shift;
2222 }
2223 
complement_values(const ir_node * a,const ir_node * b)2224 static bool complement_values(const ir_node *a, const ir_node *b)
2225 {
2226 	if (is_Not(a) && get_Not_op(a) == b)
2227 		return true;
2228 	if (is_Not(b) && get_Not_op(b) == a)
2229 		return true;
2230 	if (is_Const(a) && is_Const(b)) {
2231 		ir_tarval *tv_a = get_Const_tarval(a);
2232 		ir_tarval *tv_b = get_Const_tarval(b);
2233 		return tarval_not(tv_a) == tv_b;
2234 	}
2235 	return false;
2236 }
2237 
2238 typedef ir_tarval *(tv_fold_binop_func)(ir_tarval *a, ir_tarval *b);
2239 
2240 /**
2241  * for associative operations fold:
2242  *   op(op(x, c0), c1) to op(x, op(c0, c1)) with constants folded.
2243  * This is a "light" version of the reassociation phase
2244  */
fold_constant_associativity(ir_node * node,tv_fold_binop_func fold)2245 static ir_node *fold_constant_associativity(ir_node *node,
2246                                             tv_fold_binop_func fold)
2247 {
2248 	ir_graph  *irg;
2249 	ir_op     *op;
2250 	ir_node   *left;
2251 	ir_node   *right = get_binop_right(node);
2252 	ir_node   *left_right;
2253 	ir_node   *left_left;
2254 	ir_tarval *c0;
2255 	ir_tarval *c1;
2256 	ir_tarval *new_c;
2257 	ir_node   *new_const;
2258 	ir_node   *new_node;
2259 	if (!is_Const(right))
2260 		return node;
2261 
2262 	op   = get_irn_op(node);
2263 	left = get_binop_left(node);
2264 	if (get_irn_op(left) != op)
2265 		return node;
2266 
2267 	left_right = get_binop_right(left);
2268 	if (!is_Const(left_right))
2269 		return node;
2270 
2271 	left_left = get_binop_left(left);
2272 	c0        = get_Const_tarval(left_right);
2273 	c1        = get_Const_tarval(right);
2274 	irg       = get_irn_irg(node);
2275 	if (get_tarval_mode(c0) != get_tarval_mode(c1))
2276 		return node;
2277 	new_c     = fold(c0, c1);
2278 	if (new_c == tarval_bad)
2279 		return node;
2280 	new_const = new_r_Const(irg, new_c);
2281 	new_node  = exact_copy(node);
2282 	set_binop_left(new_node, left_left);
2283 	set_binop_right(new_node, new_const);
2284 	return new_node;
2285 }
2286 
2287 /**
2288  * Transform an Or.
2289  */
transform_node_Or_(ir_node * n)2290 static ir_node *transform_node_Or_(ir_node *n)
2291 {
2292 	ir_node *oldn = n;
2293 	ir_node *a    = get_binop_left(n);
2294 	ir_node *b    = get_binop_right(n);
2295 	ir_node *c;
2296 	ir_mode *mode;
2297 
2298 	n = fold_constant_associativity(n, tarval_or);
2299 	if (n != oldn)
2300 		return n;
2301 
2302 	if (is_Not(a) && is_Not(b)) {
2303 		/* ~a | ~b = ~(a&b) */
2304 		ir_node *block = get_nodes_block(n);
2305 
2306 		mode = get_irn_mode(n);
2307 		a = get_Not_op(a);
2308 		b = get_Not_op(b);
2309 		n = new_rd_And(get_irn_dbg_info(n), block, a, b, mode);
2310 		n = new_rd_Not(get_irn_dbg_info(n), block, n, mode);
2311 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
2312 		return n;
2313 	}
2314 
2315 	/* we can combine the relations of two compares with the same operands */
2316 	if (is_Cmp(a) && is_Cmp(b)) {
2317 		ir_node *a_left  = get_Cmp_left(a);
2318 		ir_node *a_right = get_Cmp_right(a);
2319 		ir_node *b_left  = get_Cmp_left(b);
2320 		ir_node *b_right = get_Cmp_right(b);
2321 		if (a_left == b_left && b_left == b_right) {
2322 			dbg_info   *dbgi         = get_irn_dbg_info(n);
2323 			ir_node    *block        = get_nodes_block(n);
2324 			ir_relation a_relation   = get_Cmp_relation(a);
2325 			ir_relation b_relation   = get_Cmp_relation(b);
2326 			ir_relation new_relation = a_relation | b_relation;
2327 			return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
2328 		}
2329 		/* Cmp(a!=b) or Cmp(c!=d) => Cmp((a^b)|(c^d) != 0) */
2330 		if (is_cmp_unequal(a) && is_cmp_unequal(b)
2331 		    && !mode_is_float(get_irn_mode(a_left))
2332 		    && !mode_is_float(get_irn_mode(b_left))) {
2333 			if (values_in_mode(get_irn_mode(a_left), get_irn_mode(b_left))) {
2334 				ir_graph *irg    = get_irn_irg(n);
2335 				dbg_info *dbgi   = get_irn_dbg_info(n);
2336 				ir_node  *block  = get_nodes_block(n);
2337 				ir_mode  *a_mode = get_irn_mode(a_left);
2338 				ir_mode  *b_mode = get_irn_mode(b_left);
2339 				ir_node  *xora   = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
2340 				ir_node  *xorb   = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
2341 				ir_node  *conv   = new_rd_Conv(dbgi, block, xora, b_mode);
2342 				ir_node  *orn    = new_rd_Or(dbgi, block, conv, xorb, b_mode);
2343 				ir_node  *zero   = create_zero_const(irg, b_mode);
2344 				return new_rd_Cmp(dbgi, block, orn, zero, ir_relation_less_greater);
2345 			}
2346 			if (values_in_mode(get_irn_mode(b_left), get_irn_mode(a_left))) {
2347 				ir_graph *irg    = get_irn_irg(n);
2348 				dbg_info *dbgi   = get_irn_dbg_info(n);
2349 				ir_node  *block  = get_nodes_block(n);
2350 				ir_mode  *a_mode = get_irn_mode(a_left);
2351 				ir_mode  *b_mode = get_irn_mode(b_left);
2352 				ir_node  *xora   = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
2353 				ir_node  *xorb   = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
2354 				ir_node  *conv   = new_rd_Conv(dbgi, block, xorb, a_mode);
2355 				ir_node  *orn    = new_rd_Or(dbgi, block, xora, conv, a_mode);
2356 				ir_node  *zero   = create_zero_const(irg, a_mode);
2357 				return new_rd_Cmp(dbgi, block, orn, zero, ir_relation_less_greater);
2358 			}
2359 		}
2360 	}
2361 
2362 	mode = get_irn_mode(n);
2363 	HANDLE_BINOP_PHI((eval_func) tarval_or, a, b, c, mode);
2364 
2365 	n = transform_node_Or_bf_store(n);
2366 	if (n != oldn)
2367 		return n;
2368 	n = transform_node_Or_Rotl(n);
2369 	if (n != oldn)
2370 		return n;
2371 
2372 	n = transform_bitwise_distributive(n, transform_node_Or_);
2373 	if (n != oldn)
2374 		return n;
2375 	n = transform_node_bitop_shift(n);
2376 	if (n != oldn)
2377 		return n;
2378 
2379 	return n;
2380 }
2381 
transform_node_Or(ir_node * n)2382 static ir_node *transform_node_Or(ir_node *n)
2383 {
2384 	if (is_Or_Eor_Add(n)) {
2385 		dbg_info *dbgi  = get_irn_dbg_info(n);
2386 		ir_node  *block = get_nodes_block(n);
2387 		ir_node  *left  = get_Or_left(n);
2388 		ir_node  *right = get_Or_right(n);
2389 		ir_mode  *mode  = get_irn_mode(n);
2390 		return new_rd_Add(dbgi, block, left, right, mode);
2391 	}
2392 	return transform_node_Or_(n);
2393 }
2394 
2395 /**
2396  * Transform an Eor.
2397  */
transform_node_Eor_(ir_node * n)2398 static ir_node *transform_node_Eor_(ir_node *n)
2399 {
2400 	ir_node *oldn = n;
2401 	ir_node *a    = get_binop_left(n);
2402 	ir_node *b    = get_binop_right(n);
2403 	ir_mode *mode = get_irn_mode(n);
2404 	ir_node *c;
2405 
2406 	n = fold_constant_associativity(n, tarval_eor);
2407 	if (n != oldn)
2408 		return n;
2409 
2410 	/* we can combine the relations of two compares with the same operands */
2411 	if (is_Cmp(a) && is_Cmp(b)) {
2412 		ir_node *a_left  = get_Cmp_left(a);
2413 		ir_node *a_right = get_Cmp_left(a);
2414 		ir_node *b_left  = get_Cmp_left(b);
2415 		ir_node *b_right = get_Cmp_right(b);
2416 		if (a_left == b_left && b_left == b_right) {
2417 			dbg_info   *dbgi         = get_irn_dbg_info(n);
2418 			ir_node    *block        = get_nodes_block(n);
2419 			ir_relation a_relation   = get_Cmp_relation(a);
2420 			ir_relation b_relation   = get_Cmp_relation(b);
2421 			ir_relation new_relation = a_relation ^ b_relation;
2422 			return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
2423 		}
2424 	}
2425 
2426 	HANDLE_BINOP_PHI((eval_func) tarval_eor, a, b, c, mode);
2427 
2428 	/* normalize not nodes... ~a ^ b <=> a ^ ~b */
2429 	if (is_Not(a) && operands_are_normalized(get_Not_op(a), b)) {
2430 		dbg_info *dbg      = get_irn_dbg_info(n);
2431 		ir_node  *block    = get_nodes_block(n);
2432 		ir_node  *new_not  = new_rd_Not(dbg, block, b, mode);
2433 		ir_node  *new_left = get_Not_op(a);
2434 		n = new_rd_Eor(dbg, block, new_left, new_not, mode);
2435 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
2436 		return n;
2437 	} else if (is_Not(b) && !operands_are_normalized(a, get_Not_op(b))) {
2438 		dbg_info *dbg       = get_irn_dbg_info(n);
2439 		ir_node  *block     = get_nodes_block(n);
2440 		ir_node  *new_not   = new_rd_Not(dbg, block, a, mode);
2441 		ir_node  *new_right = get_Not_op(b);
2442 		n = new_rd_Eor(dbg, block, new_not, new_right, mode);
2443 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
2444 		return n;
2445 	}
2446 
2447 	/* x ^ 1...1 -> ~1 */
2448 	if (is_Const(b) && is_Const_all_one(b)) {
2449 		n = new_r_Not(get_nodes_block(n), a, mode);
2450 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
2451 		return n;
2452 	}
2453 
2454 	n = transform_bitwise_distributive(n, transform_node_Eor_);
2455 	if (n != oldn)
2456 		return n;
2457 	n = transform_node_bitop_shift(n);
2458 	if (n != oldn)
2459 		return n;
2460 
2461 	return n;
2462 }
2463 
transform_node_Eor(ir_node * n)2464 static ir_node *transform_node_Eor(ir_node *n)
2465 {
2466 	if (is_Or_Eor_Add(n)) {
2467 		dbg_info *dbgi  = get_irn_dbg_info(n);
2468 		ir_node  *block = get_nodes_block(n);
2469 		ir_node  *left  = get_Eor_left(n);
2470 		ir_node  *right = get_Eor_right(n);
2471 		ir_mode  *mode  = get_irn_mode(n);
2472 		return new_rd_Add(dbgi, block, left, right, mode);
2473 	}
2474 	return transform_node_Eor_(n);
2475 }
2476 
2477 /**
2478  * Do the AddSub optimization, then Transform
2479  *   Constant folding on Phi
2480  *   Add(a,a)          -> Mul(a, 2)
2481  *   Add(Mul(a, x), a) -> Mul(a, x+1)
2482  * if the mode is integer or float.
2483  * Transform Add(a,-b) into Sub(a,b).
2484  * Reassociation might fold this further.
2485  */
transform_node_Add(ir_node * n)2486 static ir_node *transform_node_Add(ir_node *n)
2487 {
2488 	ir_mode *mode;
2489 	ir_node *a;
2490 	ir_node *b;
2491 	ir_node *c;
2492 	ir_node *oldn = n;
2493 
2494 	n = fold_constant_associativity(n, tarval_add);
2495 	if (n != oldn)
2496 		return n;
2497 
2498 	n = transform_node_AddSub(n);
2499 	if (n != oldn)
2500 		return n;
2501 
2502 	a    = get_Add_left(n);
2503 	b    = get_Add_right(n);
2504 	mode = get_irn_mode(n);
2505 
2506 	if (mode_is_reference(mode)) {
2507 		ir_mode *lmode = get_irn_mode(a);
2508 
2509 		if (is_Const(b) && is_Const_null(b) && mode_is_int(lmode)) {
2510 			/* an Add(a, NULL) is a hidden Conv */
2511 			dbg_info *dbg = get_irn_dbg_info(n);
2512 			return new_rd_Conv(dbg, get_nodes_block(n), a, mode);
2513 		}
2514 	}
2515 
2516 	if (is_Const(b) && get_mode_arithmetic(mode) == irma_twos_complement) {
2517 		ir_tarval *tv  = get_Const_tarval(b);
2518 		ir_tarval *min = get_mode_min(mode);
2519 		/* if all bits are set, then this has the same effect as a Not.
2520 		 * Note that the following == gives false for different modes which
2521 		 * is exactly what we want */
2522 		if (tv == min) {
2523 			dbg_info *dbgi  = get_irn_dbg_info(n);
2524 			ir_graph *irg   = get_irn_irg(n);
2525 			ir_node  *block = get_nodes_block(n);
2526 			ir_node  *cnst  = new_r_Const(irg, min);
2527 			return new_rd_Eor(dbgi, block, a, cnst, mode);
2528 		}
2529 	}
2530 
2531 	HANDLE_BINOP_PHI((eval_func) tarval_add, a, b, c, mode);
2532 
2533 	/* for FP the following optimizations are only allowed if
2534 	 * fp_strict_algebraic is disabled */
2535 	if (mode_is_float(mode)) {
2536 		ir_graph *irg = get_irn_irg(n);
2537 		if (get_irg_fp_model(irg) & fp_strict_algebraic)
2538 			return n;
2539 	}
2540 
2541 	if (mode_is_num(mode)) {
2542 		ir_graph *irg = get_irn_irg(n);
2543 		/* the following code leads to endless recursion when Mul are replaced
2544 		 * by a simple instruction chain */
2545 		if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_ARCH_DEP)
2546 				&& a == b && mode_is_int(mode)) {
2547 			ir_node *block = get_nodes_block(n);
2548 
2549 			n = new_rd_Mul(
2550 				get_irn_dbg_info(n),
2551 				block,
2552 				a,
2553 				new_r_Const_long(irg, mode, 2),
2554 				mode);
2555 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_A);
2556 			return n;
2557 		}
2558 		if (is_Minus(a)) {
2559 			n = new_rd_Sub(
2560 					get_irn_dbg_info(n),
2561 					get_nodes_block(n),
2562 					b,
2563 					get_Minus_op(a),
2564 					mode);
2565 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B);
2566 			return n;
2567 		}
2568 		if (is_Minus(b)) {
2569 			n = new_rd_Sub(
2570 					get_irn_dbg_info(n),
2571 					get_nodes_block(n),
2572 					a,
2573 					get_Minus_op(b),
2574 					mode);
2575 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B);
2576 			return n;
2577 		}
2578 		if (get_mode_arithmetic(mode) == irma_twos_complement) {
2579 			/* Here we rely on constants be on the RIGHT side */
2580 			if (is_Not(a)) {
2581 				ir_node *op = get_Not_op(a);
2582 
2583 				if (is_Const(b) && is_Const_one(b)) {
2584 					/* ~x + 1 = -x */
2585 					ir_node *blk = get_nodes_block(n);
2586 					n = new_rd_Minus(get_irn_dbg_info(n), blk, op, mode);
2587 					DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_PLUS_1);
2588 					return n;
2589 				}
2590 			}
2591 		}
2592 	}
2593 
2594 	if (is_Or_Eor_Add(n)) {
2595 		n = transform_node_Or_(n);
2596 		if (n != oldn)
2597 			return n;
2598 		n = transform_node_Eor_(n);
2599 		if (n != oldn)
2600 			return n;
2601 	}
2602 
2603 	return n;
2604 }
2605 
2606 /**
2607  * returns -cnst or NULL if impossible
2608  */
const_negate(ir_node * cnst)2609 static ir_node *const_negate(ir_node *cnst)
2610 {
2611 	ir_tarval *tv    = tarval_neg(get_Const_tarval(cnst));
2612 	dbg_info  *dbgi  = get_irn_dbg_info(cnst);
2613 	ir_graph  *irg   = get_irn_irg(cnst);
2614 	if (tv == tarval_bad) return NULL;
2615 	return new_rd_Const(dbgi, irg, tv);
2616 }
2617 
2618 /**
2619  * Do the AddSub optimization, then Transform
2620  *   Constant folding on Phi
2621  *   Sub(0,a)          -> Minus(a)
2622  *   Sub(Mul(a, x), a) -> Mul(a, x-1)
2623  *   Sub(Sub(x, y), b) -> Sub(x, Add(y,b))
2624  *   Sub(Add(a, x), x) -> a
2625  *   Sub(x, Add(x, a)) -> -a
2626  *   Sub(x, Const)     -> Add(x, -Const)
2627  */
transform_node_Sub(ir_node * n)2628 static ir_node *transform_node_Sub(ir_node *n)
2629 {
2630 	ir_mode *mode;
2631 	ir_node *oldn = n;
2632 	ir_node *a, *b, *c;
2633 
2634 	n = transform_node_AddSub(n);
2635 
2636 	a = get_Sub_left(n);
2637 	b = get_Sub_right(n);
2638 
2639 	mode = get_irn_mode(n);
2640 
2641 	if (mode_is_int(mode)) {
2642 		ir_mode *lmode = get_irn_mode(a);
2643 
2644 		if (is_Const(b) && is_Const_null(b) && mode_is_reference(lmode)) {
2645 			/* a Sub(a, NULL) is a hidden Conv */
2646 			dbg_info *dbg = get_irn_dbg_info(n);
2647 			n = new_rd_Conv(dbg, get_nodes_block(n), a, mode);
2648 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_CONV);
2649 			return n;
2650 		}
2651 
2652 		if (mode == lmode                                     &&
2653 		    get_mode_arithmetic(mode) == irma_twos_complement &&
2654 		    is_Const(a)                                       &&
2655 		    get_Const_tarval(a) == get_mode_minus_one(mode)) {
2656 			/* -1 - x -> ~x */
2657 			dbg_info *dbg = get_irn_dbg_info(n);
2658 			n = new_rd_Not(dbg, get_nodes_block(n), b, mode);
2659 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_NOT);
2660 			return n;
2661 		}
2662 	}
2663 
2664 restart:
2665 	HANDLE_BINOP_PHI((eval_func) tarval_sub, a, b, c, mode);
2666 
2667 	/* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2668 	if (mode_is_float(mode)) {
2669 		ir_graph *irg = get_irn_irg(n);
2670 		if (get_irg_fp_model(irg) & fp_strict_algebraic)
2671 			return n;
2672 	}
2673 
2674 	if (is_Const(b) && !mode_is_reference(get_irn_mode(b))) {
2675 		/* a - C -> a + (-C) */
2676 		ir_node *cnst = const_negate(b);
2677 		if (cnst != NULL) {
2678 			ir_node  *block = get_nodes_block(n);
2679 			dbg_info *dbgi  = get_irn_dbg_info(n);
2680 
2681 			n = new_rd_Add(dbgi, block, a, cnst, mode);
2682 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2683 			return n;
2684 		}
2685 	}
2686 
2687 	if (is_Minus(a)) { /* (-a) - b -> -(a + b) */
2688 		dbg_info *dbg   = get_irn_dbg_info(n);
2689 		ir_node  *block = get_nodes_block(n);
2690 		ir_node  *left  = get_Minus_op(a);
2691 		ir_node  *add   = new_rd_Add(dbg, block, left, b, mode);
2692 
2693 		n = new_rd_Minus(dbg, block, add, mode);
2694 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2695 		return n;
2696 	} else if (is_Minus(b)) { /* a - (-b) -> a + b */
2697 		dbg_info *dbg   = get_irn_dbg_info(n);
2698 		ir_node  *block = get_nodes_block(n);
2699 		ir_node  *right = get_Minus_op(b);
2700 
2701 		n = new_rd_Add(dbg, block, a, right, mode);
2702 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MINUS);
2703 		return n;
2704 	} else if (is_Sub(b)) {
2705 		/* a - (b - c) -> a + (c - b)
2706 		 *             -> (a - b) + c iff (b - c) is a pointer */
2707 		dbg_info *s_dbg   = get_irn_dbg_info(b);
2708 		ir_node  *s_left  = get_Sub_left(b);
2709 		ir_node  *s_right = get_Sub_right(b);
2710 		ir_mode  *s_mode  = get_irn_mode(b);
2711 		if (mode_is_reference(s_mode)) {
2712 			ir_node  *lowest_block = get_nodes_block(n); /* a and b are live here */
2713 			ir_node  *sub     = new_rd_Sub(s_dbg, lowest_block, a, s_left, mode);
2714 			dbg_info *a_dbg   = get_irn_dbg_info(n);
2715 
2716 			if (s_mode != mode)
2717 				s_right = new_r_Conv(lowest_block, s_right, mode);
2718 			n = new_rd_Add(a_dbg, lowest_block, sub, s_right, mode);
2719 		} else {
2720 			ir_node  *s_block = get_nodes_block(b);
2721 			ir_node  *sub     = new_rd_Sub(s_dbg, s_block, s_right, s_left, s_mode);
2722 			dbg_info *a_dbg   = get_irn_dbg_info(n);
2723 			ir_node  *a_block = get_nodes_block(n);
2724 
2725 			n = new_rd_Add(a_dbg, a_block, a, sub, mode);
2726 		}
2727 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2728 		return n;
2729 #if 0
2730 	} else if (is_Mul(b)) { /* a - (b * C) -> a + (b * -C) */
2731 		ir_node *m_right = get_Mul_right(b);
2732 		if (is_Const(m_right)) {
2733 			ir_node *cnst2 = const_negate(m_right);
2734 			if (cnst2 != NULL) {
2735 				dbg_info *m_dbg   = get_irn_dbg_info(b);
2736 				ir_node  *m_block = get_nodes_block(b);
2737 				ir_node  *m_left  = get_Mul_left(b);
2738 				ir_mode  *m_mode  = get_irn_mode(b);
2739 				ir_node  *mul     = new_rd_Mul(m_dbg, m_block, m_left, cnst2, m_mode);
2740 				dbg_info *a_dbg   = get_irn_dbg_info(n);
2741 				ir_node  *a_block = get_nodes_block(n);
2742 
2743 				n = new_rd_Add(a_dbg, a_block, a, mul, mode);
2744 				DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2745 				return n;
2746 			}
2747 		}
2748 #endif
2749 	}
2750 
2751 	/* Beware of Sub(P, P) which cannot be optimized into a simple Minus ... */
2752 	if (mode_is_num(mode) && mode == get_irn_mode(a) && is_Const(a) && is_Const_null(a)) {
2753 		n = new_rd_Minus(
2754 				get_irn_dbg_info(n),
2755 				get_nodes_block(n),
2756 				b,
2757 				mode);
2758 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_0_A);
2759 		return n;
2760 	}
2761 	if ((is_Add(a) || is_Or_Eor_Add(a)) && mode_wrap_around(mode)) {
2762 		ir_node *left  = get_binop_left(a);
2763 		ir_node *right = get_binop_right(a);
2764 
2765 		/* FIXME: Does the Conv's work only for two complement or generally? */
2766 		if (left == b) {
2767 			if (mode != get_irn_mode(right)) {
2768 				/* This Sub is an effective Cast */
2769 				right = new_r_Conv(get_nodes_block(n), right, mode);
2770 			}
2771 			n = right;
2772 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2773 			return n;
2774 		} else if (right == b) {
2775 			if (mode != get_irn_mode(left)) {
2776 				/* This Sub is an effective Cast */
2777 				left = new_r_Conv(get_nodes_block(n), left, mode);
2778 			}
2779 			n = left;
2780 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2781 			return n;
2782 		}
2783 	}
2784 	if ((is_Add(b) || is_Or_Eor_Add(b)) && mode_wrap_around(mode)) {
2785 		ir_node *left  = get_binop_left(b);
2786 		ir_node *right = get_binop_right(b);
2787 
2788 		/* FIXME: Does the Conv's work only for two complement or generally? */
2789 		if (left == a) {
2790 			ir_mode *r_mode = get_irn_mode(right);
2791 
2792 			n = new_r_Minus(get_nodes_block(n), right, r_mode);
2793 			if (mode != r_mode) {
2794 				/* This Sub is an effective Cast */
2795 				n = new_r_Conv(get_nodes_block(n), n, mode);
2796 			}
2797 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2798 			return n;
2799 		} else if (right == a) {
2800 			ir_mode *l_mode = get_irn_mode(left);
2801 
2802 			n = new_r_Minus(get_nodes_block(n), left, l_mode);
2803 			if (mode != l_mode) {
2804 				/* This Sub is an effective Cast */
2805 				n = new_r_Conv(get_nodes_block(n), n, mode);
2806 			}
2807 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2808 			return n;
2809 		}
2810 	}
2811 	if (mode_is_int(mode) && is_Conv(a) && is_Conv(b)) {
2812 		ir_mode *mode = get_irn_mode(a);
2813 
2814 		if (mode == get_irn_mode(b)) {
2815 			ir_mode *ma, *mb;
2816 			ir_node *op_a = get_Conv_op(a);
2817 			ir_node *op_b = get_Conv_op(b);
2818 
2819 			/* check if it's allowed to skip the conv */
2820 			ma = get_irn_mode(op_a);
2821 			mb = get_irn_mode(op_b);
2822 
2823 			if (mode_is_reference(ma) && mode_is_reference(mb)) {
2824 				/* SubInt(ConvInt(aP), ConvInt(bP)) -> SubInt(aP,bP) */
2825 				a = op_a; b = op_b;
2826 				set_Sub_left(n, a);
2827 				set_Sub_right(n, b);
2828 
2829 				goto restart;
2830 			}
2831 		}
2832 	}
2833 	/* do NOT execute this code if reassociation is enabled, it does the inverse! */
2834 	if (!is_reassoc_running() && is_Mul(a)) {
2835 		ir_node *ma = get_Mul_left(a);
2836 		ir_node *mb = get_Mul_right(a);
2837 
2838 		if (ma == b) {
2839 			ir_node  *blk = get_nodes_block(n);
2840 			ir_graph *irg = get_irn_irg(n);
2841 			n = new_rd_Mul(
2842 					get_irn_dbg_info(n),
2843 					blk,
2844 					ma,
2845 					new_rd_Sub(
2846 						get_irn_dbg_info(n),
2847 						blk,
2848 						mb,
2849 						new_r_Const(irg, get_mode_one(mode)),
2850 						mode),
2851 					mode);
2852 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MUL_A_X_A);
2853 			return n;
2854 		} else if (mb == b) {
2855 			ir_node  *blk = get_nodes_block(n);
2856 			ir_graph *irg = get_irn_irg(n);
2857 			n = new_rd_Mul(
2858 					get_irn_dbg_info(n),
2859 					blk,
2860 					mb,
2861 					new_rd_Sub(
2862 						get_irn_dbg_info(n),
2863 						blk,
2864 						ma,
2865 						new_r_Const(irg, get_mode_one(mode)),
2866 						mode),
2867 					mode);
2868 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MUL_A_X_A);
2869 			return n;
2870 		}
2871 	}
2872 	if (is_Sub(a)) { /* (x - y) - b -> x - (y + b) */
2873 		ir_node *x        = get_Sub_left(a);
2874 		ir_node *y        = get_Sub_right(a);
2875 		ir_node *blk      = get_nodes_block(n);
2876 		ir_mode *m_b      = get_irn_mode(b);
2877 		ir_mode *m_y      = get_irn_mode(y);
2878 		ir_mode *add_mode;
2879 		ir_node *add;
2880 
2881 		/* Determine the right mode for the Add. */
2882 		if (m_b == m_y)
2883 			add_mode = m_b;
2884 		else if (mode_is_reference(m_b))
2885 			add_mode = m_b;
2886 		else if (mode_is_reference(m_y))
2887 			add_mode = m_y;
2888 		else {
2889 			/*
2890 			 * Both modes are different but none is reference,
2891 			 * happens for instance in SubP(SubP(P, Iu), Is).
2892 			 * We have two possibilities here: Cast or ignore.
2893 			 * Currently we ignore this case.
2894 			 */
2895 			return n;
2896 		}
2897 
2898 		add = new_r_Add(blk, y, b, add_mode);
2899 
2900 		n = new_rd_Sub(get_irn_dbg_info(n), blk, x, add, mode);
2901 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_SUB_X_Y_Z);
2902 		return n;
2903 	}
2904 
2905 	if (get_mode_arithmetic(mode) == irma_twos_complement) {
2906 		/* c - ~X = X + (c+1) */
2907 		if (is_Const(a) && is_Not(b)) {
2908 			ir_tarval *tv = get_Const_tarval(a);
2909 
2910 			tv = tarval_add(tv, get_mode_one(mode));
2911 			if (tv != tarval_bad) {
2912 				ir_node  *blk = get_nodes_block(n);
2913 				ir_graph *irg = get_irn_irg(n);
2914 				ir_node *c = new_r_Const(irg, tv);
2915 				n = new_rd_Add(get_irn_dbg_info(n), blk, get_Not_op(b), c, mode);
2916 				DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_C_NOT_X);
2917 				return n;
2918 			}
2919 		}
2920 		/* x-(x&y) = x & ~y */
2921 		if (is_And(b)) {
2922 			ir_node *and_left  = get_And_left(b);
2923 			ir_node *and_right = get_And_right(b);
2924 			if (and_right == a) {
2925 				ir_node *tmp = and_left;
2926 				and_left  = and_right;
2927 				and_right = tmp;
2928 			}
2929 			if (and_left == a) {
2930 				dbg_info *dbgi  = get_irn_dbg_info(n);
2931 				ir_node  *block = get_nodes_block(n);
2932 				ir_mode  *mode  = get_irn_mode(n);
2933 				ir_node  *notn  = new_rd_Not(dbgi, block, and_right, mode);
2934 				ir_node  *andn  = new_rd_And(dbgi, block, a, notn, mode);
2935 				return andn;
2936 			}
2937 		}
2938 	}
2939 	return n;
2940 }
2941 
2942 /**
2943  * Several transformation done on n*n=2n bits mul.
2944  * These transformations must be done here because new nodes may be produced.
2945  */
transform_node_Mul2n(ir_node * n,ir_mode * mode)2946 static ir_node *transform_node_Mul2n(ir_node *n, ir_mode *mode)
2947 {
2948 	ir_node   *oldn  = n;
2949 	ir_node   *a     = get_Mul_left(n);
2950 	ir_node   *b     = get_Mul_right(n);
2951 	ir_tarval *ta    = value_of(a);
2952 	ir_tarval *tb    = value_of(b);
2953 	ir_mode   *smode = get_irn_mode(a);
2954 
2955 	if (ta == get_mode_one(smode)) {
2956 		/* (L)1 * (L)b = (L)b */
2957 		ir_node *blk = get_nodes_block(n);
2958 		n = new_rd_Conv(get_irn_dbg_info(n), blk, b, mode);
2959 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
2960 		return n;
2961 	}
2962 	else if (ta == get_mode_minus_one(smode)) {
2963 		/* (L)-1 * (L)b = (L)b */
2964 		ir_node *blk = get_nodes_block(n);
2965 		n = new_rd_Minus(get_irn_dbg_info(n), blk, b, smode);
2966 		n = new_rd_Conv(get_irn_dbg_info(n), blk, n, mode);
2967 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2968 		return n;
2969 	}
2970 	if (tb == get_mode_one(smode)) {
2971 		/* (L)a * (L)1 = (L)a */
2972 		ir_node *blk = get_nodes_block(a);
2973 		n = new_rd_Conv(get_irn_dbg_info(n), blk, a, mode);
2974 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
2975 		return n;
2976 	}
2977 	else if (tb == get_mode_minus_one(smode)) {
2978 		/* (L)a * (L)-1 = (L)-a */
2979 		ir_node *blk = get_nodes_block(n);
2980 		n = new_rd_Minus(get_irn_dbg_info(n), blk, a, smode);
2981 		n = new_rd_Conv(get_irn_dbg_info(n), blk, n, mode);
2982 		DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2983 		return n;
2984 	}
2985 	return n;
2986 }
2987 
2988 /**
2989  * Transform Mul(a,-1) into -a.
2990  * Do constant evaluation of Phi nodes.
2991  * Do architecture dependent optimizations on Mul nodes
2992  */
transform_node_Mul(ir_node * n)2993 static ir_node *transform_node_Mul(ir_node *n)
2994 {
2995 	ir_node *c, *oldn = n;
2996 	ir_mode *mode = get_irn_mode(n);
2997 	ir_node *a = get_Mul_left(n);
2998 	ir_node *b = get_Mul_right(n);
2999 
3000 	n = fold_constant_associativity(n, tarval_mul);
3001 	if (n != oldn)
3002 		return n;
3003 
3004 	if (mode != get_irn_mode(a))
3005 		return transform_node_Mul2n(n, mode);
3006 
3007 	HANDLE_BINOP_PHI((eval_func) tarval_mul, a, b, c, mode);
3008 
3009 	if (mode_is_signed(mode)) {
3010 		ir_node *r = NULL;
3011 
3012 		if (value_of(a) == get_mode_minus_one(mode))
3013 			r = b;
3014 		else if (value_of(b) == get_mode_minus_one(mode))
3015 			r = a;
3016 		if (r) {
3017 			n = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), r, mode);
3018 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
3019 			return n;
3020 		}
3021 	}
3022 	if (is_Minus(a)) {
3023 		if (is_Const(b)) { /* (-a) * const -> a * -const */
3024 			ir_node *cnst = const_negate(b);
3025 			if (cnst != NULL) {
3026 				dbg_info *dbgi  = get_irn_dbg_info(n);
3027 				ir_node  *block = get_nodes_block(n);
3028 				n = new_rd_Mul(dbgi, block, get_Minus_op(a), cnst, mode);
3029 				DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
3030 				return n;
3031 			}
3032 		} else if (is_Minus(b)) { /* (-a) * (-b) -> a * b */
3033 			dbg_info *dbgi  = get_irn_dbg_info(n);
3034 			ir_node  *block = get_nodes_block(n);
3035 			n = new_rd_Mul(dbgi, block, get_Minus_op(a), get_Minus_op(b), mode);
3036 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_MINUS);
3037 			return n;
3038 		} else if (is_Sub(b)) { /* (-a) * (b - c) -> a * (c - b) */
3039 			ir_node  *sub_l = get_Sub_left(b);
3040 			ir_node  *sub_r = get_Sub_right(b);
3041 			dbg_info *dbgi  = get_irn_dbg_info(n);
3042 			ir_node  *block = get_nodes_block(n);
3043 			ir_node  *new_b = new_rd_Sub(dbgi, block, sub_r, sub_l, mode);
3044 			n = new_rd_Mul(dbgi, block, get_Minus_op(a), new_b, mode);
3045 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS);
3046 			return n;
3047 		}
3048 	} else if (is_Minus(b)) {
3049 		if (is_Sub(a)) { /* (a - b) * (-c) -> (b - a) * c */
3050 			ir_node  *sub_l = get_Sub_left(a);
3051 			ir_node  *sub_r = get_Sub_right(a);
3052 			dbg_info *dbgi  = get_irn_dbg_info(n);
3053 			ir_node  *block = get_nodes_block(n);
3054 			ir_node  *new_a = new_rd_Sub(dbgi, block, sub_r, sub_l, mode);
3055 			n = new_rd_Mul(dbgi, block, new_a, get_Minus_op(b), mode);
3056 			DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS);
3057 			return n;
3058 		}
3059 	} else if (is_Shl(a)) {
3060 		ir_node *const shl_l = get_Shl_left(a);
3061 		if (is_Const(shl_l) && is_Const_one(shl_l)) {
3062 			/* (1 << x) * b -> b << x */
3063 			dbg_info *const dbgi  = get_irn_dbg_info(n);
3064 			ir_node  *const block = get_nodes_block(n);
3065 			ir_node  *const shl_r = get_Shl_right(a);
3066 			n = new_rd_Shl(dbgi, block, b, shl_r, mode);
3067 			// TODO add me DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_SHIFT);
3068 			return n;
3069 		}
3070 	} else if (is_Shl(b)) {
3071 		ir_node *const shl_l = get_Shl_left(b);
3072 		if (is_Const(shl_l) && is_Const_one(shl_l)) {
3073 			/* a * (1 << x) -> a << x */
3074 			dbg_info *const dbgi  = get_irn_dbg_info(n);
3075 			ir_node  *const block = get_nodes_block(n);
3076 			ir_node  *const shl_r = get_Shl_right(b);
3077 			n = new_rd_Shl(dbgi, block, a, shl_r, mode);
3078 			// TODO add me DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_SHIFT);
3079 			return n;
3080 		}
3081 	}
3082 	if (get_mode_arithmetic(mode) == irma_ieee754
3083 	    || get_mode_arithmetic(mode) == irma_x86_extended_float) {
3084 		if (is_Const(a)) {
3085 			ir_tarval *tv = get_Const_tarval(a);
3086 			if (tarval_get_exponent(tv) == 1 && tarval_zero_mantissa(tv)
3087 					&& !tarval_is_negative(tv)) {
3088 				/* 2.0 * b = b + b */
3089 				n = new_rd_Add(get_irn_dbg_info(n), get_nodes_block(n), b, b, mode);
3090 				DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_A_A);
3091 				return n;
3092 			}
3093 		}
3094 		else if (is_Const(b)) {
3095 			ir_tarval *tv = get_Const_tarval(b);
3096 			if (tarval_get_exponent(tv) == 1 && tarval_zero_mantissa(tv)
3097 					&& !tarval_is_negative(tv)) {
3098 				/* a * 2.0 = a + a */
3099 				n = new_rd_Add(get_irn_dbg_info(n), get_nodes_block(n), a, a, mode);
3100 				DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_A_A);
3101 				return n;
3102 			}
3103 		}
3104 	}
3105 	return arch_dep_replace_mul_with_shifts(n);
3106 }
3107 
3108 /**
3109  * Transform a Div Node.
3110  */
transform_node_Div(ir_node * n)3111 static ir_node *transform_node_Div(ir_node *n)
3112 {
3113 	ir_mode *mode = get_Div_resmode(n);
3114 	ir_node *a = get_Div_left(n);
3115 	ir_node *b = get_Div_right(n);
3116 	ir_node *value = n;
3117 	const ir_node *dummy;
3118 
3119 	if (mode_is_int(mode)) {
3120 		if (is_Const(b) && is_const_Phi(a)) {
3121 			/* check for Div(Phi, Const) */
3122 			value = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_div, mode, 0);
3123 			if (value) {
3124 				DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3125 				goto make_tuple;
3126 			}
3127 		} else if (is_Const(a) && is_const_Phi(b)) {
3128 			/* check for Div(Const, Phi) */
3129 			value = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_div, mode, 1);
3130 			if (value) {
3131 				DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3132 				goto make_tuple;
3133 			}
3134 		} else if (is_const_Phi(a) && is_const_Phi(b)) {
3135 			/* check for Div(Phi, Phi) */
3136 			value = apply_binop_on_2_phis(a, b, (eval_func) tarval_div, mode);
3137 			if (value) {
3138 				DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3139 				goto make_tuple;
3140 			}
3141 		}
3142 
3143 		if (a == b && value_not_zero(a, &dummy)) {
3144 			ir_graph *irg = get_irn_irg(n);
3145 			/* BEWARE: we can optimize a/a to 1 only if this cannot cause a exception */
3146 			value = new_r_Const(irg, get_mode_one(mode));
3147 			DBG_OPT_CSTEVAL(n, value);
3148 			goto make_tuple;
3149 		} else {
3150 			if (mode_is_signed(mode) && is_Const(b)) {
3151 				ir_tarval *tv = get_Const_tarval(b);
3152 
3153 				if (tv == get_mode_minus_one(mode)) {
3154 					/* a / -1 */
3155 					value = new_rd_Minus(get_irn_dbg_info(n), get_nodes_block(n), a, mode);
3156 					DBG_OPT_CSTEVAL(n, value);
3157 					goto make_tuple;
3158 				}
3159 			}
3160 			/* Try architecture dependent optimization */
3161 			value = arch_dep_replace_div_by_const(n);
3162 		}
3163 	} else {
3164 		assert(mode_is_float(mode));
3165 
3166 		/* Optimize x/c to x*(1/c) */
3167 		if (get_mode_arithmetic(mode) == irma_ieee754) {
3168 			ir_tarval *tv = value_of(b);
3169 
3170 			if (tv != tarval_bad) {
3171 				int rem = tarval_fp_ops_enabled();
3172 
3173 				/*
3174 				 * Floating point constant folding might be disabled here to
3175 				 * prevent rounding.
3176 				 * However, as we check for exact result, doing it is safe.
3177 				 * Switch it on.
3178 				 */
3179 				tarval_enable_fp_ops(1);
3180 				tv = tarval_div(get_mode_one(mode), tv);
3181 				tarval_enable_fp_ops(rem);
3182 
3183 				/* Do the transformation if the result is either exact or we are
3184 				   not using strict rules. */
3185 				if (tv != tarval_bad &&
3186 					(tarval_ieee754_get_exact() || (get_irg_fp_model(get_irn_irg(n)) & fp_strict_algebraic) == 0)) {
3187 					ir_node  *block = get_nodes_block(n);
3188 					ir_graph *irg   = get_irn_irg(block);
3189 					ir_node  *c     = new_r_Const(irg, tv);
3190 					dbg_info *dbgi  = get_irn_dbg_info(n);
3191 					value = new_rd_Mul(dbgi, block, a, c, mode);
3192 
3193 					goto make_tuple;
3194 				}
3195 			}
3196 		}
3197 	}
3198 
3199 	if (value != n) {
3200 		ir_node *mem, *blk;
3201 		ir_graph *irg;
3202 
3203 make_tuple:
3204 		/* Turn Div into a tuple (mem, jmp, bad, value) */
3205 		mem = get_Div_mem(n);
3206 		blk = get_nodes_block(n);
3207 		irg = get_irn_irg(blk);
3208 
3209 		/* skip a potential Pin */
3210 		mem = skip_Pin(mem);
3211 		turn_into_tuple(n, pn_Div_max+1);
3212 		set_Tuple_pred(n, pn_Div_M,         mem);
3213 		set_Tuple_pred(n, pn_Div_X_regular, new_r_Jmp(blk));
3214 		set_Tuple_pred(n, pn_Div_X_except,  new_r_Bad(irg, mode_X));
3215 		set_Tuple_pred(n, pn_Div_res,       value);
3216 	}
3217 	return n;
3218 }
3219 
3220 /**
3221  * Transform a Mod node.
3222  */
transform_node_Mod(ir_node * n)3223 static ir_node *transform_node_Mod(ir_node *n)
3224 {
3225 	ir_mode   *mode = get_Mod_resmode(n);
3226 	ir_node   *a    = get_Mod_left(n);
3227 	ir_node   *b    = get_Mod_right(n);
3228 	ir_graph  *irg;
3229 	ir_node   *value;
3230 	ir_tarval *tv;
3231 
3232 	if (is_Const(b) && is_const_Phi(a)) {
3233 		/* check for Div(Phi, Const) */
3234 		value = apply_binop_on_phi(a, get_Const_tarval(b), (eval_func) tarval_mod, mode, 0);
3235 		if (value) {
3236 			DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3237 			goto make_tuple;
3238 		}
3239 	}
3240 	else if (is_Const(a) && is_const_Phi(b)) {
3241 		/* check for Div(Const, Phi) */
3242 		value = apply_binop_on_phi(b, get_Const_tarval(a), (eval_func) tarval_mod, mode, 1);
3243 		if (value) {
3244 			DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3245 			goto make_tuple;
3246 		}
3247 	}
3248 	else if (is_const_Phi(a) && is_const_Phi(b)) {
3249 		/* check for Div(Phi, Phi) */
3250 		value = apply_binop_on_2_phis(a, b, (eval_func) tarval_mod, mode);
3251 		if (value) {
3252 			DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
3253 			goto make_tuple;
3254 		}
3255 	}
3256 
3257 	value = n;
3258 	tv = value_of(n);
3259 	irg = get_irn_irg(n);
3260 	if (tv != tarval_bad) {
3261 		value = new_r_Const(irg, tv);
3262 
3263 		DBG_OPT_CSTEVAL(n, value);
3264 		goto make_tuple;
3265 	} else {
3266 		ir_node       *a = get_Mod_left(n);
3267 		ir_node       *b = get_Mod_right(n);
3268 		const ir_node *dummy;
3269 
3270 		if (a == b && value_not_zero(a, &dummy)) {
3271 			/* BEWARE: we can optimize a%a to 0 only if this cannot cause a exception */
3272 			value = new_r_Const(irg, get_mode_null(mode));
3273 			DBG_OPT_CSTEVAL(n, value);
3274 			goto make_tuple;
3275 		} else {
3276 			if (mode_is_signed(mode) && is_Const(b)) {
3277 				ir_tarval *tv = get_Const_tarval(b);
3278 
3279 				if (tv == get_mode_minus_one(mode)) {
3280 					/* a % -1 = 0 */
3281 					value = new_r_Const(irg, get_mode_null(mode));
3282 					DBG_OPT_CSTEVAL(n, value);
3283 					goto make_tuple;
3284 				}
3285 			}
3286 			/* Try architecture dependent optimization */
3287 			value = arch_dep_replace_mod_by_const(n);
3288 		}
3289 	}
3290 
3291 	if (value != n) {
3292 		ir_node *mem, *blk;
3293 		ir_graph *irg;
3294 
3295 make_tuple:
3296 		/* Turn Mod into a tuple (mem, jmp, bad, value) */
3297 		mem = get_Mod_mem(n);
3298 		blk = get_nodes_block(n);
3299 		irg = get_irn_irg(blk);
3300 
3301 		/* skip a potential Pin */
3302 		mem = skip_Pin(mem);
3303 		turn_into_tuple(n, pn_Mod_max+1);
3304 		set_Tuple_pred(n, pn_Mod_M,         mem);
3305 		set_Tuple_pred(n, pn_Mod_X_regular, new_r_Jmp(blk));
3306 		set_Tuple_pred(n, pn_Mod_X_except,  new_r_Bad(irg, mode_X));
3307 		set_Tuple_pred(n, pn_Mod_res,       value);
3308 	}
3309 	return n;
3310 }
3311 
3312 /**
3313  * Transform a Cond node.
3314  *
3315  * Replace the Cond by a Jmp if it branches on a constant
3316  * condition.
3317  */
transform_node_Cond(ir_node * n)3318 static ir_node *transform_node_Cond(ir_node *n)
3319 {
3320 	ir_node   *a   = get_Cond_selector(n);
3321 	ir_graph  *irg = get_irn_irg(n);
3322 	ir_tarval *ta;
3323 	ir_node   *jmp;
3324 
3325 	/* we need block info which is not available in floating irgs */
3326 	if (get_irg_pinned(irg) == op_pin_state_floats)
3327 		return n;
3328 
3329 	ta = value_of(a);
3330 	if (ta == tarval_bad && is_Cmp(a)) {
3331 		/* try again with a direct call to compute_cmp, as we don't care
3332 		 * about the MODEB_LOWERED flag here */
3333 		ta = compute_cmp_ext(a);
3334 	}
3335 
3336 	if (ta != tarval_bad && get_irn_mode(a) == mode_b) {
3337 		/* It's a boolean Cond, branching on a boolean constant.
3338 		   Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
3339 		ir_node *blk = get_nodes_block(n);
3340 		jmp = new_r_Jmp(blk);
3341 		turn_into_tuple(n, pn_Cond_max+1);
3342 		if (ta == tarval_b_true) {
3343 			set_Tuple_pred(n, pn_Cond_false, new_r_Bad(irg, mode_X));
3344 			set_Tuple_pred(n, pn_Cond_true, jmp);
3345 		} else {
3346 			set_Tuple_pred(n, pn_Cond_false, jmp);
3347 			set_Tuple_pred(n, pn_Cond_true, new_r_Bad(irg, mode_X));
3348 		}
3349 		clear_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE);
3350 	}
3351 	return n;
3352 }
3353 
transform_node_Switch(ir_node * n)3354 static ir_node *transform_node_Switch(ir_node *n)
3355 {
3356 	ir_node   *op  = get_Switch_selector(n);
3357 	ir_tarval *val = value_of(op);
3358 	if (val != tarval_bad) {
3359 		dbg_info              *dbgi      = get_irn_dbg_info(n);
3360 		ir_graph              *irg       = get_irn_irg(n);
3361 		unsigned               n_outs    = get_Switch_n_outs(n);
3362 		ir_node               *block     = get_nodes_block(n);
3363 		ir_node               *bad       = new_r_Bad(irg, mode_X);
3364 		ir_node              **in        = XMALLOCN(ir_node*, n_outs);
3365 		const ir_switch_table *table     = get_Switch_table(n);
3366 		size_t                 n_entries = ir_switch_table_get_n_entries(table);
3367 		long                   jmp_pn    = 0;
3368 		size_t                 i;
3369 		unsigned               o;
3370 		for (i = 0; i < n_entries; ++i) {
3371 			const ir_switch_table_entry *entry
3372 				= ir_switch_table_get_entry_const(table, i);
3373 			ir_tarval *min = entry->min;
3374 			ir_tarval *max = entry->max;
3375 			if (entry->pn == 0)
3376 				continue;
3377 			if ((min == max && min == val)
3378 			    || (tarval_cmp(val, min) != ir_relation_less
3379 			        && tarval_cmp(val, max) != ir_relation_greater)) {
3380 			    jmp_pn = entry->pn;
3381 			    break;
3382 			}
3383 		}
3384 		for (o = 0; o < n_outs; ++o) {
3385 			if (o == (unsigned)jmp_pn) {
3386 				in[o] = new_rd_Jmp(dbgi, block);
3387 			} else {
3388 				in[o] = bad;
3389 			}
3390 		}
3391 		return new_r_Tuple(block, (int)n_outs, in);
3392 	}
3393 	return n;
3394 }
3395 
3396 /**
3397  * normalisation: (x & c1) >> c2   to   (x >> c2) & (c1 >> c2)
3398  *  (we can use:
3399  *    - and, or, xor          instead of &
3400  *    - Shl, Shr, Shrs, rotl  instead of >>
3401  *    (with a special case for Or/Xor + Shrs)
3402  *
3403  * This normalisation is good for things like x-(x&y) esp. in 186.crafty.
3404  */
transform_node_shift_bitop(ir_node * n)3405 static ir_node *transform_node_shift_bitop(ir_node *n)
3406 {
3407 	ir_graph  *irg   = get_irn_irg(n);
3408 	ir_node   *right = get_binop_right(n);
3409 	ir_mode   *mode  = get_irn_mode(n);
3410 	ir_node   *left;
3411 	ir_node   *bitop_left;
3412 	ir_node   *bitop_right;
3413 	ir_op     *op_left;
3414 	ir_node   *block;
3415 	dbg_info  *dbgi;
3416 	ir_node   *new_shift;
3417 	ir_node   *new_bitop;
3418 	ir_node   *new_const;
3419 	ir_tarval *tv1;
3420 	ir_tarval *tv2;
3421 	ir_tarval *tv_shift;
3422 
3423 	if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_NORMALISATION2))
3424 		return n;
3425 
3426 	assert(is_Shrs(n) || is_Shr(n) || is_Shl(n) || is_Rotl(n));
3427 
3428 	if (!is_Const(right))
3429 		return n;
3430 
3431 	left    = get_binop_left(n);
3432 	op_left = get_irn_op(left);
3433 	if (op_left != op_And && op_left != op_Or && op_left != op_Eor)
3434 		return n;
3435 
3436 	/* doing it with Shrs is not legal if the Or/Eor affects the topmost bit */
3437 	if (is_Shrs(n) && (op_left == op_Or || op_left == op_Eor)) {
3438 		/* TODO: test if sign bit is affectes */
3439 		return n;
3440 	}
3441 
3442 	bitop_right = get_binop_right(left);
3443 	if (!is_Const(bitop_right))
3444 		return n;
3445 
3446 	bitop_left = get_binop_left(left);
3447 
3448 	block = get_nodes_block(n);
3449 	dbgi  = get_irn_dbg_info(n);
3450 	tv1   = get_Const_tarval(bitop_right);
3451 	tv2   = get_Const_tarval(right);
3452 
3453 	assert(get_tarval_mode(tv1) == mode);
3454 
3455 	if (is_Shl(n)) {
3456 		new_shift = new_rd_Shl(dbgi, block, bitop_left, right, mode);
3457 		tv_shift  = tarval_shl(tv1, tv2);
3458 	} else if (is_Shr(n)) {
3459 		new_shift = new_rd_Shr(dbgi, block, bitop_left, right, mode);
3460 		tv_shift  = tarval_shr(tv1, tv2);
3461 	} else if (is_Shrs(n)) {
3462 		new_shift = new_rd_Shrs(dbgi, block, bitop_left, right, mode);
3463 		tv_shift  = tarval_shrs(tv1, tv2);
3464 	} else {
3465 		assert(is_Rotl(n));
3466 		new_shift = new_rd_Rotl(dbgi, block, bitop_left, right, mode);
3467 		tv_shift  = tarval_rotl(tv1, tv2);
3468 	}
3469 
3470 	assert(get_tarval_mode(tv_shift) == mode);
3471 	irg       = get_irn_irg(n);
3472 	new_const = new_r_Const(irg, tv_shift);
3473 
3474 	if (op_left == op_And) {
3475 		new_bitop = new_rd_And(dbgi, block, new_shift, new_const, mode);
3476 	} else if (op_left == op_Or) {
3477 		new_bitop = new_rd_Or(dbgi, block, new_shift, new_const, mode);
3478 	} else {
3479 		assert(op_left == op_Eor);
3480 		new_bitop = new_rd_Eor(dbgi, block, new_shift, new_const, mode);
3481 	}
3482 
3483 	return new_bitop;
3484 }
3485 
3486 /**
3487  * Transform an And.
3488  */
transform_node_And(ir_node * n)3489 static ir_node *transform_node_And(ir_node *n)
3490 {
3491 	ir_node *c, *oldn = n;
3492 	ir_node *a = get_And_left(n);
3493 	ir_node *b = get_And_right(n);
3494 	ir_mode *mode;
3495 
3496 	n = fold_constant_associativity(n, tarval_and);
3497 	if (n != oldn)
3498 		return n;
3499 
3500 	if (is_Cmp(a) && is_Cmp(b)) {
3501 		ir_node    *a_left     = get_Cmp_left(a);
3502 		ir_node    *a_right    = get_Cmp_right(a);
3503 		ir_node    *b_left     = get_Cmp_left(b);
3504 		ir_node    *b_right    = get_Cmp_right(b);
3505 		ir_relation a_relation = get_Cmp_relation(a);
3506 		ir_relation b_relation = get_Cmp_relation(b);
3507 		/* we can combine the relations of two compares with the same
3508 		 * operands */
3509 		if (a_left == b_left && b_left == b_right) {
3510 			dbg_info   *dbgi         = get_irn_dbg_info(n);
3511 			ir_node    *block        = get_nodes_block(n);
3512 			ir_relation new_relation = a_relation & b_relation;
3513 			return new_rd_Cmp(dbgi, block, a_left, a_right, new_relation);
3514 		}
3515 		/* Cmp(a==b) and Cmp(c==d) can be optimized to Cmp((a^b)|(c^d)==0) */
3516 		if (a_relation == b_relation && a_relation == ir_relation_equal
3517 		    && !mode_is_float(get_irn_mode(a_left))
3518 		    && !mode_is_float(get_irn_mode(b_left))) {
3519 			if (values_in_mode(get_irn_mode(a_left), get_irn_mode(b_left))) {
3520 				dbg_info *dbgi   = get_irn_dbg_info(n);
3521 				ir_node  *block  = get_nodes_block(n);
3522 				ir_mode  *a_mode = get_irn_mode(a_left);
3523 				ir_mode  *b_mode = get_irn_mode(b_left);
3524 				ir_node  *xora   = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
3525 				ir_node  *xorb   = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
3526 				ir_node  *conv   = new_rd_Conv(dbgi, block, xora, b_mode);
3527 				ir_node  *orn    = new_rd_Or(dbgi, block, conv, xorb, b_mode);
3528 				ir_graph *irg    = get_irn_irg(n);
3529 				ir_node  *zero   = create_zero_const(irg, b_mode);
3530 				return new_rd_Cmp(dbgi, block, orn, zero, ir_relation_equal);
3531 			}
3532 			if (values_in_mode(get_irn_mode(b_left), get_irn_mode(a_left))) {
3533 				dbg_info *dbgi   = get_irn_dbg_info(n);
3534 				ir_node  *block  = get_nodes_block(n);
3535 				ir_mode  *a_mode = get_irn_mode(a_left);
3536 				ir_mode  *b_mode = get_irn_mode(b_left);
3537 				ir_node  *xora   = new_rd_Eor(dbgi, block, a_left, a_right, a_mode);
3538 				ir_node  *xorb   = new_rd_Eor(dbgi, block, b_left, b_right, b_mode);
3539 				ir_node  *conv   = new_rd_Conv(dbgi, block, xorb, a_mode);
3540 				ir_node  *orn    = new_rd_Or(dbgi, block, xora, conv, a_mode);
3541 				ir_graph *irg    = get_irn_irg(n);
3542 				ir_node  *zero   = create_zero_const(irg, a_mode);
3543 				return new_rd_Cmp(dbgi, block, orn, zero, ir_relation_equal);
3544 			}
3545 		}
3546 	}
3547 
3548 	mode = get_irn_mode(n);
3549 	HANDLE_BINOP_PHI((eval_func) tarval_and, a, b, c, mode);
3550 
3551 	if (is_Or(a) || is_Or_Eor_Add(a)) {
3552 		ir_node *or_left  = get_binop_left(a);
3553 		ir_node *or_right = get_binop_right(a);
3554 		if (complement_values(or_left, b)) {
3555 			/* (a|b) & ~a => b & ~a */
3556 			dbg_info *dbgi    = get_irn_dbg_info(n);
3557 			ir_node  *block   = get_nodes_block(n);
3558 			return new_rd_And(dbgi, block, or_right, b, mode);
3559 		} else if (complement_values(or_right, b)) {
3560 			/* (a|b) & ~b => a & ~b */
3561 			dbg_info *dbgi    = get_irn_dbg_info(n);
3562 			ir_node  *block   = get_nodes_block(n);
3563 			return new_rd_And(dbgi, block, or_left, b, mode);
3564 		} else if (is_Not(b)) {
3565 			ir_node *op = get_Not_op(b);
3566 			if (is_And(op)) {
3567 				ir_node *ba = get_And_left(op);
3568 				ir_node *bb = get_And_right(op);
3569 
3570 				/* it's enough to test the following cases due to normalization! */
3571 				if (or_left == ba && or_right == bb) {
3572 					/* (a|b) & ~(a&b) = a^b */
3573 					ir_node *block = get_nodes_block(n);
3574 
3575 					n = new_rd_Eor(get_irn_dbg_info(n), block, ba, bb, mode);
3576 					DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_TO_EOR);
3577 					return n;
3578 				}
3579 			}
3580 		}
3581 	}
3582 	if (is_Or(b) || is_Or_Eor_Add(b)) {
3583 		ir_node *or_left  = get_binop_left(b);
3584 		ir_node *or_right = get_binop_right(b);
3585 		if (complement_values(or_left, a)) {
3586 			/* (a|b) & ~a => b & ~a */
3587 			dbg_info *dbgi    = get_irn_dbg_info(n);
3588 			ir_node  *block   = get_nodes_block(n);
3589 			return new_rd_And(dbgi, block, or_right, a, mode);
3590 		} else if (complement_values(or_right, a)) {
3591 			/* (a|b) & ~b => a & ~b */
3592 			dbg_info *dbgi    = get_irn_dbg_info(n);
3593 			ir_node  *block   = get_nodes_block(n);
3594 			return new_rd_And(dbgi, block, or_left, a, mode);
3595 		} else if (is_Not(a)) {
3596 			ir_node *op = get_Not_op(a);
3597 			if (is_And(op)) {
3598 				ir_node *aa = get_And_left(op);
3599 				ir_node *ab = get_And_right(op);
3600 
3601 				/* it's enough to test the following cases due to normalization! */
3602 				if (or_left == aa && or_right == ab) {
3603 					/* (a|b) & ~(a&b) = a^b */
3604 					ir_node *block = get_nodes_block(n);
3605 
3606 					n = new_rd_Eor(get_irn_dbg_info(n), block, aa, ab, mode);
3607 					DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_TO_EOR);
3608 					return n;
3609 				}
3610 			}
3611 		}
3612 	}
3613 	if (is_Eor(a) || is_Or_Eor_Add(a)) {
3614 		ir_node *al = get_binop_left(a);
3615 		ir_node *ar = get_binop_right(a);
3616 
3617 		if (al == b) {
3618 			/* (b ^ a) & b -> ~a & b */
3619 			dbg_info *dbg  = get_irn_dbg_info(n);
3620 			ir_node *block = get_nodes_block(n);
3621 
3622 			ar = new_rd_Not(dbg, block, ar, mode);
3623 			n  = new_rd_And(dbg, block, ar, b, mode);
3624 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3625 			return n;
3626 		}
3627 		if (ar == b) {
3628 			/* (a ^ b) & b -> ~a & b */
3629 			dbg_info *dbg  = get_irn_dbg_info(n);
3630 			ir_node *block = get_nodes_block(n);
3631 
3632 			al = new_rd_Not(dbg, block, al, mode);
3633 			n  = new_rd_And(dbg, block, al, b, mode);
3634 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3635 			return n;
3636 		}
3637 	}
3638 	if (is_Eor(b) || is_Or_Eor_Add(b)) {
3639 		ir_node *bl = get_binop_left(b);
3640 		ir_node *br = get_binop_right(b);
3641 
3642 		if (bl == a) {
3643 			/* a & (a ^ b) -> a & ~b */
3644 			dbg_info *dbg  = get_irn_dbg_info(n);
3645 			ir_node *block = get_nodes_block(n);
3646 
3647 			br = new_rd_Not(dbg, block, br, mode);
3648 			n  = new_rd_And(dbg, block, br, a, mode);
3649 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3650 			return n;
3651 		}
3652 		if (br == a) {
3653 			/* a & (b ^ a) -> a & ~b */
3654 			dbg_info *dbg  = get_irn_dbg_info(n);
3655 			ir_node *block = get_nodes_block(n);
3656 
3657 			bl = new_rd_Not(dbg, block, bl, mode);
3658 			n  = new_rd_And(dbg, block, bl, a, mode);
3659 			DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3660 			return n;
3661 		}
3662 	}
3663 	if (is_Not(a) && is_Not(b)) {
3664 		/* ~a & ~b = ~(a|b) */
3665 		ir_node *block = get_nodes_block(n);
3666 		ir_mode *mode = get_irn_mode(n);
3667 
3668 		a = get_Not_op(a);
3669 		b = get_Not_op(b);
3670 		n = new_rd_Or(get_irn_dbg_info(n), block, a, b, mode);
3671 		n = new_rd_Not(get_irn_dbg_info(n), block, n, mode);
3672 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
3673 		return n;
3674 	}
3675 
3676 	if (is_Const(a)) {
3677 		vrp_attr  *b_vrp = vrp_get_info(b);
3678 		ir_tarval *a_val = get_Const_tarval(a);
3679 		if (b_vrp != NULL && tarval_or(a_val, b_vrp->bits_not_set) == a_val) {
3680 			return b;
3681 		}
3682 	}
3683 
3684 	if (is_Const(b)) {
3685 		vrp_attr  *a_vrp = vrp_get_info(a);
3686 		ir_tarval *b_val = get_Const_tarval(b);
3687 		if (a_vrp != NULL && tarval_or(b_val, a_vrp->bits_not_set) == b_val) {
3688 			return a;
3689 		}
3690 	}
3691 
3692 	n = transform_bitwise_distributive(n, transform_node_And);
3693 	if (is_And(n))
3694 		n = transform_node_bitop_shift(n);
3695 
3696 	return n;
3697 }
3698 
3699 /**
3700  * Transform a Not.
3701  */
transform_node_Not(ir_node * n)3702 static ir_node *transform_node_Not(ir_node *n)
3703 {
3704 	ir_node *c, *oldn = n;
3705 	ir_node *a    = get_Not_op(n);
3706 	ir_mode *mode = get_irn_mode(n);
3707 
3708 	HANDLE_UNOP_PHI(tarval_not,a,c);
3709 
3710 	/* check for a boolean Not */
3711 	if (is_Cmp(a)) {
3712 		dbg_info *dbgi  = get_irn_dbg_info(a);
3713 		ir_node  *block = get_nodes_block(a);
3714 		ir_relation relation = get_Cmp_relation(a);
3715 		relation = get_negated_relation(relation);
3716 		n = new_rd_Cmp(dbgi, block, get_Cmp_left(a), get_Cmp_right(a), relation);
3717 		DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_CMP);
3718 		return n;
3719 	}
3720 
3721 	/* normalize ~(a ^ b) => a ^ ~b */
3722 	if (is_Eor(a) || is_Or_Eor_Add(a)) {
3723 		dbg_info *dbg       = get_irn_dbg_info(n);
3724 		ir_node  *block     = get_nodes_block(n);
3725 		ir_node  *eor_right = get_binop_right(a);
3726 		ir_node  *eor_left  = get_binop_left(a);
3727 		eor_right = new_rd_Not(dbg, block, eor_right, mode);
3728 		n = new_rd_Eor(dbg, block, eor_left, eor_right, mode);
3729 		return n;
3730 	}
3731 
3732 	if (get_mode_arithmetic(mode) == irma_twos_complement) {
3733 		if (is_Minus(a)) { /* ~-x -> x + -1 */
3734 			dbg_info *dbg   = get_irn_dbg_info(n);
3735 			ir_graph *irg   = get_irn_irg(n);
3736 			ir_node  *block = get_nodes_block(n);
3737 			ir_node  *add_l = get_Minus_op(a);
3738 			ir_node  *add_r = new_rd_Const(dbg, irg, get_mode_minus_one(mode));
3739 			n = new_rd_Add(dbg, block, add_l, add_r, mode);
3740 		} else if (is_Add(a) || is_Or_Eor_Add(a)) {
3741 			ir_node *add_r = get_binop_right(a);
3742 			if (is_Const(add_r) && is_Const_all_one(add_r)) {
3743 				/* ~(x + -1) = -x */
3744 				ir_node *op  = get_binop_left(a);
3745 				ir_node *blk = get_nodes_block(n);
3746 				n = new_rd_Minus(get_irn_dbg_info(n), blk, op, get_irn_mode(n));
3747 				DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_MINUS_1);
3748 			}
3749 		}
3750 	}
3751 	return n;
3752 }
3753 
3754 /**
3755  * Transform a Minus.
3756  * Optimize:
3757  *   -(~x) = x + 1
3758  *   -(a-b) = b - a
3759  *   -(a >>u (size-1)) = a >>s (size-1)
3760  *   -(a >>s (size-1)) = a >>u (size-1)
3761  *   -(a * const) -> a * -const
3762  */
transform_node_Minus(ir_node * n)3763 static ir_node *transform_node_Minus(ir_node *n)
3764 {
3765 	ir_node *c, *oldn = n;
3766 	ir_node *a = get_Minus_op(n);
3767 	ir_mode *mode;
3768 
3769 	HANDLE_UNOP_PHI(tarval_neg,a,c);
3770 
3771 	mode = get_irn_mode(a);
3772 	if (get_mode_arithmetic(mode) == irma_twos_complement) {
3773 		/* the following rules are only to twos-complement */
3774 		if (is_Not(a)) {
3775 			/* -(~x) = x + 1 */
3776 			ir_node   *op  = get_Not_op(a);
3777 			ir_tarval *tv  = get_mode_one(mode);
3778 			ir_node   *blk = get_nodes_block(n);
3779 			ir_graph  *irg = get_irn_irg(blk);
3780 			ir_node   *c   = new_r_Const(irg, tv);
3781 			n = new_rd_Add(get_irn_dbg_info(n), blk, op, c, mode);
3782 			DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_NOT);
3783 			return n;
3784 		}
3785 		if (is_Shr(a)) {
3786 			ir_node *c = get_Shr_right(a);
3787 
3788 			if (is_Const(c)) {
3789 				ir_tarval *tv = get_Const_tarval(c);
3790 
3791 				if (tarval_is_long(tv) && get_tarval_long(tv) == (int) get_mode_size_bits(mode) - 1) {
3792 					/* -(a >>u (size-1)) = a >>s (size-1) */
3793 					ir_node *v = get_Shr_left(a);
3794 
3795 					n = new_rd_Shrs(get_irn_dbg_info(n), get_nodes_block(n), v, c, mode);
3796 					DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_PREDICATE);
3797 					return n;
3798 				}
3799 			}
3800 		}
3801 		if (is_Shrs(a)) {
3802 			ir_node *c = get_Shrs_right(a);
3803 
3804 			if (is_Const(c)) {
3805 				ir_tarval *tv = get_Const_tarval(c);
3806 
3807 				if (tarval_is_long(tv) && get_tarval_long(tv) == (int) get_mode_size_bits(mode) - 1) {
3808 					/* -(a >>s (size-1)) = a >>u (size-1) */
3809 					ir_node *v = get_Shrs_left(a);
3810 
3811 					n = new_rd_Shr(get_irn_dbg_info(n), get_nodes_block(n), v, c, mode);
3812 					DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_PREDICATE);
3813 					return n;
3814 				}
3815 			}
3816 		}
3817 	}
3818 	if (is_Sub(a)) {
3819 		/* - (a-b) = b - a */
3820 		ir_node *la  = get_Sub_left(a);
3821 		ir_node *ra  = get_Sub_right(a);
3822 		ir_node *blk = get_nodes_block(n);
3823 
3824 		n = new_rd_Sub(get_irn_dbg_info(n), blk, ra, la, mode);
3825 		DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_SUB);
3826 		return n;
3827 	}
3828 
3829 	if (is_Mul(a)) { /* -(a * const) -> a * -const */
3830 		ir_node   *mul_l = get_Mul_left(a);
3831 		ir_node   *mul_r = get_Mul_right(a);
3832 		ir_tarval *tv    = value_of(mul_r);
3833 		if (tv != tarval_bad) {
3834 			tv = tarval_neg(tv);
3835 			if (tv != tarval_bad) {
3836 				ir_graph *irg   = get_irn_irg(n);
3837 				ir_node  *cnst  = new_r_Const(irg, tv);
3838 				dbg_info *dbg   = get_irn_dbg_info(a);
3839 				ir_node  *block = get_nodes_block(a);
3840 				n = new_rd_Mul(dbg, block, mul_l, cnst, mode);
3841 				DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_MUL_C);
3842 				return n;
3843 			}
3844 		}
3845 	}
3846 
3847 	return n;
3848 }
3849 
3850 /**
3851  * Transform a Proj(Load) with a non-null address.
3852  */
transform_node_Proj_Load(ir_node * proj)3853 static ir_node *transform_node_Proj_Load(ir_node *proj)
3854 {
3855 	if (get_irn_mode(proj) == mode_X) {
3856 		ir_node *load = get_Proj_pred(proj);
3857 
3858 		/* get the Load address */
3859 		const ir_node *addr = get_Load_ptr(load);
3860 		const ir_node *confirm;
3861 
3862 		if (value_not_null(addr, &confirm)) {
3863 			if (confirm == NULL) {
3864 				/* this node may float if it did not depend on a Confirm */
3865 				set_irn_pinned(load, op_pin_state_floats);
3866 			}
3867 			if (get_Proj_proj(proj) == pn_Load_X_except) {
3868 				ir_graph *irg = get_irn_irg(proj);
3869 				DBG_OPT_EXC_REM(proj);
3870 				return new_r_Bad(irg, mode_X);
3871 			} else {
3872 				ir_node *blk = get_nodes_block(load);
3873 				return new_r_Jmp(blk);
3874 			}
3875 		}
3876 	}
3877 	return proj;
3878 }
3879 
3880 /**
3881  * Transform a Proj(Store) with a non-null address.
3882  */
transform_node_Proj_Store(ir_node * proj)3883 static ir_node *transform_node_Proj_Store(ir_node *proj)
3884 {
3885 	if (get_irn_mode(proj) == mode_X) {
3886 		ir_node *store = get_Proj_pred(proj);
3887 
3888 		/* get the load/store address */
3889 		const ir_node *addr = get_Store_ptr(store);
3890 		const ir_node *confirm;
3891 
3892 		if (value_not_null(addr, &confirm)) {
3893 			if (confirm == NULL) {
3894 				/* this node may float if it did not depend on a Confirm */
3895 				set_irn_pinned(store, op_pin_state_floats);
3896 			}
3897 			if (get_Proj_proj(proj) == pn_Store_X_except) {
3898 				ir_graph *irg = get_irn_irg(proj);
3899 				DBG_OPT_EXC_REM(proj);
3900 				return new_r_Bad(irg, mode_X);
3901 			} else {
3902 				ir_node *blk = get_nodes_block(store);
3903 				return new_r_Jmp(blk);
3904 			}
3905 		}
3906 	}
3907 	return proj;
3908 }
3909 
3910 /**
3911  * Transform a Proj(Div) with a non-zero value.
3912  * Removes the exceptions and routes the memory to the NoMem node.
3913  */
transform_node_Proj_Div(ir_node * proj)3914 static ir_node *transform_node_Proj_Div(ir_node *proj)
3915 {
3916 	ir_node *div = get_Proj_pred(proj);
3917 	ir_node *b   = get_Div_right(div);
3918 	ir_node *res, *new_mem;
3919 	const ir_node *confirm;
3920 	long proj_nr;
3921 
3922 	if (value_not_zero(b, &confirm)) {
3923 		/* div(x, y) && y != 0 */
3924 		if (confirm == NULL) {
3925 			/* we are sure we have a Const != 0 */
3926 			new_mem = get_Div_mem(div);
3927 			new_mem = skip_Pin(new_mem);
3928 			set_Div_mem(div, new_mem);
3929 			set_irn_pinned(div, op_pin_state_floats);
3930 		}
3931 
3932 		proj_nr = get_Proj_proj(proj);
3933 		switch (proj_nr) {
3934 		case pn_Div_X_regular:
3935 			return new_r_Jmp(get_nodes_block(div));
3936 
3937 		case pn_Div_X_except: {
3938 			ir_graph *irg = get_irn_irg(proj);
3939 			/* we found an exception handler, remove it */
3940 			DBG_OPT_EXC_REM(proj);
3941 			return new_r_Bad(irg, mode_X);
3942 		}
3943 
3944 		case pn_Div_M: {
3945 			ir_graph *irg = get_irn_irg(proj);
3946 			res = get_Div_mem(div);
3947 			new_mem = get_irg_no_mem(irg);
3948 
3949 			if (confirm) {
3950 				/* This node can only float up to the Confirm block */
3951 				new_mem = new_r_Pin(get_nodes_block(confirm), new_mem);
3952 			}
3953 			set_irn_pinned(div, op_pin_state_floats);
3954 			/* this is a Div without exception, we can remove the memory edge */
3955 			set_Div_mem(div, new_mem);
3956 			return res;
3957 		}
3958 		}
3959 	}
3960 	return proj;
3961 }
3962 
3963 /**
3964  * Transform a Proj(Mod) with a non-zero value.
3965  * Removes the exceptions and routes the memory to the NoMem node.
3966  */
transform_node_Proj_Mod(ir_node * proj)3967 static ir_node *transform_node_Proj_Mod(ir_node *proj)
3968 {
3969 	ir_node *mod = get_Proj_pred(proj);
3970 	ir_node *b   = get_Mod_right(mod);
3971 	ir_node *res, *new_mem;
3972 	const ir_node *confirm;
3973 	long proj_nr;
3974 
3975 	if (value_not_zero(b, &confirm)) {
3976 		/* mod(x, y) && y != 0 */
3977 		proj_nr = get_Proj_proj(proj);
3978 
3979 		if (confirm == NULL) {
3980 			/* we are sure we have a Const != 0 */
3981 			new_mem = get_Mod_mem(mod);
3982 			new_mem = skip_Pin(new_mem);
3983 			set_Mod_mem(mod, new_mem);
3984 			set_irn_pinned(mod, op_pin_state_floats);
3985 		}
3986 
3987 		switch (proj_nr) {
3988 
3989 		case pn_Mod_X_regular:
3990 			return new_r_Jmp(get_nodes_block(mod));
3991 
3992 		case pn_Mod_X_except: {
3993 			ir_graph *irg = get_irn_irg(proj);
3994 			/* we found an exception handler, remove it */
3995 			DBG_OPT_EXC_REM(proj);
3996 			return new_r_Bad(irg, mode_X);
3997 		}
3998 
3999 		case pn_Mod_M: {
4000 			ir_graph *irg = get_irn_irg(proj);
4001 			res = get_Mod_mem(mod);
4002 			new_mem = get_irg_no_mem(irg);
4003 
4004 			if (confirm) {
4005 				/* This node can only float up to the Confirm block */
4006 				new_mem = new_r_Pin(get_nodes_block(confirm), new_mem);
4007 			}
4008 			/* this is a Mod without exception, we can remove the memory edge */
4009 			set_Mod_mem(mod, new_mem);
4010 			return res;
4011 		}
4012 		case pn_Mod_res:
4013 			if (get_Mod_left(mod) == b) {
4014 				/* a % a = 0 if a != 0 */
4015 				ir_graph *irg  = get_irn_irg(proj);
4016 				ir_mode  *mode = get_irn_mode(proj);
4017 				ir_node  *res  = new_r_Const(irg, get_mode_null(mode));
4018 
4019 				DBG_OPT_CSTEVAL(mod, res);
4020 				return res;
4021 			}
4022 		}
4023 	}
4024 	return proj;
4025 }
4026 
4027 /**
4028  * return true if the operation returns a value with exactly 1 bit set
4029  */
is_single_bit(const ir_node * node)4030 static bool is_single_bit(const ir_node *node)
4031 {
4032 	/* a first implementation, could be extended with vrp and others... */
4033 	if (is_Shl(node)) {
4034 		ir_node *shl_l  = get_Shl_left(node);
4035 		ir_mode *mode   = get_irn_mode(node);
4036 		int      modulo = get_mode_modulo_shift(mode);
4037 		/* this works if we shift a 1 and we have modulo shift */
4038 		if (is_Const(shl_l) && is_Const_one(shl_l)
4039 				&& 0 < modulo && modulo <= (int)get_mode_size_bits(mode)) {
4040 			return true;
4041 		}
4042 	} else if (is_Const(node)) {
4043 		ir_tarval *tv = get_Const_tarval(node);
4044 		return tarval_is_single_bit(tv);
4045 	}
4046 	return false;
4047 }
4048 
4049 /**
4050  * checks if node just flips a bit in another node and returns that other node
4051  * if so. @p tv should be a value having just 1 bit set
4052  */
flips_bit(const ir_node * node,ir_tarval * tv)4053 static ir_node *flips_bit(const ir_node *node, ir_tarval *tv)
4054 {
4055 	if (is_Not(node))
4056 		return get_Not_op(node);
4057 	if (is_Eor(node)) {
4058 		ir_node *right = get_Eor_right(node);
4059 		if (is_Const(right)) {
4060 			ir_tarval *right_tv = get_Const_tarval(right);
4061 			ir_mode   *mode     = get_irn_mode(node);
4062 			if (tarval_and(right_tv, tv) != get_mode_null(mode))
4063 				return get_Eor_left(node);
4064 		}
4065 	}
4066 	return NULL;
4067 }
4068 
4069 /**
4070  * Normalizes and optimizes Cmp nodes.
4071  */
transform_node_Cmp(ir_node * n)4072 static ir_node *transform_node_Cmp(ir_node *n)
4073 {
4074 	ir_node    *left     = get_Cmp_left(n);
4075 	ir_node    *right    = get_Cmp_right(n);
4076 	ir_mode    *mode     = get_irn_mode(left);
4077 	ir_tarval  *tv       = NULL;
4078 	bool        changed  = false;
4079 	bool        changedc = false;
4080 	ir_relation relation = get_Cmp_relation(n);
4081 	ir_relation possible = ir_get_possible_cmp_relations(left, right);
4082 
4083 	/* mask out impossible relations */
4084 	ir_relation new_relation = relation & possible;
4085 	if (new_relation != relation) {
4086 		relation = new_relation;
4087 		changed  = true;
4088 	}
4089 
4090 	/* Remove unnecessary conversions */
4091 	if (!mode_is_float(mode)
4092 	    || be_get_backend_param()->mode_float_arithmetic == NULL) {
4093 		if (is_Conv(left) && is_Conv(right)) {
4094 			ir_node *op_left    = get_Conv_op(left);
4095 			ir_node *op_right   = get_Conv_op(right);
4096 			ir_mode *mode_left  = get_irn_mode(op_left);
4097 			ir_mode *mode_right = get_irn_mode(op_right);
4098 
4099 			if (smaller_mode(mode_left, mode) && smaller_mode(mode_right, mode)
4100 					&& mode_left != mode_b && mode_right != mode_b) {
4101 				ir_node *block = get_nodes_block(n);
4102 
4103 				if (mode_left == mode_right) {
4104 					left    = op_left;
4105 					right   = op_right;
4106 					changed = true;
4107 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV_CONV);
4108 				} else if (smaller_mode(mode_left, mode_right)) {
4109 					left    = new_r_Conv(block, op_left, mode_right);
4110 					right   = op_right;
4111 					changed = true;
4112 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
4113 				} else if (smaller_mode(mode_right, mode_left)) {
4114 					left    = op_left;
4115 					right   = new_r_Conv(block, op_right, mode_left);
4116 					changed = true;
4117 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
4118 				}
4119 				mode = get_irn_mode(left);
4120 			}
4121 		}
4122 		if (is_Conv(left) && is_Const(right)) {
4123 			ir_node   *op_left   = get_Conv_op(left);
4124 			ir_mode   *mode_left = get_irn_mode(op_left);
4125 			if (smaller_mode(mode_left, mode) && mode_left != mode_b) {
4126 				ir_tarval *tv        = get_Const_tarval(right);
4127 				tarval_int_overflow_mode_t last_mode
4128 					= tarval_get_integer_overflow_mode();
4129 				ir_tarval *new_tv;
4130 				tarval_set_integer_overflow_mode(TV_OVERFLOW_BAD);
4131 				new_tv = tarval_convert_to(tv, mode_left);
4132 				tarval_set_integer_overflow_mode(last_mode);
4133 				if (new_tv != tarval_bad) {
4134 					ir_graph *irg = get_irn_irg(n);
4135 					left    = op_left;
4136 					right   = new_r_Const(irg, new_tv);
4137 					mode    = get_irn_mode(left);
4138 					changed = true;
4139 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
4140 				}
4141 			}
4142 		}
4143 	}
4144 
4145 	/*
4146 	 * Optimize -a CMP -b into b CMP a.
4147 	 * This works only for modes where unary Minus cannot Overflow.
4148 	 * Note that two-complement integers can Overflow so it will NOT work.
4149 	 */
4150 	if (!mode_overflow_on_unary_Minus(mode) &&
4151 			is_Minus(left) && is_Minus(right)) {
4152 		left     = get_Minus_op(left);
4153 		right    = get_Minus_op(right);
4154 		relation = get_inversed_relation(relation);
4155 		changed  = true;
4156 		DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4157 	}
4158 
4159 	/* remove operation on both sides if possible */
4160 	if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
4161 		/*
4162 		 * The following operations are NOT safe for floating point operations, for instance
4163 		 * 1.0 + inf == 2.0 + inf, =/=> x == y
4164 		 */
4165 		if (mode_is_int(mode)) {
4166 			unsigned lop = get_irn_opcode(left);
4167 
4168 			if (lop == get_irn_opcode(right)) {
4169 				ir_node *ll, *lr, *rl, *rr;
4170 
4171 				/* same operation on both sides, try to remove */
4172 				switch (lop) {
4173 				case iro_Not:
4174 				case iro_Minus:
4175 					/* ~a CMP ~b => a CMP b, -a CMP -b ==> a CMP b */
4176 					left  = get_unop_op(left);
4177 					right = get_unop_op(right);
4178 					changed = true;
4179 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4180 					break;
4181 				case iro_Add:
4182 					ll = get_Add_left(left);
4183 					lr = get_Add_right(left);
4184 					rl = get_Add_left(right);
4185 					rr = get_Add_right(right);
4186 
4187 					if (ll == rl) {
4188 						/* X + a CMP X + b ==> a CMP b */
4189 						left  = lr;
4190 						right = rr;
4191 						changed = true;
4192 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4193 					} else if (ll == rr) {
4194 						/* X + a CMP b + X ==> a CMP b */
4195 						left  = lr;
4196 						right = rl;
4197 						changed = true;
4198 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4199 					} else if (lr == rl) {
4200 						/* a + X CMP X + b ==> a CMP b */
4201 						left  = ll;
4202 						right = rr;
4203 						changed = true;
4204 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4205 					} else if (lr == rr) {
4206 						/* a + X CMP b + X ==> a CMP b */
4207 						left  = ll;
4208 						right = rl;
4209 						changed = true;
4210 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4211 					}
4212 					break;
4213 				case iro_Sub:
4214 					ll = get_Sub_left(left);
4215 					lr = get_Sub_right(left);
4216 					rl = get_Sub_left(right);
4217 					rr = get_Sub_right(right);
4218 
4219 					if (ll == rl) {
4220 						/* X - a CMP X - b ==> a CMP b */
4221 						left  = lr;
4222 						right = rr;
4223 						changed = true;
4224 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4225 					} else if (lr == rr) {
4226 						/* a - X CMP b - X ==> a CMP b */
4227 						left  = ll;
4228 						right = rl;
4229 						changed = true;
4230 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4231 					}
4232 					break;
4233 				case iro_Rotl:
4234 					if (get_Rotl_right(left) == get_Rotl_right(right)) {
4235 						/* a ROTL X CMP b ROTL X ==> a CMP b */
4236 						left  = get_Rotl_left(left);
4237 						right = get_Rotl_left(right);
4238 						changed = true;
4239 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4240 					}
4241 					break;
4242 				default:
4243 					break;
4244 				}
4245 			}
4246 
4247 			/* X+A == A, A+X == A, A-X == A -> X == 0 */
4248 			if (is_Add(left) || is_Sub(left) || is_Or_Eor_Add(left)) {
4249 				ir_node *ll = get_binop_left(left);
4250 				ir_node *lr = get_binop_right(left);
4251 
4252 				if (lr == right && (is_Add(left) || is_Or_Eor_Add(left))) {
4253 					ir_node *tmp = ll;
4254 					ll = lr;
4255 					lr = tmp;
4256 				}
4257 				if (ll == right) {
4258 					ir_graph *irg = get_irn_irg(n);
4259 					left     = lr;
4260 					right   = create_zero_const(irg, mode);
4261 					changed = true;
4262 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4263 				}
4264 			}
4265 			if (is_Add(right) || is_Sub(right) || is_Or_Eor_Add(right)) {
4266 				ir_node *rl = get_binop_left(right);
4267 				ir_node *rr = get_binop_right(right);
4268 
4269 				if (rr == left && (is_Add(right) || is_Or_Eor_Add(right))) {
4270 					ir_node *tmp = rl;
4271 					rl = rr;
4272 					rr = tmp;
4273 				}
4274 				if (rl == left) {
4275 					ir_graph *irg = get_irn_irg(n);
4276 					left     = rr;
4277 					right   = create_zero_const(irg, mode);
4278 					changed = true;
4279 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
4280 				}
4281 			}
4282 
4283 			if (is_And(left) && is_Const(right)) {
4284 				ir_node *ll = get_binop_left(left);
4285 				ir_node *lr = get_binop_right(left);
4286 				if (is_Shr(ll) && is_Const(lr)) {
4287 					/* Cmp((x >>u c1) & c2, c3) = Cmp(x & (c2 << c1), c3 << c1) */
4288 					ir_node *block = get_nodes_block(n);
4289 					ir_mode *mode = get_irn_mode(left);
4290 
4291 					ir_node *llr = get_Shr_right(ll);
4292 					if (is_Const(llr)) {
4293 						dbg_info *dbg = get_irn_dbg_info(left);
4294 						ir_graph *irg = get_irn_irg(left);
4295 
4296 						ir_tarval *c1    = get_Const_tarval(llr);
4297 						ir_tarval *c2    = get_Const_tarval(lr);
4298 						ir_tarval *c3    = get_Const_tarval(right);
4299 						ir_tarval *mask  = tarval_shl(c2, c1);
4300 						ir_tarval *value = tarval_shl(c3, c1);
4301 
4302 						left  = new_rd_And(dbg, block, get_Shr_left(ll), new_r_Const(irg, mask), mode);
4303 						right = new_r_Const(irg, value);
4304 						changed = true;
4305 					}
4306 				}
4307 			}
4308 			/* Cmp(Eor(x, y), 0) <=> Cmp(x, y) at least for the ==0,!=0
4309 			 * cases */
4310 			if (is_Const(right) && is_Const_null(right) &&
4311 			    (is_Eor(left) || is_Or_Eor_Add(left))) {
4312 				right = get_Eor_right(left);
4313 				left  = get_Eor_left(left);
4314 				changed = true;
4315 			}
4316 		}
4317 	}
4318 
4319 	if (mode_is_int(mode) && is_And(left)) {
4320 		/* a complicated Cmp(And(1bit, val), 1bit) "bit-testing" can be replaced
4321 		 * by the simpler Cmp(And(1bit, val), 0) negated pnc */
4322 		if (relation == ir_relation_equal
4323 	        || (mode_is_signed(mode) && relation == ir_relation_less_greater)
4324 	        || (!mode_is_signed(mode) && (relation & ir_relation_less_equal) == ir_relation_less)) {
4325 			ir_node *and0 = get_And_left(left);
4326 			ir_node *and1 = get_And_right(left);
4327 			if (and1 == right) {
4328 				ir_node *tmp = and0;
4329 				and0 = and1;
4330 				and1 = tmp;
4331 			}
4332 			if (and0 == right && is_single_bit(and0)) {
4333 				ir_graph *irg = get_irn_irg(n);
4334 				relation =
4335 					relation == ir_relation_equal ? ir_relation_less_greater
4336 					                              : ir_relation_equal;
4337 				right = create_zero_const(irg, mode);
4338 				changed |= 1;
4339 				goto is_bittest;
4340 			}
4341 		}
4342 
4343 		if (is_Const(right) && is_Const_null(right) &&
4344 		    (relation == ir_relation_equal
4345 		    || (relation == ir_relation_less_greater)
4346 		    || (!mode_is_signed(mode) && relation == ir_relation_greater))) {
4347 is_bittest: {
4348 			/* instead of flipping the bit before the bit-test operation negate
4349 			 * pnc */
4350 			ir_node *and0 = get_And_left(left);
4351 			ir_node *and1 = get_And_right(left);
4352 			if (is_Const(and1)) {
4353 				ir_tarval *tv = get_Const_tarval(and1);
4354 				if (tarval_is_single_bit(tv)) {
4355 					ir_node *flipped = flips_bit(and0, tv);
4356 					if (flipped != NULL) {
4357 						dbg_info *dbgi  = get_irn_dbg_info(left);
4358 						ir_node  *block = get_nodes_block(left);
4359 						relation = get_negated_relation(relation);
4360 						left = new_rd_And(dbgi, block, flipped, and1, mode);
4361 						changed |= 1;
4362 					}
4363 				}
4364 			}
4365 			}
4366 		}
4367 	}
4368 
4369 	/* replace mode_b compares with ands/ors */
4370 	if (mode == mode_b) {
4371 		ir_node  *block = get_nodes_block(n);
4372 		ir_node  *bres;
4373 
4374 		switch (relation) {
4375 			case ir_relation_less_equal:
4376 				bres = new_r_Or(block, new_r_Not(block, left, mode_b), right, mode_b);
4377 				break;
4378 			case ir_relation_less:
4379 				bres = new_r_And(block, new_r_Not(block, left, mode_b), right, mode_b);
4380 				break;
4381 			case ir_relation_greater_equal:
4382 				bres = new_r_Or(block, left, new_r_Not(block, right, mode_b), mode_b);
4383 				break;
4384 			case ir_relation_greater:
4385 				bres = new_r_And(block, left, new_r_Not(block, right, mode_b), mode_b);
4386 				break;
4387 			case ir_relation_less_greater:
4388 				bres = new_r_Eor(block, left, right, mode_b);
4389 				break;
4390 			case ir_relation_equal:
4391 				bres = new_r_Not(block, new_r_Eor(block, left, right, mode_b), mode_b);
4392 				break;
4393 			default:
4394 #ifdef DEBUG_libfirm
4395 				ir_fprintf(stderr, "Optimisation warning, unexpected mode_b Cmp %+F\n", n);
4396 #endif
4397 				bres = NULL;
4398 		}
4399 		if (bres != NULL) {
4400 			DBG_OPT_ALGSIM0(n, bres, FS_OPT_CMP_TO_BOOL);
4401 			return bres;
4402 		}
4403 	}
4404 
4405 	/*
4406 	 * First step: normalize the compare op
4407 	 * by placing the constant on the right side
4408 	 * or moving the lower address node to the left.
4409 	 */
4410 	if (!operands_are_normalized(left, right)) {
4411 		ir_node *t = left;
4412 		left  = right;
4413 		right = t;
4414 
4415 		relation = get_inversed_relation(relation);
4416 		changed  = true;
4417 	}
4418 
4419 	/*
4420 	 * Second step: Try to reduce the magnitude
4421 	 * of a constant. This may help to generate better code
4422 	 * later and may help to normalize more compares.
4423 	 * Of course this is only possible for integer values.
4424 	 */
4425 	tv = value_of(right);
4426 	if (tv != tarval_bad) {
4427 		ir_mode *mode = get_irn_mode(right);
4428 
4429 		/* cmp(mux(x, cf, ct), c2) can be eliminated:
4430 		 *   cmp(ct,c2) | cmp(cf,c2) | result
4431 		 *   -----------|------------|--------
4432 		 *   true       | true       | True
4433 		 *   false      | false      | False
4434 		 *   true       | false      | x
4435 		 *   false      | true       | not(x)
4436 		 */
4437 		if (is_Mux(left)) {
4438 			ir_node *mux_true  = get_Mux_true(left);
4439 			ir_node *mux_false = get_Mux_false(left);
4440 			if (is_Const(mux_true) && is_Const(mux_false)) {
4441 				/* we can fold true/false constant separately */
4442 				ir_tarval *tv_true  = get_Const_tarval(mux_true);
4443 				ir_tarval *tv_false = get_Const_tarval(mux_false);
4444 				ir_relation r_true  = tarval_cmp(tv_true, tv);
4445 				ir_relation r_false = tarval_cmp(tv_false, tv);
4446 				if (r_true != ir_relation_false
4447 				    || r_false != ir_relation_false) {
4448 					bool rel_true  = (r_true & relation)  != 0;
4449 					bool rel_false = (r_false & relation) != 0;
4450 					ir_node *cond = get_Mux_sel(left);
4451 					if (rel_true == rel_false) {
4452 						relation = rel_true ? ir_relation_true
4453 						                    : ir_relation_false;
4454 					} else if (rel_true) {
4455 						return cond;
4456 					} else {
4457 						dbg_info *dbgi  = get_irn_dbg_info(n);
4458 						ir_node  *block = get_nodes_block(n);
4459 						ir_node  *notn  = new_rd_Not(dbgi, block, cond, mode_b);
4460 						return notn;
4461 					}
4462 				}
4463 			}
4464 		}
4465 
4466 		/* TODO extend to arbitrary constants */
4467 		if (is_Conv(left) && tarval_is_null(tv)) {
4468 			ir_node *op      = get_Conv_op(left);
4469 			ir_mode *op_mode = get_irn_mode(op);
4470 
4471 			/*
4472 			 * UpConv(x) REL 0  ==> x REL 0
4473 			 * Don't do this for float values as it's unclear whether it is a
4474 			 * win. (on the other side it makes detection/creation of fabs hard)
4475 			 */
4476 			if (get_mode_size_bits(mode) > get_mode_size_bits(op_mode) &&
4477 			    ((relation == ir_relation_equal || relation == ir_relation_less_greater) ||
4478 				 mode_is_signed(mode) || !mode_is_signed(op_mode)) &&
4479 				!mode_is_float(mode)) {
4480 				tv   = get_mode_null(op_mode);
4481 				left = op;
4482 				mode = op_mode;
4483 				changedc = true;
4484 				DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
4485 			}
4486 		}
4487 
4488 		if (tv != tarval_bad) {
4489 			/* the following optimization is possible on modes without Overflow
4490 			 * on Unary Minus or on == and !=:
4491 			 * -a CMP c  ==>  a swap(CMP) -c
4492 			 *
4493 			 * Beware: for two-complement Overflow may occur, so only == and != can
4494 			 * be optimized, see this:
4495 			 * -MININT < 0 =/=> MININT > 0 !!!
4496 			 */
4497 			if (is_Minus(left) &&
4498 				(!mode_overflow_on_unary_Minus(mode) ||
4499 				(mode_is_int(mode) && (relation == ir_relation_equal || relation == ir_relation_less_greater)))) {
4500 				tv = tarval_neg(tv);
4501 
4502 				if (tv != tarval_bad) {
4503 					left = get_Minus_op(left);
4504 					relation = get_inversed_relation(relation);
4505 					changedc = true;
4506 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4507 				}
4508 			} else if (is_Not(left) && (relation == ir_relation_equal || relation == ir_relation_less_greater)) {
4509 				/* Not(a) ==/!= c  ==>  a ==/!= Not(c) */
4510 				tv = tarval_not(tv);
4511 
4512 				if (tv != tarval_bad) {
4513 					left = get_Not_op(left);
4514 					changedc = true;
4515 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4516 				}
4517 			}
4518 
4519 			/* for integer modes, we have more */
4520 			if (mode_is_int(mode) && !is_Const(left)) {
4521 				/* c > 0 : a < c  ==>  a <= (c-1)    a >= c  ==>  a > (c-1) */
4522 				if ((relation == ir_relation_less || relation == ir_relation_greater_equal) &&
4523 					tarval_cmp(tv, get_mode_null(mode)) == ir_relation_greater) {
4524 					tv = tarval_sub(tv, get_mode_one(mode), NULL);
4525 
4526 					if (tv != tarval_bad) {
4527 						relation ^= ir_relation_equal;
4528 						changedc = true;
4529 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4530 					}
4531 				}
4532 				/* c < 0 : a > c  ==>  a >= (c+1)    a <= c  ==>  a < (c+1) */
4533 				else if ((relation == ir_relation_greater || relation == ir_relation_less_equal) &&
4534 					tarval_cmp(tv, get_mode_null(mode)) == ir_relation_less) {
4535 					tv = tarval_add(tv, get_mode_one(mode));
4536 
4537 					if (tv != tarval_bad) {
4538 						relation ^= ir_relation_equal;
4539 						changedc = true;
4540 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4541 					}
4542 				}
4543 
4544 				/* the following reassociations work only for == and != */
4545 				if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
4546 					if (tv != tarval_bad) {
4547 						/* a-c1 == c2  ==>  a == c2+c1,  a-c1 != c2  ==>  a != c2+c1 */
4548 						if (is_Sub(left)) {
4549 							ir_node *c1 = get_Sub_right(left);
4550 							ir_tarval *tv2 = value_of(c1);
4551 
4552 							if (tv2 != tarval_bad) {
4553 								tv2 = tarval_add(tv, value_of(c1));
4554 
4555 								if (tv2 != tarval_bad) {
4556 									left    = get_Sub_left(left);
4557 									tv      = tv2;
4558 									changedc = true;
4559 									DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4560 								}
4561 							}
4562 						}
4563 						/* a+c1 == c2  ==>  a == c2-c1,  a+c1 != c2  ==>  a != c2-c1 */
4564 						else if (is_Add(left) || is_Or_Eor_Add(left)) {
4565 							ir_node *a_l = get_binop_left(left);
4566 							ir_node *a_r = get_binop_right(left);
4567 							ir_node *a;
4568 							ir_tarval *tv2;
4569 
4570 							if (is_Const(a_l)) {
4571 								a = a_r;
4572 								tv2 = value_of(a_l);
4573 							} else {
4574 								a = a_l;
4575 								tv2 = value_of(a_r);
4576 							}
4577 
4578 							if (tv2 != tarval_bad) {
4579 								tv2 = tarval_sub(tv, tv2, NULL);
4580 
4581 								if (tv2 != tarval_bad) {
4582 									left    = a;
4583 									tv      = tv2;
4584 									changedc = true;
4585 									DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4586 								}
4587 							}
4588 						}
4589 						/* -a == c ==> a == -c, -a != c ==> a != -c */
4590 						else if (is_Minus(left)) {
4591 							ir_tarval *tv2 = tarval_sub(get_mode_null(mode), tv, NULL);
4592 
4593 							if (tv2 != tarval_bad) {
4594 								left    = get_Minus_op(left);
4595 								tv      = tv2;
4596 								changedc = true;
4597 								DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4598 							}
4599 						}
4600 					}
4601 				}
4602 			}
4603 
4604 			if (relation == ir_relation_equal || relation == ir_relation_less_greater) {
4605 				switch (get_irn_opcode(left)) {
4606 					ir_node *c1;
4607 
4608 				case iro_And:
4609 					c1 = get_And_right(left);
4610 					if (is_Const(c1)) {
4611 						/*
4612 						 * And(x, C1) == C2 ==> FALSE if C2 & C1 != C2
4613 						 * And(x, C1) != C2 ==> TRUE if C2 & C1 != C2
4614 						 */
4615 						ir_tarval *mask = tarval_and(get_Const_tarval(c1), tv);
4616 						if (mask != tv) {
4617 							/* TODO: move to constant evaluation */
4618 							ir_graph *irg = get_irn_irg(n);
4619 							tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
4620 							c1 = new_r_Const(irg, tv);
4621 							DBG_OPT_CSTEVAL(n, c1);
4622 							return c1;
4623 						}
4624 
4625 						if (tarval_is_single_bit(tv)) {
4626 							/*
4627 							 * optimization for AND:
4628 							 * Optimize:
4629 							 *   And(x, C) == C  ==>  And(x, C) != 0
4630 							 *   And(x, C) != C  ==>  And(X, C) == 0
4631 							 *
4632 							 * if C is a single Bit constant.
4633 							 */
4634 
4635 							/* check for Constant's match. We have check hare the tarvals,
4636 							   because our const might be changed */
4637 							if (get_Const_tarval(c1) == tv) {
4638 								/* fine: do the transformation */
4639 								tv = get_mode_null(get_tarval_mode(tv));
4640 								relation ^= ir_relation_less_equal_greater;
4641 								changedc = true;
4642 								DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4643 							}
4644 						}
4645 					}
4646 					break;
4647 				case iro_Or:
4648 					c1 = get_Or_right(left);
4649 					if (is_Const(c1) && tarval_is_null(tv)) {
4650 						/*
4651 						 * Or(x, C) == 0  && C != 0 ==> FALSE
4652 						 * Or(x, C) != 0  && C != 0 ==> TRUE
4653 						 */
4654 						if (! tarval_is_null(get_Const_tarval(c1))) {
4655 							/* TODO: move to constant evaluation */
4656 							ir_graph *irg = get_irn_irg(n);
4657 							tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
4658 							c1 = new_r_Const(irg, tv);
4659 							DBG_OPT_CSTEVAL(n, c1);
4660 							return c1;
4661 						}
4662 					}
4663 					break;
4664 				case iro_Shl:
4665 					/*
4666 					 * optimize x << c1 == c into x & (-1 >>u c1) == c >> c1  if  c & (-1 << c1) == c
4667 					 *                             FALSE                       else
4668 					 * optimize x << c1 != c into x & (-1 >>u c1) != c >> c1  if  c & (-1 << c1) == c
4669 					 *                             TRUE                        else
4670 					 */
4671 					c1 = get_Shl_right(left);
4672 					if (is_Const(c1)) {
4673 						ir_graph  *irg    = get_irn_irg(c1);
4674 						ir_tarval *tv1    = get_Const_tarval(c1);
4675 						ir_mode   *mode   = get_irn_mode(left);
4676 						ir_tarval *minus1 = get_mode_all_one(mode);
4677 						ir_tarval *amask  = tarval_shr(minus1, tv1);
4678 						ir_tarval *cmask  = tarval_shl(minus1, tv1);
4679 						ir_node   *sl, *blk;
4680 
4681 						if (tarval_and(tv, cmask) != tv) {
4682 							/* condition not met */
4683 							tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
4684 							c1 = new_r_Const(irg, tv);
4685 							DBG_OPT_CSTEVAL(n, c1);
4686 							return c1;
4687 						}
4688 						sl   = get_Shl_left(left);
4689 						blk  = get_nodes_block(n);
4690 						left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
4691 						tv   = tarval_shr(tv, tv1);
4692 						changedc = true;
4693 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4694 					}
4695 					break;
4696 				case iro_Shr:
4697 					/*
4698 					 * optimize x >>u c1 == c into x & (-1 << c1) == c << c1  if  c & (-1 >>u c1) == c
4699 					 *                             FALSE                       else
4700 					 * optimize x >>u c1 != c into x & (-1 << c1) != c << c1  if  c & (-1 >>u c1) == c
4701 					 *                             TRUE                        else
4702 					 */
4703 					c1 = get_Shr_right(left);
4704 					if (is_Const(c1)) {
4705 						ir_graph  *irg    = get_irn_irg(c1);
4706 						ir_tarval *tv1    = get_Const_tarval(c1);
4707 						ir_mode   *mode   = get_irn_mode(left);
4708 						ir_tarval *minus1 = get_mode_all_one(mode);
4709 						ir_tarval *amask  = tarval_shl(minus1, tv1);
4710 						ir_tarval *cmask  = tarval_shr(minus1, tv1);
4711 						ir_node   *sl, *blk;
4712 
4713 						if (tarval_and(tv, cmask) != tv) {
4714 							/* condition not met */
4715 							tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
4716 							c1 = new_r_Const(irg, tv);
4717 							DBG_OPT_CSTEVAL(n, c1);
4718 							return c1;
4719 						}
4720 						sl   = get_Shr_left(left);
4721 						blk  = get_nodes_block(n);
4722 						left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
4723 						tv   = tarval_shl(tv, tv1);
4724 						changedc = true;
4725 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4726 					}
4727 					break;
4728 				case iro_Shrs:
4729 					/*
4730 					 * optimize x >>s c1 == c into x & (-1 << c1) == c << c1  if  (c >>s (BITS - c1)) \in {0,-1}
4731 					 *                             FALSE                       else
4732 					 * optimize x >>s c1 != c into x & (-1 << c1) != c << c1  if  (c >>s (BITS - c1)) \in {0,-1}
4733 					 *                             TRUE                        else
4734 					 */
4735 					c1 = get_Shrs_right(left);
4736 					if (is_Const(c1)) {
4737 						ir_graph  *irg    = get_irn_irg(c1);
4738 						ir_tarval *tv1    = get_Const_tarval(c1);
4739 						ir_mode   *mode   = get_irn_mode(left);
4740 						ir_tarval *minus1 = get_mode_all_one(mode);
4741 						ir_tarval *amask  = tarval_shl(minus1, tv1);
4742 						ir_tarval *cond   = new_tarval_from_long(get_mode_size_bits(mode), get_tarval_mode(tv1));
4743 						ir_node *sl, *blk;
4744 
4745 						cond = tarval_sub(cond, tv1, NULL);
4746 						cond = tarval_shrs(tv, cond);
4747 
4748 						if (!tarval_is_all_one(cond) && !tarval_is_null(cond)) {
4749 							/* condition not met */
4750 							tv = relation == ir_relation_equal ? get_tarval_b_false() : get_tarval_b_true();
4751 							c1 = new_r_Const(irg, tv);
4752 							DBG_OPT_CSTEVAL(n, c1);
4753 							return c1;
4754 						}
4755 						sl   = get_Shrs_left(left);
4756 						blk  = get_nodes_block(n);
4757 						left = new_rd_And(get_irn_dbg_info(left), blk, sl, new_r_Const(irg, amask), mode);
4758 						tv   = tarval_shl(tv, tv1);
4759 						changedc = true;
4760 						DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4761 					}
4762 					break;
4763 				}
4764 			}
4765 		}
4766 	}
4767 
4768 	if (changedc) {     /* need a new Const */
4769 		ir_graph *irg = get_irn_irg(n);
4770 		right = new_r_Const(irg, tv);
4771 		changed = true;
4772 	}
4773 
4774 	if ((relation == ir_relation_equal || relation == ir_relation_less_greater) && is_Const(right) && is_Const_null(right) && is_Proj(left)) {
4775 		ir_node *op = get_Proj_pred(left);
4776 
4777 		if (is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) {
4778 			ir_node *c = get_binop_right(op);
4779 
4780 			if (is_Const(c)) {
4781 				ir_tarval *tv = get_Const_tarval(c);
4782 
4783 				if (tarval_is_single_bit(tv)) {
4784 					/* special case: (x % 2^n) CMP 0 ==> x & (2^n-1) CMP 0 */
4785 					ir_node *v    = get_binop_left(op);
4786 					ir_node *blk  = get_nodes_block(op);
4787 					ir_graph *irg = get_irn_irg(op);
4788 					ir_mode *mode = get_irn_mode(v);
4789 
4790 					tv = tarval_sub(tv, get_mode_one(mode), NULL);
4791 					left = new_rd_And(get_irn_dbg_info(op), blk, v, new_r_Const(irg, tv), mode);
4792 					changed = true;
4793 					DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_MOD_TO_AND);
4794 				}
4795 			}
4796 		}
4797 	}
4798 
4799 	if (changed) {
4800 		dbg_info *dbgi  = get_irn_dbg_info(n);
4801 		ir_node  *block = get_nodes_block(n);
4802 
4803 		/* create a new compare */
4804 		n = new_rd_Cmp(dbgi, block, left, right, relation);
4805 	}
4806 
4807 	return n;
4808 }
4809 
4810 /**
4811  * Optimize CopyB(mem, x, x) into a Nop.
4812  */
transform_node_Proj_CopyB(ir_node * proj)4813 static ir_node *transform_node_Proj_CopyB(ir_node *proj)
4814 {
4815 	ir_node *copyb = get_Proj_pred(proj);
4816 	ir_node *a     = get_CopyB_dst(copyb);
4817 	ir_node *b     = get_CopyB_src(copyb);
4818 
4819 	if (a == b) {
4820 		switch (get_Proj_proj(proj)) {
4821 		case pn_CopyB_X_regular:
4822 			/* Turn CopyB into a tuple (mem, jmp, bad, bad) */
4823 			DBG_OPT_EXC_REM(proj);
4824 			proj = new_r_Jmp(get_nodes_block(copyb));
4825 			break;
4826 		case pn_CopyB_X_except: {
4827 			ir_graph *irg = get_irn_irg(proj);
4828 			DBG_OPT_EXC_REM(proj);
4829 			proj = new_r_Bad(irg, mode_X);
4830 			break;
4831 		}
4832 		default:
4833 			break;
4834 		}
4835 	}
4836 	return proj;
4837 }
4838 
4839 /**
4840  * Optimize Bounds(idx, idx, upper) into idx.
4841  */
transform_node_Proj_Bound(ir_node * proj)4842 static ir_node *transform_node_Proj_Bound(ir_node *proj)
4843 {
4844 	ir_node *oldn  = proj;
4845 	ir_node *bound = get_Proj_pred(proj);
4846 	ir_node *idx   = get_Bound_index(bound);
4847 	ir_node *pred  = skip_Proj(idx);
4848 	int ret_tuple  = 0;
4849 
4850 	if (idx == get_Bound_lower(bound))
4851 		ret_tuple = 1;
4852 	else if (is_Bound(pred)) {
4853 		/*
4854 		* idx was Bounds checked previously, it is still valid if
4855 		* lower <= pred_lower && pred_upper <= upper.
4856 		*/
4857 		ir_node *lower = get_Bound_lower(bound);
4858 		ir_node *upper = get_Bound_upper(bound);
4859 		if (get_Bound_lower(pred) == lower &&
4860 			get_Bound_upper(pred) == upper) {
4861 			/*
4862 			 * One could expect that we simply return the previous
4863 			 * Bound here. However, this would be wrong, as we could
4864 			 * add an exception Proj to a new location then.
4865 			 * So, we must turn in into a tuple.
4866 			 */
4867 			ret_tuple = 1;
4868 		}
4869 	}
4870 	if (ret_tuple) {
4871 		/* Turn Bound into a tuple (mem, jmp, bad, idx) */
4872 		switch (get_Proj_proj(proj)) {
4873 		case pn_Bound_M:
4874 			DBG_OPT_EXC_REM(proj);
4875 			proj = get_Bound_mem(bound);
4876 			break;
4877 		case pn_Bound_X_except:
4878 			DBG_OPT_EXC_REM(proj);
4879 			proj = new_r_Bad(get_irn_irg(proj), mode_X);
4880 			break;
4881 		case pn_Bound_res:
4882 			proj = idx;
4883 			DBG_OPT_ALGSIM0(oldn, proj, FS_OPT_NOP);
4884 			break;
4885 		case pn_Bound_X_regular:
4886 			DBG_OPT_EXC_REM(proj);
4887 			proj = new_r_Jmp(get_nodes_block(bound));
4888 			break;
4889 		default:
4890 			break;
4891 		}
4892 	}
4893 	return proj;
4894 }
4895 
4896 /**
4897  * Does all optimizations on nodes that must be done on its Projs
4898  * because of creating new nodes.
4899  */
transform_node_Proj(ir_node * proj)4900 static ir_node *transform_node_Proj(ir_node *proj)
4901 {
4902 	ir_node *n = get_Proj_pred(proj);
4903 
4904 	if (n->op->ops.transform_node_Proj)
4905 		return n->op->ops.transform_node_Proj(proj);
4906 	return proj;
4907 }
4908 
4909 /**
4910  * Test whether a block is unreachable
4911  * Note: That this only returns true when
4912  * IR_GRAPH_CONSTRAINT_OPTIMIZE_UNREACHABLE_CODE is set.
4913  * This is important, as you easily end up producing invalid constructs in the
4914  * unreachable code when optimizing away edges into the unreachable code.
4915  * So only set this flag when you iterate localopts to the fixpoint.
4916  * When you reach the fixpoint then all unreachable code is dead
4917  * (= can't be reached by firm edges) and you won't see the invalid constructs
4918  * anymore.
4919  */
is_block_unreachable(const ir_node * block)4920 static bool is_block_unreachable(const ir_node *block)
4921 {
4922 	const ir_graph *irg = get_irn_irg(block);
4923 	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_OPTIMIZE_UNREACHABLE_CODE))
4924 		return false;
4925 	return get_Block_dom_depth(block) < 0;
4926 }
4927 
transform_node_Block(ir_node * block)4928 static ir_node *transform_node_Block(ir_node *block)
4929 {
4930 	ir_graph *irg   = get_irn_irg(block);
4931 	int       arity = get_irn_arity(block);
4932 	ir_node  *bad   = NULL;
4933 	int       i;
4934 
4935 	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_OPTIMIZE_UNREACHABLE_CODE))
4936 		return block;
4937 
4938 	for (i = 0; i < arity; ++i) {
4939 		ir_node *const pred = get_Block_cfgpred(block, i);
4940 		if (is_Bad(pred) || !is_block_unreachable(get_nodes_block(pred)))
4941 			continue;
4942 		if (bad == NULL)
4943 			bad = new_r_Bad(irg, mode_X);
4944 		set_irn_n(block, i, bad);
4945 	}
4946 
4947 	return block;
4948 }
4949 
transform_node_Phi(ir_node * phi)4950 static ir_node *transform_node_Phi(ir_node *phi)
4951 {
4952 	int       n     = get_irn_arity(phi);
4953 	ir_mode  *mode  = get_irn_mode(phi);
4954 	ir_node  *block = get_nodes_block(phi);
4955 	ir_graph *irg   = get_irn_irg(phi);
4956 	ir_node  *bad   = NULL;
4957 	int       i;
4958 
4959 	/* Set phi-operands for bad-block inputs to bad */
4960 	for (i = 0; i < n; ++i) {
4961 		if (!is_Bad(get_Phi_pred(phi, i))) {
4962 			ir_node *pred = get_Block_cfgpred(block, i);
4963 			if (is_Bad(pred) || is_block_unreachable(get_nodes_block(pred))) {
4964 				if (bad == NULL)
4965 					bad = new_r_Bad(irg, mode);
4966 				set_irn_n(phi, i, bad);
4967 			}
4968 		}
4969 	}
4970 
4971 	/* Move Pin nodes down through Phi nodes. */
4972 	if (mode == mode_M) {
4973 		n = get_irn_arity(phi);
4974 
4975 		/* Beware of Phi0 */
4976 		if (n > 0) {
4977 			ir_node **in;
4978 			ir_node  *new_phi;
4979 			bool      has_pin = false;
4980 
4981 			NEW_ARR_A(ir_node *, in, n);
4982 
4983 			for (i = 0; i < n; ++i) {
4984 				ir_node *pred = get_irn_n(phi, i);
4985 
4986 				if (is_Pin(pred)) {
4987 					in[i]   = get_Pin_op(pred);
4988 					has_pin = true;
4989 				} else if (is_Bad(pred)) {
4990 					in[i] = pred;
4991 				} else {
4992 					return phi;
4993 				}
4994 			}
4995 
4996 			if (!has_pin)
4997 				return phi;
4998 
4999 			/* Move the Pin nodes "behind" the Phi. */
5000 			new_phi = new_r_Phi(block, n, in, mode_M);
5001 			return new_r_Pin(block, new_phi);
5002 		}
5003 	}
5004 	/* Move Confirms down through Phi nodes. */
5005 	else if (mode_is_reference(mode)) {
5006 		n = get_irn_arity(phi);
5007 
5008 		/* Beware of Phi0 */
5009 		if (n > 0) {
5010 			ir_node    *pred = get_irn_n(phi, 0);
5011 			ir_node    *bound, *new_phi, **in;
5012 			ir_relation relation;
5013 			bool        has_confirm = false;
5014 
5015 			if (! is_Confirm(pred))
5016 				return phi;
5017 
5018 			bound    = get_Confirm_bound(pred);
5019 			relation = get_Confirm_relation(pred);
5020 
5021 			NEW_ARR_A(ir_node *, in, n);
5022 			in[0] = get_Confirm_value(pred);
5023 
5024 			for (i = 1; i < n; ++i) {
5025 				pred = get_irn_n(phi, i);
5026 
5027 				if (is_Confirm(pred) &&
5028 						get_Confirm_bound(pred) == bound &&
5029 						get_Confirm_relation(pred) == relation) {
5030 					in[i]       = get_Confirm_value(pred);
5031 					has_confirm = true;
5032 				} else if (is_Bad(pred)) {
5033 					in[i] = pred;
5034 				} else {
5035 					return phi;
5036 				}
5037 			}
5038 
5039 			if (!has_confirm)
5040 				return phi;
5041 
5042 			/* move the Confirm nodes "behind" the Phi */
5043 			new_phi = new_r_Phi(block, n, in, get_irn_mode(phi));
5044 			return new_r_Confirm(block, new_phi, bound, relation);
5045 		}
5046 	}
5047 	return phi;
5048 }
5049 
5050 /**
5051  * Optimize (a >> c1) >> c2), works for Shr, Shrs, Shl, Rotl.
5052  *
5053  * Should be moved to reassociation?
5054  */
transform_node_shift(ir_node * n)5055 static ir_node *transform_node_shift(ir_node *n)
5056 {
5057 	ir_node *left, *right;
5058 	ir_mode *mode;
5059 	ir_mode *count_mode;
5060 	ir_tarval *tv1, *tv2, *res;
5061 	ir_node *in[2], *irn, *block;
5062 	ir_graph *irg;
5063 	int       modulo_shf;
5064 
5065 	left = get_binop_left(n);
5066 
5067 	/* different operations */
5068 	if (get_irn_op(left) != get_irn_op(n))
5069 		return n;
5070 
5071 	right = get_binop_right(n);
5072 	tv1   = value_of(right);
5073 	if (tv1 == tarval_bad)
5074 		return n;
5075 
5076 	tv2 = value_of(get_binop_right(left));
5077 	if (tv2 == tarval_bad)
5078 		return n;
5079 
5080 	count_mode = get_tarval_mode(tv1);
5081 	if (get_tarval_mode(tv2) != count_mode) {
5082 		/* TODO: search bigger mode or something and convert... */
5083 		return n;
5084 	}
5085 
5086 	mode       = get_irn_mode(n);
5087 	modulo_shf = get_mode_modulo_shift(mode);
5088 
5089 	if (modulo_shf > 0) {
5090 		ir_tarval *modulo_mask = new_tarval_from_long(modulo_shf-1, count_mode);
5091 
5092 		/* I'm not so sure what happens in one complement... */
5093 		assert(get_mode_arithmetic(count_mode) == irma_twos_complement);
5094 		/* modulo shifts should always be a power of 2 (otherwise modulo_mask
5095 		 * above will be invalid) */
5096 		assert(modulo_shf<=0 || is_po2(modulo_shf));
5097 
5098 		tv1 = tarval_and(tv1, modulo_mask);
5099 		tv2 = tarval_and(tv2, modulo_mask);
5100 	}
5101 	res = tarval_add(tv1, tv2);
5102 	irg = get_irn_irg(n);
5103 
5104 	/* beware: a simple replacement works only, if res < modulo shift */
5105 	if (is_Rotl(n)) {
5106 		int        bits   = get_mode_size_bits(mode);
5107 		ir_tarval *modulo = new_tarval_from_long(bits, count_mode);
5108 		res = tarval_mod(res, modulo);
5109 	} else {
5110 		long       bits      = get_mode_size_bits(mode);
5111 		ir_tarval *mode_size = new_tarval_from_long(bits, count_mode);
5112 
5113 		/* shifting too much */
5114 		if (!(tarval_cmp(res, mode_size) & ir_relation_less)) {
5115 			if (is_Shrs(n)) {
5116 				ir_node  *block = get_nodes_block(n);
5117 				dbg_info *dbgi  = get_irn_dbg_info(n);
5118 				ir_mode  *smode = get_irn_mode(right);
5119 				ir_node  *cnst  = new_r_Const_long(irg, smode, get_mode_size_bits(mode) - 1);
5120 				return new_rd_Shrs(dbgi, block, get_binop_left(left), cnst, mode);
5121 			}
5122 
5123 			return new_r_Const(irg, get_mode_null(mode));
5124 		}
5125 	}
5126 
5127 	/* ok, we can replace it */
5128 	assert(modulo_shf >= (int) get_mode_size_bits(mode));
5129 	block = get_nodes_block(n);
5130 
5131 	in[0] = get_binop_left(left);
5132 	in[1] = new_r_Const(irg, res);
5133 
5134 	irn = new_ir_node(NULL, get_Block_irg(block), block, get_irn_op(n), mode, 2, in);
5135 
5136 	DBG_OPT_ALGSIM0(n, irn, FS_OPT_REASSOC_SHIFT);
5137 
5138 	return irn;
5139 }
5140 
5141 /**
5142  * normalisation:
5143  *    (x << c1) >> c2  <=>  x OP (c2-c1) & ((-1 << c1) >> c2)
5144  *    also:
5145  *    (x >> c1) << c2  <=>  x OP (c2-c1) & ((-1 >> c1) << c2)
5146  *      (also with x >>s c1  when c1>=c2)
5147  */
transform_node_shl_shr(ir_node * n)5148 static ir_node *transform_node_shl_shr(ir_node *n)
5149 {
5150 	ir_node   *left;
5151 	ir_node   *right = get_binop_right(n);
5152 	ir_node   *x;
5153 	ir_node   *block;
5154 	ir_mode   *mode;
5155 	dbg_info  *dbgi;
5156 	ir_node   *new_const;
5157 	ir_node   *new_shift;
5158 	ir_node   *new_and;
5159 	ir_tarval *tv_shl;
5160 	ir_tarval *tv_shr;
5161 	ir_tarval *tv_shift;
5162 	ir_tarval *tv_mask;
5163 	ir_graph  *irg;
5164 	ir_relation relation;
5165 	int        need_shrs = 0;
5166 
5167 	assert(is_Shl(n) || is_Shr(n) || is_Shrs(n));
5168 
5169 	if (!is_Const(right))
5170 		return n;
5171 
5172 	left = get_binop_left(n);
5173 	mode = get_irn_mode(n);
5174 	if (is_Shl(n) && (is_Shr(left) || is_Shrs(left))) {
5175 		ir_node *shr_right = get_binop_right(left);
5176 
5177 		if (!is_Const(shr_right))
5178 			return n;
5179 
5180 		x      = get_binop_left(left);
5181 		tv_shr = get_Const_tarval(shr_right);
5182 		tv_shl = get_Const_tarval(right);
5183 
5184 		if (is_Shrs(left)) {
5185 			/* shrs variant only allowed if c1 >= c2 */
5186 			if (! (tarval_cmp(tv_shl, tv_shr) & ir_relation_greater_equal))
5187 				return n;
5188 
5189 			tv_mask = tarval_shrs(get_mode_all_one(mode), tv_shr);
5190 			need_shrs = 1;
5191 		} else {
5192 			tv_mask = tarval_shr(get_mode_all_one(mode), tv_shr);
5193 		}
5194 		tv_mask = tarval_shl(tv_mask, tv_shl);
5195 	} else if (is_Shr(n) && is_Shl(left)) {
5196 		ir_node *shl_right = get_Shl_right(left);
5197 
5198 		if (!is_Const(shl_right))
5199 			return n;
5200 
5201 		x      = get_Shl_left(left);
5202 		tv_shr = get_Const_tarval(right);
5203 		tv_shl = get_Const_tarval(shl_right);
5204 
5205 		tv_mask = tarval_shl(get_mode_all_one(mode), tv_shl);
5206 		tv_mask = tarval_shr(tv_mask, tv_shr);
5207 	} else {
5208 		return n;
5209 	}
5210 
5211 	if (get_tarval_mode(tv_shl) != get_tarval_mode(tv_shr)) {
5212 		tv_shl = tarval_convert_to(tv_shl, get_tarval_mode(tv_shr));
5213 	}
5214 
5215 	assert(tv_mask != tarval_bad);
5216 	assert(get_tarval_mode(tv_mask) == mode);
5217 
5218 	block = get_nodes_block(n);
5219 	irg   = get_irn_irg(block);
5220 	dbgi  = get_irn_dbg_info(n);
5221 
5222 	relation = tarval_cmp(tv_shl, tv_shr);
5223 	if (relation == ir_relation_less || relation == ir_relation_equal) {
5224 		tv_shift  = tarval_sub(tv_shr, tv_shl, NULL);
5225 		new_const = new_r_Const(irg, tv_shift);
5226 		if (need_shrs) {
5227 			new_shift = new_rd_Shrs(dbgi, block, x, new_const, mode);
5228 		} else {
5229 			new_shift = new_rd_Shr(dbgi, block, x, new_const, mode);
5230 		}
5231 	} else {
5232 		assert(relation == ir_relation_greater);
5233 		tv_shift  = tarval_sub(tv_shl, tv_shr, NULL);
5234 		new_const = new_r_Const(irg, tv_shift);
5235 		new_shift = new_rd_Shl(dbgi, block, x, new_const, mode);
5236 	}
5237 
5238 	new_const = new_r_Const(irg, tv_mask);
5239 	new_and   = new_rd_And(dbgi, block, new_shift, new_const, mode);
5240 
5241 	return new_and;
5242 }
5243 
get_modulo_tv_value(ir_tarval * tv,int modulo_val)5244 static ir_tarval *get_modulo_tv_value(ir_tarval *tv, int modulo_val)
5245 {
5246 	ir_mode   *mode      = get_tarval_mode(tv);
5247 	ir_tarval *modulo_tv = new_tarval_from_long(modulo_val, mode);
5248 	return tarval_mod(tv, modulo_tv);
5249 }
5250 
5251 typedef ir_node*(*new_shift_func)(dbg_info *dbgi, ir_node *block,
5252                                   ir_node *left, ir_node *right, ir_mode *mode);
5253 
5254 /**
5255  * Normalisation: if we have a shl/shr with modulo_shift behaviour
5256  * then we can use that to minimize the value of Add(x, const) or
5257  * Sub(Const, x). In particular this often avoids 1 instruction in some
5258  * backends for the Shift(x, Sub(Const, y)) case because it can be replaced
5259  * by Shift(x, Minus(y)) which does not need an explicit Const constructed.
5260  */
transform_node_shift_modulo(ir_node * n,new_shift_func new_shift)5261 static ir_node *transform_node_shift_modulo(ir_node *n,
5262                                             new_shift_func new_shift)
5263 {
5264 	ir_mode  *mode   = get_irn_mode(n);
5265 	int       modulo = get_mode_modulo_shift(mode);
5266 	ir_node  *newop  = NULL;
5267 	ir_mode  *mode_right;
5268 	ir_node  *block;
5269 	ir_node  *right;
5270 	ir_graph *irg;
5271 
5272 	if (modulo == 0)
5273 		return n;
5274 	if (get_mode_arithmetic(mode) != irma_twos_complement)
5275 		return n;
5276 	if (!is_po2(modulo))
5277 		return n;
5278 
5279 	irg        = get_irn_irg(n);
5280 	block      = get_nodes_block(n);
5281 	right      = get_binop_right(n);
5282 	mode_right = get_irn_mode(right);
5283 	if (is_Const(right)) {
5284 		ir_tarval *tv     = get_Const_tarval(right);
5285 		ir_tarval *tv_mod = get_modulo_tv_value(tv, modulo);
5286 
5287 		if (tv_mod == tv)
5288 			return n;
5289 
5290 		newop = new_r_Const(irg, tv_mod);
5291 	} else if (is_Add(right) || is_Or_Eor_Add(right)) {
5292 		ir_node *add_right = get_binop_right(right);
5293 		if (is_Const(add_right)) {
5294 			ir_tarval *tv     = get_Const_tarval(add_right);
5295 			ir_tarval *tv_mod = get_modulo_tv_value(tv, modulo);
5296 			ir_node   *newconst;
5297 			if (tv_mod == tv)
5298 				return n;
5299 
5300 			newconst = new_r_Const(irg, tv_mod);
5301 			newop    = new_r_Add(block, get_binop_left(right), newconst,
5302 			                     mode_right);
5303 		}
5304 	} else if (is_Sub(right)) {
5305 		ir_node *sub_left = get_Sub_left(right);
5306 		if (is_Const(sub_left)) {
5307 			ir_tarval *tv     = get_Const_tarval(sub_left);
5308 			ir_tarval *tv_mod = get_modulo_tv_value(tv, modulo);
5309 			ir_node  *newconst;
5310 			if (tv_mod == tv)
5311 				return n;
5312 
5313 			newconst = new_r_Const(irg, tv_mod);
5314 			newop    = new_r_Sub(block, newconst, get_Sub_right(right),
5315 			                     mode_right);
5316 		}
5317 	} else {
5318 		return n;
5319 	}
5320 
5321 	if (newop != NULL) {
5322 		dbg_info *dbgi = get_irn_dbg_info(n);
5323 		ir_node  *left = get_binop_left(n);
5324 		return new_shift(dbgi, block, left, newop, mode);
5325 	}
5326 	return n;
5327 }
5328 
5329 /**
5330  * Transform a Shr.
5331  */
transform_node_Shr(ir_node * n)5332 static ir_node *transform_node_Shr(ir_node *n)
5333 {
5334 	ir_node *c, *oldn = n;
5335 	ir_node *left  = get_Shr_left(n);
5336 	ir_node *right = get_Shr_right(n);
5337 	ir_mode *mode  = get_irn_mode(n);
5338 
5339 	HANDLE_BINOP_PHI((eval_func) tarval_shr, left, right, c, mode);
5340 	n = transform_node_shift(n);
5341 
5342 	if (is_Shr(n))
5343 		n = transform_node_shift_modulo(n, new_rd_Shr);
5344 	if (is_Shr(n))
5345 		n = transform_node_shl_shr(n);
5346 	if (is_Shr(n))
5347 		n = transform_node_shift_bitop(n);
5348 
5349 	return n;
5350 }
5351 
5352 /**
5353  * Transform a Shrs.
5354  */
transform_node_Shrs(ir_node * n)5355 static ir_node *transform_node_Shrs(ir_node *n)
5356 {
5357 	ir_node  *oldn = n;
5358 	ir_node  *a    = get_Shrs_left(n);
5359 	ir_node  *b    = get_Shrs_right(n);
5360 	ir_mode  *mode = get_irn_mode(n);
5361 	ir_node  *c;
5362 	vrp_attr *attr;
5363 
5364 	if (is_oversize_shift(n)) {
5365 		ir_node  *block = get_nodes_block(n);
5366 		dbg_info *dbgi  = get_irn_dbg_info(n);
5367 		ir_mode  *cmode = get_irn_mode(b);
5368 		long      val   = get_mode_size_bits(cmode)-1;
5369 		ir_graph *irg   = get_irn_irg(n);
5370 		ir_node  *cnst  = new_r_Const_long(irg, cmode, val);
5371 		return new_rd_Shrs(dbgi, block, a, cnst, mode);
5372 	}
5373 
5374 	HANDLE_BINOP_PHI((eval_func) tarval_shrs, a, b, c, mode);
5375 	n = transform_node_shift(n);
5376 	if (n != oldn)
5377 		return n;
5378 
5379 	n = transform_node_shift_modulo(n, new_rd_Shrs);
5380 	if (n != oldn)
5381 		return n;
5382 	n = transform_node_shift_bitop(n);
5383 	if (n != oldn)
5384 		return n;
5385 
5386 	/* normalisation: use Shr when sign bit is guaranteed to be cleared */
5387 	attr = vrp_get_info(a);
5388 	if (attr != NULL) {
5389 		unsigned   bits   = get_mode_size_bits(mode);
5390 		ir_tarval *scount = new_tarval_from_long(bits-1, mode_Iu);
5391 		ir_tarval *sign   = tarval_shl(get_mode_one(mode), scount);
5392 		if (tarval_is_null(tarval_and(attr->bits_not_set, sign))) {
5393 			dbg_info *dbgi  = get_irn_dbg_info(n);
5394 			ir_node  *block = get_nodes_block(n);
5395 			return new_rd_Shr(dbgi, block, a, b, mode);
5396 		}
5397 	}
5398 
5399 	return n;
5400 }
5401 
5402 /**
5403  * Transform a Shl.
5404  */
transform_node_Shl(ir_node * n)5405 static ir_node *transform_node_Shl(ir_node *n)
5406 {
5407 	ir_node *c, *oldn = n;
5408 	ir_node *a    = get_Shl_left(n);
5409 	ir_node *b    = get_Shl_right(n);
5410 	ir_mode *mode = get_irn_mode(n);
5411 
5412 	HANDLE_BINOP_PHI((eval_func) tarval_shl, a, b, c, mode);
5413 	n = transform_node_shift(n);
5414 
5415 	if (is_Shl(n))
5416 		n = transform_node_shift_modulo(n, new_rd_Shl);
5417 	if (is_Shl(n))
5418 		n = transform_node_shl_shr(n);
5419 	if (is_Shl(n))
5420 		n = transform_node_shift_bitop(n);
5421 
5422 	return n;
5423 }
5424 
5425 /**
5426  * Transform a Rotl.
5427  */
transform_node_Rotl(ir_node * n)5428 static ir_node *transform_node_Rotl(ir_node *n)
5429 {
5430 	ir_node *c, *oldn = n;
5431 	ir_node *a    = get_Rotl_left(n);
5432 	ir_node *b    = get_Rotl_right(n);
5433 	ir_mode *mode = get_irn_mode(n);
5434 
5435 	HANDLE_BINOP_PHI((eval_func) tarval_rotl, a, b, c, mode);
5436 	n = transform_node_shift(n);
5437 
5438 	if (is_Rotl(n))
5439 		n = transform_node_shift_bitop(n);
5440 
5441 	return n;
5442 }
5443 
5444 /**
5445  * returns mode size for may_leave_out_middle_mode
5446  */
get_significand_size(ir_mode * mode)5447 static unsigned get_significand_size(ir_mode *mode)
5448 {
5449 	const ir_mode_arithmetic arithmetic = get_mode_arithmetic(mode);
5450 	switch (arithmetic) {
5451 	case irma_ieee754:
5452 	case irma_x86_extended_float:
5453 		return get_mode_mantissa_size(mode) + 1;
5454 	case irma_twos_complement:
5455 		return get_mode_size_bits(mode);
5456 	case irma_none:
5457 		panic("Conv node with irma_none mode?");
5458 	}
5459 	panic("unexpected mode_arithmetic in get_significand_size");
5460 }
5461 
5462 /**
5463  * Returns true if a conversion from mode @p m0 to @p m1 has the same effect
5464  * as converting from @p m0 to @p m1 and then to @p m2.
5465  * Classifying the 3 modes as the big(b), middle(m) and small(s) mode this
5466  * gives the following truth table:
5467  * s -> b -> m  : true
5468  * s -> m -> b  : !signed(s) || signed(m)
5469  * m -> b -> s  : true
5470  * m -> s -> b  : false
5471  * b -> s -> m  : false
5472  * b -> m -> s  : true
5473  *
5474  * s -> b -> b  : true
5475  * s -> s -> b  : false
5476  *
5477  * additional float constraints:
5478  * F -> F -> F: fine
5479  * F -> I -> I: signedness of Is must match
5480  * I -> F -> I: signedness of Is must match
5481  * I -> I -> F: signedness of Is must match
5482  * F -> I -> F: bad
5483  * I -> F -> F: fine
5484  * F -> F -> I: fine
5485  * at least 1 float involved: signedness must match
5486  */
may_leave_out_middle_conv(ir_mode * m0,ir_mode * m1,ir_mode * m2)5487 bool may_leave_out_middle_conv(ir_mode *m0, ir_mode *m1, ir_mode *m2)
5488 {
5489 	int n_floats = mode_is_float(m0) + mode_is_float(m1) + mode_is_float(m2);
5490 	if (n_floats == 1) {
5491 #if 0
5492 		int n_signed = mode_is_signed(m0) + mode_is_signed(m1)
5493 		             + mode_is_signed(m2);
5494 		/* we assume that float modes are always signed */
5495 		if ((n_signed & 1) != 1)
5496 			return false;
5497 #else
5498 		/* because overflow gives strange results we don't touch this case */
5499 		return false;
5500 #endif
5501 	} else if (n_floats == 2 && !mode_is_float(m1)) {
5502 		return false;
5503 	}
5504 
5505 	unsigned size0 = get_significand_size(m0);
5506 	unsigned size1 = get_significand_size(m1);
5507 	unsigned size2 = get_significand_size(m2);
5508 	if (size1 < size2 && size0 >= size1)
5509 		return false;
5510 	if (size1 >= size2)
5511 		return true;
5512 	return !mode_is_signed(m0) || mode_is_signed(m1);
5513 }
5514 
5515 /**
5516  * Transform a Conv.
5517  */
transform_node_Conv(ir_node * n)5518 static ir_node *transform_node_Conv(ir_node *n)
5519 {
5520 	ir_node *c, *oldn = n;
5521 	ir_mode *mode = get_irn_mode(n);
5522 	ir_node *a    = get_Conv_op(n);
5523 
5524 	if (is_Conv(a)) {
5525 		ir_mode *a_mode = get_irn_mode(a);
5526 		ir_node *b      = get_Conv_op(a);
5527 		ir_mode *b_mode = get_irn_mode(b);
5528 		if (may_leave_out_middle_conv(b_mode, a_mode, mode)) {
5529 			dbg_info *dbgi  = get_irn_dbg_info(n);
5530 			ir_node  *block = get_nodes_block(n);
5531 			return new_rd_Conv(dbgi, block, b, mode);
5532 		}
5533 	}
5534 
5535 	if (mode != mode_b && is_const_Phi(a)) {
5536 		/* Do NOT optimize mode_b Conv's, this leads to remaining
5537 		 * Phib nodes later, because the conv_b_lower operation
5538 		 * is instantly reverted, when it tries to insert a Convb.
5539 		 */
5540 		c = apply_conv_on_phi(a, mode);
5541 		if (c) {
5542 			DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI);
5543 			return c;
5544 		}
5545 	}
5546 
5547 	if (is_Unknown(a)) { /* Conv_A(Unknown_B) -> Unknown_A */
5548 		ir_graph *irg = get_irn_irg(n);
5549 		return new_r_Unknown(irg, mode);
5550 	}
5551 
5552 	if (mode_is_reference(mode) &&
5553 	        get_mode_size_bits(mode) == get_mode_size_bits(get_irn_mode(a)) &&
5554 	        is_Add(a)) {
5555 		ir_node *l = get_Add_left(a);
5556 		ir_node *r = get_Add_right(a);
5557 		dbg_info *dbgi = get_irn_dbg_info(a);
5558 		ir_node *block = get_nodes_block(n);
5559 		if (is_Conv(l)) {
5560 			ir_node *lop = get_Conv_op(l);
5561 			if (get_irn_mode(lop) == mode) {
5562 				/* ConvP(AddI(ConvI(P), x)) -> AddP(P, x) */
5563 				n = new_rd_Add(dbgi, block, lop, r, mode);
5564 				return n;
5565 			}
5566 		}
5567 		if (is_Conv(r)) {
5568 			ir_node *rop = get_Conv_op(r);
5569 			if (get_irn_mode(rop) == mode) {
5570 				/* ConvP(AddI(x, ConvI(P))) -> AddP(x, P) */
5571 				n = new_rd_Add(dbgi, block, l, rop, mode);
5572 				return n;
5573 			}
5574 		}
5575 	}
5576 
5577 	return n;
5578 }
5579 
5580 /**
5581  * Remove dead blocks and nodes in dead blocks
5582  * in keep alive list.  We do not generate a new End node.
5583  */
transform_node_End(ir_node * n)5584 static ir_node *transform_node_End(ir_node *n)
5585 {
5586 	int i, j, n_keepalives = get_End_n_keepalives(n);
5587 	ir_node **in;
5588 
5589 	NEW_ARR_A(ir_node *, in, n_keepalives);
5590 
5591 	for (i = j = 0; i < n_keepalives; ++i) {
5592 		ir_node *ka = get_End_keepalive(n, i);
5593 		ir_node *block;
5594 		/* no need to keep Bad */
5595 		if (is_Bad(ka))
5596 			continue;
5597 		/* do not keep unreachable code */
5598 		block = is_Block(ka) ? ka : get_nodes_block(ka);
5599 		if (is_block_unreachable(block))
5600 			continue;
5601 		in[j++] = ka;
5602 	}
5603 	if (j != n_keepalives)
5604 		set_End_keepalives(n, j, in);
5605 	return n;
5606 }
5607 
ir_is_negated_value(const ir_node * a,const ir_node * b)5608 int ir_is_negated_value(const ir_node *a, const ir_node *b)
5609 {
5610 	if (is_Minus(a) && get_Minus_op(a) == b)
5611 		return true;
5612 	if (is_Minus(b) && get_Minus_op(b) == a)
5613 		return true;
5614 	if (is_Sub(a) && is_Sub(b)) {
5615 		ir_node *a_left  = get_Sub_left(a);
5616 		ir_node *a_right = get_Sub_right(a);
5617 		ir_node *b_left  = get_Sub_left(b);
5618 		ir_node *b_right = get_Sub_right(b);
5619 
5620 		if (a_left == b_right && a_right == b_left)
5621 			return true;
5622 	}
5623 
5624 	return false;
5625 }
5626 
skip_upconv(const ir_node * node)5627 static const ir_node *skip_upconv(const ir_node *node)
5628 {
5629 	while (is_Conv(node)) {
5630 		ir_mode       *mode    = get_irn_mode(node);
5631 		const ir_node *op      = get_Conv_op(node);
5632 		ir_mode       *op_mode = get_irn_mode(op);
5633 		if (!smaller_mode(op_mode, mode))
5634 			break;
5635 		node = op;
5636 	}
5637 	return node;
5638 }
5639 
ir_mux_is_abs(const ir_node * sel,const ir_node * mux_false,const ir_node * mux_true)5640 int ir_mux_is_abs(const ir_node *sel, const ir_node *mux_false,
5641                   const ir_node *mux_true)
5642 {
5643 	ir_node    *cmp_left;
5644 	ir_node    *cmp_right;
5645 	ir_mode    *mode;
5646 	ir_relation relation;
5647 
5648 	if (!is_Cmp(sel))
5649 		return 0;
5650 
5651 	/**
5652 	 * Note further that these optimization work even for floating point
5653 	 * with NaN's because -NaN == NaN.
5654 	 * However, if +0 and -0 is handled differently, we cannot use the Abs/-Abs
5655 	 * transformations.
5656 	 */
5657 	mode = get_irn_mode(mux_true);
5658 	if (mode_honor_signed_zeros(mode))
5659 		return 0;
5660 
5661 	/* must be <, <=, >=, > */
5662 	relation = get_Cmp_relation(sel);
5663 	if ((relation & ir_relation_less_greater) == 0)
5664 		return 0;
5665 
5666 	if (!ir_is_negated_value(mux_true, mux_false))
5667 		return 0;
5668 
5669 	mux_true  = skip_upconv(mux_true);
5670 	mux_false = skip_upconv(mux_false);
5671 
5672 	/* must be x cmp 0 */
5673 	cmp_right = get_Cmp_right(sel);
5674 	if (!is_Const(cmp_right) || !is_Const_null(cmp_right))
5675 		return 0;
5676 
5677 	cmp_left = get_Cmp_left(sel);
5678 	if (cmp_left == mux_false) {
5679 		if (relation & ir_relation_less) {
5680 			return 1;
5681 		} else {
5682 			assert(relation & ir_relation_greater);
5683 			return -1;
5684 		}
5685 	} else if (cmp_left == mux_true) {
5686 		if (relation & ir_relation_less) {
5687 			return -1;
5688 		} else {
5689 			assert(relation & ir_relation_greater);
5690 			return 1;
5691 		}
5692 	}
5693 
5694 	return 0;
5695 }
5696 
ir_get_abs_op(const ir_node * sel,ir_node * mux_false,ir_node * mux_true)5697 ir_node *ir_get_abs_op(const ir_node *sel, ir_node *mux_false,
5698                        ir_node *mux_true)
5699 {
5700 	ir_node *cmp_left = get_Cmp_left(sel);
5701 	return cmp_left == skip_upconv(mux_false) ? mux_false : mux_true;
5702 }
5703 
ir_is_optimizable_mux(const ir_node * sel,const ir_node * mux_false,const ir_node * mux_true)5704 bool ir_is_optimizable_mux(const ir_node *sel, const ir_node *mux_false,
5705                            const ir_node *mux_true)
5706 {
5707 	/* this code should return true each time transform_node_Mux would
5708 	 * optimize the Mux completely away */
5709 
5710 	ir_mode *mode = get_irn_mode(mux_false);
5711 	if (get_mode_arithmetic(mode) == irma_twos_complement
5712 	    && ir_mux_is_abs(sel, mux_false, mux_true))
5713 	    return true;
5714 
5715 	if (is_Cmp(sel) && mode_is_int(mode) && is_cmp_equality_zero(sel)) {
5716 		const ir_node *cmp_r = get_Cmp_right(sel);
5717 		const ir_node *cmp_l = get_Cmp_left(sel);
5718 		const ir_node *f     = mux_false;
5719 		const ir_node *t     = mux_true;
5720 
5721 		if (is_Const(t) && is_Const_null(t)) {
5722 			t = mux_false;
5723 			f = mux_true;
5724 		}
5725 
5726 		if (is_And(cmp_l) && f == cmp_r) {
5727 			ir_node *and_r = get_And_right(cmp_l);
5728 			ir_node *and_l;
5729 
5730 			if (and_r == t && is_single_bit(and_r))
5731 				return true;
5732 			and_l = get_And_left(cmp_l);
5733 			if (and_l == t && is_single_bit(and_l))
5734 				return true;
5735 		}
5736 	}
5737 
5738 	return false;
5739 }
5740 
5741 /**
5742  * Optimize a Mux(c, 0, 1) node (sometimes called a "set" instruction)
5743  */
transform_Mux_set(ir_node * n)5744 static ir_node *transform_Mux_set(ir_node *n)
5745 {
5746 	ir_node    *cond = get_Mux_sel(n);
5747 	ir_mode    *dest_mode;
5748 	ir_mode    *mode;
5749 	ir_node    *left;
5750 	ir_node    *right;
5751 	ir_relation relation;
5752 	bool        need_not;
5753 	dbg_info   *dbgi;
5754 	ir_node    *block;
5755 	ir_graph   *irg;
5756 	ir_node    *a;
5757 	ir_node    *b;
5758 	unsigned    bits;
5759 	ir_tarval  *tv;
5760 	ir_node    *shift_cnt;
5761 	ir_node    *res;
5762 
5763 	if (!is_Cmp(cond))
5764 		return n;
5765 	left = get_Cmp_left(cond);
5766 	mode = get_irn_mode(left);
5767 	if (!mode_is_int(mode) && !mode_is_reference(mode))
5768 		return n;
5769 	dest_mode = get_irn_mode(n);
5770 	if (!mode_is_int(dest_mode) && !mode_is_reference(dest_mode))
5771 		return n;
5772 	right     = get_Cmp_right(cond);
5773 	relation  = get_Cmp_relation(cond) & ~ir_relation_unordered;
5774 	if (get_mode_size_bits(mode) >= get_mode_size_bits(dest_mode)
5775 	    && !(mode_is_signed(mode) && is_Const(right) && is_Const_null(right)
5776 	         && relation != ir_relation_greater))
5777 	    return n;
5778 
5779 	need_not = false;
5780 	switch (relation) {
5781 	case ir_relation_less:
5782 		/* a < b  ->  (a - b) >> 31 */
5783 		a = left;
5784 		b = right;
5785 		break;
5786 	case ir_relation_less_equal:
5787 		/* a <= b  -> ~(a - b) >> 31 */
5788 		a        = right;
5789 		b        = left;
5790 		need_not = true;
5791 		break;
5792 	case ir_relation_greater:
5793 		/* a > b   -> (b - a) >> 31 */
5794 		a = right;
5795 		b = left;
5796 		break;
5797 	case ir_relation_greater_equal:
5798 		/* a >= b   -> ~(a - b) >> 31 */
5799 		a        = left;
5800 		b        = right;
5801 		need_not = true;
5802 		break;
5803 	default:
5804 		return n;
5805 	}
5806 
5807 	dbgi      = get_irn_dbg_info(n);
5808 	block     = get_nodes_block(n);
5809 	irg       = get_irn_irg(block);
5810 	bits      = get_mode_size_bits(dest_mode);
5811 	tv        = new_tarval_from_long(bits-1, mode_Iu);
5812 	shift_cnt = new_rd_Const(dbgi, irg, tv);
5813 
5814 	if (mode != dest_mode) {
5815 		a = new_rd_Conv(dbgi, block, a, dest_mode);
5816 		b = new_rd_Conv(dbgi, block, b, dest_mode);
5817 	}
5818 
5819 	res = new_rd_Sub(dbgi, block, a, b, dest_mode);
5820 	if (need_not) {
5821 		res = new_rd_Not(dbgi, block, res, dest_mode);
5822 	}
5823 	res = new_rd_Shr(dbgi, block, res, shift_cnt, dest_mode);
5824 	return res;
5825 }
5826 
5827 /**
5828  * Optimize a Mux into some simpler cases.
5829  */
transform_node_Mux(ir_node * n)5830 static ir_node *transform_node_Mux(ir_node *n)
5831 {
5832 	ir_node  *oldn = n;
5833 	ir_node  *sel  = get_Mux_sel(n);
5834 	ir_mode  *mode = get_irn_mode(n);
5835 	ir_node  *t    = get_Mux_true(n);
5836 	ir_node  *f    = get_Mux_false(n);
5837 	ir_graph *irg  = get_irn_irg(n);
5838 
5839 	/* implement integer abs: abs(x) = x^(x >>s 31) - (x >>s 31) */
5840 	if (get_mode_arithmetic(mode) == irma_twos_complement) {
5841 		int abs = ir_mux_is_abs(sel, f, t);
5842 		if (abs != 0) {
5843 			dbg_info *dbgi       = get_irn_dbg_info(n);
5844 			ir_node  *block      = get_nodes_block(n);
5845 			ir_node  *op         = ir_get_abs_op(sel, f, t);
5846 			int       bits       = get_mode_size_bits(mode);
5847 			ir_node  *shiftconst = new_r_Const_long(irg, mode_Iu, bits-1);
5848 			ir_node  *sext       = new_rd_Shrs(dbgi, block, op, shiftconst, mode);
5849 			ir_node  *xorn       = new_rd_Eor(dbgi, block, op, sext, mode);
5850 			ir_node  *res;
5851 			if (abs > 0) {
5852 				res = new_rd_Sub(dbgi, block, xorn, sext, mode);
5853 			} else {
5854 				res = new_rd_Sub(dbgi, block, sext, xorn, mode);
5855 			}
5856 			return res;
5857 		}
5858 	}
5859 
5860 	/* first normalization step: try to move a constant to the false side,
5861 	 * 0 preferred on false side too */
5862 	if (is_Cmp(sel) && is_Const(t) &&
5863 			(!is_Const(f) || (is_Const_null(t) && !is_Const_null(f)))) {
5864 		dbg_info *seldbgi = get_irn_dbg_info(sel);
5865 		ir_node  *block   = get_nodes_block(sel);
5866 		ir_relation relation = get_Cmp_relation(sel);
5867 		ir_node *tmp = t;
5868 		t = f;
5869 		f = tmp;
5870 
5871 		/* Mux(x, a, b) => Mux(not(x), b, a) */
5872 		relation = get_negated_relation(relation);
5873 		sel = new_rd_Cmp(seldbgi, block, get_Cmp_left(sel),
5874 				get_Cmp_right(sel), relation);
5875 		return new_rd_Mux(get_irn_dbg_info(n), get_nodes_block(n), sel, f, t, mode);
5876 	}
5877 
5878 	if (is_Const(f) && is_Const_null(f) && is_Const(t) && is_Const_one(t)) {
5879 		n = transform_Mux_set(n);
5880 		if (n != oldn)
5881 			return n;
5882 	}
5883 
5884 	/* the following optimisations create new mode_b nodes, so only do them
5885 	 * before mode_b lowering */
5886 	if (!irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_MODEB_LOWERED)) {
5887 		if (is_Mux(t)) {
5888 			ir_node*  block = get_nodes_block(n);
5889 			ir_node*  c0    = sel;
5890 			ir_node*  c1    = get_Mux_sel(t);
5891 			ir_node*  t1    = get_Mux_true(t);
5892 			ir_node*  f1    = get_Mux_false(t);
5893 			if (f == f1) {
5894 				/* Mux(cond0, Mux(cond1, x, y), y) => Mux(cond0 && cond1, x, y) */
5895 				ir_node* and_ = new_r_And(block, c0, c1, mode_b);
5896 				DBG_OPT_ALGSIM0(oldn, t1, FS_OPT_MUX_COMBINE);
5897 				return new_r_Mux(block, and_, f1, t1, mode);
5898 			} else if (f == t1) {
5899 				/* Mux(cond0, Mux(cond1, x, y), x) */
5900 				ir_node* not_c1  = new_r_Not(block, c1, mode_b);
5901 				ir_node* and_    = new_r_And(block, c0, not_c1, mode_b);
5902 				DBG_OPT_ALGSIM0(oldn, f1, FS_OPT_MUX_COMBINE);
5903 				return new_r_Mux(block, and_, t1, f1, mode);
5904 			}
5905 		} else if (is_Mux(f)) {
5906 			ir_node*  block = get_nodes_block(n);
5907 			ir_node*  c0    = sel;
5908 			ir_node*  c1    = get_Mux_sel(f);
5909 			ir_node*  t1    = get_Mux_true(f);
5910 			ir_node*  f1    = get_Mux_false(f);
5911 			if (t == t1) {
5912 				/* Mux(cond0, x, Mux(cond1, x, y)) -> typical if (cond0 || cond1) x else y */
5913 				ir_node* or_ = new_r_Or(block, c0, c1, mode_b);
5914 				DBG_OPT_ALGSIM0(oldn, f1, FS_OPT_MUX_COMBINE);
5915 				return new_r_Mux(block, or_, f1, t1, mode);
5916 			} else if (t == f1) {
5917 				/* Mux(cond0, x, Mux(cond1, y, x)) */
5918 				ir_node* not_c1  = new_r_Not(block, c1, mode_b);
5919 				ir_node* or_     = new_r_Or(block, c0, not_c1, mode_b);
5920 				DBG_OPT_ALGSIM0(oldn, t1, FS_OPT_MUX_COMBINE);
5921 				return new_r_Mux(block, or_, t1, f1, mode);
5922 			}
5923 		}
5924 
5925 		/* note: after normalization, false can only happen on default */
5926 		if (mode == mode_b) {
5927 			dbg_info *dbg   = get_irn_dbg_info(n);
5928 			ir_node  *block = get_nodes_block(n);
5929 
5930 			if (is_Const(t)) {
5931 				ir_tarval *tv_t = get_Const_tarval(t);
5932 				if (tv_t == tarval_b_true) {
5933 					if (is_Const(f)) {
5934 						/* Muxb(sel, true, false) = sel */
5935 						assert(get_Const_tarval(f) == tarval_b_false);
5936 						DBG_OPT_ALGSIM0(oldn, sel, FS_OPT_MUX_BOOL);
5937 						return sel;
5938 					} else {
5939 						/* Muxb(sel, true, x) = Or(sel, x) */
5940 						n = new_rd_Or(dbg, block, sel, f, mode_b);
5941 						DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_OR_BOOL);
5942 						return n;
5943 					}
5944 				}
5945 			} else if (is_Const(f)) {
5946 				ir_tarval *tv_f = get_Const_tarval(f);
5947 				if (tv_f == tarval_b_true) {
5948 					/* Muxb(sel, x, true) = Or(Not(sel), x) */
5949 					ir_node* not_sel = new_rd_Not(dbg, block, sel, mode_b);
5950 					DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_ORNOT_BOOL);
5951 					n = new_rd_Or(dbg, block, not_sel, t, mode_b);
5952 					return n;
5953 				} else {
5954 					/* Muxb(sel, x, false) = And(sel, x) */
5955 					assert(tv_f == tarval_b_false);
5956 					n = new_rd_And(dbg, block, sel, t, mode_b);
5957 					DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_AND_BOOL);
5958 					return n;
5959 				}
5960 			}
5961 		}
5962 	}
5963 
5964 	if (is_Cmp(sel) && mode_is_int(mode) && is_cmp_equality_zero(sel)) {
5965 		ir_relation relation = get_Cmp_relation(sel);
5966 		ir_node    *cmp_r    = get_Cmp_right(sel);
5967 		ir_node    *cmp_l    = get_Cmp_left(sel);
5968 		ir_node    *block    = get_nodes_block(n);
5969 
5970 		if (is_And(cmp_l) && f == cmp_r) {
5971 			ir_node *and_r = get_And_right(cmp_l);
5972 			ir_node *and_l;
5973 
5974 			if (and_r == t && is_single_bit(and_r)) {
5975 				if (relation == ir_relation_equal) {
5976 					/* Mux((a & (1<<n)) == 0, (1<<n), 0) == (a&(1<<n)) xor ((1<<n)) */
5977 					n = new_rd_Eor(get_irn_dbg_info(n),
5978 						block, cmp_l, t, mode);
5979 					DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
5980 				} else {
5981 					/* Mux((a & (1<<n)) != 0, (1<<n), 0) == a & (1<<n) */
5982 					n = cmp_l;
5983 					DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
5984 				}
5985 				return n;
5986 			}
5987 			and_l = get_And_left(cmp_l);
5988 			if (and_l == t && is_single_bit(and_l)) {
5989 				if (relation == ir_relation_equal) {
5990 					/* ((1 << n) & a) == 0, (1 << n), 0) */
5991 					n = new_rd_Eor(get_irn_dbg_info(n),
5992 						block, cmp_l, t, mode);
5993 					DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
5994 				} else {
5995 					/* ((1 << n) & a) != 0, (1 << n), 0) */
5996 					n = cmp_l;
5997 					DBG_OPT_ALGSIM1(oldn, sel, sel, n, FS_OPT_MUX_TO_BITOP);
5998 				}
5999 				return n;
6000 			}
6001 		}
6002 	}
6003 
6004 	return n;
6005 }
6006 
6007 /**
6008  * optimize Sync nodes that have other syncs as input we simply add the inputs
6009  * of the other sync to our own inputs
6010  */
transform_node_Sync(ir_node * n)6011 static ir_node *transform_node_Sync(ir_node *n)
6012 {
6013 	int arity = get_Sync_n_preds(n);
6014 	int i;
6015 
6016 	for (i = 0; i < arity;) {
6017 		ir_node *pred = get_Sync_pred(n, i);
6018 		int      pred_arity;
6019 		int      j;
6020 
6021 		/* Remove Bad predecessors */
6022 		if (is_Bad(pred)) {
6023 			del_Sync_n(n, i);
6024 			--arity;
6025 			continue;
6026 		}
6027 
6028 		/* Remove duplicate predecessors */
6029 		for (j = 0; j < i; ++j) {
6030 			if (get_Sync_pred(n, j) == pred) {
6031 				del_Sync_n(n, i);
6032 				--arity;
6033 				break;
6034 			}
6035 		}
6036 		if (j < i)
6037 			continue;
6038 
6039 		if (!is_Sync(pred)) {
6040 			++i;
6041 			continue;
6042 		}
6043 
6044 		del_Sync_n(n, i);
6045 		--arity;
6046 
6047 		pred_arity = get_Sync_n_preds(pred);
6048 		for (j = 0; j < pred_arity; ++j) {
6049 			ir_node *pred_pred = get_Sync_pred(pred, j);
6050 			int      k;
6051 
6052 			for (k = 0;; ++k) {
6053 				if (k >= arity) {
6054 					add_irn_n(n, pred_pred);
6055 					++arity;
6056 					break;
6057 				}
6058 				if (get_Sync_pred(n, k) == pred_pred)
6059 					break;
6060 			}
6061 		}
6062 	}
6063 
6064 	if (arity == 0) {
6065 		ir_graph *irg = get_irn_irg(n);
6066 		return new_r_Bad(irg, mode_M);
6067 	}
6068 	if (arity == 1) {
6069 		return get_Sync_pred(n, 0);
6070 	}
6071 
6072 	/* rehash the sync node */
6073 	add_identities(n);
6074 	return n;
6075 }
6076 
create_load_replacement_tuple(ir_node * n,ir_node * mem,ir_node * res)6077 static ir_node *create_load_replacement_tuple(ir_node *n, ir_node *mem,
6078                                               ir_node *res)
6079 {
6080 	ir_node  *block = get_nodes_block(n);
6081 	ir_graph *irg   = get_irn_irg(n);
6082 	ir_node  *in[pn_Load_max+1];
6083 	size_t    n_in  = 2;
6084 	in[pn_Load_M]   = mem;
6085 	in[pn_Load_res] = res;
6086 	if (ir_throws_exception(n)) {
6087 		in[pn_Load_X_regular] = new_r_Jmp(block);
6088 		in[pn_Load_X_except]  = new_r_Bad(irg, mode_X);
6089 		n_in                  = 4;
6090 		assert(pn_Load_max == 4);
6091 	}
6092 	ir_node  *tuple = new_r_Tuple(block, n_in, in);
6093 	return tuple;
6094 }
6095 
transform_node_Load(ir_node * n)6096 static ir_node *transform_node_Load(ir_node *n)
6097 {
6098 	/* don't touch volatile loads */
6099 	if (get_Load_volatility(n) == volatility_is_volatile)
6100 		return n;
6101 
6102 	ir_node *ptr = get_Load_ptr(n);
6103 	const ir_node *confirm;
6104 	if (value_not_zero(ptr, &confirm) && confirm == NULL) {
6105 		set_irn_pinned(n, op_pin_state_floats);
6106 	}
6107 
6108 	/* if our memory predecessor is a load from the same address, then reuse the
6109 	 * previous result */
6110 	ir_node *mem = get_Load_mem(n);
6111 	if (!is_Proj(mem))
6112 		return n;
6113 	ir_node *mem_pred = get_Proj_pred(mem);
6114 	if (is_Load(mem_pred)) {
6115 		ir_node *pred_load = mem_pred;
6116 
6117 		/* conservatively compare the 2 loads. TODO: This could be less strict
6118 		 * with fixup code in some situations (like smaller/bigger modes) */
6119 		if (get_Load_ptr(pred_load) != ptr)
6120 			return n;
6121 		if (get_Load_mode(pred_load) != get_Load_mode(n))
6122 			return n;
6123 		/* all combinations of aligned/unaligned pred/n should be fine so we do
6124 		 * not compare the unaligned attribute */
6125 		ir_mode  *mode  = get_Load_mode(n);
6126 		ir_node  *res   = new_r_Proj(pred_load, mode, pn_Load_res);
6127 		return create_load_replacement_tuple(n, mem, res);
6128 	} else if (is_Store(mem_pred)) {
6129 		ir_node *pred_store = mem_pred;
6130 		ir_node *value      = get_Store_value(pred_store);
6131 
6132 		if (get_Store_ptr(pred_store) != ptr)
6133 			return n;
6134 		if (get_irn_mode(value) != get_Load_mode(n))
6135 			return n;
6136 		/* all combinations of aligned/unaligned pred/n should be fine so we do
6137 		 * not compare the unaligned attribute */
6138 		return create_load_replacement_tuple(n, mem, value);
6139 	}
6140 
6141 	return n;
6142 }
6143 
transform_node_Store(ir_node * n)6144 static ir_node *transform_node_Store(ir_node *n)
6145 {
6146 	/* don't touch volatile stores */
6147 	if (get_Store_volatility(n) == volatility_is_volatile)
6148 		return n;
6149 
6150 	ir_node *ptr = get_Store_ptr(n);
6151 	const ir_node *confirm;
6152 	if (value_not_zero(ptr, &confirm) && confirm == NULL) {
6153 		set_irn_pinned(n, op_pin_state_floats);
6154 	}
6155 	return n;
6156 }
6157 
6158 /**
6159  * optimize a trampoline Call into a direct Call
6160  */
transform_node_Call(ir_node * call)6161 static ir_node *transform_node_Call(ir_node *call)
6162 {
6163 	ir_node  *callee = get_Call_ptr(call);
6164 	ir_node  *adr, *mem, *res, *bl, **in;
6165 	ir_type  *ctp, *mtp, *tp;
6166 	ir_graph *irg;
6167 	type_dbg_info *tdb;
6168 	dbg_info *db;
6169 	size_t   i, n_res, n_param;
6170 	ir_variadicity var;
6171 
6172 	if (! is_Proj(callee))
6173 		return call;
6174 	callee = get_Proj_pred(callee);
6175 	if (! is_Builtin(callee))
6176 		return call;
6177 	if (get_Builtin_kind(callee) != ir_bk_inner_trampoline)
6178 		return call;
6179 
6180 	mem = get_Call_mem(call);
6181 
6182 	if (skip_Proj(mem) == callee) {
6183 		/* memory is routed to the trampoline, skip */
6184 		mem = get_Builtin_mem(callee);
6185 	}
6186 
6187 	/* build a new call type */
6188 	mtp = get_Call_type(call);
6189 	tdb = get_type_dbg_info(mtp);
6190 
6191 	n_res   = get_method_n_ress(mtp);
6192 	n_param = get_method_n_params(mtp);
6193 	ctp     = new_d_type_method(n_param + 1, n_res, tdb);
6194 
6195 	for (i = 0; i < n_res; ++i)
6196 		set_method_res_type(ctp, i, get_method_res_type(mtp, i));
6197 
6198 	NEW_ARR_A(ir_node *, in, n_param + 1);
6199 
6200 	/* FIXME: we don't need a new pointer type in every step */
6201 	irg = get_irn_irg(call);
6202 	tp = get_irg_frame_type(irg);
6203 	tp = new_type_pointer(tp);
6204 	set_method_param_type(ctp, 0, tp);
6205 
6206 	in[0] = get_Builtin_param(callee, 2);
6207 	for (i = 0; i < n_param; ++i) {
6208 		set_method_param_type(ctp, i + 1, get_method_param_type(mtp, i));
6209 		in[i + 1] = get_Call_param(call, i);
6210 	}
6211 	var = get_method_variadicity(mtp);
6212 	set_method_variadicity(ctp, var);
6213 	/* When we resolve a trampoline, the function must be called by a this-call */
6214 	set_method_calling_convention(ctp, get_method_calling_convention(mtp) | cc_this_call);
6215 	set_method_additional_properties(ctp, get_method_additional_properties(mtp));
6216 
6217 	adr = get_Builtin_param(callee, 1);
6218 
6219 	db  = get_irn_dbg_info(call);
6220 	bl  = get_nodes_block(call);
6221 
6222 	res = new_rd_Call(db, bl, mem, adr, n_param + 1, in, ctp);
6223 	if (get_irn_pinned(call) == op_pin_state_floats)
6224 		set_irn_pinned(res, op_pin_state_floats);
6225 	return res;
6226 }
6227 
6228 /**
6229  * Tries several [inplace] [optimizing] transformations and returns an
6230  * equivalent node.  The difference to equivalent_node() is that these
6231  * transformations _do_ generate new nodes, and thus the old node must
6232  * not be freed even if the equivalent node isn't the old one.
6233  */
transform_node(ir_node * n)6234 static ir_node *transform_node(ir_node *n)
6235 {
6236 	ir_node *old_n;
6237 	unsigned iro;
6238 restart:
6239 	old_n = n;
6240 	iro   = get_irn_opcode_(n);
6241 	/* constant expression evaluation / constant folding */
6242 	if (get_opt_constant_folding()) {
6243 		/* neither constants nor Tuple values can be evaluated */
6244 		if (iro != iro_Const && get_irn_mode(n) != mode_T) {
6245 			/* try to evaluate */
6246 			ir_tarval *tv = computed_value(n);
6247 			if (tv != tarval_bad) {
6248 				/* evaluation was successful -- replace the node. */
6249 				ir_graph *irg = get_irn_irg(n);
6250 
6251 				n = new_r_Const(irg, tv);
6252 
6253 				DBG_OPT_CSTEVAL(old_n, n);
6254 				return n;
6255 			}
6256 		}
6257 	}
6258 
6259 	/* remove unnecessary nodes */
6260 	if (get_opt_constant_folding() ||
6261 		(iro == iro_Phi)  ||   /* always optimize these nodes. */
6262 		(iro == iro_Id)   ||   /* ... */
6263 		(iro == iro_Proj) ||   /* ... */
6264 		(iro == iro_Block)) {  /* Flags tested local. */
6265 		n = equivalent_node(n);
6266 		if (n != old_n)
6267 			goto restart;
6268 	}
6269 
6270 	/* Some more constant expression evaluation. */
6271 	if (get_opt_algebraic_simplification() ||
6272 		(iro == iro_Cond) ||
6273 		(iro == iro_Proj)) {    /* Flags tested local. */
6274 		if (n->op->ops.transform_node != NULL) {
6275 			n = n->op->ops.transform_node(n);
6276 			if (n != old_n) {
6277 				goto restart;
6278 			}
6279 		}
6280 	}
6281 
6282 	return n;
6283 }
6284 
register_computed_value_func(ir_op * op,computed_value_func func)6285 static void register_computed_value_func(ir_op *op, computed_value_func func)
6286 {
6287 	assert(op->ops.computed_value == NULL || op->ops.computed_value == func);
6288 	op->ops.computed_value = func;
6289 }
6290 
register_computed_value_func_proj(ir_op * op,computed_value_func func)6291 static void register_computed_value_func_proj(ir_op *op,
6292                                               computed_value_func func)
6293 {
6294 	assert(op->ops.computed_value_Proj == NULL
6295 	    || op->ops.computed_value_Proj == func);
6296 	op->ops.computed_value_Proj = func;
6297 }
6298 
register_equivalent_node_func(ir_op * op,equivalent_node_func func)6299 static void register_equivalent_node_func(ir_op *op, equivalent_node_func func)
6300 {
6301 	assert(op->ops.equivalent_node == NULL || op->ops.equivalent_node == func);
6302 	op->ops.equivalent_node = func;
6303 }
6304 
register_equivalent_node_func_proj(ir_op * op,equivalent_node_func func)6305 static void register_equivalent_node_func_proj(ir_op *op,
6306                                                equivalent_node_func func)
6307 {
6308 	assert(op->ops.equivalent_node_Proj == NULL
6309 	    || op->ops.equivalent_node_Proj == func);
6310 	op->ops.equivalent_node_Proj = func;
6311 }
6312 
register_transform_node_func(ir_op * op,transform_node_func func)6313 static void register_transform_node_func(ir_op *op, transform_node_func func)
6314 {
6315 	assert(op->ops.transform_node == NULL || op->ops.transform_node == func);
6316 	op->ops.transform_node = func;
6317 }
6318 
register_transform_node_func_proj(ir_op * op,transform_node_func func)6319 static void register_transform_node_func_proj(ir_op *op,
6320                                               transform_node_func func)
6321 {
6322 	assert(op->ops.transform_node_Proj == NULL
6323 	    || op->ops.transform_node_Proj == func);
6324 	op->ops.transform_node_Proj = func;
6325 }
6326 
ir_register_opt_node_ops(void)6327 void ir_register_opt_node_ops(void)
6328 {
6329 	register_computed_value_func(op_Add,      computed_value_Add);
6330 	register_computed_value_func(op_And,      computed_value_And);
6331 	register_computed_value_func(op_Borrow,   computed_value_Borrow);
6332 	register_computed_value_func(op_Carry,    computed_value_Carry);
6333 	register_computed_value_func(op_Cmp,      computed_value_Cmp);
6334 	register_computed_value_func(op_Confirm,  computed_value_Confirm);
6335 	register_computed_value_func(op_Const,    computed_value_Const);
6336 	register_computed_value_func(op_Conv,     computed_value_Conv);
6337 	register_computed_value_func(op_Eor,      computed_value_Eor);
6338 	register_computed_value_func(op_Minus,    computed_value_Minus);
6339 	register_computed_value_func(op_Mul,      computed_value_Mul);
6340 	register_computed_value_func(op_Mux,      computed_value_Mux);
6341 	register_computed_value_func(op_Not,      computed_value_Not);
6342 	register_computed_value_func(op_Or,       computed_value_Or);
6343 	register_computed_value_func(op_Proj,     computed_value_Proj);
6344 	register_computed_value_func(op_Rotl,     computed_value_Rotl);
6345 	register_computed_value_func(op_Shl,      computed_value_Shl);
6346 	register_computed_value_func(op_Shr,      computed_value_Shr);
6347 	register_computed_value_func(op_Shrs,     computed_value_Shrs);
6348 	register_computed_value_func(op_Sub,      computed_value_Sub);
6349 	register_computed_value_func(op_SymConst, computed_value_SymConst);
6350 	register_computed_value_func_proj(op_Div, computed_value_Proj_Div);
6351 	register_computed_value_func_proj(op_Mod, computed_value_Proj_Mod);
6352 
6353 	register_equivalent_node_func(op_Add,     equivalent_node_Add);
6354 	register_equivalent_node_func(op_And,     equivalent_node_And);
6355 	register_equivalent_node_func(op_Confirm, equivalent_node_Confirm);
6356 	register_equivalent_node_func(op_Conv,    equivalent_node_Conv);
6357 	register_equivalent_node_func(op_Eor,     equivalent_node_Eor);
6358 	register_equivalent_node_func(op_Id,      equivalent_node_Id);
6359 	register_equivalent_node_func(op_Minus,   equivalent_node_involution);
6360 	register_equivalent_node_func(op_Mul,     equivalent_node_Mul);
6361 	register_equivalent_node_func(op_Mux,     equivalent_node_Mux);
6362 	register_equivalent_node_func(op_Not,     equivalent_node_involution);
6363 	register_equivalent_node_func(op_Or,      equivalent_node_Or);
6364 	register_equivalent_node_func(op_Phi,     equivalent_node_Phi);
6365 	register_equivalent_node_func(op_Proj,    equivalent_node_Proj);
6366 	register_equivalent_node_func(op_Rotl,    equivalent_node_left_zero);
6367 	register_equivalent_node_func(op_Shl,     equivalent_node_left_zero);
6368 	register_equivalent_node_func(op_Shr,     equivalent_node_left_zero);
6369 	register_equivalent_node_func(op_Shrs,    equivalent_node_left_zero);
6370 	register_equivalent_node_func(op_Sub,     equivalent_node_Sub);
6371 	register_equivalent_node_func_proj(op_Bound, equivalent_node_Proj_Bound);
6372 	register_equivalent_node_func_proj(op_CopyB, equivalent_node_Proj_CopyB);
6373 	register_equivalent_node_func_proj(op_Div,   equivalent_node_Proj_Div);
6374 	register_equivalent_node_func_proj(op_Tuple, equivalent_node_Proj_Tuple);
6375 
6376 	register_transform_node_func(op_Add,    transform_node_Add);
6377 	register_transform_node_func(op_And,    transform_node_And);
6378 	register_transform_node_func(op_Block,  transform_node_Block);
6379 	register_transform_node_func(op_Call,   transform_node_Call);
6380 	register_transform_node_func(op_Cmp,    transform_node_Cmp);
6381 	register_transform_node_func(op_Cond,   transform_node_Cond);
6382 	register_transform_node_func(op_Conv,   transform_node_Conv);
6383 	register_transform_node_func(op_Div,    transform_node_Div);
6384 	register_transform_node_func(op_End,    transform_node_End);
6385 	register_transform_node_func(op_Eor,    transform_node_Eor);
6386 	register_transform_node_func(op_Load,   transform_node_Load);
6387 	register_transform_node_func(op_Minus,  transform_node_Minus);
6388 	register_transform_node_func(op_Mod,    transform_node_Mod);
6389 	register_transform_node_func(op_Mul,    transform_node_Mul);
6390 	register_transform_node_func(op_Mux,    transform_node_Mux);
6391 	register_transform_node_func(op_Not,    transform_node_Not);
6392 	register_transform_node_func(op_Or,     transform_node_Or);
6393 	register_transform_node_func(op_Phi,    transform_node_Phi);
6394 	register_transform_node_func(op_Proj,   transform_node_Proj);
6395 	register_transform_node_func(op_Rotl,   transform_node_Rotl);
6396 	register_transform_node_func(op_Shl,    transform_node_Shl);
6397 	register_transform_node_func(op_Shrs,   transform_node_Shrs);
6398 	register_transform_node_func(op_Shr,    transform_node_Shr);
6399 	register_transform_node_func(op_Store,  transform_node_Store);
6400 	register_transform_node_func(op_Sub,    transform_node_Sub);
6401 	register_transform_node_func(op_Switch, transform_node_Switch);
6402 	register_transform_node_func(op_Sync,   transform_node_Sync);
6403 	register_transform_node_func_proj(op_Bound, transform_node_Proj_Bound);
6404 	register_transform_node_func_proj(op_CopyB, transform_node_Proj_CopyB);
6405 	register_transform_node_func_proj(op_Div,   transform_node_Proj_Div);
6406 	register_transform_node_func_proj(op_Load,  transform_node_Proj_Load);
6407 	register_transform_node_func_proj(op_Mod,   transform_node_Proj_Mod);
6408 	register_transform_node_func_proj(op_Store, transform_node_Proj_Store);
6409 }
6410 
6411 /* **************** Common Subexpression Elimination **************** */
6412 
6413 /** The size of the hash table used, should estimate the number of nodes
6414     in a graph. */
6415 #define N_IR_NODES 512
6416 
identities_cmp(const void * elt,const void * key)6417 int identities_cmp(const void *elt, const void *key)
6418 {
6419 	ir_node *a = (ir_node *)elt;
6420 	ir_node *b = (ir_node *)key;
6421 	int i, irn_arity_a;
6422 
6423 	if (a == b) return 0;
6424 
6425 	if ((get_irn_op(a) != get_irn_op(b)) ||
6426 	    (get_irn_mode(a) != get_irn_mode(b))) return 1;
6427 
6428 	/* compare if a's in and b's in are of equal length */
6429 	irn_arity_a = get_irn_arity(a);
6430 	if (irn_arity_a != get_irn_arity(b))
6431 		return 1;
6432 
6433 	/* blocks are never the same */
6434 	if (is_Block(a))
6435 		return 1;
6436 
6437 	if (get_irn_pinned(a) == op_pin_state_pinned) {
6438 		/* for pinned nodes, the block inputs must be equal */
6439 		if (get_nodes_block(a) != get_nodes_block(b))
6440 			return 1;
6441 	} else {
6442 		ir_node *block_a = get_nodes_block(a);
6443 		ir_node *block_b = get_nodes_block(b);
6444 		if (! get_opt_global_cse()) {
6445 			/* for block-local CSE both nodes must be in the same Block */
6446 			if (block_a != block_b)
6447 				return 1;
6448 		} else {
6449 			/* The optimistic approach would be to do nothing here.
6450 			 * However doing GCSE optimistically produces a lot of partially dead code which appears
6451 			 * to be worse in practice than the missed opportunities.
6452 			 * So we use a very conservative variant here and only CSE if 1 value dominates the
6453 			 * other. */
6454 			if (!block_dominates(block_a, block_b)
6455 			    && !block_dominates(block_b, block_a))
6456 			    return 1;
6457 			/* respect the workaround rule: do not move nodes which are only
6458 			 * held by keepalive edges */
6459 			if (only_used_by_keepalive(a) || only_used_by_keepalive(b))
6460 				return 1;
6461 		}
6462 	}
6463 
6464 	/* compare a->in[0..ins] with b->in[0..ins] */
6465 	for (i = 0; i < irn_arity_a; ++i) {
6466 		ir_node *pred_a = get_irn_n(a, i);
6467 		ir_node *pred_b = get_irn_n(b, i);
6468 		if (pred_a != pred_b) {
6469 			/* if both predecessors are CSE neutral they might be different */
6470 			if (!is_irn_cse_neutral(pred_a) || !is_irn_cse_neutral(pred_b))
6471 				return 1;
6472 		}
6473 	}
6474 
6475 	/*
6476 	 * here, we already now that the nodes are identical except their
6477 	 * attributes
6478 	 */
6479 	if (a->op->ops.node_cmp_attr)
6480 		return a->op->ops.node_cmp_attr(a, b);
6481 
6482 	return 0;
6483 }
6484 
ir_node_hash(const ir_node * node)6485 unsigned ir_node_hash(const ir_node *node)
6486 {
6487 	return node->op->ops.hash(node);
6488 }
6489 
new_identities(ir_graph * irg)6490 void new_identities(ir_graph *irg)
6491 {
6492 	if (irg->value_table != NULL)
6493 		del_pset(irg->value_table);
6494 	irg->value_table = new_pset(identities_cmp, N_IR_NODES);
6495 }
6496 
del_identities(ir_graph * irg)6497 void del_identities(ir_graph *irg)
6498 {
6499 	if (irg->value_table != NULL)
6500 		del_pset(irg->value_table);
6501 }
6502 
cmp_node_nr(const void * a,const void * b)6503 static int cmp_node_nr(const void *a, const void *b)
6504 {
6505 	ir_node **p1 = (ir_node**)a;
6506 	ir_node **p2 = (ir_node**)b;
6507 	long      n1 = get_irn_node_nr(*p1);
6508 	long      n2 = get_irn_node_nr(*p2);
6509 	return (n1>n2) - (n1<n2);
6510 }
6511 
ir_normalize_node(ir_node * n)6512 void ir_normalize_node(ir_node *n)
6513 {
6514 	if (is_op_commutative(get_irn_op(n))) {
6515 		ir_node *l = get_binop_left(n);
6516 		ir_node *r = get_binop_right(n);
6517 
6518 		/* For commutative operators perform  a OP b == b OP a but keep
6519 		 * constants on the RIGHT side. This helps greatly in some
6520 		 * optimizations.  Moreover we use the idx number to make the form
6521 		 * deterministic. */
6522 		if (!operands_are_normalized(l, r)) {
6523 			set_binop_left(n, r);
6524 			set_binop_right(n, l);
6525 			hook_normalize(n);
6526 		}
6527 	} else if (is_Sync(n)) {
6528 		/* we assume that most of the time the inputs of a Sync node are already
6529 		 * sorted, so check this first as a shortcut */
6530 		bool           ins_sorted = true;
6531 		int            arity      = get_irn_arity(n);
6532 		const ir_node *last       = get_irn_n(n, 0);
6533 		int      i;
6534 		for (i = 1; i < arity; ++i) {
6535 			const ir_node *node = get_irn_n(n, i);
6536 			if (get_irn_node_nr(node) < get_irn_node_nr(last)) {
6537 				ins_sorted = false;
6538 				break;
6539 			}
6540 			last = node;
6541 		}
6542 
6543 		if (!ins_sorted) {
6544 			ir_node **ins     = get_irn_in(n)+1;
6545 			ir_node **new_ins = XMALLOCN(ir_node*, arity);
6546 			memcpy(new_ins, ins, arity*sizeof(ins[0]));
6547 			qsort(new_ins, arity, sizeof(new_ins[0]), cmp_node_nr);
6548 			set_irn_in(n, arity, new_ins);
6549 			xfree(new_ins);
6550 		}
6551 	}
6552 }
6553 
identify_remember(ir_node * n)6554 ir_node *identify_remember(ir_node *n)
6555 {
6556 	ir_graph *irg         = get_irn_irg(n);
6557 	pset     *value_table = irg->value_table;
6558 	ir_node  *nn;
6559 
6560 	if (value_table == NULL)
6561 		return n;
6562 
6563 	ir_normalize_node(n);
6564 	/* lookup or insert in hash table with given hash key. */
6565 	nn = (ir_node*)pset_insert(value_table, n, ir_node_hash(n));
6566 
6567 	if (nn != n) {
6568 		/* n is reachable again */
6569 		edges_node_revival(nn);
6570 	}
6571 
6572 	return nn;
6573 }
6574 
6575 /**
6576  * During construction we set the op_pin_state_pinned flag in the graph right
6577  * when the optimization is performed.  The flag turning on procedure global
6578  * cse could be changed between two allocations.  This way we are safe.
6579  *
6580  * @param n            The node to lookup
6581  */
identify_cons(ir_node * n)6582 static inline ir_node *identify_cons(ir_node *n)
6583 {
6584 	ir_node *old = n;
6585 
6586 	n = identify_remember(n);
6587 	if (n != old && get_nodes_block(old) != get_nodes_block(n)) {
6588 		ir_graph *irg = get_irn_irg(n);
6589 		set_irg_pinned(irg, op_pin_state_floats);
6590 	}
6591 	return n;
6592 }
6593 
add_identities(ir_node * node)6594 void add_identities(ir_node *node)
6595 {
6596 	if (!get_opt_cse())
6597 		return;
6598 	if (is_Block(node))
6599 		return;
6600 
6601 	identify_remember(node);
6602 }
6603 
visit_all_identities(ir_graph * irg,irg_walk_func visit,void * env)6604 void visit_all_identities(ir_graph *irg, irg_walk_func visit, void *env)
6605 {
6606 	ir_graph *rem = current_ir_graph;
6607 
6608 	current_ir_graph = irg;
6609 	foreach_pset(irg->value_table, ir_node, node) {
6610 		visit(node, env);
6611 	}
6612 	current_ir_graph = rem;
6613 }
6614 
optimize_node(ir_node * n)6615 ir_node *optimize_node(ir_node *n)
6616 {
6617 	ir_node   *oldn = n;
6618 	ir_graph  *irg  = get_irn_irg(n);
6619 	unsigned   iro  = get_irn_opcode(n);
6620 	ir_tarval *tv;
6621 
6622 	/* Always optimize Phi nodes: part of the construction. */
6623 	if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
6624 
6625 	/* constant expression evaluation / constant folding */
6626 	if (get_opt_constant_folding()) {
6627 		/* neither constants nor Tuple values can be evaluated */
6628 		if (iro != iro_Const && (get_irn_mode(n) != mode_T)) {
6629 			/* try to evaluate */
6630 			tv = computed_value(n);
6631 			if (tv != tarval_bad) {
6632 				ir_node *nw;
6633 				size_t node_size;
6634 
6635 				/*
6636 				 * we MUST copy the node here temporarily, because it's still
6637 				 * needed for DBG_OPT_CSTEVAL
6638 				 */
6639 				node_size = offsetof(ir_node, attr) +  n->op->attr_size;
6640 				oldn = (ir_node*)alloca(node_size);
6641 
6642 				memcpy(oldn, n, node_size);
6643 				CLONE_ARR_A(ir_node *, oldn->in, n->in);
6644 
6645 				/* ARG, copy the in array, we need it for statistics */
6646 				memcpy(oldn->in, n->in, ARR_LEN(n->in) * sizeof(n->in[0]));
6647 
6648 				/* note the inplace edges module */
6649 				edges_node_deleted(n);
6650 
6651 				/* evaluation was successful -- replace the node. */
6652 				irg_kill_node(irg, n);
6653 				nw = new_r_Const(irg, tv);
6654 
6655 				DBG_OPT_CSTEVAL(oldn, nw);
6656 				return nw;
6657 			}
6658 		}
6659 	}
6660 
6661 	/* remove unnecessary nodes */
6662 	if (get_opt_algebraic_simplification() ||
6663 	    (iro == iro_Phi)  ||   /* always optimize these nodes. */
6664 	    (iro == iro_Id)   ||
6665 	    (iro == iro_Proj) ||
6666 	    (iro == iro_Block)  )  /* Flags tested local. */
6667 		n = equivalent_node(n);
6668 
6669 	/* Common Subexpression Elimination.
6670 	 *
6671 	 * Checks whether n is already available.
6672 	 * The block input is used to distinguish different subexpressions. Right
6673 	 * now all nodes are op_pin_state_pinned to blocks, i.e., the CSE only finds common
6674 	 * subexpressions within a block.
6675 	 */
6676 	if (get_opt_cse())
6677 		n = identify_cons(n);
6678 
6679 	if (n != oldn) {
6680 		edges_node_deleted(oldn);
6681 
6682 		/* We found an existing, better node, so we can deallocate the old node. */
6683 		irg_kill_node(irg, oldn);
6684 		return n;
6685 	}
6686 
6687 	/* Some more constant expression evaluation that does not allow to
6688 	   free the node. */
6689 	iro = get_irn_opcode(n);
6690 	if (get_opt_algebraic_simplification() ||
6691 		(iro == iro_Cond) ||
6692 		(iro == iro_Proj)) {    /* Flags tested local. */
6693 		n = transform_node(n);
6694 	}
6695 
6696 	/* Now we have a legal, useful node. Enter it in hash table for CSE */
6697 	if (get_opt_cse()) {
6698 		ir_node *o = n;
6699 		n = identify_remember(o);
6700 		if (o != n)
6701 			DBG_OPT_CSE(o, n);
6702 	}
6703 
6704 	return n;
6705 }
6706 
optimize_in_place_2(ir_node * n)6707 ir_node *optimize_in_place_2(ir_node *n)
6708 {
6709 	if (!get_opt_optimize() && !is_Phi(n)) return n;
6710 
6711 	if (is_Deleted(n))
6712 		return n;
6713 
6714 	/** common subexpression elimination **/
6715 	/* Checks whether n is already available. */
6716 	/* The block input is used to distinguish different subexpressions.
6717 	 * Right now all nodes are op_pin_state_pinned to blocks, i.e., the cse
6718 	 * only finds common subexpressions within a block. */
6719 	if (get_opt_cse()) {
6720 		ir_node *o = n;
6721 		n = identify_remember(n);
6722 		if (n != o) {
6723 			DBG_OPT_CSE(o, n);
6724 			/* we have another existing node now, we do not optimize it here */
6725 			return n;
6726 		}
6727 	}
6728 
6729 	n = transform_node(n);
6730 
6731 	/* Now we can verify the node, as it has no dead inputs any more. */
6732 	irn_verify(n);
6733 
6734 	/* Now we have a legal, useful node. Enter it in hash table for cse.
6735 	 *
6736 	 * Note: This is only necessary because some of the optimisations
6737 	 * operate in-place (set_XXX_bla, turn_into_tuple, ...) which is considered
6738 	 * bad practice and should be fixed sometime.
6739 	 */
6740 	if (get_opt_cse()) {
6741 		ir_node *o = n;
6742 		n = identify_remember(o);
6743 		if (o != n)
6744 			DBG_OPT_CSE(o, n);
6745 	}
6746 
6747 	return n;
6748 }
6749 
optimize_in_place(ir_node * n)6750 ir_node *optimize_in_place(ir_node *n)
6751 {
6752 	ir_graph *irg = get_irn_irg(n);
6753 
6754 	if (get_opt_global_cse())
6755 		set_irg_pinned(irg, op_pin_state_floats);
6756 
6757 	/* FIXME: Maybe we could also test whether optimizing the node can
6758 	   change the control graph. */
6759 	clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
6760 	return optimize_in_place_2(n);
6761 }
6762