8fcb15d0de15458eeaf114217f7be73dbcfdcce5
[libfirm] / ir / ir / ircons.c
1 /*
2  * Copyright (C) 1995-2008 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
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 "irvrfy.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 /* when we need verifying */
48 #ifdef NDEBUG
49 # define IRN_VRFY_IRG(res, irg)
50 #else
51 # define IRN_VRFY_IRG(res, irg)  irn_vrfy_irg(res, irg)
52 #endif /* NDEBUG */
53
54 /**
55  * Language dependent variable initialization callback.
56  */
57 static uninitialized_local_variable_func_t *default_initialize_local_variable = NULL;
58
59 /* creates a bd constructor for a binop */
60 #define NEW_BD_BINOP(instr)                                     \
61 static ir_node *                                                \
62 new_bd_##instr(dbg_info *db, ir_node *block,                    \
63        ir_node *op1, ir_node *op2, ir_mode *mode)               \
64 {                                                               \
65   ir_node  *in[2];                                              \
66   ir_node  *res;                                                \
67   ir_graph *irg = current_ir_graph;                             \
68   in[0] = op1;                                                  \
69   in[1] = op2;                                                  \
70   res = new_ir_node(db, irg, block, op_##instr, mode, 2, in);   \
71   res = optimize_node(res);                                     \
72   IRN_VRFY_IRG(res, irg);                                       \
73   return res;                                                   \
74 }
75
76 /* creates a bd constructor for an unop */
77 #define NEW_BD_UNOP(instr)                                      \
78 static ir_node *                                                \
79 new_bd_##instr(dbg_info *db, ir_node *block,                    \
80               ir_node *op, ir_mode *mode)                       \
81 {                                                               \
82   ir_node  *res;                                                \
83   ir_graph *irg = current_ir_graph;                             \
84   res = new_ir_node(db, irg, block, op_##instr, mode, 1, &op);  \
85   res = optimize_node(res);                                     \
86   IRN_VRFY_IRG(res, irg);                                       \
87   return res;                                                   \
88 }
89
90 /* creates a bd constructor for an divop */
91 #define NEW_BD_DIVOP(instr)                                     \
92 static ir_node *                                                \
93 new_bd_##instr(dbg_info *db, ir_node *block,                    \
94             ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) \
95 {                                                               \
96   ir_node  *in[3];                                              \
97   ir_node  *res;                                                \
98   ir_graph *irg = current_ir_graph;                             \
99   in[0] = memop;                                                \
100   in[1] = op1;                                                  \
101   in[2] = op2;                                                  \
102   res = new_ir_node(db, irg, block, op_##instr, mode_T, 3, in); \
103   res->attr.divmod.exc.pin_state = state;                       \
104   res->attr.divmod.resmode = mode;                              \
105   res->attr.divmod.no_remainder = 0;                            \
106   res = optimize_node(res);                                     \
107   IRN_VRFY_IRG(res, irg);                                       \
108   return res;                                                   \
109 }
110
111 /* creates a rd constructor for a binop */
112 #define NEW_RD_BINOP(instr)                                     \
113 ir_node *                                                       \
114 new_rd_##instr(dbg_info *db, ir_graph *irg, ir_node *block,     \
115        ir_node *op1, ir_node *op2, ir_mode *mode)               \
116 {                                                               \
117   ir_node  *res;                                                \
118   ir_graph *rem = current_ir_graph;                             \
119   current_ir_graph = irg;                                       \
120   res = new_bd_##instr(db, block, op1, op2, mode);              \
121   current_ir_graph = rem;                                       \
122   return res;                                                   \
123 }
124
125 /* creates a rd constructor for an unop */
126 #define NEW_RD_UNOP(instr)                                      \
127 ir_node *                                                       \
128 new_rd_##instr(dbg_info *db, ir_graph *irg, ir_node *block,     \
129               ir_node *op, ir_mode *mode)                       \
130 {                                                               \
131   ir_node  *res;                                                \
132   ir_graph *rem = current_ir_graph;                             \
133   current_ir_graph = irg;                                       \
134   res = new_bd_##instr(db, block, op, mode);                    \
135   current_ir_graph = rem;                                       \
136   return res;                                                   \
137 }
138
139 /* creates a rd constructor for an divop */
140 #define NEW_RD_DIVOP(instr)                                     \
141 ir_node *                                                       \
142 new_rd_##instr(dbg_info *db, ir_graph *irg, ir_node *block,     \
143             ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, op_pin_state state) \
144 {                                                               \
145   ir_node  *res;                                                \
146   ir_graph *rem = current_ir_graph;                             \
147   current_ir_graph = irg;                                       \
148   res = new_bd_##instr(db, block, memop, op1, op2, mode, state);\
149   current_ir_graph = rem;                                       \
150   return res;                                                   \
151 }
152
153 /* creates a d constructor for an binop */
154 #define NEW_D_BINOP(instr)                                                    \
155 ir_node *                                                                     \
156 new_d_##instr(dbg_info *db, ir_node *op1, ir_node *op2, ir_mode *mode) {      \
157   return new_bd_##instr(db, current_ir_graph->current_block, op1, op2, mode); \
158 }
159
160 /* creates a d constructor for an unop */
161 #define NEW_D_UNOP(instr)                                                     \
162 ir_node *                                                                     \
163 new_d_##instr(dbg_info *db, ir_node *op, ir_mode *mode) {                     \
164   return new_bd_##instr(db, current_ir_graph->current_block, op, mode);       \
165 }
166
167 #include "gen_ir_cons.c.inl"
168
169 static ir_node *new_bd_Start(dbg_info *db, ir_node *block)
170 {
171         ir_node  *res;
172         ir_graph *irg = current_ir_graph;
173
174         res = new_ir_node(db, irg, block, op_Start, mode_T, 0, NULL);
175
176         IRN_VRFY_IRG(res, irg);
177         return res;
178 }  /* new_bd_Start */
179
180 static ir_node *new_bd_End(dbg_info *db, ir_node *block)
181 {
182         ir_node  *res;
183         ir_graph *irg = current_ir_graph;
184
185         res = new_ir_node(db, irg, block, op_End, mode_X, -1, NULL);
186
187         IRN_VRFY_IRG(res, irg);
188         return res;
189 }  /* new_bd_End */
190
191 /**
192  * Creates a Phi node with all predecessors.  Calling this constructor
193  * is only allowed if the corresponding block is mature.
194  */
195 static ir_node *new_bd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode)
196 {
197         ir_node  *res;
198         ir_graph *irg = current_ir_graph;
199         int i;
200         int has_unknown = 0;
201
202         /* Don't assert that block matured: the use of this constructor is strongly
203            restricted ... */
204         if (get_Block_matured(block))
205                 assert(get_irn_arity(block) == arity);
206
207         res = new_ir_node(db, irg, block, op_Phi, mode, arity, in);
208
209         res->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
210
211         for (i = arity - 1; i >= 0; --i)
212                 if (is_Unknown(in[i])) {
213                         has_unknown = 1;
214                         break;
215                 }
216
217         if (!has_unknown) res = optimize_node(res);
218         IRN_VRFY_IRG(res, irg);
219
220         /* Memory Phis in endless loops must be kept alive.
221            As we can't distinguish these easily we keep all of them alive. */
222         if (is_Phi(res) && mode == mode_M)
223                 add_End_keepalive(get_irg_end(irg), res);
224         return res;
225 }  /* new_bd_Phi */
226
227 static ir_node *new_bd_Const_type(dbg_info *db, tarval *con, ir_type *tp)
228 {
229         ir_node  *res;
230         ir_graph *irg = current_ir_graph;
231
232         res = new_ir_node(db, irg, get_irg_start_block(irg), op_Const, get_tarval_mode(con), 0, NULL);
233         res->attr.con.tarval = con;
234         set_Const_type(res, tp);  /* Call method because of complex assertion. */
235         res = optimize_node (res);
236         assert(get_Const_type(res) == tp);
237         IRN_VRFY_IRG(res, irg);
238
239         return res;
240 }  /* new_bd_Const_type */
241
242 static ir_node *new_bd_Const(dbg_info *db, tarval *con)
243 {
244         ir_graph *irg = current_ir_graph;
245
246         return new_rd_Const_type(db, irg, con, firm_unknown_type);
247 }  /* new_bd_Const */
248
249 static ir_node *new_bd_Const_long(dbg_info *db, ir_mode *mode, long value)
250 {
251         ir_graph *irg = current_ir_graph;
252
253         return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
254 }  /* new_bd_Const_long */
255
256 static ir_node *new_bd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
257 {
258         ir_node  *res;
259
260         assert(arg->op == op_Cond);
261         arg->attr.cond.default_proj = max_proj;
262         res = new_rd_Proj(db, arg, mode_X, max_proj);
263         return res;
264 }  /* new_bd_defaultProj */
265
266 static ir_node *new_bd_Sel(dbg_info *db, ir_node *block, ir_node *store,
267                            ir_node *objptr, int arity, ir_node **in,
268                            ir_entity *ent)
269 {
270         ir_node  **r_in;
271         ir_node  *res;
272         int      r_arity;
273         ir_graph *irg = current_ir_graph;
274         ir_mode  *mode = is_Method_type(get_entity_type(ent)) ? mode_P_code : mode_P_data;
275
276         assert(ent != NULL && is_entity(ent) && "entity expected in Sel construction");
277
278         r_arity = arity + 2;
279         NEW_ARR_A(ir_node *, r_in, r_arity);  /* uses alloca */
280         r_in[0] = store;
281         r_in[1] = objptr;
282         memcpy(&r_in[2], in, sizeof(ir_node *) * arity);
283         /*
284          * Sel's can select functions which should be of mode mode_P_code.
285          */
286         res = new_ir_node(db, irg, block, op_Sel, mode, r_arity, r_in);
287         res->attr.sel.entity = ent;
288         res = optimize_node(res);
289         IRN_VRFY_IRG(res, irg);
290         return res;
291 }  /* new_bd_Sel */
292
293 static ir_node *new_bd_SymConst_type(dbg_info *db, ir_node *block,
294                                      ir_mode *mode, symconst_symbol value,
295                                      symconst_kind symkind, ir_type *tp)
296 {
297         ir_graph *irg = current_ir_graph;
298         ir_node  *res = new_ir_node(db, irg, block, op_SymConst, mode, 0, NULL);
299
300         res->attr.symc.kind = symkind;
301         res->attr.symc.sym  = value;
302         res->attr.symc.tp   = tp;
303
304         res = optimize_node(res);
305         IRN_VRFY_IRG(res, irg);
306         return res;
307 }  /* new_bd_SymConst_type */
308
309 static ir_node *new_bd_Sync(dbg_info *db, ir_node *block)
310 {
311         ir_node  *res;
312         ir_graph *irg = current_ir_graph;
313
314         res = new_ir_node(db, irg, block, op_Sync, mode_M, -1, NULL);
315         /* no need to call optimize node here, Sync are always created with no predecessors */
316         IRN_VRFY_IRG(res, irg);
317         return res;
318 }  /* new_bd_Sync */
319
320 static ir_node *new_bd_ASM(dbg_info *db, ir_node *block, int arity,
321                            ir_node *in[], ir_asm_constraint *inputs, int n_outs,
322                                  ir_asm_constraint *outputs, int n_clobber,
323                                  ident *clobber[], ident *text)
324 {
325         ir_node  *res;
326         ir_graph *irg = current_ir_graph;
327
328         res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in);
329         res->attr.assem.pin_state = op_pin_state_pinned;
330         res->attr.assem.input_constraints
331                 = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
332         res->attr.assem.output_constraints
333                 = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
334         res->attr.assem.clobbers = NEW_ARR_D(ident *, irg->obst, n_clobber);
335         res->attr.assem.text     = text;
336
337         memcpy(res->attr.assem.input_constraints,  inputs,  sizeof(inputs[0]) * arity);
338         memcpy(res->attr.assem.output_constraints, outputs, sizeof(outputs[0]) * n_outs);
339         memcpy(res->attr.assem.clobbers, clobber, sizeof(clobber[0]) * n_clobber);
340
341         res = optimize_node(res);
342         IRN_VRFY_IRG(res, irg);
343         return res;
344 }  /* new_bd_ASM */
345
346 /* --------------------------------------------- */
347 /* private interfaces, for professional use only */
348 /* --------------------------------------------- */
349
350 ir_node *new_rd_Start(dbg_info *db, ir_graph *irg, ir_node *block)
351 {
352         ir_graph *rem = current_ir_graph;
353         ir_node  *res;
354
355         current_ir_graph = irg;
356         res = new_bd_Start(db, block);
357         current_ir_graph = rem;
358
359         return res;
360 }  /* new_rd_Start */
361
362 ir_node *new_rd_End(dbg_info *db, ir_graph *irg, ir_node *block)
363 {
364         ir_node  *res;
365         ir_graph *rem = current_ir_graph;
366
367         current_ir_graph = irg;
368         res = new_bd_End(db, block);
369         current_ir_graph = rem;
370
371         return res;
372 }  /* new_rd_End */
373
374 /* Creates a Phi node with all predecessors.  Calling this constructor
375    is only allowed if the corresponding block is mature.  */
376 ir_node *new_rd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode)
377 {
378         ir_node  *res;
379         ir_graph *rem = current_ir_graph;
380
381         current_ir_graph = get_Block_irg(block);
382         res = new_bd_Phi(db, block,arity, in, mode);
383         current_ir_graph = rem;
384
385         return res;
386 }  /* new_rd_Phi */
387
388 ir_node *new_rd_Const_type(dbg_info *db, ir_graph *irg, tarval *con, ir_type *tp)
389 {
390         ir_node  *res;
391         ir_graph *rem = current_ir_graph;
392
393         current_ir_graph = irg;
394         res = new_bd_Const_type(db, con, tp);
395         current_ir_graph = rem;
396
397         return res;
398 }  /* new_rd_Const_type */
399
400 ir_node *new_rd_Const(dbg_info *db, ir_graph *irg, tarval *con)
401 {
402         ir_node  *res;
403 //#ifdef USE_ORIGINAL
404         ir_graph *rem = current_ir_graph;
405
406         current_ir_graph = irg;
407         res = new_bd_Const_type(db, con, firm_unknown_type);
408         current_ir_graph = rem;
409 //#else
410 //      res = new_rd_Const_type(db, irg, con, firm_unknown_type);
411 //#endif
412
413         return res;
414 }  /* new_rd_Const */
415
416 ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode, long value)
417 {
418         return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
419 }  /* new_rd_Const_long */
420
421 ir_node *new_rd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
422 {
423         return new_bd_defaultProj(db, arg, max_proj);
424 }  /* new_rd_defaultProj */
425
426 ir_node *new_rd_simpleSel(dbg_info *db, ir_node *block, ir_node *store,
427                           ir_node *objptr, ir_entity *ent)
428 {
429         ir_node  *res;
430         ir_graph *rem = current_ir_graph;
431
432         current_ir_graph = get_Block_irg(block);
433         res = new_bd_Sel(db, block, store, objptr, 0, NULL, ent);
434         current_ir_graph = rem;
435
436         return res;
437 }  /* new_rd_simpleSel */
438
439 ir_node *new_rd_SymConst_type(dbg_info *db, ir_graph *irg, ir_mode *mode,
440                               symconst_symbol value, symconst_kind symkind,
441                               ir_type *tp)
442 {
443         ir_node  *res;
444         ir_graph *rem = current_ir_graph;
445         ir_node  *block = get_irg_start_block(irg);
446
447         current_ir_graph = irg;
448         res = new_bd_SymConst_type(db, block, mode, value, symkind, tp);
449         current_ir_graph = rem;
450
451         return res;
452 }  /* new_rd_SymConst_type */
453
454 ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
455                          symconst_symbol value, symconst_kind symkind)
456 {
457         return new_rd_SymConst_type(db, irg, mode, value, symkind, firm_unknown_type);
458 }  /* new_rd_SymConst */
459
460 ir_node *new_rd_SymConst_addr_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol, ir_type *tp)
461 {
462         symconst_symbol sym;
463         sym.entity_p = symbol;
464         return new_rd_SymConst_type(db, irg, mode, sym, symconst_addr_ent, tp);
465 }  /* new_rd_SymConst_addr_ent */
466
467 ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol, ir_type *tp)
468 {
469         symconst_symbol sym;
470         sym.entity_p = symbol;
471         return new_rd_SymConst_type(db, irg, mode, sym, symconst_ofs_ent, tp);
472 }  /* new_rd_SymConst_ofs_ent */
473
474 ir_node *new_rd_SymConst_type_tag(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
475 {
476         symconst_symbol sym;
477         sym.type_p = symbol;
478         return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_tag, tp);
479 }  /* new_rd_SymConst_type_tag */
480
481 ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
482 {
483         symconst_symbol sym;
484         sym.type_p = symbol;
485         return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_size, tp);
486 }  /* new_rd_SymConst_size */
487
488 ir_node *new_rd_SymConst_align(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
489 {
490         symconst_symbol sym;
491         sym.type_p = symbol;
492         return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_align, tp);
493 }  /* new_rd_SymConst_align */
494
495 ir_node *new_rd_Sync(dbg_info *db, ir_node *block, int arity, ir_node *in[])
496 {
497         ir_node  *res;
498         ir_graph *rem = current_ir_graph;
499         int      i;
500
501         current_ir_graph = get_Block_irg(block);
502         res = new_bd_Sync(db, block);
503         current_ir_graph = rem;
504
505         for (i = 0; i < arity; ++i)
506                 add_Sync_pred(res, in[i]);
507
508         return res;
509 }  /* new_rd_Sync */
510
511 ir_node *new_rd_ASM(dbg_info *db, ir_node *block,
512                     int arity, ir_node *in[], ir_asm_constraint *inputs,
513                     int n_outs, ir_asm_constraint *outputs,
514                     int n_clobber, ident *clobber[], ident *text)
515 {
516         ir_node  *res;
517         ir_graph *rem = current_ir_graph;
518
519         current_ir_graph = get_Block_irg(block);
520         res = new_bd_ASM(db, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
521         current_ir_graph = rem;
522
523         return res;
524 }  /* new_rd_ASM */
525
526 ir_node *new_r_Start(ir_graph *irg, ir_node *block)
527 {
528         return new_rd_Start(NULL, irg, block);
529 }
530 ir_node *new_r_End(ir_graph *irg, ir_node *block)
531 {
532         return new_rd_End(NULL, irg, block);
533 }
534 ir_node *new_r_Const(ir_graph *irg, tarval *con)
535 {
536         return new_rd_Const(NULL, irg, con);
537 }
538 ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value)
539 {
540         return new_rd_Const_long(NULL, irg, mode, value);
541 }
542 ir_node *new_r_Const_type(ir_graph *irg, tarval *con, ir_type *tp)
543 {
544         return new_rd_Const_type(NULL, irg, con, tp);
545 }
546 ir_node *new_r_SymConst(ir_graph *irg, ir_mode *mode, symconst_symbol value,
547                         symconst_kind symkind)
548 {
549         return new_rd_SymConst(NULL, irg, mode, value, symkind);
550 }
551 ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr,
552                          ir_entity *ent)
553 {
554         return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
555 }
556 ir_node *new_r_Phi(ir_node *block, int arity, ir_node **in, ir_mode *mode)
557 {
558         return new_rd_Phi(NULL, block, arity, in, mode);
559 }
560 ir_node *new_r_Sync(ir_node *block, int arity, ir_node *in[])
561 {
562         return new_rd_Sync(NULL, block, arity, in);
563 }
564 ir_node *new_r_defaultProj(ir_node *arg, long max_proj)
565 {
566         return new_rd_defaultProj(NULL, arg, max_proj);
567 }
568 ir_node *new_r_Bad(ir_graph *irg)
569 {
570         return get_irg_bad(irg);
571 }
572 ir_node *new_r_NoMem(ir_graph *irg)
573 {
574         return get_irg_no_mem(irg);
575 }
576 ir_node *new_r_ASM(ir_node *block,
577                    int arity, ir_node *in[], ir_asm_constraint *inputs,
578                    int n_outs, ir_asm_constraint *outputs,
579                    int n_clobber, ident *clobber[], ident *text)
580 {
581         return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
582 }
583
584 /** ********************/
585 /** public interfaces  */
586 /** construction tools */
587
588 ir_node *new_d_Start(dbg_info *db)
589 {
590         ir_node *res;
591
592         res = new_ir_node(db, current_ir_graph, current_ir_graph->current_block,
593                           op_Start, mode_T, 0, NULL);
594
595         res = optimize_node(res);
596         IRN_VRFY_IRG(res, current_ir_graph);
597         return res;
598 }  /* new_d_Start */
599
600 ir_node *new_d_End(dbg_info *db)
601 {
602         ir_node *res;
603         res = new_ir_node(db, current_ir_graph,  current_ir_graph->current_block,
604                           op_End, mode_X, -1, NULL);
605         res = optimize_node(res);
606         IRN_VRFY_IRG(res, current_ir_graph);
607
608         return res;
609 }  /* new_d_End */
610
611 /* ***********************************************************************/
612 /* Methods necessary for automatic Phi node creation                     */
613 /*
614   ir_node *phi_merge            (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
615   ir_node *get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
616   ir_node *new_rd_Phi0          (ir_graph *irg, ir_node *block, ir_mode *mode)
617   ir_node *new_rd_Phi_in        (ir_graph *irg, ir_node *block, ir_mode *mode, ir_node **in, int ins)
618
619   Call Graph:   ( A ---> B == A "calls" B)
620
621        get_value         mature_immBlock
622           |                   |
623           |                   |
624           |                   |
625           |          ---> phi_merge
626           |         /       /   \
627           |        /       /     \
628          \|/      /      |/_      \
629        get_r_value_internal        |
630                 |                  |
631                 |                  |
632                \|/                \|/
633            new_rd_Phi0          new_rd_Phi_in
634
635 * *************************************************************************** */
636
637 /** Creates a Phi node with 0 predecessors. */
638 static inline ir_node *new_rd_Phi0(ir_graph *irg, ir_node *block, ir_mode *mode)
639 {
640         ir_node *res;
641
642         res = new_ir_node(NULL, irg, block, op_Phi, mode, 0, NULL);
643         IRN_VRFY_IRG(res, irg);
644         return res;
645 }  /* new_rd_Phi0 */
646
647
648 /**
649  * Internal constructor of a Phi node by a phi_merge operation.
650  *
651  * @param irg    the graph on which the Phi will be constructed
652  * @param block  the block in which the Phi will be constructed
653  * @param mode   the mod eof the Phi node
654  * @param in     the input array of the phi node
655  * @param ins    number of elements in the input array
656  * @param phi0   in non-NULL: the Phi0 node in the same block that represents
657  *               the value for which the new Phi is constructed
658  */
659 static inline ir_node *new_rd_Phi_in(ir_graph *irg, ir_node *block,
660                                      ir_mode *mode, ir_node **in, int ins,
661                                      ir_node *phi0)
662 {
663         int i;
664         ir_node *res, *known;
665
666         /* Allocate a new node on the obstack.  The allocation copies the in
667            array. */
668         res = new_ir_node(NULL, irg, block, op_Phi, mode, ins, in);
669         res->attr.phi.u.backedge = new_backedge_arr(irg->obst, ins);
670
671         /* This loop checks whether the Phi has more than one predecessor.
672            If so, it is a real Phi node and we break the loop.  Else the
673            Phi node merges the same definition on several paths and therefore
674            is not needed.
675            Note: We MUST consider Bad nodes, else we might get data flow cycles in dead loops! */
676         known = res;
677         for (i = ins - 1; i >= 0; --i)  {
678                 assert(in[i]);
679
680                 in[i] = skip_Id(in[i]);  /* increases the number of freed Phis. */
681
682                 /* Optimize self referencing Phis:  We can't detect them yet properly, as
683                 they still refer to the Phi0 they will replace.  So replace right now. */
684                 if (phi0 && in[i] == phi0)
685                         in[i] = res;
686
687                 if (in[i] == res || in[i] == known)
688                         continue;
689
690                 if (known == res)
691                         known = in[i];
692                 else
693                         break;
694         }
695
696         /* i < 0: there is at most one predecessor, we don't need a phi node. */
697         if (i < 0) {
698                 if (res != known) {
699                         edges_node_deleted(res, current_ir_graph);
700                         obstack_free(current_ir_graph->obst, res);
701                         if (is_Phi(known)) {
702                                 /* If pred is a phi node we want to optimize it: If loops are matured in a bad
703                                    order, an enclosing Phi know may get superfluous. */
704                                 res = optimize_in_place_2(known);
705                                 if (res != known)
706                                         exchange(known, res);
707                         }
708                         else
709                                 res = known;
710                 } else {
711                         /* A undefined value, e.g., in unreachable code. */
712                         res = new_Bad();
713                 }
714         } else {
715                 res = optimize_node(res);  /* This is necessary to add the node to the hash table for cse. */
716                 IRN_VRFY_IRG(res, irg);
717                 /* Memory Phis in endless loops must be kept alive.
718                    As we can't distinguish these easily we keep all of them alive. */
719                 if (is_Phi(res) && mode == mode_M)
720                         add_End_keepalive(get_irg_end(irg), res);
721         }
722
723         return res;
724 }  /* new_rd_Phi_in */
725
726 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode);
727
728 static ir_node *phi_merge(ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins);
729
730 /**
731  * Construct a new frag_array for node n.
732  * Copy the content from the current graph_arr of the corresponding block:
733  * this is the current state.
734  * Set ProjM(n) as current memory state.
735  * Further the last entry in frag_arr of current block points to n.  This
736  * constructs a chain block->last_frag_op-> ... first_frag_op of all frag ops in the block.
737  */
738 static inline ir_node **new_frag_arr(ir_node *n)
739 {
740         ir_node **arr;
741         int opt;
742
743         arr = NEW_ARR_D (ir_node *, current_ir_graph->obst, current_ir_graph->n_loc);
744         memcpy(arr, current_ir_graph->current_block->attr.block.graph_arr,
745                sizeof(ir_node *)*current_ir_graph->n_loc);
746
747         /* turn off optimization before allocating Proj nodes, as res isn't
748            finished yet. */
749         opt = get_opt_optimize(); set_optimize(0);
750         /* Here we rely on the fact that all frag ops have Memory as first result! */
751         if (is_Call(n)) {
752                 arr[0] = new_Proj(n, mode_M, pn_Call_M);
753         } else if (is_CopyB(n)) {
754                 arr[0] = new_Proj(n, mode_M, pn_CopyB_M);
755         } else {
756                 assert((pn_Quot_M == pn_DivMod_M) &&
757                        (pn_Quot_M == pn_Div_M)    &&
758                        (pn_Quot_M == pn_Mod_M)    &&
759                        (pn_Quot_M == pn_Load_M)   &&
760                        (pn_Quot_M == pn_Store_M)  &&
761                        (pn_Quot_M == pn_Alloc_M)  &&
762                        (pn_Quot_M == pn_Bound_M));
763                 arr[0] = new_Proj(n, mode_M, pn_Alloc_M);
764         }
765         set_optimize(opt);
766
767         current_ir_graph->current_block->attr.block.graph_arr[current_ir_graph->n_loc-1] = n;
768         return arr;
769 }  /* new_frag_arr */
770
771 /**
772  * Returns the frag_arr from a node.
773  */
774 static inline ir_node **get_frag_arr(ir_node *n)
775 {
776         switch (get_irn_opcode(n)) {
777         case iro_Call:
778                 return n->attr.call.exc.frag_arr;
779         case iro_Alloc:
780                 return n->attr.alloc.exc.frag_arr;
781         case iro_Load:
782                 return n->attr.load.exc.frag_arr;
783         case iro_Store:
784                 return n->attr.store.exc.frag_arr;
785         default:
786                 return n->attr.except.frag_arr;
787         }
788 }  /* get_frag_arr */
789
790 static void set_frag_value(ir_node **frag_arr, int pos, ir_node *val)
791 {
792 #ifdef DEBUG_libfirm
793         int i;
794
795         for (i = 1024; i >= 0; --i)
796 #else
797         for (;;)
798 #endif
799         {
800                 if (frag_arr[pos] == NULL)
801                         frag_arr[pos] = val;
802                 if (frag_arr[current_ir_graph->n_loc - 1] != NULL) {
803                         ir_node **arr = get_frag_arr(frag_arr[current_ir_graph->n_loc - 1]);
804                         assert(arr != frag_arr && "Endless recursion detected");
805                         frag_arr = arr;
806                 } else
807                         return;
808         }
809         assert(!"potential endless recursion in set_frag_value");
810 }  /* set_frag_value */
811
812 static ir_node *get_r_frag_value_internal(ir_node *block, ir_node *cfOp,
813                                           int pos, ir_mode *mode)
814 {
815         ir_node *res;
816         ir_node **frag_arr;
817
818         assert(is_fragile_op(cfOp) && !is_Bad(cfOp));
819
820         frag_arr = get_frag_arr(cfOp);
821         res = frag_arr[pos];
822         if (res == NULL) {
823                 if (block->attr.block.graph_arr[pos] != NULL) {
824                         /* There was a set_value() after the cfOp and no get_value() before that
825                            set_value().  We must build a Phi node now. */
826                         if (block->attr.block.is_matured) {
827                                 int ins = get_irn_arity(block);
828                                 ir_node **nin;
829                                 NEW_ARR_A(ir_node *, nin, ins);
830                                 res = phi_merge(block, pos, mode, nin, ins);
831                         } else {
832                                 res = new_rd_Phi0(current_ir_graph, block, mode);
833                                 res->attr.phi.u.pos    = pos;
834                                 res->attr.phi.next     = block->attr.block.phis;
835                                 block->attr.block.phis = res;
836                         }
837                         assert(res != NULL);
838                         /* It's a Phi, we can write this into all graph_arrs with NULL */
839                         set_frag_value(block->attr.block.graph_arr, pos, res);
840                 } else {
841                         res = get_r_value_internal(block, pos, mode);
842                         set_frag_value(block->attr.block.graph_arr, pos, res);
843                 }
844         }
845         return res;
846 }  /* get_r_frag_value_internal */
847
848 /**
849  * Check whether a control flownode  cf_pred represents an exception flow.
850  *
851  * @param cf_pred     the control flow node
852  * @param prev_cf_op  if cf_pred is a Proj, the predecessor node, else equal to cf_pred
853  */
854 static int is_exception_flow(ir_node *cf_pred, ir_node *prev_cf_op)
855 {
856         /*
857          * Note: all projections from a raise are "exceptional control flow" we we handle it
858          * like a normal Jmp, because there is no "regular" one.
859          * That's why Raise is no "fragile_op"!
860          */
861         if (is_fragile_op(prev_cf_op)) {
862                 if (is_Proj(cf_pred)) {
863                         if (get_Proj_proj(cf_pred) == pn_Generic_X_regular) {
864                                 /* the regular control flow, NO exception */
865                                 return 0;
866                         }
867                         assert(get_Proj_proj(cf_pred) == pn_Generic_X_except);
868                         return 1;
869                 }
870                 /* Hmm, exception but not a Proj? */
871                 panic("unexpected condition: fragile op without a proj");
872         }
873         return 0;
874 }  /* is_exception_flow */
875
876 /**
877  * Computes the predecessors for the real phi node, and then
878  * allocates and returns this node.  The routine called to allocate the
879  * node might optimize it away and return a real value.
880  * This function must be called with an in-array of proper size.
881  */
882 static ir_node *phi_merge(ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
883 {
884         ir_node *prevBlock, *res, *phi0, *phi0_all;
885         int i;
886
887         /* If this block has no value at pos create a Phi0 and remember it
888            in graph_arr to break recursions.
889            Else we may not set graph_arr as there a later value is remembered. */
890         phi0 = NULL;
891         if (block->attr.block.graph_arr[pos] == NULL) {
892                 ir_graph *irg = current_ir_graph;
893
894                 if (block == get_irg_start_block(irg)) {
895                         /* Collapsing to Bad tarvals is no good idea.
896                            So we call a user-supplied routine here that deals with this case as
897                            appropriate for the given language. Sorrily the only help we can give
898                            here is the position.
899
900                            Even if all variables are defined before use, it can happen that
901                            we get to the start block, if a Cond has been replaced by a tuple
902                            (bad, jmp).  In this case we call the function needlessly, eventually
903                            generating an non existent error.
904                            However, this SHOULD NOT HAPPEN, as bad control flow nodes are intercepted
905                            before recurring.
906                          */
907                         if (default_initialize_local_variable != NULL) {
908                                 ir_node *rem = get_cur_block();
909
910                                 set_cur_block(block);
911                                 block->attr.block.graph_arr[pos] = default_initialize_local_variable(irg, mode, pos - 1);
912                                 set_cur_block(rem);
913                         }
914                         else
915                                 block->attr.block.graph_arr[pos] = new_Unknown(mode);
916                         /* We don't need to care about exception ops in the start block.
917                            There are none by definition. */
918                         return block->attr.block.graph_arr[pos];
919                 } else {
920                         phi0 = new_rd_Phi0(irg, block, mode);
921                         block->attr.block.graph_arr[pos] = phi0;
922                         if (get_opt_precise_exc_context()) {
923                                 /* Set graph_arr for fragile ops.  Also here we should break recursion.
924                                    We could choose a cyclic path through an cfop.  But the recursion would
925                                    break at some point. */
926                                 set_frag_value(block->attr.block.graph_arr, pos, phi0);
927                         }
928                 }
929         }
930
931         /* This loop goes to all predecessor blocks of the block the Phi node
932            is in and there finds the operands of the Phi node by calling
933            get_r_value_internal.  */
934         for (i = 1; i <= ins; ++i) {
935                 ir_node *cf_pred = block->in[i];
936                 ir_node *prevCfOp = skip_Proj(cf_pred);
937                 assert(prevCfOp);
938                 if (is_Bad(prevCfOp)) {
939                         /* In case a Cond has been optimized we would get right to the start block
940                         with an invalid definition. */
941                         nin[i-1] = new_Bad();
942                         continue;
943                 }
944                 prevBlock = prevCfOp->in[0]; /* go past control flow op to prev block */
945                 assert(prevBlock);
946                 if (!is_Bad(prevBlock)) {
947                         if (get_opt_precise_exc_context() && is_exception_flow(cf_pred, prevCfOp)) {
948                                 assert(get_r_frag_value_internal(prevBlock, prevCfOp, pos, mode));
949                                 nin[i-1] = get_r_frag_value_internal(prevBlock, prevCfOp, pos, mode);
950                         } else
951                                 nin[i-1] = get_r_value_internal(prevBlock, pos, mode);
952                 } else {
953                         nin[i-1] = new_Bad();
954                 }
955         }
956
957         /* We want to pass the Phi0 node to the constructor: this finds additional
958            optimization possibilities.
959            The Phi0 node either is allocated in this function, or it comes from
960            a former call to get_r_value_internal(). In this case we may not yet
961            exchange phi0, as this is done in mature_immBlock(). */
962         if (phi0 == NULL) {
963                 phi0_all = block->attr.block.graph_arr[pos];
964                 if (! is_Phi0(phi0_all)            ||
965                     get_irn_arity(phi0_all) != 0   ||
966                     get_nodes_block(phi0_all) != block)
967                         phi0_all = NULL;
968         } else {
969                 phi0_all = phi0;
970         }
971
972         /* After collecting all predecessors into the array nin a new Phi node
973            with these predecessors is created.  This constructor contains an
974            optimization: If all predecessors of the Phi node are identical it
975            returns the only operand instead of a new Phi node.  */
976         res = new_rd_Phi_in(current_ir_graph, block, mode, nin, ins, phi0_all);
977
978         /* In case we allocated a Phi0 node at the beginning of this procedure,
979            we need to exchange this Phi0 with the real Phi. */
980         if (phi0 != NULL) {
981                 exchange(phi0, res);
982                 block->attr.block.graph_arr[pos] = res;
983                 /* Don't set_frag_value as it does not overwrite.  Doesn't matter, is
984                    only an optimization. */
985         }
986
987         return res;
988 }  /* phi_merge */
989
990 /**
991  * This function returns the last definition of a value.  In case
992  * this value was last defined in a previous block, Phi nodes are
993  * inserted.  If the part of the firm graph containing the definition
994  * is not yet constructed, a dummy Phi node is returned.
995  *
996  * @param block   the current block
997  * @param pos     the value number of the value searched
998  * @param mode    the mode of this value (needed for Phi construction)
999  */
1000 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
1001 {
1002         ir_node *res;
1003         /* There are 4 cases to treat.
1004
1005            1. The block is not mature and we visit it the first time.  We can not
1006               create a proper Phi node, therefore a Phi0, i.e., a Phi without
1007               predecessors is returned.  This node is added to the linked list (block
1008               attribute "phis") of the containing block to be completed when this block is
1009               matured. (Completion will add a new Phi and turn the Phi0 into an Id
1010               node.)
1011
1012            2. The value is already known in this block, graph_arr[pos] is set and we
1013               visit the block the first time.  We can return the value without
1014               creating any new nodes.
1015
1016            3. The block is mature and we visit it the first time.  A Phi node needs
1017               to be created (phi_merge).  If the Phi is not needed, as all it's
1018               operands are the same value reaching the block through different
1019               paths, it's optimized away and the value itself is returned.
1020
1021            4. The block is mature, and we visit it the second time.  Now two
1022               subcases are possible:
1023               * The value was computed completely the last time we were here. This
1024                 is the case if there is no loop.  We can return the proper value.
1025               * The recursion that visited this node and set the flag did not
1026                 return yet.  We are computing a value in a loop and need to
1027                 break the recursion.  This case only happens if we visited
1028             the same block with phi_merge before, which inserted a Phi0.
1029             So we return the Phi0.
1030         */
1031
1032         /* case 4 -- already visited. */
1033         if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) {
1034                 /* As phi_merge allocates a Phi0 this value is always defined. Here
1035                 is the critical difference of the two algorithms. */
1036                 assert(block->attr.block.graph_arr[pos]);
1037                 return block->attr.block.graph_arr[pos];
1038         }
1039
1040         /* visited the first time */
1041         set_irn_visited(block, get_irg_visited(current_ir_graph));
1042
1043         /* Get the local valid value */
1044         res = block->attr.block.graph_arr[pos];
1045
1046         /* case 2 -- If the value is actually computed, return it. */
1047         if (res != NULL)
1048                 return res;
1049
1050         if (block->attr.block.is_matured) { /* case 3 */
1051
1052                 /* The Phi has the same amount of ins as the corresponding block. */
1053                 int ins = get_irn_arity(block);
1054                 ir_node **nin;
1055                 NEW_ARR_A(ir_node *, nin, ins);
1056
1057                 /* Phi merge collects the predecessors and then creates a node. */
1058                 res = phi_merge(block, pos, mode, nin, ins);
1059
1060         } else {  /* case 1 */
1061                 /* The block is not mature, we don't know how many in's are needed.  A Phi
1062                    with zero predecessors is created.  Such a Phi node is called Phi0
1063                    node.  The Phi0 is then added to the list of Phi0 nodes in this block
1064                    to be matured by mature_immBlock later.
1065                    The Phi0 has to remember the pos of it's internal value.  If the real
1066                    Phi is computed, pos is used to update the array with the local
1067                    values. */
1068                 res = new_rd_Phi0(current_ir_graph, block, mode);
1069                 res->attr.phi.u.pos    = pos;
1070                 res->attr.phi.next     = block->attr.block.phis;
1071                 block->attr.block.phis = res;
1072         }
1073
1074         assert(is_ir_node(res) && "phi_merge() failed to construct a definition");
1075
1076         /* The local valid value is available now. */
1077         block->attr.block.graph_arr[pos] = res;
1078
1079         return res;
1080 }  /* get_r_value_internal */
1081
1082 /* ************************************************************************** */
1083
1084 /*
1085  * Finalize a Block node, when all control flows are known.
1086  * Acceptable parameters are only Block nodes.
1087  */
1088 void mature_immBlock(ir_node *block)
1089 {
1090         int ins;
1091         ir_node *n, **nin;
1092         ir_node *next;
1093
1094         assert(is_Block(block));
1095         if (!get_Block_matured(block)) {
1096                 ir_graph *irg = current_ir_graph;
1097
1098                 ins = ARR_LEN(block->in) - 1;
1099                 /* Fix block parameters */
1100                 block->attr.block.backedge = new_backedge_arr(irg->obst, ins);
1101
1102                 /* An array for building the Phi nodes. */
1103                 NEW_ARR_A(ir_node *, nin, ins);
1104
1105                 /* Traverse a chain of Phi nodes attached to this block and mature
1106                 these, too. **/
1107                 for (n = block->attr.block.phis; n; n = next) {
1108                         inc_irg_visited(irg);
1109                         next = n->attr.phi.next;
1110                         exchange(n, phi_merge(block, n->attr.phi.u.pos, n->mode, nin, ins));
1111                 }
1112
1113                 block->attr.block.is_matured = 1;
1114
1115                 /* Now, as the block is a finished Firm node, we can optimize it.
1116                    Since other nodes have been allocated since the block was created
1117                    we can not free the node on the obstack.  Therefore we have to call
1118                    optimize_in_place().
1119                    Unfortunately the optimization does not change a lot, as all allocated
1120                    nodes refer to the unoptimized node.
1121                    We can call optimize_in_place_2(), as global cse has no effect on blocks. */
1122                 block = optimize_in_place_2(block);
1123                 IRN_VRFY_IRG(block, irg);
1124         }
1125 }  /* mature_immBlock */
1126
1127 ir_node *new_d_Phi(dbg_info *db, int arity, ir_node **in, ir_mode *mode)
1128 {
1129         return new_bd_Phi(db, current_ir_graph->current_block, arity, in, mode);
1130 }  /* new_d_Phi */
1131
1132 ir_node *new_d_Const(dbg_info *db, tarval *con)
1133 {
1134         return new_bd_Const(db, con);
1135 }  /* new_d_Const */
1136
1137 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
1138 {
1139         return new_bd_Const_long(db, mode, value);
1140 }  /* new_d_Const_long */
1141
1142 ir_node *new_d_Const_type(dbg_info *db, tarval *con, ir_type *tp)
1143 {
1144         return new_bd_Const_type(db, con, tp);
1145 }  /* new_d_Const_type */
1146
1147
1148 ir_node *new_d_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
1149 {
1150         ir_node *res;
1151         assert(arg->op == op_Cond);
1152         arg->attr.cond.default_proj = max_proj;
1153         res = new_d_Proj(db, arg, mode_X, max_proj);
1154         return res;
1155 }  /* new_d_defaultProj */
1156
1157 /**
1158  * Allocate a frag array for a node if the current graph state is phase_building.
1159  *
1160  * @param irn         the node for which the frag array should be allocated
1161  * @param op          the opcode of the (original) node, if does not match opcode of irn,
1162  *                    nothing is done
1163  * @param frag_store  the address of the frag store in irn attributes, if this
1164  *                    address contains a value != NULL, does nothing
1165  */
1166 void firm_alloc_frag_arr(ir_node *irn, ir_op *op, ir_node ***frag_store)
1167 {
1168         if (get_opt_precise_exc_context()) {
1169                 if ((current_ir_graph->phase_state == phase_building) &&
1170                     (get_irn_op(irn) == op) && /* Could be optimized away. */
1171                     !*frag_store)    /* Could be a cse where the arr is already set. */ {
1172                         *frag_store = new_frag_arr(irn);
1173                 }
1174         }
1175 }  /* firm_alloc_frag_arr */
1176
1177 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr, ir_entity *ent)
1178 /* GL: objptr was called frame before.  Frame was a bad choice for the name
1179    as the operand could as well be a pointer to a dynamic object. */
1180 {
1181         return new_bd_Sel(db, current_ir_graph->current_block,
1182                           store, objptr, 0, NULL, ent);
1183 }  /* new_d_simpleSel */
1184
1185 ir_node *new_d_SymConst_type(dbg_info *db, ir_mode *mode, symconst_symbol value, symconst_kind kind, ir_type *tp)
1186 {
1187         return new_bd_SymConst_type(db, get_irg_start_block(current_ir_graph), mode,
1188                                     value, kind, tp);
1189 }  /* new_d_SymConst_type */
1190
1191 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value, symconst_kind kind)
1192 {
1193         return new_bd_SymConst_type(db, get_irg_start_block(current_ir_graph), mode,
1194                                     value, kind, firm_unknown_type);
1195 }  /* new_d_SymConst */
1196
1197 ir_node *new_d_Sync(dbg_info *db, int arity, ir_node *in[])
1198 {
1199         return new_rd_Sync(db, current_ir_graph->current_block, arity, in);
1200 }  /* new_d_Sync */
1201
1202 ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], ir_asm_constraint *inputs,
1203                    int n_outs, ir_asm_constraint *outputs, int n_clobber,
1204                    ident *clobber[], ident *text)
1205 {
1206         return new_bd_ASM(db, current_ir_graph->current_block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
1207 }  /* new_d_ASM */
1208
1209 /* ********************************************************************* */
1210 /* Comfortable interface with automatic Phi node construction.           */
1211 /* (Uses also constructors of ?? interface, except new_Block.            */
1212 /* ********************************************************************* */
1213
1214 /*  Block construction */
1215 /* immature Block without predecessors */
1216 ir_node *new_d_immBlock(dbg_info *db)
1217 {
1218         ir_node *res;
1219
1220         assert(get_irg_phase_state(current_ir_graph) == phase_building);
1221         /* creates a new dynamic in-array as length of in is -1 */
1222         res = new_ir_node(db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
1223
1224         /* macroblock head */
1225         res->in[0] = res;
1226
1227         res->attr.block.is_matured  = 0;
1228         res->attr.block.is_dead     = 0;
1229         res->attr.block.is_mb_head  = 1;
1230         res->attr.block.irg.irg     = current_ir_graph;
1231         res->attr.block.backedge    = NULL;
1232         res->attr.block.in_cg       = NULL;
1233         res->attr.block.cg_backedge = NULL;
1234         res->attr.block.extblk      = NULL;
1235         res->attr.block.region      = NULL;
1236         res->attr.block.mb_depth    = 0;
1237         res->attr.block.entity      = NULL;
1238
1239         set_Block_block_visited(res, 0);
1240
1241         /* Create and initialize array for Phi-node construction. */
1242         res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
1243                                               current_ir_graph->n_loc);
1244         memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
1245
1246         /* Immature block may not be optimized! */
1247         IRN_VRFY_IRG(res, current_ir_graph);
1248
1249         return res;
1250 }  /* new_d_immBlock */
1251
1252 ir_node *new_immBlock(void)
1253 {
1254         return new_d_immBlock(NULL);
1255 }  /* new_immBlock */
1256
1257 /* immature PartBlock with its predecessors */
1258 ir_node *new_d_immPartBlock(dbg_info *db, ir_node *pred_jmp)
1259 {
1260         ir_node *res = new_d_immBlock(db);
1261         ir_node *blk = get_nodes_block(pred_jmp);
1262
1263         res->in[0] = blk->in[0];
1264         assert(res->in[0] != NULL);
1265         add_immBlock_pred(res, pred_jmp);
1266
1267         res->attr.block.is_mb_head = 0;
1268         res->attr.block.mb_depth = blk->attr.block.mb_depth + 1;
1269
1270         return res;
1271 }  /* new_d_immPartBlock */
1272
1273 ir_node *new_immPartBlock(ir_node *pred_jmp)
1274 {
1275         return new_d_immPartBlock(NULL, pred_jmp);
1276 }  /* new_immPartBlock */
1277
1278 /* add an edge to a jmp/control flow node */
1279 void add_immBlock_pred(ir_node *block, ir_node *jmp)
1280 {
1281         int n = ARR_LEN(block->in) - 1;
1282
1283         assert(is_Block(block) && "Error: Must be a Block");
1284         assert(!block->attr.block.is_matured && "Error: Block already matured!\n");
1285         assert(block->attr.block.is_mb_head && "Error: Cannot add a predecessor to a PartBlock");
1286         assert(is_ir_node(jmp));
1287
1288         ARR_APP1(ir_node *, block->in, jmp);
1289         /* Call the hook */
1290         hook_set_irn_n(block, n, jmp, NULL);
1291 }  /* add_immBlock_pred */
1292
1293 /* changing the current block */
1294 void set_cur_block(ir_node *target)
1295 {
1296         current_ir_graph->current_block = target;
1297 }  /* set_cur_block */
1298
1299 /* ************************ */
1300 /* parameter administration */
1301
1302 /* get a value from the parameter array from the current block by its index */
1303 ir_node *get_d_value(dbg_info *db, int pos, ir_mode *mode)
1304 {
1305         ir_graph *irg = current_ir_graph;
1306         assert(get_irg_phase_state(irg) == phase_building);
1307         inc_irg_visited(irg);
1308         (void) db;
1309
1310         assert(pos >= 0);
1311
1312         return get_r_value_internal(irg->current_block, pos + 1, mode);
1313 }  /* get_d_value */
1314
1315 /* get a value from the parameter array from the current block by its index */
1316 ir_node *get_value(int pos, ir_mode *mode)
1317 {
1318         return get_d_value(NULL, pos, mode);
1319 }  /* get_value */
1320
1321 /**
1322  * helper function for guess_mode: recursively look for a definition for
1323  * local variable @p pos, returns its mode if found.
1324  */
1325 static ir_mode *guess_recursively(ir_node *block, int pos)
1326 {
1327         ir_node *value;
1328         int      n_preds;
1329         int      i;
1330
1331         if (irn_visited(block))
1332                 return NULL;
1333         mark_irn_visited(block);
1334
1335         /* already have a defintion -> we can simply look at its mode */
1336         value = block->attr.block.graph_arr[pos];
1337         if (value != NULL)
1338                 return get_irn_mode(value);
1339
1340         /* now we try to guess, by looking at the predecessor blocks */
1341         n_preds = get_irn_arity(block);
1342         for (i = 0; i < n_preds; ++i) {
1343                 ir_node *pred_block = get_Block_cfgpred_block(block, i);
1344                 ir_mode *mode       = guess_recursively(pred_block, pos);
1345                 if (mode != NULL)
1346                         return mode;
1347         }
1348
1349         /* no way to guess */
1350         return NULL;
1351 }
1352
1353 ir_mode *ir_guess_mode(int pos)
1354 {
1355         ir_graph *irg   = current_ir_graph;
1356         ir_node  *block = irg->current_block;
1357         ir_node  *value = block->attr.block.graph_arr[pos+1];
1358         ir_mode  *mode;
1359
1360         /* already have a defintion -> we can simply look at its mode */
1361         if (value != NULL)
1362                 return get_irn_mode(value);
1363
1364         ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
1365         inc_irg_visited(current_ir_graph);
1366         mode = guess_recursively(block, pos+1);
1367         ir_free_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
1368
1369         return mode;
1370 }
1371
1372 /* set a value at position pos in the parameter array from the current block */
1373 void set_value(int pos, ir_node *value)
1374 {
1375         ir_graph *irg = current_ir_graph;
1376         assert(get_irg_phase_state(irg) == phase_building);
1377         assert(pos >= 0);
1378         assert(pos+1 < irg->n_loc);
1379         assert(is_ir_node(value));
1380         irg->current_block->attr.block.graph_arr[pos + 1] = value;
1381 }  /* set_value */
1382
1383 /* Find the value number for a node in the current block.*/
1384 int find_value(ir_node *value)
1385 {
1386         int i;
1387         ir_node *bl = current_ir_graph->current_block;
1388
1389         for (i = ARR_LEN(bl->attr.block.graph_arr) - 1; i >= 1; --i)
1390                 if (bl->attr.block.graph_arr[i] == value)
1391                         return i - 1;
1392         return -1;
1393 }  /* find_value */
1394
1395 /* get the current store */
1396 ir_node *get_store(void)
1397 {
1398         ir_graph *irg = current_ir_graph;
1399
1400         assert(get_irg_phase_state(irg) == phase_building);
1401         /* GL: one could call get_value instead */
1402         inc_irg_visited(irg);
1403         return get_r_value_internal(irg->current_block, 0, mode_M);
1404 }  /* get_store */
1405
1406 /* set the current store: handles automatic Sync construction for Load nodes */
1407 void set_store(ir_node *store)
1408 {
1409         ir_node *load, *pload, *pred, *in[2];
1410
1411         assert(get_irg_phase_state(current_ir_graph) == phase_building);
1412         /* Beware: due to dead code elimination, a store might become a Bad node even in
1413            the construction phase. */
1414         assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
1415
1416         if (get_opt_auto_create_sync()) {
1417                 /* handle non-volatile Load nodes by automatically creating Sync's */
1418                 load = skip_Proj(store);
1419                 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
1420                         pred = get_Load_mem(load);
1421
1422                         if (is_Sync(pred)) {
1423                                 /* a Load after a Sync: move it up */
1424                                 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
1425
1426                                 set_Load_mem(load, get_memop_mem(mem));
1427                                 add_Sync_pred(pred, store);
1428                                 store = pred;
1429                         } else {
1430                                 pload = skip_Proj(pred);
1431                                 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
1432                                         /* a Load after a Load: create a new Sync */
1433                                         set_Load_mem(load, get_Load_mem(pload));
1434
1435                                         in[0] = pred;
1436                                         in[1] = store;
1437                                         store = new_Sync(2, in);
1438                                 }
1439                         }
1440                 }
1441         }
1442         current_ir_graph->current_block->attr.block.graph_arr[0] = store;
1443 }  /* set_store */
1444
1445 void keep_alive(ir_node *ka)
1446 {
1447         add_End_keepalive(get_irg_end(current_ir_graph), ka);
1448 }  /* keep_alive */
1449
1450 /* --- Useful access routines --- */
1451 /* Returns the current block of the current graph.  To set the current
1452    block use set_cur_block. */
1453 ir_node *get_cur_block(void)
1454 {
1455         return get_irg_current_block(current_ir_graph);
1456 }  /* get_cur_block */
1457
1458 /* Returns the frame type of the current graph */
1459 ir_type *get_cur_frame_type(void)
1460 {
1461         return get_irg_frame_type(current_ir_graph);
1462 }  /* get_cur_frame_type */
1463
1464
1465 /* ********************************************************************* */
1466 /* initialize */
1467
1468 /* call once for each run of the library */
1469 void ir_set_uninitialized_local_variable_func(
1470                 uninitialized_local_variable_func_t *func)
1471 {
1472         default_initialize_local_variable = func;
1473 }
1474
1475 void irg_finalize_cons(ir_graph *irg)
1476 {
1477         set_irg_phase_state(irg, phase_high);
1478 }
1479
1480 void irp_finalize_cons(void)
1481 {
1482         int i;
1483         for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
1484                 irg_finalize_cons(get_irp_irg(i));
1485         }
1486         irp->phase_state = phase_high;
1487 }
1488
1489 ir_node *new_Start(void)
1490 {
1491         return new_d_Start(NULL);
1492 }
1493 ir_node *new_End(void)
1494 {
1495         return new_d_End(NULL);
1496 }
1497 ir_node *new_Const(tarval *con)
1498 {
1499         return new_d_Const(NULL, con);
1500 }
1501
1502 ir_node *new_Const_long(ir_mode *mode, long value)
1503 {
1504         return new_d_Const_long(NULL, mode, value);
1505 }
1506
1507 ir_node *new_Const_type(tarval *con, ir_type *tp)
1508 {
1509         return new_d_Const_type(NULL, con, tp);
1510 }
1511
1512 ir_node *new_SymConst_type(ir_mode *mode, symconst_symbol value, symconst_kind kind, ir_type *type)
1513 {
1514         return new_d_SymConst_type(NULL, mode, value, kind, type);
1515 }
1516 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
1517 {
1518         return new_d_SymConst(NULL, mode, value, kind);
1519 }
1520 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
1521 {
1522         return new_d_simpleSel(NULL, store, objptr, ent);
1523 }
1524 ir_node *new_Phi(int arity, ir_node **in, ir_mode *mode)
1525 {
1526         return new_d_Phi(NULL, arity, in, mode);
1527 }
1528 ir_node *new_Sync(int arity, ir_node *in[])
1529 {
1530         return new_d_Sync(NULL, arity, in);
1531 }
1532 ir_node *new_defaultProj(ir_node *arg, long max_proj)
1533 {
1534         return new_d_defaultProj(NULL, arg, max_proj);
1535 }
1536 ir_node *new_Bad(void)
1537 {
1538         return get_irg_bad(current_ir_graph);
1539 }
1540 ir_node *new_NoMem(void)
1541 {
1542         return get_irg_no_mem(current_ir_graph);
1543 }
1544 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
1545                  int n_outs, ir_asm_constraint *outputs,
1546                  int n_clobber, ident *clobber[], ident *text)
1547 {
1548         return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
1549 }
1550
1551 /* create a new anchor node */
1552 ir_node *new_Anchor(ir_graph *irg)
1553 {
1554         ir_node *in[anchor_last];
1555         memset(in, 0, sizeof(in));
1556         return new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last, in);
1557 }