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