Simplify control flow.
[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                         inc_irg_visited(irg);
234
235                         value = get_r_value_internal(cfgpred, pos, mode);
236                 }
237                 in[i] = value;
238         }
239
240         phi->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
241         set_irn_in(phi, arity, in);
242
243         irn_verify_irg(phi, irg);
244
245         /* Memory Phis in endless loops must be kept alive.
246            As we can't distinguish these easily we keep all of them alive. */
247         if (mode == mode_M)
248                 add_End_keepalive(get_irg_end(irg), phi);
249
250         try_remove_unnecessary_phi(phi);
251         return phi;
252 }
253
254 /**
255  * This function returns the last definition of a value.  In case
256  * this value was last defined in a previous block, Phi nodes are
257  * inserted.  If the part of the firm graph containing the definition
258  * is not yet constructed, a dummy Phi node is returned.
259  *
260  * @param block   the current block
261  * @param pos     the value number of the value searched
262  * @param mode    the mode of this value (needed for Phi construction)
263  */
264 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
265 {
266         ir_node  *res = block->attr.block.graph_arr[pos];
267         ir_graph *irg = get_irn_irg(block);
268         if (res != NULL)
269                 return res;
270
271         /* We ran into a cycle. This may happen in unreachable loops. */
272         if (irn_visited_else_mark(block)) {
273                 /* Since the loop is unreachable, return a Bad. */
274                 return new_r_Bad(irg, mode);
275         }
276
277         /* in a matured block we can immediately determine the phi arguments */
278         if (get_Block_matured(block)) {
279                 int arity = get_irn_arity(block);
280                 /* no predecessors: use unknown value */
281                 if (arity == 0) {
282                         if (block == get_irg_start_block(irg)) {
283                                 if (default_initialize_local_variable != NULL) {
284                                         ir_node *rem = get_r_cur_block(irg);
285                                         set_r_cur_block(irg, block);
286                                         res = default_initialize_local_variable(irg, mode, pos - 1);
287                                         set_r_cur_block(irg, rem);
288                                 } else {
289                                         res = new_r_Unknown(irg, mode);
290                                 }
291                         } else {
292                                 /* unreachable block, use Bad */
293                                 res = new_r_Bad(irg, mode);
294                         }
295                 /* one predecessor just use its value */
296                 } else if (arity == 1) {
297                         ir_node *cfgpred = get_Block_cfgpred(block, 0);
298                         if (is_Bad(cfgpred)) {
299                                 res = new_r_Bad(irg, mode);
300                         } else {
301                                 ir_node *cfgpred_block = get_nodes_block(cfgpred);
302                                 res = get_r_value_internal(cfgpred_block, pos, mode);
303                         }
304                 /* multiple predecessors construct Phi */
305                 } else {
306                         res = new_rd_Phi0(NULL, block, mode, pos);
307                         /* enter phi0 into our variable value table to break cycles
308                          * arising from set_phi_arguments */
309                         block->attr.block.graph_arr[pos] = res;
310                         res = set_phi_arguments(res, pos);
311                 }
312         } else {
313                 /* in case of immature block we have to keep a Phi0 */
314                 res = new_rd_Phi0(NULL, block, mode, pos);
315                 /* enqueue phi so we can set arguments once the block matures */
316                 res->attr.phi.next     = block->attr.block.phis;
317                 block->attr.block.phis = res;
318         }
319         block->attr.block.graph_arr[pos] = res;
320         return res;
321 }
322
323 void mature_immBlock(ir_node *block)
324 {
325         size_t   n_preds;
326         ir_node  *next;
327         ir_node  *phi;
328         ir_node **new_in;
329         ir_graph *irg;
330
331         assert(is_Block(block));
332         if (get_Block_matured(block))
333                 return;
334
335         irg     = get_irn_irg(block);
336         n_preds = ARR_LEN(block->in) - 1;
337         /* Fix block parameters */
338         block->attr.block.backedge = new_backedge_arr(irg->obst, n_preds);
339
340         /* Traverse a chain of Phi nodes attached to this block and mature
341         these, too. */
342         for (phi = block->attr.block.phis; phi != NULL; phi = next) {
343                 ir_node *new_value;
344                 int      pos = phi->attr.phi.u.pos;
345
346                 next = phi->attr.phi.next;
347                 new_value = set_phi_arguments(phi, pos);
348                 if (block->attr.block.graph_arr[pos] == phi) {
349                         block->attr.block.graph_arr[pos] = new_value;
350                 }
351         }
352
353         set_Block_matured(block, 1);
354
355         /* create final in-array for the block */
356         if (block->attr.block.dynamic_ins) {
357                 new_in = NEW_ARR_D(ir_node*, irg->obst, n_preds+1);
358                 memcpy(new_in, block->in, (n_preds+1) * sizeof(new_in[0]));
359                 DEL_ARR_F(block->in);
360                 block->in = new_in;
361                 block->attr.block.dynamic_ins = false;
362         }
363
364         /* Now, as the block is a finished Firm node, we can optimize it.
365            Since other nodes have been allocated since the block was created
366            we can not free the node on the obstack.  Therefore we have to call
367            optimize_in_place().
368            Unfortunately the optimization does not change a lot, as all allocated
369            nodes refer to the unoptimized node.
370            We can call optimize_in_place_2(), as global cse has no effect on blocks.
371          */
372         irn_verify_irg(block, irg);
373         block = optimize_in_place_2(block);
374 }
375
376 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
377 {
378         assert(get_irg_phase_state(current_ir_graph) == phase_building);
379         return new_rd_Const_long(db, current_ir_graph, mode, value);
380 }
381
382 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
383                          ir_entity *ent)
384 {
385         assert(get_irg_phase_state(current_ir_graph) == phase_building);
386         return new_rd_Sel(db, current_ir_graph->current_block,
387                           store, objptr, 0, NULL, ent);
388 }
389
390 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value,
391                         symconst_kind kind)
392 {
393         assert(get_irg_phase_state(current_ir_graph) == phase_building);
394         return new_rd_SymConst(db, current_ir_graph, mode, value, kind);
395 }
396
397 ir_node *new_d_ASM(dbg_info *db, ir_node *mem, int arity, ir_node *in[],
398                    ir_asm_constraint *inputs,
399                    size_t n_outs, ir_asm_constraint *outputs,
400                    size_t n_clobber, ident *clobber[], ident *text)
401 {
402         assert(get_irg_phase_state(current_ir_graph) == phase_building);
403         return new_rd_ASM(db, current_ir_graph->current_block, mem, arity, in,
404                           inputs, n_outs, outputs, n_clobber, clobber, text);
405 }
406
407 ir_node *new_rd_strictConv(dbg_info *dbgi, ir_node *block, ir_node * irn_op, ir_mode * mode)
408 {
409         ir_node *res;
410         ir_graph *irg = get_Block_irg(block);
411
412         ir_node *in[1];
413         in[0] = irn_op;
414
415         res = new_ir_node(dbgi, irg, block, op_Conv, mode, 1, in);
416         res->attr.conv.strict = 1;
417         irn_verify_irg(res, irg);
418         res = optimize_node(res);
419         return res;
420 }
421
422 ir_node *new_r_strictConv(ir_node *block, ir_node * irn_op, ir_mode * mode)
423 {
424         return new_rd_strictConv(NULL, block, irn_op, mode);
425 }
426
427 ir_node *new_d_strictConv(dbg_info *dbgi, ir_node * irn_op, ir_mode * mode)
428 {
429         ir_node *res;
430         assert(get_irg_phase_state(current_ir_graph) == phase_building);
431         res = new_rd_strictConv(dbgi, current_ir_graph->current_block, irn_op, mode);
432         return res;
433 }
434
435 ir_node *new_strictConv(ir_node * irn_op, ir_mode * mode)
436 {
437         return new_d_strictConv(NULL, irn_op, mode);
438 }
439
440 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)
441 {
442         ir_node *res;
443         ir_graph *irg = get_Block_irg(block);
444
445         ir_node *in[3];
446         in[0] = irn_mem;
447         in[1] = irn_left;
448         in[2] = irn_right;
449
450         res = new_ir_node(dbgi, irg, block, op_Div, mode_T, 3, in);
451         res->attr.div.resmode = resmode;
452         res->attr.div.no_remainder = 1;
453         res->attr.div.exc.pin_state = pin_state;
454         irn_verify_irg(res, irg);
455         res = optimize_node(res);
456         return res;
457 }
458
459 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)
460 {
461         return new_rd_DivRL(NULL, block, irn_mem, irn_left, irn_right, resmode, pin_state);
462 }
463
464 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)
465 {
466         ir_node *res;
467         assert(get_irg_phase_state(current_ir_graph) == phase_building);
468         res = new_rd_DivRL(dbgi, current_ir_graph->current_block, irn_mem, irn_left, irn_right, resmode, pin_state);
469         return res;
470 }
471
472 ir_node *new_DivRL(ir_node * irn_mem, ir_node * irn_left, ir_node * irn_right, ir_mode* resmode, op_pin_state pin_state)
473 {
474         return new_d_DivRL(NULL, irn_mem, irn_left, irn_right, resmode, pin_state);
475 }
476
477 ir_node *new_rd_immBlock(dbg_info *dbgi, ir_graph *irg)
478 {
479         ir_node *res;
480
481         assert(get_irg_phase_state(irg) == phase_building);
482         /* creates a new dynamic in-array as length of in is -1 */
483         res = new_ir_node(dbgi, irg, NULL, op_Block, mode_BB, -1, NULL);
484
485         set_Block_matured(res, 0);
486         res->attr.block.dynamic_ins = true;
487         res->attr.block.irg.irg     = irg;
488         res->attr.block.backedge    = NULL;
489         res->attr.block.entity      = NULL;
490
491         set_Block_block_visited(res, 0);
492
493         /* Create and initialize array for Phi-node construction. */
494         res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
495         memset(res->attr.block.graph_arr, 0, sizeof(ir_node*) * irg->n_loc);
496
497         /* Immature block may not be optimized! */
498         irn_verify_irg(res, irg);
499
500         return res;
501 }
502
503 ir_node *new_r_immBlock(ir_graph *irg)
504 {
505         return new_rd_immBlock(NULL, irg);
506 }
507
508 ir_node *new_d_immBlock(dbg_info *dbgi)
509 {
510         return new_rd_immBlock(dbgi, current_ir_graph);
511 }
512
513 ir_node *new_immBlock(void)
514 {
515         return new_rd_immBlock(NULL, current_ir_graph);
516 }
517
518 void add_immBlock_pred(ir_node *block, ir_node *jmp)
519 {
520         int n = ARR_LEN(block->in) - 1;
521
522         assert(is_Block(block) && "Error: Must be a Block");
523         assert(!get_Block_matured(block) && "Error: Block already matured!\n");
524         assert(is_ir_node(jmp));
525
526         ARR_APP1(ir_node *, block->in, jmp);
527         /* Call the hook */
528         hook_set_irn_n(block, n, jmp, NULL);
529 }
530
531 void set_cur_block(ir_node *target)
532 {
533         set_r_cur_block(current_ir_graph, target);
534 }
535
536 void set_r_cur_block(ir_graph *irg, ir_node *target)
537 {
538         assert(get_irg_phase_state(irg) == phase_building);
539         assert(target == NULL || is_Block(target));
540         assert(target == NULL || get_irn_irg(target) == irg);
541         irg->current_block = target;
542 }
543
544 ir_node *get_r_cur_block(ir_graph *irg)
545 {
546         assert(get_irg_phase_state(irg) == phase_building);
547         return irg->current_block;
548 }
549
550 ir_node *get_cur_block(void)
551 {
552         return get_r_cur_block(current_ir_graph);
553 }
554
555 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
556 {
557         assert(get_irg_phase_state(irg) == phase_building);
558         assert(pos >= 0);
559         inc_irg_visited(irg);
560
561         return get_r_value_internal(irg->current_block, pos + 1, mode);
562 }
563
564 ir_node *get_value(int pos, ir_mode *mode)
565 {
566         return get_r_value(current_ir_graph, pos, mode);
567 }
568
569 /**
570  * helper function for guess_mode: recursively look for a definition for
571  * local variable @p pos, returns its mode if found.
572  */
573 static ir_mode *guess_recursively(ir_node *block, int pos)
574 {
575         ir_node *value;
576         int      n_preds;
577         int      i;
578
579         if (irn_visited_else_mark(block))
580                 return NULL;
581
582         /* already have a defintion -> we can simply look at its mode */
583         value = block->attr.block.graph_arr[pos];
584         if (value != NULL)
585                 return get_irn_mode(value);
586
587         /* now we try to guess, by looking at the predecessor blocks */
588         n_preds = get_irn_arity(block);
589         for (i = 0; i < n_preds; ++i) {
590                 ir_node *pred_block = get_Block_cfgpred_block(block, i);
591                 ir_mode *mode       = guess_recursively(pred_block, pos);
592                 if (mode != NULL)
593                         return mode;
594         }
595
596         /* no way to guess */
597         return NULL;
598 }
599
600 ir_mode *ir_r_guess_mode(ir_graph *irg, int pos)
601 {
602         ir_node  *block = irg->current_block;
603         ir_node  *value = block->attr.block.graph_arr[pos+1];
604         ir_mode  *mode;
605
606         /* already have a defintion -> we can simply look at its mode */
607         if (value != NULL)
608                 return get_irn_mode(value);
609
610         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
611         inc_irg_visited(irg);
612         mode = guess_recursively(block, pos+1);
613         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
614
615         return mode;
616 }
617
618 ir_mode *ir_guess_mode(int pos)
619 {
620         return ir_r_guess_mode(current_ir_graph, pos);
621 }
622
623 void set_r_value(ir_graph *irg, int pos, ir_node *value)
624 {
625         assert(get_irg_phase_state(irg) == phase_building);
626         assert(pos >= 0);
627         assert(pos+1 < irg->n_loc);
628         assert(is_ir_node(value));
629         irg->current_block->attr.block.graph_arr[pos + 1] = value;
630 }
631
632 void set_value(int pos, ir_node *value)
633 {
634         set_r_value(current_ir_graph, pos, value);
635 }
636
637 ir_node *get_r_store(ir_graph *irg)
638 {
639         assert(get_irg_phase_state(irg) == phase_building);
640         inc_irg_visited(irg);
641         return get_r_value_internal(irg->current_block, 0, mode_M);
642 }
643
644 ir_node *get_store(void)
645 {
646         return get_r_store(current_ir_graph);
647 }
648
649 void set_r_store(ir_graph *irg, ir_node *store)
650 {
651         ir_node *load, *pload, *pred, *in[2];
652
653         assert(get_irg_phase_state(irg) == phase_building);
654         /* Beware: due to dead code elimination, a store might become a Bad node even in
655            the construction phase. */
656         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
657
658         if (get_opt_auto_create_sync()) {
659                 /* handle non-volatile Load nodes by automatically creating Sync's */
660                 load = skip_Proj(store);
661                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
662                         pred = get_Load_mem(load);
663
664                         if (is_Sync(pred)) {
665                                 /* a Load after a Sync: move it up */
666                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
667
668                                 set_Load_mem(load, get_memop_mem(mem));
669                                 add_Sync_pred(pred, store);
670                                 store = pred;
671                         } else {
672                                 pload = skip_Proj(pred);
673                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
674                                         /* a Load after a Load: create a new Sync */
675                                         set_Load_mem(load, get_Load_mem(pload));
676
677                                         in[0] = pred;
678                                         in[1] = store;
679                                         store = new_r_Sync(irg->current_block, 2, in);
680                                 }
681                         }
682                 }
683         }
684         irg->current_block->attr.block.graph_arr[0] = store;
685 }
686
687 void set_store(ir_node *store)
688 {
689         set_r_store(current_ir_graph, store);
690 }
691
692 void keep_alive(ir_node *ka)
693 {
694         ir_graph *irg = get_irn_irg(ka);
695         add_End_keepalive(get_irg_end(irg), ka);
696 }
697
698 void ir_set_uninitialized_local_variable_func(
699                 uninitialized_local_variable_func_t *func)
700 {
701         default_initialize_local_variable = func;
702 }
703
704 void irg_finalize_cons(ir_graph *irg)
705 {
706         ir_node *end_block = get_irg_end_block(irg);
707         mature_immBlock(end_block);
708
709         set_irg_phase_state(irg, phase_high);
710 }
711
712 void irp_finalize_cons(void)
713 {
714         size_t i, n;
715         for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
716                 irg_finalize_cons(get_irp_irg(i));
717         }
718         irp->phase_state = phase_high;
719 }
720
721 ir_node *new_Const_long(ir_mode *mode, long value)
722 {
723         return new_d_Const_long(NULL, mode, value);
724 }
725
726 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
727 {
728         return new_d_SymConst(NULL, mode, value, kind);
729 }
730 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
731 {
732         return new_d_simpleSel(NULL, store, objptr, ent);
733 }
734 ir_node *new_ASM(ir_node *mem, int arity, ir_node *in[],
735                  ir_asm_constraint *inputs, size_t n_outs,
736                  ir_asm_constraint *outputs, size_t n_clobber,
737                  ident *clobber[], ident *text)
738 {
739         return new_d_ASM(NULL, mem, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
740 }
741
742 ir_node *new_r_Anchor(ir_graph *irg)
743 {
744         ir_node *in[anchor_last+1];
745         ir_node *res;
746         size_t   i;
747         memset(in, 0, sizeof(in));
748         res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last+1, in);
749         res->attr.anchor.irg.irg = irg;
750
751         /* hack to get get_irn_irg working: set block to ourself and allow
752          * get_Block_irg for anchor */
753         res->in[0] = res;
754
755         /* we can't have NULL inputs so reference ourselfes for now */
756         for (i = 0; i <= (size_t)anchor_last; ++i) {
757                 set_irn_n(res, i, res);
758         }
759
760         return res;
761 }
762
763 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
764 {
765         ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
766         res->attr.block.irg.irg = irg;
767         res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
768         set_Block_matured(res, 1);
769         /* Create and initialize array for Phi-node construction. */
770         if (get_irg_phase_state(irg) == phase_building) {
771                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
772                 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
773         }
774         irn_verify_irg(res, irg);
775         return res;
776 }