valueset: Remove the unused link field.
[libfirm] / ir / ir / ircons.c
index 6ac3a88..881616c 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,38 +56,34 @@ 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);
 
-       res->attr.assem.pin_state = op_pin_state_pinned;
-       res->attr.assem.input_constraints
-               = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
-       res->attr.assem.output_constraints
-               = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
-       res->attr.assem.clobbers = NEW_ARR_D(ident *, irg->obst, n_clobber);
-       res->attr.assem.text     = text;
+       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);
+
+       struct obstack *const obst = get_irg_obstack(irg);
+       res->attr.assem.pin_state          = op_pin_state_pinned;
+       res->attr.assem.input_constraints  = NEW_ARR_D(ir_asm_constraint, obst, arity);
+       res->attr.assem.output_constraints = NEW_ARR_D(ir_asm_constraint, obst, n_outs);
+       res->attr.assem.clobbers           = NEW_ARR_D(ident*,            obst, n_clobber);
+       res->attr.assem.text               = text;
 
        memcpy(res->attr.assem.input_constraints,  inputs,  sizeof(inputs[0]) * arity);
        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 +101,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 +120,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 +148,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,26 +227,18 @@ 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 {
-                       inc_irg_visited(irg);
-
                        value = get_r_value_internal(cfgpred, pos, mode);
                }
                in[i] = value;
        }
 
-       phi->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
+       phi->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), 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)
-               add_End_keepalive(get_irg_end(irg), phi);
-
        try_remove_unnecessary_phi(phi);
        return phi;
 }
@@ -284,35 +260,32 @@ static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
        if (res != NULL)
                return res;
 
-       /* We ran into a cycle. This may happen in unreachable loops. */
-       if (irn_visited(block)) {
-               /* Since the loop is unreachable, return a Bad. */
-               return new_r_Bad(irg);
-       }
-
-       mark_irn_visited(block);
-
        /* in a matured block we can immediately determine the phi arguments */
        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 {
@@ -333,12 +306,6 @@ 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;
@@ -346,14 +313,13 @@ void mature_immBlock(ir_node *block)
        ir_node  *phi;
        ir_graph *irg;
 
-       assert(is_Block(block));
        if (get_Block_matured(block))
                return;
 
        irg     = get_irn_irg(block);
        n_preds = ARR_LEN(block->in) - 1;
        /* Fix block parameters */
-       block->attr.block.backedge = new_backedge_arr(irg->obst, n_preds);
+       block->attr.block.backedge = new_backedge_arr(get_irg_obstack(irg), n_preds);
 
        /* Traverse a chain of Phi nodes attached to this block and mature
        these, too. */
@@ -370,6 +336,14 @@ void mature_immBlock(ir_node *block)
 
        set_Block_matured(block, 1);
 
+       /* create final in-array for the block */
+       if (block->attr.block.dynamic_ins) {
+               ir_node **const new_in = DUP_ARR_D(ir_node*, get_irg_obstack(irg), block->in);
+               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
@@ -378,31 +352,20 @@ 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)
 {
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
+       assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        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)
 {
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
+       assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        return new_rd_Sel(db, current_ir_graph->current_block,
                          store, objptr, 0, NULL, ent);
 }
@@ -410,51 +373,18 @@ ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value,
                         symconst_kind kind)
 {
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
+       assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        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);
+       assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
+       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)
@@ -471,8 +401,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;
 }
 
