move get_irn_edge_kind to internal API
[libfirm] / ir / ir / ircons.c
index 9a166e6..297b5b5 100644 (file)
@@ -23,7 +23,6 @@
  *          representation.
  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Boris Boesler
  *          Michael Beck, Matthias Braun
- * @version $Id$
  */
 #include "config.h"
 
@@ -57,23 +56,20 @@ ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode,
        return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
 }
 
-ir_node *new_rd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
-{
-       ir_node *res;
-
-       assert(is_Cond(arg));
-       arg->attr.cond.default_proj = max_proj;
-       res = new_rd_Proj(db, arg, mode_X, max_proj);
-       return res;
-}
-
-ir_node *new_rd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[],
-                    ir_asm_constraint *inputs, int n_outs,
-                       ir_asm_constraint *outputs, int n_clobber,
+ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem,
+                    int arity, ir_node *in[], ir_asm_constraint *inputs,
+                    size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber,
                        ident *clobber[], ident *text)
 {
        ir_graph *irg = get_irn_irg(block);
-       ir_node  *res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in);
+
+       int r_arity = arity+1;
+       ir_node **r_in;
+       NEW_ARR_A(ir_node*, r_in, r_arity);
+       r_in[0] = mem;
+       memcpy(&r_in[1], in, arity*sizeof(ir_node*));
+
+       ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, r_arity, r_in);
 
        res->attr.assem.pin_state = op_pin_state_pinned;
        res->attr.assem.input_constraints
@@ -87,8 +83,8 @@ ir_node *new_rd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[],
        memcpy(res->attr.assem.output_constraints, outputs, sizeof(outputs[0]) * n_outs);
        memcpy(res->attr.assem.clobbers, clobber, sizeof(clobber[0]) * n_clobber);
 
-       res = optimize_node(res);
        irn_verify_irg(res, irg);
+       res = optimize_node(res);
        return res;
 }
 
@@ -106,8 +102,8 @@ ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
        res->attr.symc.kind = symkind;
        res->attr.symc.sym  = value;
 
-       res = optimize_node(res);
        irn_verify_irg(res, irg);
+       res = optimize_node(res);
        return res;
 }
 
@@ -125,13 +121,6 @@ ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_
        return new_rd_SymConst(db, irg, mode, sym, symconst_ofs_ent);
 }
 
