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