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