Add a tail_call attribute the Call nodes to mark possible tail calls.
[libfirm] / ir / ir / irnode.c
index 9b30aaf..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;
@@ -518,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) {
@@ -798,9 +799,8 @@ 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);
 }
 
 ir_entity *create_Block_entity(ir_node *block) {
@@ -1386,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));
@@ -2540,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);
 }
 
 
@@ -2770,7 +2780,7 @@ int (is_irn_forking)(const ir_node *node) {
 }
 
 void (copy_node_attr)(const ir_node *old_node, ir_node *new_node) {
-       return _copy_node_attr(old_node, new_node);
+       _copy_node_attr(old_node, new_node);
 }
 
 /* Return the type associated with the value produced by n