beifg: Factorise code to count interference components.
[libfirm] / ir / ir / ircons.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief   Various irnode constructors. Automatic construction of SSA
9  *          representation.
10  * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Boris Boesler
11  *          Michael Beck, Matthias Braun
12  */
13 #include "config.h"
14
15 #include "irprog_t.h"
16 #include "irgraph_t.h"
17 #include "irnode_t.h"
18 #include "irmode_t.h"
19 #include "ircons_t.h"
20 #include "irverify.h"
21 #include "irop_t.h"
22 #include "iropt_t.h"
23 #include "irgmod.h"
24 #include "irhooks.h"
25 #include "array_t.h"
26 #include "irbackedge_t.h"
27 #include "irflag_t.h"
28 #include "iredges_t.h"
29 #include "irflag_t.h"
30 #include "error.h"
31
32 #include "gen_ir_cons.c.inl"
33
34 /**
35  * Language dependent variable initialization callback.
36  */
37 static uninitialized_local_variable_func_t *default_initialize_local_variable = NULL;
38
39 ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode,
40                            long value)
41 {
42         return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
43 }
44
45 ir_node *new_rd_ASM(dbg_info *db, ir_node *block, ir_node *mem,
46                     int arity, ir_node *in[], ir_asm_constraint *inputs,
47                     size_t n_outs, ir_asm_constraint *outputs, size_t n_clobber,
48                         ident *clobber[], ident *text)
49 {
50         ir_graph *irg = get_irn_irg(block);
51
52         int r_arity = arity+1;
53         ir_node **r_in;
54         NEW_ARR_A(ir_node*, r_in, r_arity);
55         r_in[0] = mem;
56         memcpy(&r_in[1], in, arity*sizeof(ir_node*));
57
58         ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, r_arity, r_in);
59
60         struct obstack *const obst = get_irg_obstack(irg);
61         res->attr.assem.pin_state          = op_pin_state_pinned;
62         res->attr.assem.input_constraints  = NEW_ARR_D(ir_asm_constraint, obst, arity);
63         res->attr.assem.output_constraints = NEW_ARR_D(ir_asm_constraint, obst, n_outs);
64         res->attr.assem.clobbers           = NEW_ARR_D(ident*,            obst, n_clobber);
65         res->attr.assem.text               = text;
66
67         memcpy(res->attr.assem.input_constraints,  inputs,  sizeof(inputs[0]) * arity);
68         memcpy(res->attr.assem.output_constraints, outputs, sizeof(outputs[0]) * n_outs);
69         memcpy(res->attr.assem.clobbers, clobber, sizeof(clobber[0]) * n_clobber);
70
71         irn_verify_irg(res, irg);
72         res = optimize_node(res);
73         return res;
74 }
75
76 ir_node *new_rd_simpleSel(dbg_info *db, ir_node *block, ir_node *store,
77                           ir_node *objptr, ir_entity *ent)
78 {
79         return new_rd_Sel(db, block, store, objptr, 0, NULL, ent);
80 }
81
82 ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
83                          symconst_symbol value, symconst_kind symkind)
84 {
85         ir_node *block = get_irg_start_block(irg);
86         ir_node *res   = new_ir_node(db, irg, block, op_SymConst, mode, 0, NULL);
87         res->attr.symc.kind = symkind;
88         res->attr.symc.sym  = value;
89
90         irn_verify_irg(res, irg);
91         res = optimize_node(res);
92         return res;
93 }
94
95 ir_node *new_rd_SymConst_addr_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol)
96 {
97         symconst_symbol sym;
98         sym.entity_p = symbol;
99         return new_rd_SymConst(db, irg, mode, sym, symconst_addr_ent);
100 }
101
102 ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol)
103 {
104         symconst_symbol sym;
105         sym.entity_p = symbol;
106         return new_rd_SymConst(db, irg, mode, sym, symconst_ofs_ent);
107 }
108
109 ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
110 {
111         symconst_symbol sym;
112         sym.type_p = symbol;
113         return new_rd_SymConst(db, irg, mode, sym, symconst_type_size);
114 }
115
116 ir_node *new_rd_SymConst_align(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
117 {
118         symconst_symbol sym;
119         sym.type_p = symbol;
120         return new_rd_SymConst(db, irg, mode, sym, symconst_type_align);
121 }
122
123 ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value)
124 {
125         return new_rd_Const_long(NULL, irg, mode, value);
126 }
127 ir_node *new_r_SymConst(ir_graph *irg, ir_mode *mode, symconst_symbol value,
128                         symconst_kind symkind)
129 {
130         return new_rd_SymConst(NULL, irg, mode, value, symkind);
131 }
132 ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr,
133                          ir_entity *ent)
134 {
135         return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
136 }
137 ir_node *new_r_ASM(ir_node *block, ir_node *mem,
138                    int arity, ir_node *in[], ir_asm_constraint *inputs,
139                    size_t n_outs, ir_asm_constraint *outputs,
140                    size_t n_clobber, ident *clobber[], ident *text)
141 {
142         return new_rd_ASM(NULL, block, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
143 }
144
145 /** Creates a Phi node with 0 predecessors. */
146 static inline ir_node *new_rd_Phi0(dbg_info *dbgi, ir_node *block,
147                                    ir_mode *mode, int pos)
148 {
149         ir_graph *irg = get_irn_irg(block);
150         ir_node  *res = new_ir_node(dbgi, irg, block, op_Phi, mode, 0, NULL);
151         res->attr.phi.u.pos = pos;
152         irn_verify_irg(res, irg);
153         return res;
154 }
155
156 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode);
157
158 static void try_remove_unnecessary_phi(ir_node *phi)
159 {
160         ir_node *phi_value = NULL;
161         int      arity     = get_irn_arity(phi);
162         int      i;
163
164         /* see if all inputs are either pointing to a single value or
165          * are self references */
166         for (i = 0; i < arity; ++i) {
167                 ir_node *in = get_irn_n(phi, i);
168                 if (in == phi)
169                         continue;
170                 if (in == phi_value)
171                         continue;
172                 /** found a different value from the one we already found, can't remove
173                  * the phi (yet) */
174                 if (phi_value != NULL)
175                         return;
176                 phi_value = in;
177         }
178         if (phi_value == NULL)
179                 return;
180
181         /* if we're here then all phi inputs have been either phi_value
182          * or self-references, we can replace the phi by phi_value.
183          * We do this with an Id-node */
184         exchange(phi, phi_value);
185
186         /* recursively check phi_value, because it could be that we were the last
187          * phi-node in a loop-body. Then our arguments is an unnecessary phi in
188          * the loop header which can be eliminated now */
189         if (is_Phi(phi_value)) {
190                 try_remove_unnecessary_phi(phi_value);
191         }
192 }
193
194 /**
195  * Computes the predecessors for the real phi node, and then
196  * allocates and returns this node.  The routine called to allocate the
197  * node might optimize it away and return a real value.
198  * This function must be called with an in-array of proper size.
199  */
200 static ir_node *set_phi_arguments(ir_node *phi, int pos)
201 {
202         ir_node  *block        = get_nodes_block(phi);
203         ir_graph *irg          = get_irn_irg(block);
204         int       arity        = get_irn_arity(block);
205         ir_node **in           = ALLOCAN(ir_node*, arity);
206         ir_mode  *mode         = get_irn_mode(phi);
207         int       i;
208
209         /* This loop goes to all predecessor blocks of the block the Phi node
210            is in and there finds the operands of the Phi node by calling
211            get_r_value_internal.  */
212         for (i = 0; i < arity; ++i) {
213                 ir_node *cfgpred = get_Block_cfgpred_block(block, i);
214                 ir_node *value;
215                 if (is_Bad(cfgpred)) {
216                         value = new_r_Bad(irg, mode);
217                 } else {
218                         value = get_r_value_internal(cfgpred, pos, mode);
219                 }
220                 in[i] = value;
221         }
222
223         phi->attr.phi.u.backedge = new_backedge_arr(get_irg_obstack(irg), arity);
224         set_irn_in(phi, arity, in);
225
226         irn_verify_irg(phi, irg);
227
228         try_remove_unnecessary_phi(phi);
229         return phi;
230 }
231
232 /**
233  * This function returns the last definition of a value.  In case
234  * this value was last defined in a previous block, Phi nodes are
235  * inserted.  If the part of the firm graph containing the definition
236  * is not yet constructed, a dummy Phi node is returned.
237  *
238  * @param block   the current block
239  * @param pos     the value number of the value searched
240  * @param mode    the mode of this value (needed for Phi construction)
241  */
242 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
243 {
244         ir_node  *res = block->attr.block.graph_arr[pos];
245         ir_graph *irg = get_irn_irg(block);
246         if (res != NULL)
247                 return res;
248
249         /* in a matured block we can immediately determine the phi arguments */
250         if (get_Block_matured(block)) {
251                 int arity = get_irn_arity(block);
252                 /* no predecessors: use unknown value */
253                 if (arity == 0) {
254                         if (block == get_irg_start_block(irg)) {
255                                 if (default_initialize_local_variable != NULL) {
256                                         ir_node *rem = get_r_cur_block(irg);
257                                         set_r_cur_block(irg, block);
258                                         res = default_initialize_local_variable(irg, mode, pos - 1);
259                                         set_r_cur_block(irg, rem);
260                                 } else {
261                                         res = new_r_Unknown(irg, mode);
262                                 }
263                         } else {
264                                 /* unreachable block, use Bad */
265                                 res = new_r_Bad(irg, mode);
266                         }
267                 /* one predecessor just use its value */
268                 } else if (arity == 1) {
269                         ir_node *cfgpred = get_Block_cfgpred(block, 0);
270                         if (is_Bad(cfgpred)) {
271                                 res = new_r_Bad(irg, mode);
272                         } else {
273                                 ir_node *cfgpred_block = get_nodes_block(cfgpred);
274                                 res = get_r_value_internal(cfgpred_block, pos, mode);
275                         }
276                 /* multiple predecessors construct Phi */
277                 } else {
278                         res = new_rd_Phi0(NULL, block, mode, pos);
279                         /* enter phi0 into our variable value table to break cycles
280                          * arising from set_phi_arguments */
281                         block->attr.block.graph_arr[pos] = res;
282                         res = set_phi_arguments(res, pos);
283                 }
284         } else {
285                 /* in case of immature block we have to keep a Phi0 */
286                 res = new_rd_Phi0(NULL, block, mode, pos);
287                 /* enqueue phi so we can set arguments once the block matures */
288                 res->attr.phi.next     = block->attr.block.phis;
289                 block->attr.block.phis = res;
290         }
291         block->attr.block.graph_arr[pos] = res;
292         return res;
293 }
294
295 void mature_immBlock(ir_node *block)
296 {
297         size_t   n_preds;
298         ir_node  *next;
299         ir_node  *phi;
300         ir_graph *irg;
301
302         if (get_Block_matured(block))
303                 return;
304
305         irg     = get_irn_irg(block);
306         n_preds = ARR_LEN(block->in) - 1;
307         /* Fix block parameters */
308         block->attr.block.backedge = new_backedge_arr(get_irg_obstack(irg), n_preds);
309
310         /* Traverse a chain of Phi nodes attached to this block and mature
311         these, too. */
312         for (phi = block->attr.block.phis; phi != NULL; phi = next) {
313                 ir_node *new_value;
314                 int      pos = phi->attr.phi.u.pos;
315
316                 next = phi->attr.phi.next;
317                 new_value = set_phi_arguments(phi, pos);
318                 if (block->attr.block.graph_arr[pos] == phi) {
319                         block->attr.block.graph_arr[pos] = new_value;
320                 }
321         }
322
323         set_Block_matured(block, 1);
324
325         /* create final in-array for the block */
326         if (block->attr.block.dynamic_ins) {
327                 ir_node **const new_in = DUP_ARR_D(ir_node*, get_irg_obstack(irg), block->in);
328                 DEL_ARR_F(block->in);
329                 block->in = new_in;
330                 block->attr.block.dynamic_ins = false;
331         }
332
333         /* Now, as the block is a finished Firm node, we can optimize it.
334            Since other nodes have been allocated since the block was created
335            we can not free the node on the obstack.  Therefore we have to call
336            optimize_in_place().
337            Unfortunately the optimization does not change a lot, as all allocated
338            nodes refer to the unoptimized node.
339            We can call optimize_in_place_2(), as global cse has no effect on blocks.
340          */
341         irn_verify_irg(block, irg);
342         optimize_in_place_2(block);
343 }
344
345 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
346 {
347         assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
348         return new_rd_Const_long(db, current_ir_graph, mode, value);
349 }
350
351 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
352                          ir_entity *ent)
353 {
354         assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
355         return new_rd_Sel(db, current_ir_graph->current_block,
356                           store, objptr, 0, NULL, ent);
357 }
358
359 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value,
360                         symconst_kind kind)
361 {
362         assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
363         return new_rd_SymConst(db, current_ir_graph, mode, value, kind);
364 }
365
366 ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[],
367                    ir_asm_constraint *inputs,
368                    size_t n_outs, ir_asm_constraint *outputs,
369                    size_t n_clobber, ident *clobber[], ident *text)
370 {
371         assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
372         return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in,
373                           inputs, n_outs, outputs, n_clobber, clobber, text);
374 }
375
376 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)
377 {
378         ir_node *res;
379         ir_graph *irg = get_Block_irg(block);
380
381         ir_node *in[3];
382         in[0] = irn_mem;
383         in[1] = irn_left;
384         in[2] = irn_right;
385
386         res = new_ir_node(dbgi, irg, block, op_Div, mode_T, 3, in);
387         res->attr.div.resmode = resmode;
388         res->attr.div.no_remainder = 1;
389         res->attr.div.exc.pin_state = pin_state;
390         irn_verify_irg(res, irg);
391         res = optimize_node(res);
392         return res;
393 }
394
395 ir_node *new_r_DivRL(ir_node *block, ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
396 {
397         return new_rd_DivRL(NULL, block, irn_mem, irn_left, irn_right, resmode, pin_state);
398 }
399
400 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)
401 {
402         ir_node *res;
403         assert(irg_is_constrained(current_ir_graph, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
404         res = new_rd_DivRL(dbgi, current_ir_graph->current_block, irn_mem, irn_left, irn_right, resmode, pin_state);
405         return res;
406 }
407
408 ir_node *new_DivRL(ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
409 {
410         return new_d_DivRL(NULL, irn_mem, irn_left, irn_right, resmode, pin_state);
411 }
412
413 ir_node *new_rd_immBlock(dbg_info *dbgi, ir_graph *irg)
414 {
415         ir_node *res;
416
417         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
418         /* creates a new dynamic in-array as length of in is -1 */
419         res = new_ir_node(dbgi, irg, NULL, op_Block, mode_BB, -1, NULL);
420
421         set_Block_matured(res, 0);
422         res->attr.block.dynamic_ins = true;
423         res->attr.block.irg.irg     = irg;
424         res->attr.block.backedge    = NULL;
425         res->attr.block.entity      = NULL;
426
427         set_Block_block_visited(res, 0);
428
429         /* Create and initialize array for Phi-node construction. */
430         res->attr.block.graph_arr = NEW_ARR_DZ(ir_node*, get_irg_obstack(irg), irg->n_loc);
431
432         /* Immature block may not be optimized! */
433         irn_verify_irg(res, irg);
434
435         return res;
436 }
437
438 ir_node *new_r_immBlock(ir_graph *irg)
439 {
440         return new_rd_immBlock(NULL, irg);
441 }
442
443 ir_node *new_d_immBlock(dbg_info *dbgi)
444 {
445         return new_rd_immBlock(dbgi, current_ir_graph);
446 }
447
448 ir_node *new_immBlock(void)
449 {
450         return new_rd_immBlock(NULL, current_ir_graph);
451 }
452
453 void add_immBlock_pred(ir_node *block, ir_node *jmp)
454 {
455         int n = ARR_LEN(block->in) - 1;
456
457         assert(is_Block(block) && "Error: Must be a Block");
458         assert(!get_Block_matured(block) && "Error: Block already matured!\n");
459         assert(is_ir_node(jmp));
460
461         ARR_APP1(ir_node *, block->in, jmp);
462         /* Call the hook */
463         hook_set_irn_n(block, n, jmp, NULL);
464 }
465
466 void set_cur_block(ir_node *target)
467 {
468         set_r_cur_block(current_ir_graph, target);
469 }
470
471 void set_r_cur_block(ir_graph *irg, ir_node *target)
472 {
473         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
474         assert(target == NULL || is_Block(target));
475         assert(target == NULL || get_irn_irg(target) == irg);
476         irg->current_block = target;
477 }
478
479 ir_node *get_r_cur_block(ir_graph *irg)
480 {
481         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
482         return irg->current_block;
483 }
484
485 ir_node *get_cur_block(void)
486 {
487         return get_r_cur_block(current_ir_graph);
488 }
489
490 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
491 {
492         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
493         assert(pos >= 0);
494
495         return get_r_value_internal(irg->current_block, pos + 1, mode);
496 }
497
498 ir_node *get_value(int pos, ir_mode *mode)
499 {
500         return get_r_value(current_ir_graph, pos, mode);
501 }
502
503 /**
504  * helper function for guess_mode: recursively look for a definition for
505  * local variable @p pos, returns its mode if found.
506  */
507 static ir_mode *guess_recursively(ir_node *block, int pos)
508 {
509         ir_node *value;
510         int      n_preds;
511         int      i;
512
513         if (irn_visited_else_mark(block))
514                 return NULL;
515
516         /* already have a defintion -> we can simply look at its mode */
517         value = block->attr.block.graph_arr[pos];
518         if (value != NULL)
519                 return get_irn_mode(value);
520
521         /* now we try to guess, by looking at the predecessor blocks */
522         n_preds = get_irn_arity(block);
523         for (i = 0; i < n_preds; ++i) {
524                 ir_node *pred_block = get_Block_cfgpred_block(block, i);
525                 ir_mode *mode       = guess_recursively(pred_block, pos);
526                 if (mode != NULL)
527                         return mode;
528         }
529
530         /* no way to guess */
531         return NULL;
532 }
533
534 ir_mode *ir_r_guess_mode(ir_graph *irg, int pos)
535 {
536         ir_node  *block = irg->current_block;
537         ir_node  *value = block->attr.block.graph_arr[pos+1];
538         ir_mode  *mode;
539
540         /* already have a defintion -> we can simply look at its mode */
541         if (value != NULL)
542                 return get_irn_mode(value);
543
544         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
545         inc_irg_visited(irg);
546         mode = guess_recursively(block, pos+1);
547         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
548
549         return mode;
550 }
551
552 ir_mode *ir_guess_mode(int pos)
553 {
554         return ir_r_guess_mode(current_ir_graph, pos);
555 }
556
557 void set_r_value(ir_graph *irg, int pos, ir_node *value)
558 {
559         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
560         assert(pos >= 0);
561         assert(pos+1 < irg->n_loc);
562         assert(is_ir_node(value));
563         irg->current_block->attr.block.graph_arr[pos + 1] = value;
564 }
565
566 void set_value(int pos, ir_node *value)
567 {
568         set_r_value(current_ir_graph, pos, value);
569 }
570
571 ir_node *get_r_store(ir_graph *irg)
572 {
573         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
574         return get_r_value_internal(irg->current_block, 0, mode_M);
575 }
576
577 ir_node *get_store(void)
578 {
579         return get_r_store(current_ir_graph);
580 }
581
582 void set_r_store(ir_graph *irg, ir_node *store)
583 {
584         ir_node *load, *pload, *pred, *in[2];
585
586         assert(irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION));
587         /* Beware: due to dead code elimination, a store might become a Bad node even in
588            the construction phase. */
589         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
590
591         if (get_opt_auto_create_sync()) {
592                 /* handle non-volatile Load nodes by automatically creating Sync's */
593                 load = skip_Proj(store);
594                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
595                         pred = get_Load_mem(load);
596
597                         if (is_Sync(pred)) {
598                                 /* a Load after a Sync: move it up */
599                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
600
601                                 set_Load_mem(load, get_memop_mem(mem));
602                                 add_Sync_pred(pred, store);
603                                 store = pred;
604                         } else {
605                                 pload = skip_Proj(pred);
606                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
607                                         /* a Load after a Load: create a new Sync */
608                                         set_Load_mem(load, get_Load_mem(pload));
609
610                                         in[0] = pred;
611                                         in[1] = store;
612                                         store = new_r_Sync(irg->current_block, 2, in);
613                                 }
614                         }
615                 }
616         }
617         irg->current_block->attr.block.graph_arr[0] = store;
618 }
619
620 void set_store(ir_node *store)
621 {
622         set_r_store(current_ir_graph, store);
623 }
624
625 void keep_alive(ir_node *ka)
626 {
627         ir_graph *irg = get_irn_irg(ka);
628         add_End_keepalive(get_irg_end(irg), ka);
629 }
630
631 void ir_set_uninitialized_local_variable_func(
632                 uninitialized_local_variable_func_t *func)
633 {
634         default_initialize_local_variable = func;
635 }
636
637 void irg_finalize_cons(ir_graph *irg)
638 {
639         ir_node *end_block = get_irg_end_block(irg);
640         mature_immBlock(end_block);
641
642         clear_irg_constraints(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION);
643 }
644
645 void irp_finalize_cons(void)
646 {
647         size_t i, n;
648         for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
649                 irg_finalize_cons(get_irp_irg(i));
650         }
651 }
652
653 ir_node *new_Const_long(ir_mode *mode, long value)
654 {
655         return new_d_Const_long(NULL, mode, value);
656 }
657
658 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
659 {
660         return new_d_SymConst(NULL, mode, value, kind);
661 }
662 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
663 {
664         return new_d_simpleSel(NULL, store, objptr, ent);
665 }
666 ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[],
667                  ir_asm_constraint *inputs, size_t n_outs,
668                  ir_asm_constraint *outputs, size_t n_clobber,
669                  ident *clobber[], ident *text)
670 {
671         return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
672 }
673
674 ir_node *new_r_Anchor(ir_graph *irg)
675 {
676         ir_node *in[anchor_last+1];
677         ir_node *res;
678         size_t   i;
679         memset(in, 0, sizeof(in));
680         res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, 0, NULL);
681         res->attr.anchor.irg.irg = irg;
682
683         /* hack to get get_irn_irg in set_irn_in() working */
684         res->in[0] = res;
685
686         /* we can't have NULL inputs so reference ourselves for now */
687         for (i = 0; i <= (size_t)anchor_last; ++i) {
688                 in[i] = res;
689         }
690         set_irn_in(res, anchor_last+1, in);
691
692         return res;
693 }
694
695 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
696 {
697         ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
698         res->attr.block.irg.irg = irg;
699         res->attr.block.backedge = new_backedge_arr(get_irg_obstack(irg), arity);
700         set_Block_matured(res, 1);
701         /* Create and initialize array for Phi-node construction. */
702         if (irg_is_constrained(irg, IR_GRAPH_CONSTRAINT_CONSTRUCTION)) {
703                 res->attr.block.graph_arr = NEW_ARR_DZ(ir_node*, get_irg_obstack(irg), irg->n_loc);
704         }
705         irn_verify_irg(res, irg);
706         return res;
707 }