/*
- * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
#include "irtools.h"
#include "irprintf.h"
#include "irpass_t.h"
+#include "iropt_t.h"
-/* the famous clear_link implementation. */
-void firm_clear_link(ir_node *n, void *env) {
+void firm_clear_link(ir_node *n, void *env)
+{
(void) env;
set_irn_link(n, NULL);
}
-/* the famous clear_node_and_phi_links() implementation. */
-void firm_clear_node_and_phi_links(ir_node *n, void *env) {
+void firm_clear_node_and_phi_links(ir_node *n, void *env)
+{
(void) env;
set_irn_link(n, NULL);
if (is_Block(n))
set_Phi_next(n, NULL);
}
-/*
- * Copies a node to a new irg. The Ins of the new node point to
- * the predecessors on the old irg. n->link points to the new node.
- *
- * Does NOT copy standard nodes like Start, End etc that are fixed
- * in an irg. Instead, the corresponding nodes of the new irg are returned.
- * Note further, that the new nodes have no block.
- */
-void
-copy_irn_to_irg(ir_node *n, ir_graph *irg) {
+void firm_clear_block_phis(ir_node *node, void *env)
+{
+ (void) env;
+ if (is_Block(node)) {
+ set_Block_phis(node, NULL);
+ } else if (is_Phi(node)) {
+ set_Phi_next(node, NULL);
+ }
+}
+
+void firm_collect_block_phis(ir_node *node, void *env)
+{
+ (void) env;
+ if (is_Phi(node))
+ add_Block_phi(get_nodes_block(node), node);
+}
+
+void copy_irn_to_irg(ir_node *n, ir_graph *irg)
+{
ir_op *op = get_irn_op(n);
ir_graph *old_irg;
ir_node *nn = NULL;
/* do not copy standard nodes */
- if (op == op_Bad)
- nn = get_irg_bad(irg);
- else if (op == op_NoMem)
+ if (op == op_NoMem)
n = get_irg_no_mem(irg);
else if (op == op_Block) {
old_irg = get_irn_irg(n);
/* Copy the attributes. These might point to additional data. If this
was allocated on the old obstack the pointers now are dangling. This
frees e.g. the memory of the graph_arr allocated in new_immBlock. */
- copy_node_attr(n, nn);
- new_backedge_info(nn);
+ copy_node_attr(irg, n, nn);
set_irn_link(n, nn);
- /* fix the irg for blocks */
- if (is_Block(nn)) {
+ /* fix the irg for nodes containing a reference to it */
+ if (ir_has_irg_ref(nn)) {
nn->attr.block.irg.irg = irg;
-
- /* we cannot allow blocks WITHOUT macroblock input */
- set_Block_MacroBlock(nn, get_Block_MacroBlock(n));
}
}
-/*
- * Creates an exact copy of a node.
- * The copy resides in the same graph in the same block.
- */
-ir_node *exact_copy(const ir_node *n) {
- ir_graph *irg = get_irn_irg(n);
- ir_node *res, *block = NULL;
-
- if (is_no_Block(n))
- block = get_nodes_block(n);
-
- res = new_ir_node(get_irn_dbg_info(n),
- irg,
- block,
- get_irn_op(n),
- get_irn_mode(n),
- get_irn_arity(n),
- get_irn_in(n) + 1);
+ir_node *irn_copy_into_irg(const ir_node *node, ir_graph *irg)
+{
+ ir_node *block = NULL;
+ ir_op *op = get_irn_op(node);
+ int arity = get_irn_arity(node);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_mode *mode = get_irn_mode(node);
+ ir_node *res;
+ int n_deps;
+ int i;
+
+ if (op != op_Block)
+ block = get_nodes_block(node);
+
+ if (op->opar == oparity_dynamic) {
+ int i;
+ res = new_ir_node(dbgi, irg, block, op, mode, -1, NULL);
+ for (i = 0; i < arity; ++i) {
+ ir_node *in = get_irn_n(node, i);
+ add_irn_n(res, in);
+ }
+ } else {
+ ir_node **ins = get_irn_in(node)+1;
+ res = new_ir_node(dbgi, irg, block, op, mode, arity, ins);
+ }
+ /* copy the attributes */
+ copy_node_attr(irg, node, res);
- /* Copy the attributes. These might point to additional data. If this
- was allocated on the old obstack the pointers now are dangling. This
- frees e.g. the memory of the graph_arr allocated in new_immBlock. */
- copy_node_attr(n, res);
- new_backedge_info(res);
-
- if (is_Block(n)) {
- set_Block_MacroBlock(res, get_Block_MacroBlock(n));
+ /* duplicate dependency edges */
+ n_deps = get_irn_deps(node);
+ for (i = 0; i < n_deps; ++i) {
+ ir_node *dep = get_irn_dep(node, i);
+ add_irn_dep(res, dep);
}
+
return res;
}
-/*
- * Dump a pset containing Firm objects.
- */
-void firm_pset_dump(pset *set) {
- void *obj;
-
- foreach_pset(set, obj) {
- ir_fprintf(stderr, "%+F\n", obj);
- }
+ir_node *exact_copy(const ir_node *node)
+{
+ return irn_copy_into_irg(node, get_irn_irg(node));
}
-/**
- * Wrapper for running void function(ir_graph *irg) as an ir_graph pass.
- */
-static int void_pass_wrapper(ir_graph *irg, void *context) {
- void (*function)(ir_graph *irg) = context;
- function(irg);
- return 0;
-} /* void_pass_wrapper */
-
-/* Creates an ir_graph pass for running void function(ir_graph *irg). */
-ir_graph_pass_t *def_graph_pass(
- const char *name, int verify, int dump,
- void (*function)(ir_graph *irg))
+static ir_node *get_new_node(const ir_node *old_node)
{
- struct ir_graph_pass_t *pass = XMALLOCZ(ir_graph_pass_t);
+ return (ir_node*) get_irn_link(old_node);
+}
- pass->kind = k_ir_prog_pass;
- pass->run_on_irg = void_pass_wrapper;
- pass->context = function;
- pass->name = name;
- pass->verify = verify != 0;
- pass->dump = dump != 0;
+void irn_rewire_inputs(ir_node *node)
+{
+ ir_node *new_node;
+ int arity;
+ int i;
- INIT_LIST_HEAD(&pass->list);
+ new_node = get_new_node(node);
- return pass;
-} /* def_graph_pass */
+ if (!is_Block(node)) {
+ ir_node *block = get_nodes_block(node);
+ ir_node *new_block = get_new_node(block);
+ set_nodes_block(new_node, new_block);
+ }
-/**
- * Wrapper for running void function(ir_graph *irg) as an ir_graph pass.
- */
-static int int_pass_wrapper(ir_graph *irg, void *context) {
- int (*function)(ir_graph *irg) = context;
- return function(irg);
-} /* int_pass_wrapper */
-
-/* Creates an ir_graph pass for running void function(ir_graph *irg). */
-ir_graph_pass_t *def_graph_pass_ret(
- const char *name, int verify, int dump,
- int (*function)(ir_graph *irg))
-{
- struct ir_graph_pass_t *pass = XMALLOCZ(ir_graph_pass_t);
+ arity = get_irn_arity(new_node);
+ for (i = 0; i < arity; ++i) {
+ ir_node *in = get_irn_n(node, i);
+ ir_node *new_in = get_new_node(in);
+ set_irn_n(new_node, i, new_in);
+ }
- pass->kind = k_ir_prog_pass;
- pass->run_on_irg = int_pass_wrapper;
- pass->context = function;
- pass->name = name;
- pass->verify = verify != 0;
- pass->dump = dump != 0;
+ /* Now the new node is complete. We can add it to the hash table for CSE. */
+ add_identities(new_node);
+}
- INIT_LIST_HEAD(&pass->list);
+void firm_pset_dump(pset *set)
+{
+ void *obj;
- return pass;
-} /* def_graph_pass_ret */
+ foreach_pset(set, void*, obj) {
+ ir_fprintf(stderr, "%+F\n", obj);
+ }
+}