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