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