273e3c1d258ee85d25fa2934f7c375e00d27fec7
[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.extblk      = NULL;
479         res->attr.block.entity      = NULL;
480
481         set_Block_block_visited(res, 0);
482
483         /* Create and initialize array for Phi-node construction. */
484         res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
485         memset(res->attr.block.graph_arr, 0, sizeof(ir_node*) * irg->n_loc);
486
487         /* Immature block may not be optimized! */
488         irn_verify_irg(res, irg);
489
490         return res;
491 }
492
493 ir_node *new_r_immBlock(ir_graph *irg)
494 {
495         return new_rd_immBlock(NULL, irg);
496 }
497
498 ir_node *new_d_immBlock(dbg_info *dbgi)
499 {
500         return new_rd_immBlock(dbgi, current_ir_graph);
501 }
502
503 ir_node *new_immBlock(void)
504 {
505         return new_rd_immBlock(NULL, current_ir_graph);
506 }
507
508 void add_immBlock_pred(ir_node *block, ir_node *jmp)
509 {
510         int n = ARR_LEN(block->in) - 1;
511
512         assert(is_Block(block) && "Error: Must be a Block");
513         assert(!get_Block_matured(block) && "Error: Block already matured!\n");
514         assert(is_ir_node(jmp));
515
516         ARR_APP1(ir_node *, block->in, jmp);
517         /* Call the hook */
518         hook_set_irn_n(block, n, jmp, NULL);
519 }
520
521 void set_cur_block(ir_node *target)
522 {
523         set_r_cur_block(current_ir_graph, target);
524 }
525
526 void set_r_cur_block(ir_graph *irg, ir_node *target)
527 {
528         assert(get_irg_phase_state(irg) == phase_building);
529         assert(target == NULL || is_Block(target));
530         assert(target == NULL || get_irn_irg(target) == irg);
531         irg->current_block = target;
532 }
533
534 ir_node *get_r_cur_block(ir_graph *irg)
535 {
536         assert(get_irg_phase_state(irg) == phase_building);
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 ir_node *get_r_store(ir_graph *irg)
628 {
629         assert(get_irg_phase_state(irg) == phase_building);
630         inc_irg_visited(irg);
631         return get_r_value_internal(irg->current_block, 0, mode_M);
632 }
633
634 ir_node *get_store(void)
635 {
636         return get_r_store(current_ir_graph);
637 }
638
639 void set_r_store(ir_graph *irg, ir_node *store)
640 {
641         ir_node *load, *pload, *pred, *in[2];
642
643         assert(get_irg_phase_state(irg) == phase_building);
644         /* Beware: due to dead code elimination, a store might become a Bad node even in
645            the construction phase. */
646         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
647
648         if (get_opt_auto_create_sync()) {
649                 /* handle non-volatile Load nodes by automatically creating Sync's */
650                 load = skip_Proj(store);
651                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
652                         pred = get_Load_mem(load);
653
654                         if (is_Sync(pred)) {
655                                 /* a Load after a Sync: move it up */
656                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
657
658                                 set_Load_mem(load, get_memop_mem(mem));
659                                 add_Sync_pred(pred, store);
660                                 store = pred;
661                         } else {
662                                 pload = skip_Proj(pred);
663                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
664                                         /* a Load after a Load: create a new Sync */
665                                         set_Load_mem(load, get_Load_mem(pload));
666
667                                         in[0] = pred;
668                                         in[1] = store;
669                                         store = new_r_Sync(irg->current_block, 2, in);
670                                 }
671                         }
672                 }
673         }
674         irg->current_block->attr.block.graph_arr[0] = store;
675 }
676
677 void set_store(ir_node *store)
678 {
679         set_r_store(current_ir_graph, store);
680 }
681
682 void keep_alive(ir_node *ka)
683 {
684         ir_graph *irg = get_irn_irg(ka);
685         add_End_keepalive(get_irg_end(irg), ka);
686 }
687
688 void ir_set_uninitialized_local_variable_func(
689                 uninitialized_local_variable_func_t *func)
690 {
691         default_initialize_local_variable = func;
692 }
693
694 void irg_finalize_cons(ir_graph *irg)
695 {
696         ir_node *end_block = get_irg_end_block(irg);
697         mature_immBlock(end_block);
698
699         set_irg_phase_state(irg, phase_high);
700 }
701
702 void irp_finalize_cons(void)
703 {
704         size_t i, n;
705         for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
706                 irg_finalize_cons(get_irp_irg(i));
707         }
708         irp->phase_state = phase_high;
709 }
710
711 ir_node *new_Const_long(ir_mode *mode, long value)
712 {
713         return new_d_Const_long(NULL, mode, value);
714 }
715
716 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
717 {
718         return new_d_SymConst(NULL, mode, value, kind);
719 }
720 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
721 {
722         return new_d_simpleSel(NULL, store, objptr, ent);
723 }
724 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
725                  size_t n_outs, ir_asm_constraint *outputs,
726                  size_t n_clobber, ident *clobber[], ident *text)
727 {
728         return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
729 }
730
731 ir_node *new_r_Anchor(ir_graph *irg)
732 {
733         ir_node *in[anchor_last+1];
734         ir_node *res;
735         size_t   i;
736         memset(in, 0, sizeof(in));
737         res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last+1, in);
738         res->attr.anchor.irg.irg = irg;
739
740         /* hack to get get_irn_irg working: set block to ourself and allow
741          * get_Block_irg for anchor */
742         res->in[0] = res;
743
744         /* we can't have NULL inputs so reference ourselfes for now */
745         for (i = 0; i <= (size_t)anchor_last; ++i) {
746                 set_irn_n(res, i, res);
747         }
748
749         return res;
750 }
751
752 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
753 {
754         ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
755         res->attr.block.irg.irg = irg;
756         res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
757         set_Block_matured(res, 1);
758         /* Create and initialize array for Phi-node construction. */
759         if (get_irg_phase_state(irg) == phase_building) {
760                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
761                 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
762         }
763         irn_verify_irg(res, irg);
764         return res;
765 }