#include "irgraph_t.h"
#include "irprog_t.h"
-#include "ircons.h"
+#include "iroptimize.h"
+#include "ircons_t.h"
#include "iropt_t.h"
-#include "cfopt.h"
#include "irgopt.h"
#include "irgmod.h"
#include "irgwalk.h"
*/
static void optimize_in_place_wrapper (ir_node *n, void *env) {
ir_node *optimized = optimize_in_place_2(n);
- if (optimized != n) exchange (n, optimized);
+ (void) env;
+
+ if (optimized != n) {
+ exchange (n, optimized);
+ }
}
/**
* Block-Walker: uses dominance depth to mark dead blocks.
*/
static void kill_dead_blocks(ir_node *block, void *env) {
+ (void) env;
+
if (get_Block_dom_depth(block) < 0) {
/*
* Note that the new dominance code correctly handles
* Copies new predecessors of old node to new node remembered in link.
* Spare the Bad predecessors of Phi and Block nodes.
*/
-void
-copy_preds(ir_node *n, void *env) {
+static void copy_preds(ir_node *n, void *env) {
ir_node *nn, *block;
int i, j, irn_arity;
+ (void) env;
nn = get_new_node(n);
/* Note: from yet, the visited flag of the graph is equal to vfl + 1 */
/* visit the anchors as well */
- for (i = anchor_max - 1; i >= 0; --i) {
- ir_node *n = irg->anchors[i];
+ for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
+ ir_node *n = get_irg_anchor(irg, i);
if (n && (get_irn_visited(n) <= vfl)) {
set_irg_visited(irg, vfl);
static void
copy_graph_env(int copy_node_nr) {
ir_graph *irg = current_ir_graph;
- ir_node *old_end, *n;
+ ir_node *old_end, *new_anchor;
int i;
/* remove end_except and end_reg nodes */
/* Not all nodes remembered in irg might be reachable
from the end node. Assure their link is set to NULL, so that
we can test whether new nodes have been computed. */
- for (i = anchor_max - 1; i >= 0; --i) {
- if (irg->anchors[i])
- set_new_node(irg->anchors[i], NULL);
+ for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
+ ir_node *n = get_irg_anchor(irg, i);
+ if (n != NULL)
+ set_new_node(n, NULL);
}
/* we use the block walk flag for removing Bads from Blocks ins. */
inc_irg_block_visited(irg);
/* copy the graph */
copy_graph(irg, copy_node_nr);
- /* fix the fields in irg */
- old_end = get_irg_end(irg);
- for (i = anchor_max - 1; i >= 0; --i) {
- n = irg->anchors[i];
+ /* fix the anchor */
+ old_end = get_irg_end(irg);
+ new_anchor = new_Anchor(irg);
+
+ for (i = get_irg_n_anchors(irg) - 1; i >= 0; --i) {
+ ir_node *n = get_irg_anchor(irg, i);
if (n)
- irg->anchors[i] = get_new_node(n);
+ set_irn_n(new_anchor, i, get_new_node(n));
}
free_End(old_end);
+ irg->anchor = new_anchor;
+
+ /* ensure the new anchor is placed in the endblock */
+ set_irn_n(new_anchor, -1, get_irg_end_block(irg));
}
/**
static void relink_bad_block_predecessors(ir_node *n, void *env) {
ir_node **new_in, *irn;
int i, new_irn_n, old_irn_arity, new_irn_arity = 0;
+ (void) env;
/* if link field of block is NULL, look for bad predecessors otherwise
this is already done */
static void dead_node_hook(void *context, ir_graph *irg, int start) {
survive_dce_t *sd = context;
+ (void) irg;
/* Create a new map before the dead node elimination is performed. */
if (start) {
static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw) {
survive_dce_t *sd = context;
survive_dce_list_t *list = pmap_get(sd->places, old);
+ (void) irg;
/* If the node is to be patched back, write the new address to all registered locations. */
if (list) {
/* -- Performing dead node elimination inlines the graph -- */
/* Copies the nodes to the obstack of current_ir_graph. Updates links to new
entities. */
- /* @@@ endless loops are not copied!! -- they should be, I think... */
irg_walk(get_irg_end(called_graph), copy_node_inline, copy_preds,
get_irg_frame_type(called_graph));
/* -- archive keepalives -- */
irn_arity = get_irn_arity(end);
- for (i = 0; i < irn_arity; i++)
- add_End_keepalive(get_irg_end(current_ir_graph), get_irn_n(end, i));
+ for (i = 0; i < irn_arity; i++) {
+ ir_node *ka = get_End_keepalive(end, i);
+ if (! is_Bad(ka))
+ add_End_keepalive(get_irg_end(current_ir_graph), ka);
+ }
/* The new end node will die. We need not free as the in array is on the obstack:
copy_node() only generated 'D' arrays. */
}
}
+/* deepest common ancestor in the dominator tree of all nodes'
+ blocks depending on us; our final placement has to dominate DCA. */
+static ir_node *get_deepest_common_ancestor(ir_node *node, ir_node *dca)
+{
+ int i;
+
+ for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
+ ir_node *succ = get_irn_out(node, i);
+ ir_node *succ_blk;
+
+ if (is_End(succ)) {
+ /*
+ * This consumer is the End node, a keep alive edge.
+ * This is not a real consumer, so we ignore it
+ */
+ continue;
+ }
+
+ if(is_Proj(succ)) {
+ dca = get_deepest_common_ancestor(succ, dca);
+ } else {
+ /* ignore if succ is in dead code */
+ succ_blk = get_irn_n(succ, -1);
+ if (is_Block_unreachable(succ_blk))
+ continue;
+ dca = consumer_dom_dca(dca, succ, node);
+ }
+ }
+
+ return dca;
+}
+
+static void set_projs_block(ir_node *node, ir_node *block)
+{
+ int i;
+
+ for (i = get_irn_n_outs(node) - 1; i >= 0; --i) {
+ ir_node *succ = get_irn_out(node, i);
+
+ assert(is_Proj(succ));
+
+ if(get_irn_mode(succ) == mode_T) {
+ set_projs_block(succ, block);
+ }
+ set_nodes_block(succ, block);
+ }
+}
+
/**
* Find the latest legal block for N and place N into the
* `optimal' Block between the latest and earliest legal block.
(op != op_SymConst) &&
(op != op_Proj))
{
- ir_node *dca = NULL; /* deepest common ancestor in the
- dominator tree of all nodes'
- blocks depending on us; our final
- placement has to dominate DCA. */
- for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
- ir_node *succ = get_irn_out(n, i);
- ir_node *succ_blk;
-
- if (get_irn_op(succ) == op_End) {
- /*
- * This consumer is the End node, a keep alive edge.
- * This is not a real consumer, so we ignore it
- */
- continue;
- }
-
- /* ignore if succ is in dead code */
- succ_blk = get_irn_n(succ, -1);
- if (is_Block_unreachable(succ_blk))
- continue;
- dca = consumer_dom_dca(dca, succ, n);
- }
- if (dca) {
+ /* deepest common ancestor in the dominator tree of all nodes'
+ blocks depending on us; our final placement has to dominate
+ DCA. */
+ ir_node *dca = get_deepest_common_ancestor(n, NULL);
+ if (dca != NULL) {
set_nodes_block(n, dca);
move_out_of_loops(n, early_blk);
+ if(get_irn_mode(n) == mode_T) {
+ set_projs_block(n, get_nodes_block(n));
+ }
}
}
}