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