@@ -484,7 +414,7 @@ ir_node *new_r_DivRL(ir_node *block, ir_node * irn_mem, ir_node * irn_left, ir_n
 ir_node *new_d_DivRL(dbg_info *dbgi, ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
 {
        ir_node *res;
-       assert(get_irg_phase_state(current_ir_graph) == phase_building);
+       assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        res = new_rd_DivRL(dbgi, current_ir_graph->current_block, irn_mem, irn_left, irn_right, resmode, pin_state);
        return res;
 }
@@ -498,25 +428,20 @@ ir_node *new_rd_immBlock(dbg_info *dbgi, ir_graph *irg)
 {
        ir_node *res;
 
-       assert(get_irg_phase_state(irg) == phase_building);
+       assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        /* creates a new dynamic in-array as length of in is -1 */
        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);
 
        /* Create and initialize array for Phi-node construction. */
-       res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
-       memset(res->attr.block.graph_arr, 0, sizeof(ir_node*) * irg->n_loc);
+       res->attr.block.graph_arr = NEW_ARR_DZ(ir_node*, get_irg_obstack(irg), irg->n_loc);
 
        /* Immature block may not be optimized! */
        irn_verify_irg(res, irg);
@@ -554,18 +479,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(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
+       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(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        return irg->current_block;
 }
 
@@ -576,9 +503,8 @@ ir_node *get_cur_block(void)
 
 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
 {
-       assert(get_irg_phase_state(irg) == phase_building);
+       assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        assert(pos >= 0);
-       inc_irg_visited(irg);
 
        return get_r_value_internal(irg->current_block, pos + 1, mode);
 }
@@ -598,9 +524,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,7 +570,7 @@ ir_mode *ir_guess_mode(int pos)
 
 void set_r_value(ir_graph *irg, int pos, ir_node *value)
 {
-       assert(get_irg_phase_state(irg) == phase_building);
+       assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        assert(pos >= 0);
        assert(pos+1 < irg->n_loc);
        assert(is_ir_node(value));
@@ -657,27 +582,9 @@ 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);
-       inc_irg_visited(irg);
+       assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        return get_r_value_internal(irg->current_block, 0, mode_M);
 }
 
@@ -690,7 +597,7 @@ void set_r_store(ir_graph *irg, ir_node *store)
 {
        ir_node *load, *pload, *pred, *in[2];
 
-       assert(get_irg_phase_state(irg) == phase_building);
+       assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
        /* Beware: due to dead code elimination, a store might become a Bad node even in
           the construction phase. */
        assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
@@ -743,7 +650,10 @@ void ir_set_uninitialized_local_variable_func(
 
 void irg_finalize_cons(ir_graph *irg)
 {
-       set_irg_phase_state(irg, phase_high);
+       ir_node *end_block = get_irg_end_block(irg);
+       mature_immBlock(end_block);
+
+       clear_irg_constraints(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION);
 }
 
 void irp_finalize_cons(void)
@@ -752,7 +662,6 @@ void irp_finalize_cons(void)
        for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
                irg_finalize_cons(get_irp_irg(i));
        }
-       irp->phase_state = phase_high;
 }
 
 ir_node *new_Const_long(ir_mode *mode, long value)
@@ -768,29 +677,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, 0, NULL);
        res->attr.anchor.irg.irg = irg;
 
-       /* hack to get get_irn_irg working: set block to ourself and allow
-        * get_Block_irg for anchor */
+       /* hack to get get_irn_irg in set_irn_in() working */
        res->in[0] = res;
 
+       /* we can't have NULL inputs so reference ourselves for now */
+       for (i = 0; i <= (size_t)anchor_last; ++i) {
+               in[i] = res;
+       }
+       set_irn_in(res, anchor_last+1, in);
+
        return res;
 }
 
@@ -798,12 +710,11 @@ ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
 {
        ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
        res->attr.block.irg.irg = irg;
-       res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
+       res->attr.block.backedge = new_backedge_arr(get_irg_obstack(irg), arity);
        set_Block_matured(res, 1);
        /* Create and initialize array for Phi-node construction. */
-       if (get_irg_phase_state(irg) == phase_building) {
-               res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
-               memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
+       if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION)) {
+               res->attr.block.graph_arr = NEW_ARR_DZ(ir_node*, get_irg_obstack(irg), irg->n_loc);
        }
        irn_verify_irg(res, irg);
        return res;