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