Add a tail_call attribute the Call nodes to mark possible tail calls.
[libfirm] / ir / ir / irnode.c
index 2666aa9..f626fd9 100644 (file)
@@ -269,11 +269,11 @@ void set_irn_in(ir_node *node, int arity, ir_node **in) {
 }
 
 ir_node *(get_irn_intra_n)(const ir_node *node, int n) {
-       return _get_irn_intra_n (node, n);
+       return _get_irn_intra_n(node, n);
 }
 
 ir_node *(get_irn_inter_n)(const ir_node *node, int n) {
-       return _get_irn_inter_n (node, n);
+       return _get_irn_inter_n(node, n);
 }
 
 ir_node *(*_get_irn_n)(const ir_node *node, int n) = _get_irn_intra_n;
@@ -404,11 +404,6 @@ void (set_irn_mode)(ir_node *node, ir_mode *mode) {
        _set_irn_mode(node, mode);
 }
 
-ir_modecode get_irn_modecode(const ir_node *node) {
-       assert(node);
-       return node->mode->code;
-}
-
 /** Gets the string representation of the mode .*/
 const char *get_irn_modename(const ir_node *node) {
        assert(node);
@@ -523,9 +518,10 @@ symconst_attr *get_irn_symconst_attr(ir_node *node) {
        return &node->attr.symc;
 }
 
-ir_type *get_irn_call_attr(ir_node *node) {
+call_attr *get_irn_call_attr(ir_node *node) {
        assert(is_Call(node));
-       return node->attr.call.type = skip_tid(node->attr.call.type);
+       node->attr.call.type = skip_tid(node->attr.call.type);
+       return &node->attr.call;
 }
 
 sel_attr *get_irn_sel_attr(ir_node *node) {
@@ -803,25 +799,46 @@ ir_node *get_irn_MacroBlock(const ir_node *n) {
 }
 
 /* returns the graph of a Block. */
-ir_graph *get_Block_irg(const ir_node *block) {
-       assert(is_Block(block));
-       return block->attr.block.irg;
+ir_graph *(get_Block_irg)(const ir_node *block) {
+       return _get_Block_irg(block);
 }
 
-int has_Block_label(const ir_node *block) {
+ir_entity *create_Block_entity(ir_node *block) {
+       ir_entity *entity;
        assert(is_Block(block));
-       return block->attr.block.has_label;
+
+       entity = block->attr.block.entity;
+       if (entity == NULL) {
+               ir_label_t  nr;
+               ir_type   *glob;
+
+               glob = get_glob_type();
+               entity = new_entity(glob, id_unique("block_%u"), get_code_type());
+               nr = get_irp_next_label_nr();
+               set_entity_label(entity, nr);
+               set_entity_compiler_generated(entity, 1);
+               set_entity_allocation(entity, allocation_static);
+
+               block->attr.block.entity = entity;
+       }
+       return entity;
 }
 
-ir_label_t get_Block_label(const ir_node *block) {
+ir_entity *get_Block_entity(const ir_node *block) {
        assert(is_Block(block));
-       return block->attr.block.label;
+       return block->attr.block.entity;
 }
 
-void set_Block_label(ir_node *block, ir_label_t label) {
+void set_Block_entity(ir_node *block, ir_entity *entity)
+{
        assert(is_Block(block));
-       block->attr.block.has_label = 1;
-       block->attr.block.label = label;
+       assert(get_entity_type(entity) == get_code_type());
+       block->attr.block.entity = entity;
+}
+
+int has_Block_entity(const ir_node *block)
+{
+       return block->attr.block.entity != NULL;
 }
 
 ir_node *(get_Block_phis)(const ir_node *block) {
@@ -1218,16 +1235,6 @@ set_SymConst_symbol(ir_node *node, union symconst_symbol sym) {
        node->attr.symc.sym = sym;
 }
 
-ir_label_t get_SymConst_label(const ir_node *node) {
-       assert(is_SymConst(node) && SYMCONST_HAS_LABEL(get_SymConst_kind(node)));
-       return node->attr.symc.sym.label;
-}
-
-void set_SymConst_label(ir_node *node, ir_label_t label) {
-       assert(is_SymConst(node) && SYMCONST_HAS_LABEL(get_SymConst_kind(node)));
-       node->attr.symc.sym.label = label;
-}
-
 ir_type *
 get_SymConst_value_type(ir_node *node) {
        assert(is_SymConst(node));
@@ -1379,6 +1386,18 @@ set_Call_type(ir_node *node, ir_type *tp) {
        node->attr.call.type = tp;
 }
 
+unsigned
+get_Call_tail_call(const ir_node *node) {
+       assert(is_Call(node));
+       return node->attr.call.tail_call;
+}
+
+void
+set_Call_tail_call(ir_node *node, unsigned tail_call) {
+       assert(is_Call(node));
+       node->attr.call.tail_call = tail_call != 0;
+}
+
 ir_node *
 get_Builtin_mem(const ir_node *node) {
        assert(is_Builtin(node));
@@ -2533,10 +2552,8 @@ get_irn_irg(const ir_node *node) {
         */
        if (! is_Block(node))
                node = get_irn_n(node, -1);
-       if (is_Bad(node))  /* sometimes bad is predecessor of nodes instead of block: in case of optimization */
-               node = get_irn_n(node, -1);
-       assert(is_Block(node));
-       return node->attr.block.irg;
+       /* note that get_Block_irg() can handle Bad nodes */
+       return get_Block_irg(node);
 }
 
 
@@ -2762,6 +2779,10 @@ int (is_irn_forking)(const ir_node *node) {
        return _is_irn_forking(node);
 }
 
+void (copy_node_attr)(const ir_node *old_node, ir_node *new_node) {
+       _copy_node_attr(old_node, new_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. */