From: Michael Beck Date: Mon, 21 Feb 2005 12:09:41 +0000 (+0000) Subject: implemented get_Proj_type(), moved get_irn_type() here, X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=cf79d3e7dfc60cb5ec8f2cdab9b620b40ff14566;p=libfirm implemented get_Proj_type(), moved get_irn_type() here, used new ir_op get_type operation [r5191] --- diff --git a/ir/ir/irnode.c b/ir/ir/irnode.c index 6051b15e4..114245fe1 100644 --- a/ir/ir/irnode.c +++ b/ir/ir/irnode.c @@ -1734,6 +1734,38 @@ set_Sync_pred (ir_node *node, int pos, ir_node *pred) { set_irn_n(node, pos, pred); } +type *get_Proj_type(ir_node *n) +{ + type *tp = NULL; + ir_node *pred = get_Proj_pred(n); + + switch (get_irn_opcode(pred)) { + case iro_Proj: { + ir_node *pred_pred; + /* Deal with Start / Call here: we need to know the Proj Nr. */ + assert(get_irn_mode(pred) == mode_T); + pred_pred = get_Proj_pred(pred); + if (get_irn_op(pred_pred) == op_Start) { + type *mtp = get_entity_type(get_irg_entity(get_irn_irg(pred_pred))); + tp = get_method_param_type(mtp, get_Proj_proj(n)); + } else if (get_irn_op(pred_pred) == op_Call) { + type *mtp = get_Call_type(pred_pred); + tp = get_method_res_type(mtp, get_Proj_proj(n)); + } + } break; + case iro_Start: break; + case iro_Call: break; + case iro_Load: { + ir_node *a = get_Load_ptr(pred); + if (get_irn_op(a) == op_Sel) + tp = get_entity_type(get_Sel_entity(a)); + } break; + default: + break; + } + return tp; +} + ir_node * get_Proj_pred (ir_node *node) { assert (is_Proj(node)); @@ -2108,6 +2140,27 @@ is_forking_op(const ir_node *node) { return is_op_forking(get_irn_op(node)); } +type *(get_irn_type)(ir_node *node) { + return _get_irn_type(node); +} + +/** the get_type operation must be always implemented */ +static type *get_Null_type(ir_node *n) { + return NULL; +} + +/* set the get_type operation */ +ir_op *firm_set_default_get_type(ir_op *op) +{ + switch (op->code) { + case iro_Const: op->get_type = get_Const_type; break; + case iro_SymConst: op->get_type = get_SymConst_value_type; break; + case iro_Cast: op->get_type = get_Cast_type; break; + case iro_Proj: op->get_type = get_Proj_type; break; + default: op->get_type = get_Null_type; break; + } + return op; +} #ifdef DEBUG_libfirm void dump_irn (ir_node *n) { diff --git a/ir/ir/irnode.h b/ir/ir/irnode.h index f5a8f0331..282c1f877 100644 --- a/ir/ir/irnode.h +++ b/ir/ir/irnode.h @@ -816,8 +816,15 @@ int get_Sync_n_preds (ir_node *node); ir_node *get_Sync_pred (ir_node *node, int pos); void set_Sync_pred (ir_node *node, int pos, ir_node *pred); +/** Returns the source language type of a Proj node. + * Must be an atomic type. Mode of type must be mode of node. + */ +type *get_Proj_type (ir_node *node); + +/** Return the predecessor of a Proj node. */ ir_node *get_Proj_pred (ir_node *node); void set_Proj_pred (ir_node *node, ir_node *pred); +/** Return the projection number of a Proj node. */ long get_Proj_proj (ir_node *node); void set_Proj_proj (ir_node *node, long proj); @@ -893,6 +900,11 @@ ir_node *get_fragile_op_mem(ir_node *node); * operation: Cond. */ int is_forking_op(const ir_node *node); +/** Return the type associated with the value produced by n + * if the node remarks this type as it is the case for + * Cast, Const, SymConst and some Proj nodes. */ +type *get_irn_type(ir_node *n); + /** * Access custom node data. * The data must have been registered with diff --git a/ir/ir/irnode_t.h b/ir/ir/irnode_t.h index 6edc48f8f..47e178dbc 100644 --- a/ir/ir/irnode_t.h +++ b/ir/ir/irnode_t.h @@ -272,11 +272,14 @@ store_attr get_irn_store_attr (ir_node *node); except_attr get_irn_except_attr (ir_node *node); /** @} */ -/* +/** * The amount of additional space for custom data to be allocated upon creating a new node. */ extern unsigned firm_add_node_size; +/** Set the get_type operation of an ir_op. */ +ir_op *firm_set_default_get_type(ir_op *op); + /*-------------------------------------------------------------------*/ /* These function are most used in libfirm. Give them as static */ /* functions so they can be inlined. */ @@ -554,26 +557,27 @@ _is_Block_dead(const ir_node *block) { } static INLINE tarval *_get_Const_tarval (ir_node *node) { - assert (node->op == op_Const); + assert (_get_irn_op(node) == op_Const); return node->attr.con.tv; } - -static INLINE cnst_classify_t _classify_Const(ir_node *node) -{ - ir_op *op; +static INLINE cnst_classify_t _classify_Const(ir_node *node) { + ir_op *op; assert(_is_ir_node(node)); - op = _get_irn_op(node); + op = _get_irn_op(node); - if(op == op_Const) - return classify_tarval(_get_Const_tarval(node)); - else if(op == op_SymConst) - return CNST_SYMCONST; + if(op == op_Const) + return classify_tarval(_get_Const_tarval(node)); + else if(op == op_SymConst) + return CNST_SYMCONST; - return CNST_NO_CONST; + return CNST_NO_CONST; } +static INLINE type *_get_irn_type(ir_node *node) { + return _get_irn_op(node)->get_type(node); +} /* this section MUST contain all inline functions */ #define is_ir_node(thing) _is_ir_node(thing) @@ -601,7 +605,8 @@ static INLINE cnst_classify_t _classify_Const(ir_node *node) #define is_Block(node) _is_Block(node) #define set_Block_dead(block) _set_Block_dead(block) #define is_Block_dead(block) _is_Block_dead(block) -#define get_Const_tarval(node) _get_Const_tarval(node) -#define classify_Const(node) _classify_Const(node) +#define get_Const_tarval(node) _get_Const_tarval(node) +#define classify_Const(node) _classify_Const(node) +#define get_irn_type(node) _get_irn_type(node) # endif /* _IRNODE_T_H_ */