X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fcommon%2Firtools.c;h=5accaf5d01c76421629437697433d19de7bb4cbf;hb=86d52903da8846456936ce528f72a0d738861a73;hp=0ada1157f1691d18a7ef908c0750a80db1a7423d;hpb=ddfcdcb1227bd6fb6720f8485dc62995f7bfd98f;p=libfirm diff --git a/ir/common/irtools.c b/ir/common/irtools.c index 0ada1157f..5accaf5d0 100644 --- a/ir/common/irtools.c +++ b/ir/common/irtools.c @@ -1,5 +1,5 @@ /* - * 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. * @@ -21,7 +21,6 @@ * @file * @brief Some often needed tool-functions * @author Michael Beck - * @version $Id$ */ #include "config.h" @@ -33,15 +32,16 @@ #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)) @@ -50,24 +50,31 @@ void firm_clear_node_and_phi_links(ir_node *n, void *env) { 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); @@ -111,136 +118,94 @@ copy_irn_to_irg(ir_node *n, ir_graph *irg) { /* 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. 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); + /* copy the attributes */ + copy_node_attr(irg, node, 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_graph_wrapper(ir_graph *irg, void *context) { - void (*function)(ir_graph *irg) = context; - function(irg); - return 0; -} /* void_graph_wrapper */ - -/* Creates an ir_graph pass for running void function(ir_graph *irg). */ -ir_graph_pass_t *def_graph_pass( - const char *name, 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); - - pass->kind = k_ir_graph_pass; - pass->run_on_irg = void_graph_wrapper; - pass->context = function; - pass->name = name; - - INIT_LIST_HEAD(&pass->list); - - return pass; -} /* def_graph_pass */ + return (ir_node*) get_irn_link(old_node); +} -/** - * Wrapper for running void function(ir_graph *irg) as an ir_graph pass. - */ -static int int_graph_wrapper(ir_graph *irg, void *context) { - int (*function)(ir_graph *irg) = context; - return function(irg); -} /* int_graph_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)) +void irn_rewire_inputs(ir_node *node) { - struct ir_graph_pass_t *pass = XMALLOCZ(ir_graph_pass_t); - - pass->kind = k_ir_graph_pass; - pass->run_on_irg = int_graph_wrapper; - pass->context = function; - pass->name = name; + ir_node *new_node; + int arity; + int i; - INIT_LIST_HEAD(&pass->list); + new_node = get_new_node(node); - return pass; -} /* def_graph_pass_ret */ + 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(void) as an ir_prog pass. - */ -static int void_prog_wrapper(ir_prog *irp, void *context) { - void (*function)(void) = context; - - (void)irp; - function(); - return 0; -} /* void_graph_wrapper */ - -/* Creates an ir_prog pass for running void function(void). */ -ir_prog_pass_t *def_prog_pass( - const char *name, - void (*function)(void)) -{ - struct ir_prog_pass_t *pass = XMALLOCZ(ir_prog_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_irprog = void_prog_wrapper; - pass->context = function; - pass->name = name; + /* 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_prog_pass */ + foreach_pset(set, void*, obj) { + ir_fprintf(stderr, "%+F\n", obj); + } +}