-ir_node *new_rd_SymConst_type_tag(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
-{
-       symconst_symbol sym;
-       sym.type_p = symbol;
-       return new_rd_SymConst(db, irg, mode, sym, symconst_type_tag);
-}
-
 ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
 {
        symconst_symbol sym;
@@ -160,16 +149,12 @@ ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr,
 {
        return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
 }
-ir_node *new_r_defaultProj(ir_node *arg, long max_proj)
-{
-       return new_rd_defaultProj(NULL, arg, max_proj);
-}
-ir_node *new_r_ASM(ir_node *block,
+ir_node *new_r_ASM(ir_node *block, ir_node *mem,
                    int arity, ir_node *in[], ir_asm_constraint *inputs,
-                   int n_outs, ir_asm_constraint *outputs,
-                   int n_clobber, ident *clobber[], ident *text)
+                   size_t n_outs, ir_asm_constraint *outputs,
+                   size_t n_clobber, ident *clobber[], ident *text)
 {
-       return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+       return new_rd_ASM(NULL, block, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
 }
 
 /** Creates a Phi node with 0 predecessors. */
@@ -243,7 +228,7 @@ static ir_node *set_phi_arguments(ir_node *phi, int pos)
                ir_node *cfgpred = get_Block_cfgpred_block(block, i);
                ir_node *value;
                if (is_Bad(cfgpred)) {
-                       value = new_r_Bad(irg);
+                       value = new_r_Bad(irg, mode);
                } else {
                        value = get_r_value_internal(cfgpred, pos, mode);
                }
@@ -252,13 +237,12 @@ static ir_node *set_phi_arguments(ir_node *phi, int pos)
 
        phi->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
        set_irn_in(phi, arity, in);
-       set_irn_op(phi, op_Phi);
 
        irn_verify_irg(phi, irg);
 
        /* Memory Phis in endless loops must be kept alive.
           As we can't distinguish these easily we keep all of them alive. */
-       if (is_Phi(phi) && mode == mode_M)
+       if (mode == mode_M)
                add_End_keepalive(get_irg_end(irg), phi);
 
        try_remove_unnecessary_phi(phi);
@@ -277,7 +261,8 @@ static ir_node *set_phi_arguments(ir_node *phi, int pos)
  */
 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
 {
-       ir_node *res = block->attr.block.graph_arr[pos];
+       ir_node  *res = block->attr.block.graph_arr[pos];
+       ir_graph *irg = get_irn_irg(block);
        if (res != NULL)
                return res;
 
@@ -285,23 +270,28 @@ static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
        if (get_Block_matured(block)) {
                int arity = get_irn_arity(block);
                /* no predecessors: use unknown value */
-               if (arity == 0 && block == get_irg_start_block(get_irn_irg(block))) {
-                       ir_graph *irg = get_irn_irg(block);
-                       if (default_initialize_local_variable != NULL) {
-                               ir_node *rem = get_r_cur_block(irg);
-                               set_r_cur_block(irg, block);
-                               res = default_initialize_local_variable(irg, mode, pos - 1);
-                               set_r_cur_block(irg, rem);
+               if (arity == 0) {
+                       if (block == get_irg_start_block(irg)) {
+                               if (default_initialize_local_variable != NULL) {
+                                       ir_node *rem = get_r_cur_block(irg);
+                                       set_r_cur_block(irg, block);
+                                       res = default_initialize_local_variable(irg, mode, pos - 1);
+                                       set_r_cur_block(irg, rem);
+                               } else {
+                                       res = new_r_Unknown(irg, mode);
+                               }
                        } else {
-                               res = new_r_Unknown(irg, mode);
+                               /* unreachable block, use Bad */
+                               res = new_r_Bad(irg, mode);
                        }
                /* one predecessor just use its value */
                } else if (arity == 1) {
-                       ir_node *cfgpred = get_Block_cfgpred_block(block, 0);
+                       ir_node *cfgpred = get_Block_cfgpred(block, 0);
                        if (is_Bad(cfgpred)) {
-                               res = cfgpred;
+                               res = new_r_Bad(irg, mode);
                        } else {
-                               res = get_r_value_internal(cfgpred, pos, mode);
+                               ir_node *cfgpred_block = get_nodes_block(cfgpred);
+                               res = get_r_value_internal(cfgpred_block, pos, mode);
                        }
                /* multiple predecessors construct Phi */
                } else {
@@ -322,17 +312,12 @@ static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
        return res;
 }
 
-/* ************************************************************************** */
-
-/*
- * Finalize a Block node, when all control flows are known.
- * Acceptable parameters are only Block nodes.
- */
 void mature_immBlock(ir_node *block)
 {
        size_t   n_preds;
        ir_node  *next;
        ir_node  *phi;
+       ir_node **new_in;
        ir_graph *irg;
 
        assert(is_Block(block));
@@ -359,6 +344,15 @@ void mature_immBlock(ir_node *block)
 
        set_Block_matured(block, 1);
 
+       /* create final in-array for the block */
+       if (block->attr.block.dynamic_ins) {
+               new_in = NEW_ARR_D(ir_node*, irg->obst, n_preds+1);
+               memcpy(new_in, block->in, (n_preds+1) * sizeof(new_in[0]));
+               DEL_ARR_F(block->in);
+               block->in = new_in;
+               block->attr.block.dynamic_ins = false;
+       }
+
        /* Now, as the block is a finished Firm node, we can optimize it.
           Since other nodes have been allocated since the block was created
           we can not free the node on the obstack.  Therefore we have to call
@@ -367,8 +361,8 @@ void mature_immBlock(ir_node *block)
           nodes refer to the unoptimized node.
           We can call optimize_in_place_2(), as global cse has no effect on blocks.
         */
-       block = optimize_in_place_2(block);
        irn_verify_irg(block, irg);
+       optimize_in_place_2(block);
 }
 
 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
@@ -377,17 +371,6 @@ ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
        return new_rd_Const_long(db, current_ir_graph, mode, value);
 }
 
-ir_node *new_d_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
-{
-       ir_node *res;
-       assert(is_Cond(arg) || is_Bad(arg));
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
-       if (is_Cond(arg))
-               arg->attr.cond.default_proj = max_proj;
-       res = new_d_Proj(db, arg, mode_X, max_proj);
-       return res;
-}
-
 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
                          ir_entity *ent)
 {
@@ -403,47 +386,14 @@ ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value,
        return new_rd_SymConst(db, current_ir_graph, mode, value, kind);
 }
 
-ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[],
+ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[],
                    ir_asm_constraint *inputs,
-                   int n_outs, ir_asm_constraint *outputs, int n_clobber,
-                   ident *clobber[], ident *text)
+                   size_t n_outs, ir_asm_constraint *outputs,
+                   size_t n_clobber, ident *clobber[], ident *text)
 {
        assert(get_irg_phase_state(current_ir_graph) == phase_building);
-       return new_rd_ASM(db, current_ir_graph->current_block, arity, in, inputs,
-                         n_outs, outputs, n_clobber, clobber, text);
-}
-
-ir_node *new_rd_strictConv(dbg_info *dbgi, ir_node *block, ir_node * irn_op, ir_mode * mode)
-{
-       ir_node *res;
-       ir_graph *irg = get_Block_irg(block);
-
-       ir_node *in[1];
-       in[0] = irn_op;
-
-       res = new_ir_node(dbgi, irg, block, op_Conv, mode, 1, in);
-       res->attr.conv.strict = 1;
-       res = optimize_node(res);
-       irn_verify_irg(res, irg);
-       return res;
-}
-
-ir_node *new_r_strictConv(ir_node *block, ir_node * irn_op, ir_mode * mode)
-{
-       return new_rd_strictConv(NULL, block, irn_op, mode);
-}
-
-ir_node *new_d_strictConv(dbg_info *dbgi, ir_node * irn_op, ir_mode * mode)
-{
-       ir_node *res;
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
-       res = new_rd_strictConv(dbgi, current_ir_graph->current_block, irn_op, mode);
-       return res;
-}
-
-ir_node *new_strictConv(ir_node * irn_op, ir_mode * mode)
-{
-       return new_d_strictConv(NULL, irn_op, mode);
+       return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in,
+                         inputs, n_outs, outputs, n_clobber, clobber, text);
 }
 
 ir_node *new_rd_DivRL(dbg_info *dbgi, ir_node *block, ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
@@ -460,8 +410,8 @@ ir_node *new_rd_DivRL(dbg_info *dbgi, ir_node *block, ir_node * irn_mem, ir_node
        res->attr.div.resmode = resmode;
        res->attr.div.no_remainder = 1;
        res->attr.div.exc.pin_state = pin_state;
-       res = optimize_node(res);
        irn_verify_irg(res, irg);
+       res = optimize_node(res);
        return res;
 }
 
@@ -492,13 +442,9 @@ ir_node *new_rd_immBlock(dbg_info *dbgi, ir_graph *irg)
        res = new_ir_node(dbgi, irg, NULL, op_Block, mode_BB, -1, NULL);
 
        set_Block_matured(res, 0);
-       res->attr.block.is_dead     = 0;
+       res->attr.block.dynamic_ins = true;
        res->attr.block.irg.irg     = irg;
        res->attr.block.backedge    = NULL;
-       res->attr.block.in_cg       = NULL;
-       res->attr.block.cg_backedge = NULL;
-       res->attr.block.extblk      = NULL;
-       res->attr.block.region      = NULL;
        res->attr.block.entity      = NULL;
 
        set_Block_block_visited(res, 0);
@@ -543,18 +489,20 @@ void add_immBlock_pred(ir_node *block, ir_node *jmp)
 
 void set_cur_block(ir_node *target)
 {
-       assert(target == NULL || current_ir_graph == get_irn_irg(target));
-       current_ir_graph->current_block = target;
+       set_r_cur_block(current_ir_graph, target);
 }
 
 void set_r_cur_block(ir_graph *irg, ir_node *target)
 {
-       assert(target == NULL || irg == get_irn_irg(target));
+       assert(get_irg_phase_state(irg) == phase_building);
+       assert(target == NULL || is_Block(target));
+       assert(target == NULL || get_irn_irg(target) == irg);
        irg->current_block = target;
 }
 
 ir_node *get_r_cur_block(ir_graph *irg)
 {
+       assert(get_irg_phase_state(irg) == phase_building);
        return irg->current_block;
 }
 
@@ -586,9 +534,8 @@ static ir_mode *guess_recursively(ir_node *block, int pos)
        int      n_preds;
        int      i;
 
-       if (irn_visited(block))
+       if (irn_visited_else_mark(block))
                return NULL;
-       mark_irn_visited(block);
 
        /* already have a defintion -> we can simply look at its mode */
        value = block->attr.block.graph_arr[pos];
@@ -645,23 +592,6 @@ void set_value(int pos, ir_node *value)
        set_r_value(current_ir_graph, pos, value);
 }
 
-int r_find_value(ir_graph *irg, ir_node *value)
-{
-       size_t i;
-       ir_node *bl = irg->current_block;
-
-       for (i = ARR_LEN(bl->attr.block.graph_arr); i > 1;) {
-               if (bl->attr.block.graph_arr[--i] == value)
-                       return i - 1;
-       }
-       return -1;
-}
-
-int find_value(ir_node *value)
-{
-       return r_find_value(current_ir_graph, value);
-}
-
 ir_node *get_r_store(ir_graph *irg)
 {
        assert(get_irg_phase_state(irg) == phase_building);
@@ -730,6 +660,9 @@ void ir_set_uninitialized_local_variable_func(
 
 void irg_finalize_cons(ir_graph *irg)
 {
+       ir_node *end_block = get_irg_end_block(irg);
+       mature_immBlock(end_block);
+
        set_irg_phase_state(irg, phase_high);
 }
 
@@ -755,29 +688,32 @@ ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
 {
        return new_d_simpleSel(NULL, store, objptr, ent);
 }
-ir_node *new_defaultProj(ir_node *arg, long max_proj)
+ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[],
+                 ir_asm_constraint *inputs, size_t n_outs,
+                 ir_asm_constraint *outputs, size_t n_clobber,
+                 ident *clobber[], ident *text)
 {
-       return new_d_defaultProj(NULL, arg, max_proj);
-}
-ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
-                 int n_outs, ir_asm_constraint *outputs,
-                 int n_clobber, ident *clobber[], ident *text)
-{
-       return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
+       return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
 }
 
 ir_node *new_r_Anchor(ir_graph *irg)
 {
-       ir_node *in[anchor_last];
+       ir_node *in[anchor_last+1];
        ir_node *res;
+       size_t   i;
        memset(in, 0, sizeof(in));
-       res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last, in);
+       res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last+1, in);
        res->attr.anchor.irg.irg = irg;
 
        /* hack to get get_irn_irg working: set block to ourself and allow
         * get_Block_irg for anchor */
        res->in[0] = res;
 
+       /* we can't have NULL inputs so reference ourselfes for now */
+       for (i = 0; i <= (size_t)anchor_last; ++i) {
+               set_irn_n(res, i, res);
+       }
+
        return res;
 }