X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fir%2Firnode.c;h=94cbf54f2c83c7fd37cb857500f9dd2934b85906;hb=aef37e8f6923edb63c4293f3df0402007cdc530b;hp=78e7a9b97417d06434b7500c03cbf9dc350bbac2;hpb=e05c39b81949eb6454a8d9e2374ddd2d1cec076d;p=libfirm diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 78e7a9b97..94cbf54f2 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -1,25 +1,29 @@ -/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe -** All rights reserved. -** -** Authors: Martin Trapp, Christian Schaefer, Goetz Lindenmaier -** -*/ - -/* $Id$ */ +/* + * Project: libFIRM + * File name: ir/ir/irnode.c + * Purpose: Representation of an intermediate operation. + * Author: Martin Trapp, Christian Schaefer + * Modified by: Goetz Lindenmaier + * Created: + * CVS-ID: $Id$ + * Copyright: (c) 1998-2003 Universität Karlsruhe + * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + */ #ifdef HAVE_CONFIG_H # include #endif #include +#include "ident.h" #include "irnode_t.h" #include "irgraph_t.h" -#include "ident_t.h" #include "irmode_t.h" -#include "typegmod_t.h" +#include "typegmod.h" #include "array.h" #include "irbackedge_t.h" #include "irdump.h" +#include "irflag.h" #ifdef DEBUG_libfirm #include "irprog_t.h" @@ -33,23 +37,24 @@ #define END_KEEPALIVE_OFFSET 0 /* Declarations for inlineing */ -INLINE ir_node ** get_irn_in (ir_node *node); -INLINE ir_mode *get_irn_mode (ir_node *node); -INLINE ir_op *get_irn_op (ir_node *node); -INLINE opcode get_irn_opcode (ir_node *node); -INLINE ident *get_irn_opident (ir_node *node); +INLINE ir_node ** get_irn_in (const ir_node *node); +INLINE ir_mode *get_irn_mode (const ir_node *node); +INLINE ir_op *get_irn_op (const ir_node *node); +INLINE opcode get_irn_opcode (const ir_node *node); +INLINE ident *get_irn_opident (const ir_node *node); INLINE type *get_SymConst_type (ir_node *node); INLINE ir_node *skip_nop (ir_node *node); -INLINE ir_node *skip_nop (ir_node *node); -INLINE int is_Proj (ir_node *node); +INLINE int is_Proj (const ir_node *node); -static char *pnc_name_arr [] = {"False", "Eq", "Lt", "Le", - "Gt", "Ge", "Lg", "Leg", "Uo", - "Ue", "Ul", "Ule", "Ug", "Uge", - "Ne", "True" }; +static const char *pnc_name_arr [] = { + "False", "Eq", "Lt", "Le", + "Gt", "Ge", "Lg", "Leg", "Uo", + "Ue", "Ul", "Ule", "Ug", "Uge", + "Ne", "True" +}; -INLINE char *get_pnc_string(int pnc) { +INLINE const char *get_pnc_string(int pnc) { return pnc_name_arr[pnc]; } @@ -77,10 +82,14 @@ get_negated_pnc(int pnc) { return 99; /* to shut up gcc */ } -static char *pns_name_arr [] = {"initial_exec", "global_store", - "frame_base", "globals", "args"}; +const char *pns_name_arr [] = { + "initial_exec", "global_store", + "frame_base", "globals", "args" +}; -static char *symconst_name_arr [] = {"type_tag", "size", "linkage_ptr_info"}; +const char *symconst_name_arr [] = { + "type_tag", "size", "linkage_ptr_info" +}; void init_irnode (void) @@ -130,80 +139,43 @@ copy_attrs (ir_node *old, ir_node *new) { memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old))); } -/* IR-Nodes with attributes */ +/** getting some parameters from ir_nodes **/ + int -ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN) -{ - int printed = 0; - ir_node *np = XP_GETARG (ir_node *, 0); +is_ir_node (void *thing) { + assert(thing); + if (get_kind(thing) == k_ir_node) + return 1; + else + return 0; +} - if (!np) { - XPS (""); - return printed; - } +/* returns the number of predecessors without the block predecessor. */ +INLINE int +get_irn_intra_arity (const ir_node *node) { + assert(node); + return ARR_LEN(node->in) - 1; +} - XPF1 ("%I", get_irn_opident(np)); - - switch (get_irn_opcode (np)) { /* node label */ - case iro_Const: - XPF1 ("%I", get_irn_mode(np)->name); - XPS (" : "); - XPF1 ("%v", get_irn_const_attr); - break; - case iro_Proj: - if (get_irn_mode (np) == mode_b) { - XPC (" "); - XP (pnc_name_arr[get_irn_proj_attr(np)]); - } else if (get_irn_opcode (get_irn_in (np)[1]) == iro_Start) { - XPC (" "); - XP (pns_name_arr[get_irn_proj_attr(np)]); - } else { - XPF1 ("%I", get_irn_mode(np)->name); - XPC (" "); - XPF1 ("%d", get_irn_proj_attr(np)); - } - break; - case iro_SymConst: - XPF1 ("%I", get_irn_mode(np)->name); - XPC (" "); - XP (symconst_name_arr[get_irn_symconst_attr(np).num]); - XPF1 (" %#N", get_type_ident(get_SymConst_type(np))); - break; - case iro_Start: /* don't dump mode of these */ - case iro_Cond: - case iro_Block: - case iro_Call: - case iro_Jmp: - case iro_Return: - case iro_End: - case iro_Break: - case iro_EndReg: - case iro_EndExcept: - case iro_CallBegin: - break; - default: - XPF1 ("%I", get_irn_mode(np)->name); +/* returns the number of predecessors without the block predecessor. */ +INLINE int +get_irn_inter_arity (const ir_node *node) { + assert(node); + if (get_irn_opcode(node) == iro_Filter) { + assert(node->attr.filter.in_cg); + return ARR_LEN(node->attr.filter.in_cg) - 1; + } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) { + return ARR_LEN(node->attr.block.in_cg) - 1; } - - return printed; + return get_irn_intra_arity(node); } -/** getting some parameters from ir_nodes **/ - /* returns the number of predecessors without the block predecessor. */ INLINE int -get_irn_arity (ir_node *node) { +get_irn_arity (const ir_node *node) { assert(node); - if (interprocedural_view) { /* handle Filter and Block specially */ - if (get_irn_opcode(node) == iro_Filter) { - assert(node->attr.filter.in_cg); - return ARR_LEN(node->attr.filter.in_cg) - 1; - } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) { - return ARR_LEN(node->attr.block.in_cg) - 1; - } - /* else fall through */ - } - return ARR_LEN(node->in) - 1; + if (interprocedural_view) return get_irn_inter_arity(node); + return get_irn_intra_arity(node); } /* Returns the array with ins. This array is shifted with respect to the @@ -213,7 +185,7 @@ get_irn_arity (ir_node *node) { lists of operands as predecessors of Block or arguments of a Call are consecutive. */ INLINE ir_node ** -get_irn_in (ir_node *node) { +get_irn_in (const ir_node *node) { assert(node); if (interprocedural_view) { /* handle Filter and Block specially */ if (get_irn_opcode(node) == iro_Filter) { @@ -248,9 +220,28 @@ set_irn_in (ir_node *node, int arity, ir_node **in) { *arr = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1); (*arr)[0] = block; } + fix_backedges(current_ir_graph->obst, node); memcpy((*arr) + 1, in, sizeof(ir_node *) * arity); } +INLINE ir_node * +get_irn_intra_n (ir_node *node, int n) { + return (node->in[n + 1] = skip_nop(node->in[n + 1])); +} + +INLINE ir_node* +get_irn_inter_n (ir_node *node, int n) { + /* handle Filter and Block specially */ + if (get_irn_opcode(node) == iro_Filter) { + assert(node->attr.filter.in_cg); + return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1])); + } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) { + return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1])); + } + + return get_irn_intra_n (node, n); +} + /* to iterate through the predecessors without touching the array */ /* To iterate over the operands iterate from 0 to i < get_irn_arity(), to iterate includind the Block predecessor iterate from i = -1 to @@ -262,20 +253,13 @@ get_irn_n (ir_node *node, int n) { if (-1 > n || get_irn_arity(node) <= n) { printf("pos: %d, arity: %d ", n, get_irn_arity(node)); DDMN(node); - } + } /**/ assert(node); assert(-1 <= n && n < get_irn_arity(node)); - if (interprocedural_view) { /* handle Filter and Block specially */ - if (get_irn_opcode(node) == iro_Filter) { - assert(node->attr.filter.in_cg); - return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1])); - } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) { - return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1])); - } - /* else fall through */ - } - return (node->in[n + 1] = skip_nop(node->in[n + 1])); + if (interprocedural_view) return get_irn_inter_n (node, n); + return get_irn_intra_n (node, n); } + INLINE void set_irn_n (ir_node *node, int n, ir_node *in) { assert(node && -1 <= n && n < get_irn_arity(node)); @@ -301,29 +285,44 @@ set_irn_n (ir_node *node, int n, ir_node *in) { } INLINE ir_mode * -get_irn_mode (ir_node *node) +get_irn_mode (const ir_node *node) { assert (node); return node->mode; } +INLINE void +set_irn_mode (ir_node *node, ir_mode *mode) +{ + assert (node); + node->mode=mode; + return; +} + INLINE modecode -get_irn_modecode (ir_node *node) +get_irn_modecode (const ir_node *node) { assert (node); return node->mode->code; } +/** Gets the string representation of the mode .*/ +INLINE const char * +get_irn_modename (const ir_node *node) +{ + assert(node); + return get_mode_name(node->mode); +} INLINE ident * -get_irn_modeident (ir_node *node) +get_irn_modeident (const ir_node *node) { assert(node); - return node->mode->name; + return get_mode_ident(node->mode); } INLINE ir_op * -get_irn_op (ir_node *node) +get_irn_op (const ir_node *node) { assert (node); return node->op; @@ -338,28 +337,30 @@ set_irn_op (ir_node *node, ir_op *op) } INLINE opcode -get_irn_opcode (ir_node *node) +get_irn_opcode (const ir_node *node) { assert (node); + assert (k_ir_node == get_kind(node)); + assert (node -> op); return node->op->code; } INLINE const char * -get_irn_opname (ir_node *node) +get_irn_opname (const ir_node *node) { assert(node); - return id_to_str(node->op->name); + return get_id_str(node->op->name); } INLINE ident * -get_irn_opident (ir_node *node) +get_irn_opident (const ir_node *node) { assert(node); return node->op->name; } INLINE unsigned long -get_irn_visited (ir_node *node) +get_irn_visited (const ir_node *node) { assert (node); return node->visited; @@ -379,13 +380,13 @@ mark_irn_visited (ir_node *node) { } INLINE int -irn_not_visited (ir_node *node) { +irn_not_visited (const ir_node *node) { assert (node); return (node->visited < current_ir_graph->visited); } INLINE int -irn_visited (ir_node *node) { +irn_visited (const ir_node *node) { assert (node); return (node->visited >= current_ir_graph->visited); } @@ -393,27 +394,31 @@ irn_visited (ir_node *node) { INLINE void set_irn_link (ir_node *node, void *link) { assert (node); + /* Link field is used for Phi construction and various optimizations + in iropt. */ + assert(get_irg_phase_state(current_ir_graph) != phase_building); + node->link = link; } INLINE void * -get_irn_link (ir_node *node) { +get_irn_link (const ir_node *node) { assert (node); return node->link; } /* Outputs a unique number for this node */ INLINE long -get_irn_node_nr(ir_node *node) { +get_irn_node_nr(const ir_node *node) { assert(node); #ifdef DEBUG_libfirm return node->node_nr; #else - return 0; + return (long)&node; #endif } -INLINE tarval * +INLINE const_attr get_irn_const_attr (ir_node *node) { assert (node->op == op_Const); @@ -491,6 +496,42 @@ set_nodes_Block (ir_node *node, ir_node *block) { set_irn_n(node, -1, block); } +/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base) + * from Start. If so returns frame type, else Null. */ +type *is_frame_pointer(ir_node *n) { + if ((get_irn_op(n) == op_Proj) && + (get_Proj_proj(n) == pn_Start_P_frame_base)) { + ir_node *start = get_Proj_pred(n); + if (get_irn_op(start) == op_Start) { + return get_irg_frame_type(get_irn_irg(start)); + } + } + return NULL; +} + +/* Test whether arbitrary node is globals pointer, i.e. Proj(pn_Start_P_globals) + * from Start. If so returns global type, else Null. */ +type *is_globals_pointer(ir_node *n) { + if ((get_irn_op(n) == op_Proj) && + (get_Proj_proj(n) == pn_Start_P_globals)) { + ir_node *start = get_Proj_pred(n); + if (get_irn_op(start) == op_Start) { + return get_glob_type(); + } + } + return NULL; +} + +/* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base) + * from Start. If so returns 1, else 0. */ +int is_value_arg_pointer(ir_node *n) { + if ((get_irn_op(n) == op_Proj) && + (get_Proj_proj(n) == pn_Start_P_value_arg_base) && + (get_irn_op(get_Proj_pred(n)) == op_Start)) + return 1; + return 0; +} + /* Returns an array with the predecessors of the Block. Depending on the implementation of the graph datastructure this can be a copy of the internal representation of predecessors as well as the internal @@ -511,13 +552,13 @@ get_Block_n_cfgpreds (ir_node *node) { INLINE ir_node * get_Block_cfgpred (ir_node *node, int pos) { - /* debug @@@ */ assert (node->op == op_Block); + /* debug @@@ if (-1 > pos || get_irn_arity(node) <= pos) { dump_ir_block_graph(current_ir_graph); printf("pos: %d, arity: %d ", pos, get_irn_arity(node)); DDMN(node); - } + } */ assert(node); assert(-1 <= pos && pos < get_irn_arity(node)); return get_irn_n(node, pos); } @@ -576,7 +617,7 @@ set_Block_graph_arr (ir_node *node, int pos, ir_node *value) { node->attr.block.graph_arr[pos+1] = value; } -/* handler handling for Blocks */ +/* handler handling for Blocks * / void set_Block_handler (ir_node *block, ir_node *handler) { assert ((block->op == op_Block)); @@ -590,7 +631,7 @@ get_Block_handler (ir_node *block) { return (block->attr.block.handler_entry); } -/* handler handling for Nodes */ +/ * handler handling for Nodes * / void set_Node_handler (ir_node *node, ir_node *handler) { set_Block_handler (get_nodes_Block (node), handler); @@ -601,7 +642,7 @@ get_Node_handler (ir_node *node) { return (get_Block_handler (get_nodes_Block (node))); } -/* exc_t handling for Blocks */ +/ * exc_t handling for Blocks * / void set_Block_exc (ir_node *block, exc_t exc) { assert ((block->op == op_Block)); block->attr.block.exc = exc; @@ -609,11 +650,10 @@ void set_Block_exc (ir_node *block, exc_t exc) { exc_t get_Block_exc (ir_node *block) { assert ((block->op == op_Block)); - return (block->attr.block.exc); } -/* exc_t handling for Nodes */ +/ * exc_t handling for Nodes * / void set_Node_exc (ir_node *node, exc_t exc) { set_Block_exc (get_nodes_Block (node), exc); } @@ -621,6 +661,7 @@ void set_Node_exc (ir_node *node, exc_t exc) { exc_t get_Node_exc (ir_node *node) { return (get_Block_exc (get_nodes_Block (node))); } +*/ void set_Block_cg_cfgpred_arr(ir_node * node, int arity, ir_node ** in) { assert(node->op == op_Block); @@ -628,6 +669,14 @@ void set_Block_cg_cfgpred_arr(ir_node * node, int arity, ir_node ** in) { node->attr.block.in_cg = NEW_ARR_D(ir_node *, current_ir_graph->obst, arity + 1); node->attr.block.in_cg[0] = NULL; node->attr.block.cg_backedge = new_backedge_arr(current_ir_graph->obst, arity); + { + /* Fix backedge array. fix_backedges operates depending on + interprocedural_view. */ + bool ipv = interprocedural_view; + interprocedural_view = true; + fix_backedges(current_ir_graph->obst, node); + interprocedural_view = ipv; + } } memcpy(node->attr.block.in_cg + 1, in, sizeof(ir_node *) * arity); } @@ -645,8 +694,8 @@ ir_node ** get_Block_cg_cfgpred_arr(ir_node * node) { } int get_Block_cg_n_cfgpreds(ir_node * node) { - assert(node->op == op_Block && node->attr.block.in_cg); - return ARR_LEN(node->attr.block.in_cg) - 1; + assert(node->op == op_Block); + return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1; } ir_node * get_Block_cg_cfgpred(ir_node * node, int pos) { @@ -659,6 +708,20 @@ void remove_Block_cg_cfgpred_arr(ir_node * node) { node->attr.block.in_cg = NULL; } +/* Start references the irg it is in. */ +INLINE ir_graph * +get_Start_irg(ir_node *node) { + return get_irn_irg(node); +} + +INLINE void +set_Start_irg(ir_node *node, ir_graph *irg) { + assert(node->op == op_Start); + assert(is_ir_graph(irg)); + assert(0 && " Why set irg? "); + //node->attr.start.irg = irg; +} + INLINE int get_End_n_keepalives(ir_node *end) { assert (end->op == op_End); @@ -686,19 +749,18 @@ set_End_keepalive(ir_node *end, int pos, ir_node *ka) { INLINE void free_End (ir_node *end) { assert (end->op == op_End); + end->kind = k_BAD; /* DEL_ARR_F(end->in); GL @@@ tut nicht ! */ end->in = NULL; /* @@@ make sure we get an error if we use the in array afterwards ... */ } ir_graph *get_EndReg_irg (ir_node *end) { - assert (end->op == op_EndReg); - return end->attr.end.irg; + return get_irn_irg(end); } ir_graph *get_EndExcept_irg (ir_node *end) { - assert (end->op == op_EndReg); - return end->attr.end.irg; + return get_irn_irg(end); } /* @@ -806,7 +868,7 @@ set_Return_res (ir_node *node, int pos, ir_node *res){ INLINE ir_node * get_Raise_mem (ir_node *node) { - assert (node->op == op_Return); + assert (node->op == op_Raise); return get_irn_n(node, 0); } @@ -830,17 +892,43 @@ set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) { INLINE tarval *get_Const_tarval (ir_node *node) { assert (node->op == op_Const); - return get_irn_const_attr(node); + return node->attr.con.tv; } INLINE void set_Const_tarval (ir_node *node, tarval *con) { assert (node->op == op_Const); - node->attr.con = con; + node->attr.con.tv = con; +} + + +/* 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 + entity type. */ +INLINE type * +get_Const_type (ir_node *node) { + assert (node->op == op_Const); + return node->attr.con.tp; } +INLINE void +set_Const_type (ir_node *node, type *tp) { + assert (node->op == op_Const); + if (tp != unknown_type) { + assert (is_atomic_type(tp)); + assert (get_type_mode(tp) == get_irn_mode(node)); + assert (!tarval_is_entity(get_Const_tarval(node)) || + (is_pointer_type(tp) && + (get_pointer_points_to_type(tp) == + get_entity_type(get_tarval_entity(get_Const_tarval(node)))))); + } + + node->attr.con.tp = tp; +} + + INLINE symconst_kind -get_SymConst_kind (ir_node *node) { +get_SymConst_kind (const ir_node *node) { assert (node->op == op_SymConst); return node->attr.i.num; } @@ -860,11 +948,11 @@ get_SymConst_type (ir_node *node) { } INLINE void -set_SymConst_type (ir_node *node, type *type) { +set_SymConst_type (ir_node *node, type *tp) { assert ( (node->op == op_SymConst) && ( get_SymConst_kind(node) == type_tag || get_SymConst_kind(node) == size)); - node->attr.i.tori.typ = type; + node->attr.i.tori.typ = tp; } INLINE ident * @@ -997,7 +1085,7 @@ set_InstOf_obj (ir_node *node, ir_node *obj) { /* For unary and binary arithmetic operations the access to the operands can be factored out. Left is the first, right the second arithmetic value as listed in tech report 0999-33. - unops are: Minus, Abs, Not, Conv + unops are: Minus, Abs, Not, Conv, Cast binops are: Add, Sub, Mul, Quot, DivMod, Div, Mod, And, Or, Eor, Shl, Shr, Shrs, Rotate, Cmp */ @@ -1069,10 +1157,14 @@ get_Call_type (ir_node *node) { } INLINE void -set_Call_type (ir_node *node, type *type) { +set_Call_type (ir_node *node, type *tp) { assert (node->op == op_Call); - assert (is_method_type(type)); - node->attr.call.cld_tp = type; + assert (is_method_type(tp)); + node->attr.call.cld_tp = tp; +} + +int Call_has_callees(ir_node *node) { + return (node->attr.call.callee_arr != NULL); } int get_Call_n_callees(ir_node * node) { @@ -1107,8 +1199,7 @@ void set_CallBegin_ptr (ir_node *node, ir_node *ptr) { set_irn_n(node, 0, ptr); } ir_graph * get_CallBegin_irg (ir_node *node) { - assert(node->op == op_CallBegin); - return node->attr.callbegin.irg; + return get_irn_irg(node); } ir_node * get_CallBegin_call (ir_node *node) { assert(node->op == op_CallBegin); @@ -1579,44 +1670,63 @@ set_Conv_op (ir_node *node, ir_node *op) { set_irn_n(node, 0, op); } +INLINE ir_node * +get_Cast_op (ir_node *node) { + assert (node->op == op_Cast); + return get_irn_n(node, 0); +} +INLINE void +set_Cast_op (ir_node *node, ir_node *op) { + assert (node->op == op_Cast); + set_irn_n(node, 0, op); +} -int +INLINE type * +get_Cast_type (ir_node *node) { + assert (node->op == op_Cast); + return node->attr.cast.totype; +} + +INLINE void +set_Cast_type (ir_node *node, type *to_tp) { + assert (node->op == op_Cast); + node->attr.cast.totype = to_tp; +} + +INLINE int is_unop (ir_node *node) { return ( node->op == op_Minus || node->op == op_Abs || node->op == op_Not || - node->op == op_Conv ); + node->op == op_Conv || + node->op == op_Cast ); } INLINE ir_node * get_unop_op (ir_node *node) { - assert ( node->op == op_Minus || - node->op == op_Abs || - node->op == op_Not || - node->op == op_Conv ); + assert (is_unop(node)); switch (get_irn_opcode (node)) { case iro_Minus: return get_Minus_op(node); break; case iro_Abs: return get_Abs_op(node); break; case iro_Not: return get_Not_op(node); break; case iro_Conv: return get_Conv_op(node); break; + case iro_Cast: return get_Cast_op(node); break; default: return NULL; } } INLINE void set_unop_op (ir_node *node, ir_node *op) { - assert (node->op == op_Minus || - node->op == op_Abs || - node->op == op_Not || - node->op == op_Conv ); - switch (get_irn_opcode (node)) { + assert (is_unop(node)); + switch (get_irn_opcode (node)) { case iro_Minus: set_Minus_op(node, op); break; case iro_Abs: set_Abs_op(node, op); break; case iro_Not: set_Not_op(node, op); break; case iro_Conv: set_Conv_op(node, op); break; + case iro_Cast: set_Cast_op(node, op); break; default: ; - } + } } @@ -1791,6 +1901,11 @@ set_binop_right (ir_node *node, ir_node *right) { }; } +INLINE int is_Phi (ir_node *n) { + assert(n); + return ((get_irn_op(n) == op_Phi) || + (get_irn_op(n) == op_Filter && interprocedural_view)); +} INLINE ir_node ** get_Phi_preds_arr (ir_node *node) { @@ -1800,7 +1915,7 @@ get_Phi_preds_arr (ir_node *node) { INLINE int get_Phi_n_preds (ir_node *node) { - assert (node->op == op_Phi); + assert (is_Phi(node)); return (get_irn_arity(node)); } @@ -1812,13 +1927,13 @@ INLINE void set_Phi_n_preds (ir_node *node, int n_preds) { INLINE ir_node * get_Phi_pred (ir_node *node, int pos) { - assert (node->op == op_Phi); + assert (is_Phi(node)); return get_irn_n(node, pos); } INLINE void set_Phi_pred (ir_node *node, int pos, ir_node *pred) { - assert (node->op == op_Phi); + assert (is_Phi(node)); set_irn_n(node, pos, pred); } @@ -1914,9 +2029,9 @@ get_Alloc_type (ir_node *node) { } INLINE void -set_Alloc_type (ir_node *node, type *type) { +set_Alloc_type (ir_node *node, type *tp) { assert (node->op == op_Alloc); - node->attr.a.type = type; + node->attr.a.type = tp; } INLINE where_alloc @@ -1975,9 +2090,9 @@ get_Free_type (ir_node *node) { } INLINE void -set_Free_type (ir_node *node, type *type) { +set_Free_type (ir_node *node, type *tp) { assert (node->op == op_Free); - node->attr.f = type; + node->attr.f = tp; } INLINE ir_node ** @@ -2083,6 +2198,31 @@ set_Id_pred (ir_node *node, ir_node *pred) { set_irn_n(node, 0, pred); } +INLINE ir_node *get_Confirm_value (ir_node *node) { + assert (node->op == op_Confirm); + return get_irn_n(node, 0); +} +INLINE void set_Confirm_value (ir_node *node, ir_node *value) { + assert (node->op == op_Confirm); + set_irn_n(node, 0, value); +} +INLINE ir_node *get_Confirm_bound (ir_node *node) { + assert (node->op == op_Confirm); + return get_irn_n(node, 1); +} +INLINE void set_Confirm_bound (ir_node *node, ir_node *bound) { + assert (node->op == op_Confirm); + set_irn_n(node, 0, bound); +} +INLINE pn_Cmp get_Confirm_cmp (ir_node *node) { + assert (node->op == op_Confirm); + return node->attr.confirm_cmp; +} +INLINE void set_Confirm_cmp (ir_node *node, pn_Cmp cmp) { + assert (node->op == op_Confirm); + node->attr.confirm_cmp = cmp; +} + INLINE ir_node * get_Filter_pred (ir_node *node) { @@ -2139,14 +2279,10 @@ ir_node *get_Filter_cg_pred(ir_node *node, int pos) { INLINE ir_graph * get_irn_irg(ir_node *node) { - if (get_irn_op(node) == op_CallBegin) { - return node->attr.callbegin.irg; - } else if (get_irn_op(node) == op_EndReg || - get_irn_op(node) == op_EndExcept) { - return node->attr.end.irg; - } else { - assert(0 && "no irg attr"); - } + if (get_irn_op(node) != op_Block) + node = get_nodes_block(node); + assert(get_irn_op(node) == op_Block); + return node->attr.block.irg; } @@ -2168,6 +2304,8 @@ INLINE ir_node * skip_Tuple (ir_node *node) { ir_node *pred; + if (!get_opt_normalize()) return node; + node = skip_nop(node); if (get_irn_op(node) == op_Proj) { pred = skip_nop(get_Proj_pred(node)); @@ -2179,15 +2317,29 @@ skip_Tuple (ir_node *node) { return node; } +/* This should compact Id-cycles to self-cycles. It has the same (or less?) complexity + than any other approach, as Id chains are resolved and all point to the real node, or + all id's are self loops. */ INLINE ir_node * skip_nop (ir_node *node) { /* don't assert node !!! */ - if (node && (node->op == op_Id) && (node != get_Id_pred(node))) { - /* Don't use get_Id_pred: We get into an endless loop for - self-referencing Ids. */ + if (!get_opt_normalize()) return node; + + /* Don't use get_Id_pred: We get into an endless loop for + self-referencing Ids. */ + if (node && (node->op == op_Id) && (node != node->in[0+1])) { + ir_node *rem_pred = node->in[0+1]; + ir_node *res; + assert (get_irn_arity (node) > 0); - return node->in[0+1]; + + node->in[0+1] = node; + res = skip_nop(rem_pred); + if (res->op == op_Id) /* self-loop */ return node; + + node->in[0+1] = res; + return res; } else { return node; } @@ -2213,7 +2365,20 @@ is_no_Block (ir_node *node) { } INLINE int -is_Proj (ir_node *node) { +is_Block (ir_node *node) { + assert(node); + return (get_irn_opcode(node) == iro_Block); +} + +/* returns true if node is a Unknown node. */ +INLINE int +is_Unknown (ir_node *node) { + assert(node); + return (get_irn_opcode(node) == iro_Unknown); +} + +INLINE int +is_Proj (const ir_node *node) { assert(node); return node->op == op_Proj || (!interprocedural_view && node->op == op_Filter); @@ -2227,10 +2392,14 @@ is_cfop(ir_node *node) { /* Returns true if the operation manipulates interprocedural control flow: CallBegin, EndReg, EndExcept */ -int is_ip_cfop(ir_node *node) { +INLINE int is_ip_cfop(ir_node *node) { return is_ip_cfopcode(get_irn_op(node)); } +ir_graph *get_ip_cfop_irg(ir_node *n) { + return get_irn_irg(n); +} + /* Returns true if the operation can change the control flow because of an exception. */ int