X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firnode.c;h=d4e9c683a1a0e83b05917ee80c20baa624142f79;hb=8afc2ffa646f8d7510c014b8179b812c7ca9a769;hp=ace85a92972231736f276205fc0fa2750f19369d;hpb=de97549df292e264a71eabdf04b7ea7ffa1c6afa;p=libfirm diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index ace85a929..d4e9c683a 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -11,9 +11,12 @@ */ #ifdef HAVE_CONFIG_H -# include +# include "config.h" +#endif + +#ifdef HAVE_STRING_H +# include #endif -#include #include "ident.h" #include "irnode_t.h" @@ -24,8 +27,9 @@ #include "irdump.h" #include "irop_t.h" #include "irprog_t.h" +#include "iredges_t.h" -#include "firmstat.h" +#include "irhooks.h" /* some constants fixing the positions of nodes predecessors in the in array */ @@ -84,9 +88,34 @@ const char *symconst_name_arr [] = { "type_tag", "size", "addr_name", "addr_ent" }; +/** + * Indicates, whether additional data can be registered to ir nodes. + * If set to 1, this is not possible anymore. + */ +static int forbid_new_data = 0; + +/** + * The amount of additional space for custom data to be allocated upon + * creating a new node. + */ +unsigned firm_add_node_size = 0; + + +/* register new space for every node */ +unsigned register_additional_node_data(unsigned size) { + assert(!forbid_new_data && "Too late to register additional node data"); + + if (forbid_new_data) + return 0; + + return firm_add_node_size += size; +} + + void -init_irnode (void) -{ +init_irnode(void) { + /* Forbid the addition of new data to an ir node. */ + forbid_new_data = 1; } /* @@ -100,11 +129,13 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo int arity, ir_node **in) { ir_node *res; - int node_size = offsetof (ir_node, attr) + op->attr_size; + size_t node_size = offsetof(ir_node, attr) + op->attr_size + firm_add_node_size; + char *p; assert(irg && op && mode); - res = (ir_node *) obstack_alloc (irg->obst, node_size); - memset((void *)res, 0, node_size); + p = obstack_alloc (irg->obst, node_size); + memset(p, 0, node_size); + res = (ir_node *) (p + firm_add_node_size); res->kind = k_ir_node; res->op = op; @@ -117,6 +148,7 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1)); memcpy (&res->in[1], in, sizeof (ir_node *) * arity); } + res->in[0] = block; set_irn_dbg_info(res, db); res->out = NULL; @@ -125,41 +157,45 @@ new_ir_node (dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mo res->node_nr = get_irp_new_node_nr(); #endif - stat_new_node(res); +#ifdef FIRM_EDGES_INPLACE + { + int i, n; + int not_a_block = !is_Block(res); - return res; -} + INIT_LIST_HEAD(&res->edge_info.outs_head); -/* Copies all attributes stored in the old node to the new node. - Assumes both have the same opcode and sufficient size. */ -void -copy_attrs (const ir_node *old_node, ir_node *new_node) { - assert(get_irn_op(old_node) == get_irn_op(new_node)); - memcpy(&new_node->attr, &old_node->attr, get_op_attr_size(get_irn_op(old_node))); + for(i = 0, n = arity + not_a_block; i < n; ++i) + edges_notify_edge(res, i - not_a_block, res->in[i], NULL, irg); + } +#endif + + hook_new_node(irg, res); + + return res; } /*-- getting some parameters from ir_nodes --*/ int (is_ir_node)(const void *thing) { - return __is_ir_node(thing); + return _is_ir_node(thing); } int (get_irn_intra_arity)(const ir_node *node) { - return __get_irn_intra_arity(node); + return _get_irn_intra_arity(node); } int (get_irn_inter_arity)(const ir_node *node) { - return __get_irn_inter_arity(node); + return _get_irn_inter_arity(node); } -int (*__get_irn_arity)(const ir_node *node) = __get_irn_intra_arity; +int (*_get_irn_arity)(const ir_node *node) = _get_irn_intra_arity; int (get_irn_arity)(const ir_node *node) { - return __get_irn_arity(node); + return _get_irn_arity(node); } /* Returns the array with ins. This array is shifted with respect to the @@ -209,26 +245,29 @@ set_irn_in (ir_node *node, int arity, ir_node **in) { } ir_node * -(get_irn_intra_n)(ir_node *node, int n) { - return __get_irn_intra_n (node, n); +(get_irn_intra_n)(const ir_node *node, int n) { + return _get_irn_intra_n (node, n); } ir_node * -(get_irn_inter_n)(ir_node *node, int n) { - return __get_irn_inter_n (node, n); +(get_irn_inter_n)(const ir_node *node, int n) { + return _get_irn_inter_n (node, n); } -ir_node *(*__get_irn_n)(ir_node *node, int n) = __get_irn_intra_n; +ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n; ir_node * -(get_irn_n)(ir_node *node, int n) { - return __get_irn_n(node, n); +(get_irn_n)(const ir_node *node, int n) { + return _get_irn_n(node, n); } void set_irn_n (ir_node *node, int n, ir_node *in) { - assert(node && node->kind == k_ir_node && -1 <= n && n < get_irn_arity(node)); + assert(node && node->kind == k_ir_node); + assert(-1 <= n); + assert(n < get_irn_arity(node)); assert(in && in->kind == k_ir_node); + if ((n == -1) && (get_irn_opcode(node) == iro_Filter)) { /* Change block pred in both views! */ node->in[n + 1] = in; @@ -247,18 +286,27 @@ set_irn_n (ir_node *node, int n, ir_node *in) { } /* else fall through */ } + + /* Call the hook */ + hook_set_irn_n(node, n, in, node->in[n + 1]); + +#ifdef FIRM_EDGES_INPLACE + /* Here, we rely on src and tgt being in the current ir graph */ + edges_notify_edge(node, n, in, node->in[n + 1], current_ir_graph); +#endif + node->in[n + 1] = in; } ir_mode * (get_irn_mode)(const ir_node *node) { - return __get_irn_mode(node); + return _get_irn_mode(node); } void (set_irn_mode)(ir_node *node, ir_mode *mode) { - __set_irn_mode(node, mode); + _set_irn_mode(node, mode); } modecode @@ -286,7 +334,7 @@ get_irn_modeident (const ir_node *node) ir_op * (get_irn_op)(const ir_node *node) { - return __get_irn_op(node); + return _get_irn_op(node); } /* should be private to the library: */ @@ -300,7 +348,7 @@ set_irn_op (ir_node *node, ir_op *op) opcode (get_irn_opcode)(const ir_node *node) { - return __get_irn_opcode(node); + return _get_irn_opcode(node); } const char * @@ -323,43 +371,43 @@ get_irn_opident (const ir_node *node) unsigned long (get_irn_visited)(const ir_node *node) { - return __get_irn_visited(node); + return _get_irn_visited(node); } void (set_irn_visited)(ir_node *node, unsigned long visited) { - __set_irn_visited(node, visited); + _set_irn_visited(node, visited); } void (mark_irn_visited)(ir_node *node) { - __mark_irn_visited(node); + _mark_irn_visited(node); } int (irn_not_visited)(const ir_node *node) { - return __irn_not_visited(node); + return _irn_not_visited(node); } int (irn_visited)(const ir_node *node) { - return __irn_visited(node); + return _irn_visited(node); } void (set_irn_link)(ir_node *node, void *link) { - __set_irn_link(node, link); + _set_irn_link(node, link); } void * (get_irn_link)(const ir_node *node) { - return __get_irn_link(node); + return _get_irn_link(node); } op_pin_state (get_irn_pinned)(const ir_node *node) { - return __get_irn_pinned(node); + return _get_irn_pinned(node); } void set_irn_pinned(ir_node *node, op_pin_state state) { @@ -367,7 +415,7 @@ void set_irn_pinned(ir_node *node, op_pin_state state) { if (get_irn_op(node) == op_Tuple) return; - assert(node && get_op_pinned(get_irn_op(node)) == op_pin_state_exc_pinned); + assert(node && get_op_pinned(get_irn_op(node)) >= op_pin_state_exc_pinned); assert(state == op_pin_state_pinned || state == op_pin_state_floats); node->attr.except.pin_state = state; @@ -389,6 +437,12 @@ struct section *firm_get_irn_section(ir_node *n) { void firm_set_irn_section(ir_node *n, struct section *s) { n->sec = s; } +#else +/* Dummies needed for firmjni. */ +struct abstval *get_irn_abst_value(ir_node *n) { return NULL; } +void set_irn_abst_value(ir_node *n, struct abstval *os) {} +struct section *firm_get_irn_section(ir_node *n) { return NULL; } +void firm_set_irn_section(ir_node *n, struct section *s) {} #endif /* DO_HEAPANALYSIS */ @@ -424,11 +478,11 @@ get_irn_alloc_attr (ir_node *node) return node->attr.a; } -type * +free_attr get_irn_free_attr (ir_node *node) { assert (node->op == op_Free); - return node->attr.f = skip_tid(node->attr.f); + return node->attr.f; } symconst_attr @@ -445,13 +499,6 @@ get_irn_call_attr (ir_node *node) return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp); } -type * -get_irn_funccall_attr (ir_node *node) -{ - assert (node->op == op_FuncCall); - return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp); -} - sel_attr get_irn_sel_attr (ir_node *node) { @@ -491,7 +538,7 @@ except_attr get_irn_except_attr (ir_node *node) { assert (node->op == op_Div || node->op == op_Quot || - node->op == op_DivMod || node->op == op_Mod); + node->op == op_DivMod || node->op == op_Mod || node->op == op_Call || node->op == op_Alloc); return node->attr.except; } @@ -499,7 +546,7 @@ get_irn_except_attr (ir_node *node) /* this works for all except Block */ ir_node * -get_nodes_block (ir_node *node) { +get_nodes_block (const ir_node *node) { assert (!(node->op == op_Block)); return get_irn_n(node, -1); } @@ -566,9 +613,8 @@ get_Block_n_cfgpreds (ir_node *node) { ir_node * get_Block_cfgpred (ir_node *node, int pos) { - assert(node); - assert (node->op == op_Block); assert(-1 <= pos && pos < get_irn_arity(node)); + assert(node->op == op_Block); return get_irn_n(node, pos); } @@ -671,6 +717,14 @@ void remove_Block_cg_cfgpred_arr(ir_node * node) { node->attr.block.in_cg = NULL; } +ir_node *(set_Block_dead)(ir_node *block) { + return _set_Block_dead(block); +} + +int (is_Block_dead)(const ir_node *block) { + return _is_Block_dead(block); +} + void set_Start_irg(ir_node *node, ir_graph *irg) { assert(node->op == op_Start); @@ -845,9 +899,8 @@ set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) { set_irn_n(node, 1, exo_ptr); } -tarval *get_Const_tarval (ir_node *node) { - assert (node->op == op_Const); - return node->attr.con.tv; +tarval *(get_Const_tarval)(ir_node *node) { + return _get_Const_tarval(node); } void @@ -856,6 +909,11 @@ set_Const_tarval (ir_node *node, tarval *con) { node->attr.con.tv = con; } +cnst_classify_t (classify_Const)(ir_node *node) +{ + return _classify_Const(node); +} + /* The source language type. Must be an atomic type. Mode of type must be mode of node. For tarvals from entities type must be pointer to @@ -869,7 +927,7 @@ get_Const_type (ir_node *node) { void set_Const_type (ir_node *node, type *tp) { assert (node->op == op_Const); - if (tp != unknown_type) { + if (tp != firm_unknown_type) { assert (is_atomic_type(tp)); assert (get_type_mode(tp) == get_irn_mode(node)); } @@ -1137,7 +1195,7 @@ get_Call_type (ir_node *node) { void set_Call_type (ir_node *node, type *tp) { assert (node->op == op_Call); - assert ((get_unknown_type() == tp) || is_method_type(tp)); + assert ((get_unknown_type() == tp) || is_Method_type(tp)); node->attr.call.cld_tp = tp; } @@ -1187,95 +1245,6 @@ void set_CallBegin_call (ir_node *node, ir_node *call) { node->attr.callbegin.call = call; } -ir_node * -get_FuncCall_ptr (ir_node *node) { - assert (node->op == op_FuncCall); - return get_irn_n(node, 0); -} - -void -set_FuncCall_ptr (ir_node *node, ir_node *ptr) { - assert (node->op == op_FuncCall); - set_irn_n(node, 0, ptr); -} - -ir_node ** -get_FuncCall_param_arr (ir_node *node) { - assert (node->op == op_FuncCall); - return (ir_node **)&get_irn_in(node)[FUNCCALL_PARAM_OFFSET]; -} - -int -get_FuncCall_n_params (ir_node *node) { - assert (node->op == op_FuncCall); - return (get_irn_arity(node) - FUNCCALL_PARAM_OFFSET); -} - -int -get_FuncCall_arity (ir_node *node) { - assert (node->op == op_FuncCall); - return get_FuncCall_n_params(node); -} - -/* void -set_FuncCall_arity (ir_node *node, ir_node *arity) { - assert (node->op == op_FuncCall); -} -*/ - -ir_node * -get_FuncCall_param (ir_node *node, int pos) { - assert (node->op == op_FuncCall); - return get_irn_n(node, pos + FUNCCALL_PARAM_OFFSET); -} - -void -set_FuncCall_param (ir_node *node, int pos, ir_node *param) { - assert (node->op == op_FuncCall); - set_irn_n(node, pos + FUNCCALL_PARAM_OFFSET, param); -} - -type * -get_FuncCall_type (ir_node *node) { - assert (node->op == op_FuncCall); - return node->attr.call.cld_tp = skip_tid(node->attr.call.cld_tp); -} - -void -set_FuncCall_type (ir_node *node, type *tp) { - assert (node->op == op_FuncCall); - assert (is_method_type(tp)); - node->attr.call.cld_tp = tp; -} - -int FuncCall_has_callees(ir_node *node) { - return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) && - (node->attr.call.callee_arr != NULL)); -} - -int get_FuncCall_n_callees(ir_node * node) { - assert(node->op == op_FuncCall && node->attr.call.callee_arr); - return ARR_LEN(node->attr.call.callee_arr); -} - -entity * get_FuncCall_callee(ir_node * node, int pos) { - assert(node->op == op_FuncCall && node->attr.call.callee_arr); - return node->attr.call.callee_arr[pos]; -} - -void set_FuncCall_callee_arr(ir_node * node, int n, entity ** arr) { - assert(node->op == op_FuncCall); - if (node->attr.call.callee_arr == NULL || get_Call_n_callees(node) != n) { - node->attr.call.callee_arr = NEW_ARR_D(entity *, current_ir_graph->obst, n); - } - memcpy(node->attr.call.callee_arr, arr, n * sizeof(entity *)); -} - -void remove_FuncCall_callee_arr(ir_node * node) { - assert(node->op == op_FuncCall); - node->attr.call.callee_arr = NULL; -} - #define BINOP(OP) \ ir_node * get_##OP##_left(ir_node *node) { \ @@ -1392,7 +1361,7 @@ set_Cast_type (ir_node *node, type *to_tp) { int (is_unop)(const ir_node *node) { - return __is_unop(node); + return _is_unop(node); } ir_node * @@ -1414,7 +1383,7 @@ set_unop_op (ir_node *node, ir_node *op) { int (is_binop)(const ir_node *node) { - return __is_binop(node); + return _is_binop(node); } ir_node * @@ -1451,7 +1420,7 @@ set_binop_right (ir_node *node, ir_node *right) { assert (node->op->opar == oparity_binary); } -int is_Phi (ir_node *n) { +int is_Phi (const ir_node *n) { ir_op *op; assert(n); @@ -1466,7 +1435,7 @@ int is_Phi (ir_node *n) { return 0; } -int is_Phi0 (ir_node *n) { +int is_Phi0 (const ir_node *n) { assert(n); return ((get_irn_op(n) == op_Phi) && @@ -1715,13 +1684,25 @@ set_Free_size (ir_node *node, ir_node *size) { type * get_Free_type (ir_node *node) { assert (node->op == op_Free); - return node->attr.f = skip_tid(node->attr.f); + return node->attr.f.type = skip_tid(node->attr.f.type); } void set_Free_type (ir_node *node, type *tp) { assert (node->op == op_Free); - node->attr.f = tp; + node->attr.f.type = tp; +} + +where_alloc +get_Free_where (ir_node *node) { + assert (node->op == op_Free); + return node->attr.f.where; +} + +void +set_Free_where (ir_node *node, where_alloc where) { + assert (node->op == op_Free); + node->attr.f.where = where; } ir_node ** @@ -1905,10 +1886,38 @@ ir_node *get_Filter_cg_pred(ir_node *node, int pos) { return node->attr.filter.in_cg[pos + 1]; } +/* Mux support */ +ir_node *get_Mux_sel (ir_node *node) { + assert(node->op == op_Mux); + return node->in[1]; +} +void set_Mux_sel (ir_node *node, ir_node *sel) { + assert(node->op == op_Mux); + node->in[1] = sel; +} + +ir_node *get_Mux_false (ir_node *node) { + assert(node->op == op_Mux); + return node->in[2]; +} +void set_Mux_false (ir_node *node, ir_node *ir_false) { + assert(node->op == op_Mux); + node->in[2] = ir_false; +} + +ir_node *get_Mux_true (ir_node *node) { + assert(node->op == op_Mux); + return node->in[3]; +} +void set_Mux_true (ir_node *node, ir_node *ir_true) { + assert(node->op == op_Mux); + node->in[3] = ir_true; +} + ir_graph * -get_irn_irg(ir_node *node) { - if (get_irn_op(node) != op_Block) +get_irn_irg(const ir_node *node) { + if (! is_Block(node)) node = get_nodes_block(node); if (is_Bad(node)) /* sometimes bad is predecessor of nodes instead of block: in case of optimization */ node = get_nodes_block(node); @@ -2026,17 +2035,17 @@ skip_Id (ir_node *node) { int (is_Bad)(const ir_node *node) { - return __is_Bad(node); + return _is_Bad(node); } int (is_no_Block)(const ir_node *node) { - return __is_no_Block(node); + return _is_no_Block(node); } int (is_Block)(const ir_node *node) { - return __is_Block(node); + return _is_Block(node); } /* returns true if node is a Unknown node. */ @@ -2101,6 +2110,7 @@ is_forking_op(const ir_node *node) { return is_op_forking(get_irn_op(node)); } + #ifdef DEBUG_libfirm void dump_irn (ir_node *n) { int i, arity = get_irn_arity(n);