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