** iropt --- optimizations intertwined with IR construction.
*/
-# include "iropt.h"
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+# include "irnode_t.h"
+# include "irgraph_t.h"
+# include "iropt_t.h"
# include "ircons.h"
# include "irgmod.h"
# include "irvrfy.h"
# include "tv.h"
+# include "tune.h"
+# include "debinfo.h"
/* Make types visible to allow most efficient access */
# include "entity_t.h"
calls the optimization. */
assert(get_Block_matured(n));
- /* a single entry Block following a single exit Block can be merged */
+ /* A single entry Block following a single exit Block can be merged,
+ if it is not the Start block. */
/* !!! Beware, all Phi-nodes of n must have been optimized away.
- This is true, as the block is matured before optimize is called. */
+ This should be true, as the block is matured before optimize is called.
+ But what about Phi-cycles with the Phi0/Id that could not be resolved? */
if (get_Block_n_cfgpreds(n) == 1
&& get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) {
n = get_nodes_Block(get_Block_cfgpred(n, 0));
- } else if (n != current_ir_graph->start_block) {
+ } else if ((n != current_ir_graph->start_block) &&
+ (n != current_ir_graph->end_block) ) {
int i;
/* If all inputs are dead, this block is dead too, except if it is
- the start block. This is a step of unreachable code elimination */
+ the start or end block. This is a step of unreachable code
+ elimination */
for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
if (!is_Bad(get_Block_cfgpred(n, i))) break;
}
themselves.
*/
int i, n_preds;
+
+
ir_node *block = NULL; /* to shutup gcc */
ir_node *first_val = NULL; /* to shutup gcc */
ir_node *scnd_val = NULL; /* to shutup gcc */
}
}
#endif
+
/* Find first non-self-referencing input */
for (i = 0; i < n_preds; ++i) {
first_val = follow_Id(get_Phi_pred(n, i));
}
/* A totally Bad or self-referencing Phi (we didn't break the above loop) */
- if (i > n_preds) { n = new_Bad(); break; }
+ if (i >= n_preds) { n = new_Bad(); break; }
scnd_val = NULL;
}
/* Fold, if no multiple distinct non-self-referencing inputs */
- if (i > n_preds) {
- n = a;
+ if (i >= n_preds) {
+ n = first_val;
} else {
/* skip the remaining Ids. */
while (++i < n_preds) {
return n;
}
-/***************** Common Subexpression Elimination *****************/
+/* **************** Common Subexpression Elimination **************** */
/* Compare function for two nodes in the hash table. Gets two */
/* nodes as parameters. */
return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
|| (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
case iro_Call:
- return (get_irn_call_attr(a)->kind != get_irn_call_attr(b)->kind)
- || (get_irn_call_attr(a)->arity != get_irn_call_attr(b)->arity);
+ return (get_irn_call_attr(a) != get_irn_call_attr(b));
case iro_Sel:
return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
|| (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
if ( op != op_Block && op != op_Phi && op != op_Tuple) {
for (i = -1; i < get_irn_arity(node); i++) {
if (is_Bad(get_irn_n(node, i))) {
- node = new_Bad();
- break;
+ return new_Bad();
}
}
}
+#if 0
+ /* If Block has only Bads as predecessors it's garbage. */
+ /* If Phi has only Bads as predecessors it's garbage. */
+ if (op == op_Block || op == op_Phi) {
+ for (i = 0; i < get_irn_arity(node); i++) {
+ if (!is_Bad(get_irn_n(node, i))) break;
+ }
+ if (i = get_irn_arity(node)) node = new_Bad();
+ }
+#endif
return node;
}
ir_node *
optimize_in_place (ir_node *n)
{
-
tarval *tv;
ir_node *old_n = n;
+ if (!get_optimize()) return n;
+
/* if not optimize return n */
if (n == NULL) {
/* Here this is possible. Why? */
tv = computed_value (n);
if (tv != NULL) {
/* evaluation was succesful -- replace the node. */
- return new_Const (get_tv_mode (tv), tv);
+ n = new_Const (get_tv_mode (tv), tv);
+ deb_info_copy(n, old_n, id_from_str("const_eval", 10));
+ return n;
/* xprintf("* optimize: computed node %I\n", n->op->name);*/
}
}
}
/* remove unnecessary nodes */
- if (get_opt_constant_folding())
- // if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
+ /*if (get_opt_constant_folding()) */
+ if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
n = equivalent_node (n);
/** common subexpression elimination **/
/* Now we can verify the node, as it has no dead inputs any more. */
irn_vrfy(n);
- /* Now we have a legal, useful node. Enter it in hash table for cse */
- if (get_opt_cse()) {
- /* aborts ??! set/pset can not handle several hash tables??!
- No, suddenly it works. */
+ /* Now we have a legal, useful node. Enter it in hash table for cse.
+ Blocks should be unique anyways. (Except the successor of start:
+ is cse with the start block!) */
+ if (get_opt_cse() && (get_irn_opcode(n) != iro_Block))
n = identify_remember (current_ir_graph->value_table, n);
- }
return n;
}