1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
4 ** Authors: Christian Schaefer, Goetz Lindenmaier
6 ** iropt --- optimizations intertwined with IR construction.
15 /* Make types visible to allow most efficient access */
16 # include "entity_t.h"
18 /* Trivial inlineable routine for copy propagation.
19 Does follow Ids, needed to optimize inlined code. */
20 static inline ir_node *
21 follow_Id (ir_node *n)
23 while (get_irn_op (n) == op_Id) n = get_Id_pred (n);
27 static inline tarval *
30 if ((n != NULL) && (get_irn_op(n) == op_Const))
31 return get_Const_tarval(n);
36 /* if n can be computed, return the value, else NULL. Performs
37 constant folding. GL: Only if n is arithmetic operator? */
39 computed_value (ir_node *n)
43 ir_node *a = NULL, *b = NULL; /* initialized to shut up gcc */
44 tarval *ta = NULL, *tb = NULL; /* initialized to shut up gcc */
48 /* get the operands we will work on for simple cases. */
50 a = get_binop_left(n);
51 b = get_binop_right(n);
52 } else if (is_unop(n)) {
56 /* if the operands are constants, get the target value, else set it NULL.
57 (a and b may be NULL if we treat a node that is no computation.) */
61 /* Perform the constant evaluation / computation. */
62 switch (get_irn_opcode(n)) {
64 res = get_Const_tarval(n);
66 if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
67 && (get_irn_mode(a) != mode_p)) {
68 res = tarval_add (ta, tb);
72 if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
73 && (get_irn_mode(a) != mode_p)) {
74 res = tarval_sub (ta, tb);
76 res = tarval_mode_null [get_irn_modecode (n)];
80 if (ta && mode_is_float(get_irn_mode(a)))
81 res = /*tarval_minus (ta);*/ res;
84 if (ta && tb) /* tarval_mul tests for equivalent modes itself */ {
85 res = tarval_mul (ta, tb);
87 /* calls computed_value recursive and returns the 0 with proper
88 mode. Why is this an extra case? */
90 if ( (tarval_classify ((v = computed_value (a))) == 0)
91 || (tarval_classify ((v = computed_value (b))) == 0)) {
98 res = /*tarval_abs (ta);*/ res;
99 /* allowed or problems with max/min ?? */
103 res = tarval_and (ta, tb);
106 if ( (tarval_classify ((v = computed_value (a))) == 0)
107 || (tarval_classify ((v = computed_value (b))) == 0)) {
114 res = tarval_or (ta, tb);
117 if ( (tarval_classify ((v = computed_value (a))) == -1)
118 || (tarval_classify ((v = computed_value (b))) == -1)) {
123 case iro_Eor: if (ta && tb) { res = tarval_eor (ta, tb); } break;
124 case iro_Not: if (ta) { /*res = tarval_not (ta)*/; } break;
125 case iro_Shl: if (ta && tb) { res = tarval_shl (ta, tb); } break;
126 case iro_Shr: if (ta && tb) { res = tarval_shr (ta, tb); } break;
127 case iro_Shrs: if(ta && tb) { /*res = tarval_shrs (ta, tb)*/; } break;
128 case iro_Rot: if (ta && tb) { /*res = tarval_rot (ta, tb)*/; } break;
129 case iro_Conv: if(ta) { res = tarval_convert_to (ta, get_irn_mode (n)); }
135 a = get_Proj_pred(n);
136 /* Optimize Cmp nodes.
137 This performs a first step of unreachable code elimination.
138 Proj can not be computed, but folding a Cmp above the Proj here is
139 not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
141 There are several case where we can evaluate a Cmp node:
142 1. The nodes compared are both the same. If we compare for
143 equal, this will return true, else it will return false.
144 This step relies on cse.
145 2. The predecessors of Cmp are target values. We can evaluate
147 3. The predecessors are Allocs or void* constants. Allocs never
148 return NULL, they raise an exception. Therefore we can predict
150 if (get_irn_op(a) == op_Cmp) {
151 aa = get_Cmp_left(a);
152 ab = get_Cmp_right(a);
153 if (aa == ab) { /* 1.: */
154 /* This is a tric with the bits used for encoding the Cmp
155 Proj numbers, the following statement is not the same:
156 res = tarval_from_long (mode_b, (get_Proj_proj(n) == Eq)): */
157 res = tarval_from_long (mode_b, (get_Proj_proj(n) & irpn_Eq));
159 tarval *taa = computed_value (aa);
160 tarval *tab = computed_value (ab);
161 if (taa && tab) { /* 2.: */
162 /* strange checks... */
163 ir_pncmp flags = tarval_comp (taa, tab);
164 if (flags != irpn_False) {
165 res = tarval_from_long (mode_b, get_Proj_proj(n) & flags);
167 } else { /* check for 3.: */
168 ir_node *aaa = skip_nop(skip_Proj(aa));
169 ir_node *aba = skip_nop(skip_Proj(ab));
170 if ( ( (/* aa is ProjP and aaa is Alloc */
171 (get_irn_op(aa) == op_Proj)
172 && (get_irn_mode(aa) == mode_p)
173 && (get_irn_op(aaa) == op_Alloc))
174 && ( (/* ab is constant void */
175 (get_irn_op(ab) == op_Const)
176 && (get_irn_mode(ab) == mode_p)
177 && (get_Const_tarval(ab) == tarval_p_void))
178 || (/* ab is other Alloc */
179 (get_irn_op(ab) == op_Proj)
180 && (get_irn_mode(ab) == mode_p)
181 && (get_irn_op(aba) == op_Alloc)
183 || (/* aa is void and aba is Alloc */
184 (get_irn_op(aa) == op_Const)
185 && (get_irn_mode(aa) == mode_p)
186 && (get_Const_tarval(aa) == tarval_p_void)
187 && (get_irn_op(ab) == op_Proj)
188 && (get_irn_mode(ab) == mode_p)
189 && (get_irn_op(aba) == op_Alloc)))
191 res = tarval_from_long (mode_b, get_Proj_proj(n) & irpn_Ne);
195 /* printf(" # comp_val: Proj node, not optimized\n"); */
207 /* returns 1 if the a and b are pointers to different locations. */
209 different_identity (ir_node *a, ir_node *b)
211 assert (get_irn_mode (a) == mode_p
212 && get_irn_mode (b) == mode_p);
214 if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
215 ir_node *a1 = get_Proj_pred (a);
216 ir_node *b1 = get_Proj_pred (b);
217 if (a1 != b1 && get_irn_op (a1) == op_Alloc
218 && get_irn_op (b1) == op_Alloc)
225 /* equivalent_node returns a node equivalent to N. It skips all nodes that
226 perform no actual computation, as, e.g., the Id nodes. It does not create
227 new nodes. It is therefore safe to free N if the node returned is not N.
228 If a node returns a Tuple we can not just skip it. If the size of the
229 in array fits, we transform n into a tuple (e.g., Div). */
231 equivalent_node (ir_node *n)
234 ir_node *a = NULL; /* to shutup gcc */
235 ir_node *b = NULL; /* to shutup gcc */
236 ir_node *c = NULL; /* to shutup gcc */
238 ins = get_irn_arity (n);
240 /* get the operands we will work on */
242 a = get_binop_left(n);
243 b = get_binop_right(n);
244 } else if (is_unop(n)) {
248 /* skip unnecessary nodes. */
249 switch (get_irn_opcode (n)) {
252 /* The Block constructor does not call optimize, but mature_block
253 calls the optimization. */
254 assert(get_Block_matured(n));
256 /* A single entry Block following a single exit Block can be merged,
257 if it is not the Start block. */
258 /* !!! Beware, all Phi-nodes of n must have been optimized away.
259 This is true, as the block is matured before optimize is called. */
260 if (get_Block_n_cfgpreds(n) == 1
261 && get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) {
262 n = get_nodes_Block(get_Block_cfgpred(n, 0));
264 } else if (n != current_ir_graph->start_block) {
266 /* If all inputs are dead, this block is dead too, except if it is
267 the start block. This is a step of unreachable code elimination */
268 for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
269 if (!is_Bad(get_Block_cfgpred(n, i))) break;
271 if (i == get_Block_n_cfgpreds(n))
277 case iro_Jmp: /* GL: Why not same for op_Raise?? */
278 /* unreachable code elimination */
279 if (is_Bad(get_nodes_Block(n))) n = new_Bad();
281 /* We do not evaluate Cond here as we replace it by a new node, a Jmp.
282 See cases for iro_Cond and iro_Proj in transform_node. */
283 /** remove stuff as x+0, x*1 x&true ... constant expression evaluation **/
284 case iro_Or: if (a == b) {n = a; break;}
289 /* After running compute_node there is only one constant predecessor.
290 Find this predecessors value and remember the other node: */
291 if ((tv = computed_value (a))) {
293 } else if ((tv = computed_value (b))) {
297 /* If this predecessors constant value is zero, the operation is
298 unnecessary. Remove it: */
299 if (tarval_classify (tv) == 0) {
309 /* these operations are not commutative. Test only one predecessor. */
310 if (tarval_classify (computed_value (b)) == 0) {
312 /* Test if b > #bits of a ==> return 0 / divide b by #bits
313 --> transform node? */
316 case iro_Not: /* NotNot x == x */
317 case iro_Minus: /* --x == x */ /* ??? Is this possible or can --x raise an
318 out of bounds exception if min =! max? */
319 if (get_irn_op(get_unop_op(n)) == get_irn_op(n))
320 n = get_unop_op(get_unop_op(n));
323 /* Mul is commutative and has again an other neutral element. */
324 if (tarval_classify (computed_value (a)) == 1) {
326 } else if (tarval_classify (computed_value (b)) == 1) {
331 /* Div is not commutative. */
332 if (tarval_classify (computed_value (b)) == 1) { /* div(x, 1) == x */
333 /* Turn Div into a tuple (mem, bad, a) */
334 ir_node *mem = get_Div_mem(n);
335 turn_into_tuple(n, 3);
336 set_Tuple_pred(n, 0, mem);
337 set_Tuple_pred(n, 1, new_Bad());
338 set_Tuple_pred(n, 2, a);
341 /* GL: Why are they skipped? DivMod allocates new nodes --> it's
342 teated in transform node.
343 case iro_Mod, Quot, DivMod
347 /* And has it's own neutral element */
348 else if (tarval_classify (computed_value (a)) == -1) {
350 } else if (tarval_classify (computed_value (b)) == -1) {
355 if (get_irn_mode(n) == get_irn_mode(a)) { /* No Conv necessary */
357 } else if (get_irn_mode(n) == mode_b) {
358 if (get_irn_op(a) == op_Conv &&
359 get_irn_mode (get_Conv_op(a)) == mode_b) {
360 n = get_Conv_op(a); /* Convb(Conv*(xxxb(...))) == xxxb(...) */
367 /* Several optimizations:
368 - no Phi in start block.
369 - remove Id operators that are inputs to Phi
370 - fold Phi-nodes, iff they have only one predecessor except
374 ir_node *block = NULL; /* to shutup gcc */
375 ir_node *first_val = NULL; /* to shutup gcc */
376 ir_node *scnd_val = NULL; /* to shutup gcc */
378 n_preds = get_Phi_n_preds(n);
380 block = get_nodes_Block(n);
381 assert(get_irn_op (block) == op_Block);
383 /* there should be no Phi nodes in the Start region. */
384 if (block == current_ir_graph->start_block) {
389 if (n_preds == 0) { /* Phi of dead Region without predecessors. */
390 /* GL: why not return new_Bad? */
395 /* first we test for a special case: */
396 /* Confirm is a special node fixing additional information for a
397 value that is known at a certain point. This is useful for
398 dataflow analysis. */
400 ir_node *a = follow_Id (get_Phi_pred(n, 0));
401 ir_node *b = follow_Id (get_Phi_pred(n, 1));
402 if ( (get_irn_op(a) == op_Confirm)
403 && (get_irn_op(b) == op_Confirm)
404 && (follow_Id (get_irn_n(a, 0)) == follow_Id(get_irn_n(b, 0)))
405 && (get_irn_n(a, 1) == get_irn_n (b, 1))
406 && (a->data.num == (~b->data.num & irpn_True) )) {
407 n = follow_Id (get_irn_n(a, 0));
412 /* Find first non-self-referencing input */
413 for (i = 0; i < n_preds; ++i) {
414 first_val = follow_Id(get_Phi_pred(n, i));
416 set_Phi_pred(n, i, first_val);
417 if ( (first_val != n) /* not self pointer */
418 && (get_irn_op(first_val) != op_Bad) /* value not dead */
419 && !(is_Bad (get_Block_cfgpred(block, i))) ) { /* not dead control flow */
420 break; /* then found first value. */
424 /* A totally Bad or self-referencing Phi (we didn't break the above loop) */
425 if (i > n_preds) { n = new_Bad(); break; }
429 /* follow_Id () for rest of inputs, determine if any of these
430 are non-self-referencing */
431 while (++i < n_preds) {
432 scnd_val = follow_Id(get_Phi_pred(n, i));
434 set_Phi_pred(n, i, scnd_val);
436 && (scnd_val != first_val)
437 && (get_irn_op(scnd_val) != op_Bad)
438 && !(is_Bad (get_Block_cfgpred(block, i))) ) {
443 /* Fold, if no multiple distinct non-self-referencing inputs */
447 /* skip the remaining Ids. */
448 while (++i < n_preds) {
449 set_Phi_pred(n, i, follow_Id(get_Phi_pred(n, i)));
457 a = skip_Proj(get_Load_mem(n));
458 b = skip_Proj(get_Load_ptr(n));
460 if (get_irn_op(a) == op_Store) {
461 if ( different_identity (b, get_Store_ptr(a))) {
462 /* load and store use different pointers, therefore load
463 needs not take store's memory but the state before. */
464 set_Load_mem (n, get_Store_mem(a));
465 } else if (( 0 /* ???didn't get cryptic test that returns 0 */ )) {
471 /* remove unnecessary store. */
473 a = skip_Proj(get_Store_mem(n));
474 b = get_Store_ptr(n);
475 c = skip_Proj(get_Store_value(n));
477 if (get_irn_op(a) == op_Store
478 && get_Store_ptr(a) == b
479 && skip_Proj(get_Store_value(a)) == c) {
480 /* We have twice exactly the same store -- a write after write. */
482 } else if (get_irn_op(c) == op_Load
483 && (a == c || skip_Proj(get_Load_mem(c)) == a)
484 && get_Load_ptr(c) == b )
485 /* !!!??? and a cryptic test */ {
486 /* We just loaded the value from the same memory, i.e., the store
487 doesn't change the memory -- a write after read. */
488 turn_into_tuple(n, 2);
489 set_Tuple_pred(n, 0, a);
490 set_Tuple_pred(n, 1, new_Bad());
497 a = get_Proj_pred(n);
499 if ( get_irn_op(a) == op_Tuple) {
500 /* Remove the Tuple/Proj combination. */
501 if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
502 n = get_Tuple_pred(a, get_Proj_proj(n));
504 assert(0); /* This should not happen! (GL added this assert) */
507 } else if (get_irn_mode(n) == mode_X &&
508 is_Bad(get_nodes_Block(n))) {
509 /* Remove dead control flow. */
523 } /* end equivalent_node() */
526 /* tries several [inplace] [optimizing] transformations and returns a
527 equivalent node. The difference to equivalent_node is that these
528 transformations _do_ generate new nodes, and thus the old node must
529 not be freed even if the equivalent node isn't the old one. */
531 transform_node (ir_node *n)
534 ir_node *a = NULL, *b;
537 switch (get_irn_opcode(n)) {
543 a = get_DivMod_left(n);
544 b = get_DivMod_right(n);
545 mode = get_irn_mode(a);
547 if (!( mode_is_int(get_irn_mode(a))
548 && mode_is_int(get_irn_mode(b))))
552 a = new_Const (mode, tarval_from_long (mode, 1));
553 b = new_Const (mode, tarval_from_long (mode, 0));
560 if (tarval_classify(tb) == 1) {
561 b = new_Const (mode, tarval_from_long (mode, 0));
565 resa = tarval_div (ta, tb);
566 if (!resa) break; /* Causes exception!!! Model by replacing through
567 Jmp for X result!? */
568 resb = tarval_mod (ta, tb);
569 if (!resb) break; /* Causes exception! */
570 a = new_Const (mode, resa);
571 b = new_Const (mode, resb);
574 } else if (tarval_classify (ta) == 0) {
579 if (evaluated) { /* replace by tuple */
580 ir_node *mem = get_DivMod_mem(n);
581 turn_into_tuple(n, 4);
582 set_Tuple_pred(n, 0, mem);
583 set_Tuple_pred(n, 1, new_Bad()); /* no exception */
584 set_Tuple_pred(n, 2, a);
585 set_Tuple_pred(n, 3, b);
586 assert(get_nodes_Block(n));
592 /* Replace the Cond by a Jmp if it branches on a constant
595 a = get_Cond_selector(n);
598 if (ta && (get_irn_mode(a) == mode_b)) {
599 /* It's a boolean Cond, branching on a boolean constant.
600 Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
601 jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
602 turn_into_tuple(n, 2);
603 if (tv_val_b(ta) == 1) /* GL: I hope this returns 1 if true */ {
604 set_Tuple_pred(n, 0, new_Bad());
605 set_Tuple_pred(n, 1, jmp);
607 set_Tuple_pred(n, 0, jmp);
608 set_Tuple_pred(n, 1, new_Bad());
610 } else if (ta && (get_irn_mode(a) == mode_I)) {
611 /* I don't want to allow Tuples smaller than the biggest Proj.
612 Also this tuple might get really big...
613 I generate the Jmp here, and remember it in link. Link is used
614 when optimizing Proj. */
615 set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
616 } else if ( (get_irn_op(get_Cond_selector(n)) == op_Eor)
617 && (get_irn_mode(get_Cond_selector(n)) == mode_b)
618 && (tarval_classify(computed_value(get_Eor_right(a))) == 1)) {
619 /* The Eor is a negate. Generate a new Cond without the negate,
620 simulate the negate by exchanging the results. */
621 set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
623 } else if ( (get_irn_op(get_Cond_selector(n)) == op_Not)
624 && (get_irn_mode(get_Cond_selector(n)) == mode_b)) {
625 /* A Not before the Cond. Generate a new Cond without the Not,
626 simulate the Not by exchanging the results. */
627 set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
634 a = get_Proj_pred(n);
636 if ( (get_irn_op(a) == op_Cond)
638 && get_irn_op(get_irn_link(a)) == op_Cond) {
639 /* Use the better Cond if the Proj projs from a Cond which get's
640 its result from an Eor/Not. */
641 assert ( ( (get_irn_op(get_Cond_selector(a)) == op_Eor)
642 || (get_irn_op(get_Cond_selector(a)) == op_Not))
643 && (get_irn_mode(get_Cond_selector(a)) == mode_b)
644 && (get_irn_op(get_irn_link(a)) == op_Cond)
645 && (get_Cond_selector(get_irn_link(a)) ==
646 get_Eor_left(get_Cond_selector(a))));
647 set_Proj_pred(n, get_irn_link(a));
648 if (get_Proj_proj(n) == 0)
652 } else if ( (get_irn_op(a) == op_Cond)
653 && (get_irn_mode(get_Cond_selector(a)) == mode_I)
655 /* The Cond is a Switch on a Constant */
656 if (get_Proj_proj(n) == tv_val_CHIL(value_of(a))) {
657 /* The always taken branch, reuse the existing Jmp. */
658 if (!get_irn_link(a)) /* well, if it exists ;-> */
659 set_irn_link(a, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
660 assert(get_irn_op(get_irn_link(a)) == op_Jmp);
663 /* a never taken branch */
669 case iro_Eor: { /* @@@ not tested as boolean Eor not allowed any more. */
671 b = get_Eor_right(n);
673 if ( (get_irn_mode(n) == mode_b)
674 && (get_irn_op(a) == op_Proj)
675 && (get_irn_mode(a) == mode_b)
676 && (tarval_classify (computed_value (b)) == 1)
677 && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
678 /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
679 n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
680 mode_b, get_negated_pnc(get_Proj_proj(a)));
681 else if ( (get_irn_mode(n) == mode_b)
682 && (tarval_classify (computed_value (b)) == 1))
683 /* The Eor is a Not. Replace it by a Not. */
684 /* ????!!!Extend to bitfield 1111111. */
685 n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b);
691 if ( (get_irn_mode(n) == mode_b)
692 && (get_irn_op(a) == op_Proj)
693 && (get_irn_mode(a) == mode_b)
694 && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
695 /* We negate a Cmp. The Cmp has the negated result anyways! */
696 n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
697 mode_b, get_negated_pnc(get_Proj_proj(a)));
705 /***************** Common Subexpression Elimination *****************/
707 /* Compare function for two nodes in the hash table. Gets two */
708 /* nodes as parameters. */
709 /* @@@ a+b != b+a ? */
711 vt_cmp (const void *elt, const void *key)
719 if (a == b) return 0;
721 if ((get_irn_op(a) != get_irn_op(b)) ||
722 (get_irn_mode(a) != get_irn_mode(b))) return 1;
724 /* compare if a's in and b's in are equal */
725 /* GL: we optimize only nodes with in arrays of fixed sizes.
726 if (get_irn_arity (a) != -2) {
727 ins = get_irn_arity (a);
728 if (ins != get_irn_arity (b)) return 1;
729 ain = get_irn_in (a);
730 bin = get_irn_in (b);
733 if (get_irn_arity (a) != get_irn_arity(b))
736 /* compare a->in[0..ins] with b->in[0..ins], i.e., include the block. */
737 /* do if (*ain++ != *bin++) return 1; while (ins--); */
738 for (i = -1; i < get_irn_arity(a); i++)
739 if (get_irn_n(a, i) != get_irn_n(b, i))
743 switch (get_irn_opcode(a)) {
745 return get_irn_const_attr (a) != get_irn_const_attr (b);
747 return get_irn_proj_attr (a) != get_irn_proj_attr (b);
749 return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
750 || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
752 return (get_irn_free_attr(a) != get_irn_free_attr(b));
754 return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
755 || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
757 return (get_irn_call_attr(a)->kind != get_irn_call_attr(b)->kind)
758 || (get_irn_call_attr(a)->arity != get_irn_call_attr(b)->arity);
760 return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
761 || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
762 || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
763 || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
764 || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type)
765 || (get_irn_sel_attr(a).ltyp != get_irn_sel_attr(b).ltyp);
767 return get_irn_phi_attr (a) != get_irn_phi_attr (b);
775 ir_node_hash (ir_node *node)
780 /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
781 h = get_irn_arity(node);
783 /* consider all in nodes... except the block. */
784 for (i = 0; i < get_irn_arity(node); i++) {
785 h = 9*h + (unsigned long)get_irn_n(node, i);
789 h = 9*h + (unsigned long) get_irn_mode (node);
791 h = 9*h + (unsigned long) get_irn_op (node);
797 new_identities (void)
799 return new_pset (vt_cmp, TUNE_NIR_NODES);
803 del_identities (pset *value_table)
805 del_pset (value_table);
808 /* Return the canonical node computing the same value as n.
809 Looks up the node in a hash table. */
810 static inline ir_node *
811 identify (pset *value_table, ir_node *n)
815 if (!value_table) return n;
817 switch (get_irn_opcode (n)) {
824 /* for commutative operators perform a OP b == b OP a */
825 if (get_binop_left(n) > get_binop_right(n)) {
826 ir_node *h = get_binop_left(n);
827 set_binop_left(n, get_binop_right(n));
828 set_binop_right(n, h);
834 o = pset_find (value_table, n, ir_node_hash (n));
840 /* Return the canonical node computing the same value as n.
841 Looks up the node in a hash table, enters it in the table
842 if it isn't there yet. */
844 identify_remember (pset *value_table, ir_node *node)
848 if (!value_table) return node;
850 /* lookup or insert in hash table with given hash key. */
851 o = pset_insert (value_table, node, ir_node_hash (node));
853 if (o == node) return node;
858 /* garbage in, garbage out. If a node has a dead input, i.e., the
859 Bad node is input to the node, return the Bad node. */
860 static inline ir_node *
864 ir_op* op = get_irn_op(node);
866 /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
867 blocks predecessors is dead. */
868 if ( op != op_Block && op != op_Phi && op != op_Tuple) {
869 for (i = -1; i < get_irn_arity(node); i++) {
870 if (is_Bad(get_irn_n(node, i))) {
880 /* These optimizations deallocate nodes from the obstack.
881 It can only be called if it is guaranteed that no other nodes
882 reference this one, i.e., right after construction of a node. */
884 optimize (ir_node *n)
889 /* Allways optimize Phi nodes: part of the construction. */
890 if ((!get_optimize()) && (get_irn_op(n) != op_Phi)) return n;
892 /* if not optimize return n */
894 printf(" attention: empty node!!! \n");
898 /* constant expression evaluation / constant folding */
899 if (get_opt_constant_folding()) {
900 /* constants can not be evaluated */
901 if (get_irn_op(n) != op_Const) {
902 /* try to evaluate */
903 tv = computed_value (n);
905 /* evaluation was succesful -- replace the node. */
906 obstack_free (current_ir_graph->obst, n);
907 return new_Const (get_tv_mode (tv), tv);
912 /* remove unnecessary nodes */
913 if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
914 n = equivalent_node (n);
916 /** common subexpression elimination **/
917 /* Checks whether n is already available. */
918 /* The block input is used to distinguish different subexpressions. Right
919 now all nodes are pinned to blocks, i.e., the cse only finds common
920 subexpressions within a block. */
922 n = identify (current_ir_graph->value_table, n);
923 /* identify found a cse, so deallocate the old node. */
925 obstack_free (current_ir_graph->obst, old_n);
926 /* The AmRoq fiasco returns n here. Martin's version doesn't. */
929 /* Some more constant expression evaluation that does not allow to
931 if (get_opt_constant_folding())
932 n = transform_node (n);
934 /* Remove nodes with dead (Bad) input. */
936 /* Now we can verify the node, as it has no dead inputs any more. */
939 /* Now we have a legal, useful node. Enter it in hash table for cse */
941 n = identify_remember (current_ir_graph->value_table, n);
944 #if 0 /* GL: what's the use of this?? */
945 if ((current_ir_graph->state & irgs_building) && IR_KEEP_ALIVE (n)) {
946 assert (~current_ir_graph->state & irgs_keep_alives_in_arr);
947 pdeq_putr (current_ir_graph->keep.living, n);
954 /* These optimizations never deallocate nodes. This can cause dead
955 nodes lying on the obstack. Remove these by a dead node elimination,
956 i.e., a copying garbage collection. */
958 optimize_in_place (ir_node *n)
964 /* if not optimize return n */
966 /* Here this is possible. Why? */
970 /* constant expression evaluation / constant folding */
971 if (get_opt_constant_folding()) {
972 /* constants can not be evaluated */
973 if (get_irn_op(n) != op_Const) {
974 /* try to evaluate */
975 tv = computed_value (n);
977 /* evaluation was succesful -- replace the node. */
978 return new_Const (get_tv_mode (tv), tv);
979 /* xprintf("* optimize: computed node %I\n", n->op->name);*/
984 /* remove unnecessary nodes */
985 if (get_opt_constant_folding())
986 // if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
987 n = equivalent_node (n);
989 /** common subexpression elimination **/
990 /* Checks whether n is already available. */
991 /* The block input is used to distinguish different subexpressions. Right
992 now all nodes are pinned to blocks, i.e., the cse only finds common
993 subexpressions within a block. */
995 n = identify (current_ir_graph->value_table, n);
997 /* identify found a cse, so deallocate the old node. */
999 /* The AmRoq fiasco returns n here. Martin's version doesn't. */
1002 /* Some more constant expression evaluation. */
1003 if (get_opt_constant_folding())
1004 n = transform_node (n);
1006 /* Remove nodes with dead (Bad) input. */
1008 /* Now we can verify the node, as it has no dead inputs any more. */
1011 /* Now we have a legal, useful node. Enter it in hash table for cse */
1012 if (get_opt_cse()) {
1013 /* aborts ??! set/pset can not handle several hash tables??!
1014 No, suddenly it works. */
1015 n = identify_remember (current_ir_graph->value_table, n);