Do not generate trailing whitespaces.
[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(target == NULL || get_irn_mode(target) == mode_BB);
531         assert(target == NULL || get_irn_irg(target)  == irg);
532         irg->current_block = target;
533 }
534
535 ir_node *get_r_cur_block(ir_graph *irg)
536 {
537         return irg->current_block;
538 }
539
540 ir_node *get_cur_block(void)
541 {
542         return get_r_cur_block(current_ir_graph);
543 }
544
545 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
546 {
547         assert(get_irg_phase_state(irg) == phase_building);
548         assert(pos >= 0);
549         inc_irg_visited(irg);
550
551         return get_r_value_internal(irg->current_block, pos + 1, mode);
552 }
553
554 ir_node *get_value(int pos, ir_mode *mode)
555 {
556         return get_r_value(current_ir_graph, pos, mode);
557 }
558
559 /**
560  * helper function for guess_mode: recursively look for a definition for
561  * local variable @p pos, returns its mode if found.
562  */
563 static ir_mode *guess_recursively(ir_node *block, int pos)
564 {
565         ir_node *value;
566         int      n_preds;
567         int      i;
568
569         if (irn_visited_else_mark(block))
570                 return NULL;
571
572         /* already have a defintion -> we can simply look at its mode */
573         value = block->attr.block.graph_arr[pos];
574         if (value != NULL)
575                 return get_irn_mode(value);
576
577         /* now we try to guess, by looking at the predecessor blocks */
578         n_preds = get_irn_arity(block);
579         for (i = 0; i < n_preds; ++i) {
580                 ir_node *pred_block = get_Block_cfgpred_block(block, i);
581                 ir_mode *mode       = guess_recursively(pred_block, pos);
582                 if (mode != NULL)
583                         return mode;
584         }
585
586         /* no way to guess */
587         return NULL;
588 }
589
590 ir_mode *ir_r_guess_mode(ir_graph *irg, int pos)
591 {
592         ir_node  *block = irg->current_block;
593         ir_node  *value = block->attr.block.graph_arr[pos+1];
594         ir_mode  *mode;
595
596         /* already have a defintion -> we can simply look at its mode */
597         if (value != NULL)
598                 return get_irn_mode(value);
599
600         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
601         inc_irg_visited(irg);
602         mode = guess_recursively(block, pos+1);
603         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
604
605         return mode;
606 }
607
608 ir_mode *ir_guess_mode(int pos)
609 {
610         return ir_r_guess_mode(current_ir_graph, pos);
611 }
612
613 void set_r_value(ir_graph *irg, int pos, ir_node *value)
614 {
615         assert(get_irg_phase_state(irg) == phase_building);
616         assert(pos >= 0);
617         assert(pos+1 < irg->n_loc);
618         assert(is_ir_node(value));
619         irg->current_block->attr.block.graph_arr[pos + 1] = value;
620 }
621
622 void set_value(int pos, ir_node *value)
623 {
624         set_r_value(current_ir_graph, pos, value);
625 }
626
627 int r_find_value(ir_graph *irg, ir_node *value)
628 {
629         size_t i;
630         ir_node *bl = irg->current_block;
631
632         for (i = ARR_LEN(bl->attr.block.graph_arr); i > 1;) {
633                 if (bl->attr.block.graph_arr[--i] == value)
634                         return i - 1;
635         }
636         return -1;
637 }
638
639 int find_value(ir_node *value)
640 {
641         return r_find_value(current_ir_graph, value);
642 }
643
644 ir_node *get_r_store(ir_graph *irg)
645 {
646         assert(get_irg_phase_state(irg) == phase_building);
647         inc_irg_visited(irg);
648         return get_r_value_internal(irg->current_block, 0, mode_M);
649 }
650
651 ir_node *get_store(void)
652 {
653         return get_r_store(current_ir_graph);
654 }
655
656 void set_r_store(ir_graph *irg, ir_node *store)
657 {
658         ir_node *load, *pload, *pred, *in[2];
659
660         assert(get_irg_phase_state(irg) == phase_building);
661         /* Beware: due to dead code elimination, a store might become a Bad node even in
662            the construction phase. */
663         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
664
665         if (get_opt_auto_create_sync()) {
666                 /* handle non-volatile Load nodes by automatically creating Sync's */
667                 load = skip_Proj(store);
668                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
669                         pred = get_Load_mem(load);
670
671                         if (is_Sync(pred)) {
672                                 /* a Load after a Sync: move it up */
673                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
674
675                                 set_Load_mem(load, get_memop_mem(mem));
676                                 add_Sync_pred(pred, store);
677                                 store = pred;
678                         } else {
679                                 pload = skip_Proj(pred);
680                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
681                                         /* a Load after a Load: create a new Sync */
682                                         set_Load_mem(load, get_Load_mem(pload));
683
684                                         in[0] = pred;
685                                         in[1] = store;
686                                         store = new_r_Sync(irg->current_block, 2, in);
687                                 }
688                         }
689                 }
690         }
691         irg->current_block->attr.block.graph_arr[0] = store;
692 }
693
694 void set_store(ir_node *store)
695 {
696         set_r_store(current_ir_graph, store);
697 }
698
699 void keep_alive(ir_node *ka)
700 {
701         ir_graph *irg = get_irn_irg(ka);
702         add_End_keepalive(get_irg_end(irg), ka);
703 }
704
705 void ir_set_uninitialized_local_variable_func(
706                 uninitialized_local_variable_func_t *func)
707 {
708         default_initialize_local_variable = func;
709 }
710
711 void irg_finalize_cons(ir_graph *irg)
712 {
713         ir_node *end_block = get_irg_end_block(irg);
714         mature_immBlock(end_block);
715
716         set_irg_phase_state(irg, phase_high);
717 }
718
719 void irp_finalize_cons(void)
720 {
721         size_t i, n;
722         for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
723                 irg_finalize_cons(get_irp_irg(i));
724         }
725         irp->phase_state = phase_high;
726 }
727
728 ir_node *new_Const_long(ir_mode *mode, long value)
729 {
730         return new_d_Const_long(NULL, mode, value);
731 }
732
733 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
734 {
735         return new_d_SymConst(NULL, mode, value, kind);
736 }
737 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
738 {
739         return new_d_simpleSel(NULL, store, objptr, ent);
740 }
741 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
742                  size_t n_outs, ir_asm_constraint *outputs,
743                  size_t n_clobber, ident *clobber[], ident *text)
744 {
745         return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
746 }
747
748 ir_node *new_r_Anchor(ir_graph *irg)
749 {
750         ir_node *in[anchor_last+1];
751         ir_node *res;
752         size_t   i;
753         memset(in, 0, sizeof(in));
754         res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last+1, in);
755         res->attr.anchor.irg.irg = irg;
756
757         /* hack to get get_irn_irg working: set block to ourself and allow
758          * get_Block_irg for anchor */
759         res->in[0] = res;
760
761         /* we can't have NULL inputs so reference ourselfes for now */
762         for (i = 0; i <= (size_t)anchor_last; ++i) {
763                 set_irn_n(res, i, res);
764         }
765
766         return res;
767 }
768
769 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
770 {
771         ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
772         res->attr.block.irg.irg = irg;
773         res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
774         set_Block_matured(res, 1);
775         /* Create and initialize array for Phi-node construction. */
776         if (get_irg_phase_state(irg) == phase_building) {
777                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
778                 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
779         }
780         irn_verify_irg(res, irg);
781         return res;
782 }