remove old+unused structure analysis
[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.entity      = NULL;
510
511         set_Block_block_visited(res, 0);
512
513         /* Create and initialize array for Phi-node construction. */
514         res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
515         memset(res->attr.block.graph_arr, 0, sizeof(ir_node*) * irg->n_loc);
516
517         /* Immature block may not be optimized! */
518         irn_verify_irg(res, irg);
519
520         return res;
521 }
522
523 ir_node *new_r_immBlock(ir_graph *irg)
524 {
525         return new_rd_immBlock(NULL, irg);
526 }
527
528 ir_node *new_d_immBlock(dbg_info *dbgi)
529 {
530         return new_rd_immBlock(dbgi, current_ir_graph);
531 }
532
533 ir_node *new_immBlock(void)
534 {
535         return new_rd_immBlock(NULL, current_ir_graph);
536 }
537
538 void add_immBlock_pred(ir_node *block, ir_node *jmp)
539 {
540         int n = ARR_LEN(block->in) - 1;
541
542         assert(is_Block(block) && "Error: Must be a Block");
543         assert(!get_Block_matured(block) && "Error: Block already matured!\n");
544         assert(is_ir_node(jmp));
545
546         ARR_APP1(ir_node *, block->in, jmp);
547         /* Call the hook */
548         hook_set_irn_n(block, n, jmp, NULL);
549 }
550
551 void set_cur_block(ir_node *target)
552 {
553         set_r_cur_block(current_ir_graph, target);
554 }
555
556 void set_r_cur_block(ir_graph *irg, ir_node *target)
557 {
558         assert(target == NULL || get_irn_mode(target) == mode_BB);
559         assert(target == NULL || get_irn_irg(target)  == irg);
560         irg->current_block = target;
561 }
562
563 ir_node *get_r_cur_block(ir_graph *irg)
564 {
565         return irg->current_block;
566 }
567
568 ir_node *get_cur_block(void)
569 {
570         return get_r_cur_block(current_ir_graph);
571 }
572
573 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
574 {
575         assert(get_irg_phase_state(irg) == phase_building);
576         assert(pos >= 0);
577         inc_irg_visited(irg);
578
579         return get_r_value_internal(irg->current_block, pos + 1, mode);
580 }
581
582 ir_node *get_value(int pos, ir_mode *mode)
583 {
584         return get_r_value(current_ir_graph, pos, mode);
585 }
586
587 /**
588  * helper function for guess_mode: recursively look for a definition for
589  * local variable @p pos, returns its mode if found.
590  */
591 static ir_mode *guess_recursively(ir_node *block, int pos)
592 {
593         ir_node *value;
594         int      n_preds;
595         int      i;
596
597         if (irn_visited_else_mark(block))
598                 return NULL;
599
600         /* already have a defintion -> we can simply look at its mode */
601         value = block->attr.block.graph_arr[pos];
602         if (value != NULL)
603                 return get_irn_mode(value);
604
605         /* now we try to guess, by looking at the predecessor blocks */
606         n_preds = get_irn_arity(block);
607         for (i = 0; i < n_preds; ++i) {
608                 ir_node *pred_block = get_Block_cfgpred_block(block, i);
609                 ir_mode *mode       = guess_recursively(pred_block, pos);
610                 if (mode != NULL)
611                         return mode;
612         }
613
614         /* no way to guess */
615         return NULL;
616 }
617
618 ir_mode *ir_r_guess_mode(ir_graph *irg, int pos)
619 {
620         ir_node  *block = irg->current_block;
621         ir_node  *value = block->attr.block.graph_arr[pos+1];
622         ir_mode  *mode;
623
624         /* already have a defintion -> we can simply look at its mode */
625         if (value != NULL)
626                 return get_irn_mode(value);
627
628         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
629         inc_irg_visited(irg);
630         mode = guess_recursively(block, pos+1);
631         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED);
632
633         return mode;
634 }
635
636 ir_mode *ir_guess_mode(int pos)
637 {
638         return ir_r_guess_mode(current_ir_graph, pos);
639 }
640
641 void set_r_value(ir_graph *irg, int pos, ir_node *value)
642 {
643         assert(get_irg_phase_state(irg) == phase_building);
644         assert(pos >= 0);
645         assert(pos+1 < irg->n_loc);
646         assert(is_ir_node(value));
647         irg->current_block->attr.block.graph_arr[pos + 1] = value;
648 }
649
650 void set_value(int pos, ir_node *value)
651 {
652         set_r_value(current_ir_graph, pos, value);
653 }
654
655 int r_find_value(ir_graph *irg, ir_node *value)
656 {
657         size_t i;
658         ir_node *bl = irg->current_block;
659
660         for (i = ARR_LEN(bl->attr.block.graph_arr); i > 1;) {
661                 if (bl->attr.block.graph_arr[--i] == value)
662                         return i - 1;
663         }
664         return -1;
665 }
666
667 int find_value(ir_node *value)
668 {
669         return r_find_value(current_ir_graph, value);
670 }
671
672 ir_node *get_r_store(ir_graph *irg)
673 {
674         assert(get_irg_phase_state(irg) == phase_building);
675         inc_irg_visited(irg);
676         return get_r_value_internal(irg->current_block, 0, mode_M);
677 }
678
679 ir_node *get_store(void)
680 {
681         return get_r_store(current_ir_graph);
682 }
683
684 void set_r_store(ir_graph *irg, ir_node *store)
685 {
686         ir_node *load, *pload, *pred, *in[2];
687
688         assert(get_irg_phase_state(irg) == phase_building);
689         /* Beware: due to dead code elimination, a store might become a Bad node even in
690            the construction phase. */
691         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
692
693         if (get_opt_auto_create_sync()) {
694                 /* handle non-volatile Load nodes by automatically creating Sync's */
695                 load = skip_Proj(store);
696                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
697                         pred = get_Load_mem(load);
698
699                         if (is_Sync(pred)) {
700                                 /* a Load after a Sync: move it up */
701                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
702
703                                 set_Load_mem(load, get_memop_mem(mem));
704                                 add_Sync_pred(pred, store);
705                                 store = pred;
706                         } else {
707                                 pload = skip_Proj(pred);
708                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
709                                         /* a Load after a Load: create a new Sync */
710                                         set_Load_mem(load, get_Load_mem(pload));
711
712                                         in[0] = pred;
713                                         in[1] = store;
714                                         store = new_r_Sync(irg->current_block, 2, in);
715                                 }
716                         }
717                 }
718         }
719         irg->current_block->attr.block.graph_arr[0] = store;
720 }
721
722 void set_store(ir_node *store)
723 {
724         set_r_store(current_ir_graph, store);
725 }
726
727 void keep_alive(ir_node *ka)
728 {
729         ir_graph *irg = get_irn_irg(ka);
730         add_End_keepalive(get_irg_end(irg), ka);
731 }
732
733 void ir_set_uninitialized_local_variable_func(
734                 uninitialized_local_variable_func_t *func)
735 {
736         default_initialize_local_variable = func;
737 }
738
739 void irg_finalize_cons(ir_graph *irg)
740 {
741         set_irg_phase_state(irg, phase_high);
742 }
743
744 void irp_finalize_cons(void)
745 {
746         size_t i, n;
747         for (i = 0, n = get_irp_n_irgs(); i < n; ++i) {
748                 irg_finalize_cons(get_irp_irg(i));
749         }
750         irp->phase_state = phase_high;
751 }
752
753 ir_node *new_Const_long(ir_mode *mode, long value)
754 {
755         return new_d_Const_long(NULL, mode, value);
756 }
757
758 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
759 {
760         return new_d_SymConst(NULL, mode, value, kind);
761 }
762 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
763 {
764         return new_d_simpleSel(NULL, store, objptr, ent);
765 }
766 ir_node *new_defaultProj(ir_node *arg, long max_proj)
767 {
768         return new_d_defaultProj(NULL, arg, max_proj);
769 }
770 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
771                  int n_outs, ir_asm_constraint *outputs,
772                  int n_clobber, ident *clobber[], ident *text)
773 {
774         return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
775 }
776
777 ir_node *new_r_Anchor(ir_graph *irg)
778 {
779         ir_node *in[anchor_last];
780         ir_node *res;
781         memset(in, 0, sizeof(in));
782         res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last, in);
783         res->attr.anchor.irg.irg = irg;
784
785         /* hack to get get_irn_irg working: set block to ourself and allow
786          * get_Block_irg for anchor */
787         res->in[0] = res;
788
789         return res;
790 }
791
792 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
793 {
794         ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
795         res->attr.block.irg.irg = irg;
796         res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
797         set_Block_matured(res, 1);
798         /* Create and initialize array for Phi-node construction. */
799         if (get_irg_phase_state(irg) == phase_building) {
800                 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
801                 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
802         }
803         irn_verify_irg(res, irg);
804         return res;
805 }