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