2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Various irnode constructors. Automatic construction of SSA
24 * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Boris Boesler
31 #include "irgraph_t.h"
41 #include "irbackedge_t.h"
43 #include "iredges_t.h"
47 /* when we need verifying */
49 # define IRN_VERIFY_IRG(res, irg)
51 # define IRN_VERIFY_IRG(res, irg) irn_verify_irg(res, irg)
55 * Language dependent variable initialization callback.
57 static uninitialized_local_variable_func_t *default_initialize_local_variable = NULL;
59 #include "gen_ir_cons.c.inl"
61 static ir_node *new_bd_Start(dbg_info *db, ir_node *block)
64 ir_graph *irg = get_irn_irg(block);
66 res = new_ir_node(db, irg, block, op_Start, mode_T, 0, NULL);
68 IRN_VERIFY_IRG(res, irg);
72 static ir_node *new_bd_End(dbg_info *db, ir_node *block)
75 ir_graph *irg = get_irn_irg(block);
77 res = new_ir_node(db, irg, block, op_End, mode_X, -1, NULL);
79 IRN_VERIFY_IRG(res, irg);
84 * Creates a Phi node with all predecessors. Calling this constructor
85 * is only allowed if the corresponding block is mature.
87 static ir_node *new_bd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode)
90 ir_graph *irg = get_irn_irg(block);
94 /* Don't assert that block matured: the use of this constructor is strongly
96 if (get_Block_matured(block))
97 assert(get_irn_arity(block) == arity);
99 res = new_ir_node(db, irg, block, op_Phi, mode, arity, in);
101 res->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
103 for (i = arity - 1; i >= 0; --i)
104 if (is_Unknown(in[i])) {
109 if (!has_unknown) res = optimize_node(res);
110 IRN_VERIFY_IRG(res, irg);
112 /* Memory Phis in endless loops must be kept alive.
113 As we can't distinguish these easily we keep all of them alive. */
114 if (is_Phi(res) && mode == mode_M)
115 add_End_keepalive(get_irg_end(irg), res);
119 static ir_node *new_bd_Const_type(dbg_info *db, tarval *con, ir_type *tp)
122 ir_graph *irg = current_ir_graph;
124 res = new_ir_node(db, irg, get_irg_start_block(irg), op_Const, get_tarval_mode(con), 0, NULL);
125 res->attr.con.tarval = con;
126 set_Const_type(res, tp); /* Call method because of complex assertion. */
127 res = optimize_node (res);
128 assert(get_Const_type(res) == tp);
129 IRN_VERIFY_IRG(res, irg);
132 } /* new_bd_Const_type */
134 static ir_node *new_bd_Const(dbg_info *db, tarval *con)
136 ir_graph *irg = current_ir_graph;
138 return new_rd_Const_type(db, irg, con, firm_unknown_type);
141 static ir_node *new_bd_Const_long(dbg_info *db, ir_mode *mode, long value)
143 ir_graph *irg = current_ir_graph;
145 return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
146 } /* new_bd_Const_long */
148 static ir_node *new_bd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
152 assert(is_Cond(arg));
153 arg->attr.cond.default_proj = max_proj;
154 res = new_rd_Proj(db, arg, mode_X, max_proj);
156 } /* new_bd_defaultProj */
158 static ir_node *new_bd_Sel(dbg_info *db, ir_node *block, ir_node *store,
159 ir_node *objptr, int arity, ir_node **in,
165 ir_graph *irg = get_irn_irg(block);
166 ir_mode *mode = is_Method_type(get_entity_type(ent)) ? mode_P_code : mode_P_data;
168 assert(ent != NULL && is_entity(ent) && "entity expected in Sel construction");
171 NEW_ARR_A(ir_node *, r_in, r_arity); /* uses alloca */
174 memcpy(&r_in[2], in, sizeof(ir_node *) * arity);
176 * Sel's can select functions which should be of mode mode_P_code.
178 res = new_ir_node(db, irg, block, op_Sel, mode, r_arity, r_in);
179 res->attr.sel.entity = ent;
180 res = optimize_node(res);
181 IRN_VERIFY_IRG(res, irg);
185 static ir_node *new_bd_SymConst_type(dbg_info *db, ir_node *block,
186 ir_mode *mode, symconst_symbol value,
187 symconst_kind symkind, ir_type *tp)
189 ir_graph *irg = get_irn_irg(block);
190 ir_node *res = new_ir_node(db, irg, block, op_SymConst, mode, 0, NULL);
192 res->attr.symc.kind = symkind;
193 res->attr.symc.sym = value;
194 res->attr.symc.tp = tp;
196 res = optimize_node(res);
197 IRN_VERIFY_IRG(res, irg);
199 } /* new_bd_SymConst_type */
201 static ir_node *new_bd_Sync(dbg_info *db, ir_node *block)
204 ir_graph *irg = get_irn_irg(block);
206 res = new_ir_node(db, irg, block, op_Sync, mode_M, -1, NULL);
207 /* no need to call optimize node here, Sync are always created with no predecessors */
208 IRN_VERIFY_IRG(res, irg);
212 static ir_node *new_bd_ASM(dbg_info *db, ir_node *block, int arity,
213 ir_node *in[], ir_asm_constraint *inputs, int n_outs,
214 ir_asm_constraint *outputs, int n_clobber,
215 ident *clobber[], ident *text)
218 ir_graph *irg = get_irn_irg(block);
220 res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in);
221 res->attr.assem.pin_state = op_pin_state_pinned;
222 res->attr.assem.input_constraints
223 = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
224 res->attr.assem.output_constraints
225 = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
226 res->attr.assem.clobbers = NEW_ARR_D(ident *, irg->obst, n_clobber);
227 res->attr.assem.text = text;
229 memcpy(res->attr.assem.input_constraints, inputs, sizeof(inputs[0]) * arity);
230 memcpy(res->attr.assem.output_constraints, outputs, sizeof(outputs[0]) * n_outs);
231 memcpy(res->attr.assem.clobbers, clobber, sizeof(clobber[0]) * n_clobber);
233 res = optimize_node(res);
234 IRN_VERIFY_IRG(res, irg);
238 /* --------------------------------------------- */
239 /* private interfaces, for professional use only */
240 /* --------------------------------------------- */
242 ir_node *new_rd_Start(dbg_info *db, ir_graph *irg, ir_node *block)
244 ir_graph *rem = current_ir_graph;
247 current_ir_graph = irg;
248 res = new_bd_Start(db, block);
249 current_ir_graph = rem;
254 ir_node *new_rd_End(dbg_info *db, ir_graph *irg, ir_node *block)
257 ir_graph *rem = current_ir_graph;
259 current_ir_graph = irg;
260 res = new_bd_End(db, block);
261 current_ir_graph = rem;
266 /* Creates a Phi node with all predecessors. Calling this constructor
267 is only allowed if the corresponding block is mature. */
268 ir_node *new_rd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in, ir_mode *mode)
271 ir_graph *rem = current_ir_graph;
273 current_ir_graph = get_Block_irg(block);
274 res = new_bd_Phi(db, block,arity, in, mode);
275 current_ir_graph = rem;
280 ir_node *new_rd_Const_type(dbg_info *db, ir_graph *irg, tarval *con, ir_type *tp)
283 ir_graph *rem = current_ir_graph;
285 current_ir_graph = irg;
286 res = new_bd_Const_type(db, con, tp);
287 current_ir_graph = rem;
290 } /* new_rd_Const_type */
292 ir_node *new_rd_Const(dbg_info *db, ir_graph *irg, tarval *con)
295 ir_graph *rem = current_ir_graph;
297 current_ir_graph = irg;
298 res = new_bd_Const_type(db, con, firm_unknown_type);
299 current_ir_graph = rem;
304 ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode, long value)
306 return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
307 } /* new_rd_Const_long */
309 ir_node *new_rd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
311 return new_bd_defaultProj(db, arg, max_proj);
312 } /* new_rd_defaultProj */
314 ir_node *new_rd_simpleSel(dbg_info *db, ir_node *block, ir_node *store,
315 ir_node *objptr, ir_entity *ent)
318 ir_graph *rem = current_ir_graph;
320 current_ir_graph = get_Block_irg(block);
321 res = new_bd_Sel(db, block, store, objptr, 0, NULL, ent);
322 current_ir_graph = rem;
325 } /* new_rd_simpleSel */
327 ir_node *new_rd_SymConst_type(dbg_info *db, ir_graph *irg, ir_mode *mode,
328 symconst_symbol value, symconst_kind symkind,
332 ir_graph *rem = current_ir_graph;
333 ir_node *block = get_irg_start_block(irg);
335 current_ir_graph = irg;
336 res = new_bd_SymConst_type(db, block, mode, value, symkind, tp);
337 current_ir_graph = rem;
340 } /* new_rd_SymConst_type */
342 ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
343 symconst_symbol value, symconst_kind symkind)
345 return new_rd_SymConst_type(db, irg, mode, value, symkind, firm_unknown_type);
346 } /* new_rd_SymConst */
348 ir_node *new_rd_SymConst_addr_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol, ir_type *tp)
351 sym.entity_p = symbol;
352 return new_rd_SymConst_type(db, irg, mode, sym, symconst_addr_ent, tp);
353 } /* new_rd_SymConst_addr_ent */
355 ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol, ir_type *tp)
358 sym.entity_p = symbol;
359 return new_rd_SymConst_type(db, irg, mode, sym, symconst_ofs_ent, tp);
360 } /* new_rd_SymConst_ofs_ent */
362 ir_node *new_rd_SymConst_type_tag(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
366 return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_tag, tp);
367 } /* new_rd_SymConst_type_tag */
369 ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
373 return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_size, tp);
374 } /* new_rd_SymConst_size */
376 ir_node *new_rd_SymConst_align(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol, ir_type *tp)
380 return new_rd_SymConst_type(db, irg, mode, sym, symconst_type_align, tp);
381 } /* new_rd_SymConst_align */
383 ir_node *new_rd_Sync(dbg_info *db, ir_node *block, int arity, ir_node *in[])
386 ir_graph *rem = current_ir_graph;
389 current_ir_graph = get_Block_irg(block);
390 res = new_bd_Sync(db, block);
391 current_ir_graph = rem;
393 for (i = 0; i < arity; ++i)
394 add_Sync_pred(res, in[i]);
399 ir_node *new_rd_ASM(dbg_info *db, ir_node *block,
400 int arity, ir_node *in[], ir_asm_constraint *inputs,
401 int n_outs, ir_asm_constraint *outputs,
402 int n_clobber, ident *clobber[], ident *text)
405 ir_graph *rem = current_ir_graph;
407 current_ir_graph = get_Block_irg(block);
408 res = new_bd_ASM(db, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
409 current_ir_graph = rem;
414 ir_node *new_r_Start(ir_graph *irg, ir_node *block)
416 return new_rd_Start(NULL, irg, block);
418 ir_node *new_r_End(ir_graph *irg, ir_node *block)
420 return new_rd_End(NULL, irg, block);
422 ir_node *new_r_Const(ir_graph *irg, tarval *con)
424 return new_rd_Const(NULL, irg, con);
426 ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value)
428 return new_rd_Const_long(NULL, irg, mode, value);
430 ir_node *new_r_Const_type(ir_graph *irg, tarval *con, ir_type *tp)
432 return new_rd_Const_type(NULL, irg, con, tp);
434 ir_node *new_r_SymConst(ir_graph *irg, ir_mode *mode, symconst_symbol value,
435 symconst_kind symkind)
437 return new_rd_SymConst(NULL, irg, mode, value, symkind);
439 ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr,
442 return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
444 ir_node *new_r_Phi(ir_node *block, int arity, ir_node **in, ir_mode *mode)
446 return new_rd_Phi(NULL, block, arity, in, mode);
448 ir_node *new_r_Sync(ir_node *block, int arity, ir_node *in[])
450 return new_rd_Sync(NULL, block, arity, in);
452 ir_node *new_r_defaultProj(ir_node *arg, long max_proj)
454 return new_rd_defaultProj(NULL, arg, max_proj);
456 ir_node *new_r_Bad(ir_graph *irg)
458 return get_irg_bad(irg);
460 ir_node *new_r_NoMem(ir_graph *irg)
462 return get_irg_no_mem(irg);
464 ir_node *new_r_ASM(ir_node *block,
465 int arity, ir_node *in[], ir_asm_constraint *inputs,
466 int n_outs, ir_asm_constraint *outputs,
467 int n_clobber, ident *clobber[], ident *text)
469 return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
472 /** ********************/
473 /** public interfaces */
474 /** construction tools */
476 ir_node *new_d_Start(dbg_info *db)
480 res = new_ir_node(db, current_ir_graph, current_ir_graph->current_block,
481 op_Start, mode_T, 0, NULL);
483 res = optimize_node(res);
484 IRN_VERIFY_IRG(res, current_ir_graph);
488 ir_node *new_d_End(dbg_info *db)
491 res = new_ir_node(db, current_ir_graph, current_ir_graph->current_block,
492 op_End, mode_X, -1, NULL);
493 res = optimize_node(res);
494 IRN_VERIFY_IRG(res, current_ir_graph);
499 /* ***********************************************************************/
500 /* Methods necessary for automatic Phi node creation */
502 ir_node *phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
503 ir_node *get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
504 ir_node *new_rd_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
505 ir_node *new_rd_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode, ir_node **in, int ins)
507 Call Graph: ( A ---> B == A "calls" B)
509 get_value mature_immBlock
517 get_r_value_internal |
521 new_rd_Phi0 new_rd_Phi_in
523 * *************************************************************************** */
525 /** Creates a Phi node with 0 predecessors. */
526 static inline ir_node *new_rd_Phi0(ir_graph *irg, ir_node *block, ir_mode *mode)
530 res = new_ir_node(NULL, irg, block, op_Phi, mode, 0, NULL);
531 IRN_VERIFY_IRG(res, irg);
537 * Internal constructor of a Phi node by a phi_merge operation.
539 * @param irg the graph on which the Phi will be constructed
540 * @param block the block in which the Phi will be constructed
541 * @param mode the mod eof the Phi node
542 * @param in the input array of the phi node
543 * @param ins number of elements in the input array
544 * @param phi0 in non-NULL: the Phi0 node in the same block that represents
545 * the value for which the new Phi is constructed
547 static inline ir_node *new_rd_Phi_in(ir_graph *irg, ir_node *block,
548 ir_mode *mode, ir_node **in, int ins,
552 ir_node *res, *known;
554 /* Allocate a new node on the obstack. The allocation copies the in
556 res = new_ir_node(NULL, irg, block, op_Phi, mode, ins, in);
557 res->attr.phi.u.backedge = new_backedge_arr(irg->obst, ins);
559 /* This loop checks whether the Phi has more than one predecessor.
560 If so, it is a real Phi node and we break the loop. Else the
561 Phi node merges the same definition on several paths and therefore
563 Note: We MUST consider Bad nodes, else we might get data flow cycles in dead loops! */
565 for (i = ins - 1; i >= 0; --i) {
568 in[i] = skip_Id(in[i]); /* increases the number of freed Phis. */
570 /* Optimize self referencing Phis: We can't detect them yet properly, as
571 they still refer to the Phi0 they will replace. So replace right now. */
572 if (phi0 && in[i] == phi0)
575 if (in[i] == res || in[i] == known)
584 /* i < 0: there is at most one predecessor, we don't need a phi node. */
587 edges_node_deleted(res, current_ir_graph);
588 obstack_free(current_ir_graph->obst, res);
590 /* If pred is a phi node we want to optimize it: If loops are matured in a bad
591 order, an enclosing Phi know may get superfluous. */
592 res = optimize_in_place_2(known);
594 exchange(known, res);
599 /* A undefined value, e.g., in unreachable code. */
603 res = optimize_node(res); /* This is necessary to add the node to the hash table for cse. */
604 IRN_VERIFY_IRG(res, irg);
605 /* Memory Phis in endless loops must be kept alive.
606 As we can't distinguish these easily we keep all of them alive. */
607 if (is_Phi(res) && mode == mode_M)
608 add_End_keepalive(get_irg_end(irg), res);
612 } /* new_rd_Phi_in */
614 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode);
616 static ir_node *phi_merge(ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins);
619 * Computes the predecessors for the real phi node, and then
620 * allocates and returns this node. The routine called to allocate the
621 * node might optimize it away and return a real value.
622 * This function must be called with an in-array of proper size.
624 static ir_node *phi_merge(ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
626 ir_node *prevBlock, *res, *phi0, *phi0_all;
629 /* If this block has no value at pos create a Phi0 and remember it
630 in graph_arr to break recursions.
631 Else we may not set graph_arr as there a later value is remembered. */
633 if (block->attr.block.graph_arr[pos] == NULL) {
634 ir_graph *irg = current_ir_graph;
636 if (block == get_irg_start_block(irg)) {
637 /* Collapsing to Bad tarvals is no good idea.
638 So we call a user-supplied routine here that deals with this
639 case as appropriate for the given language. Sorrily the only
640 help we can give here is the position.
642 Even if all variables are defined before use, it can happen that
643 we get to the start block, if a Cond has been replaced by a tuple
644 (bad, jmp). In this case we call the function needlessly,
645 eventually generating an non existent error.
646 However, this SHOULD NOT HAPPEN, as bad control flow nodes are
647 intercepted before recurring.
649 if (default_initialize_local_variable != NULL) {
650 ir_node *rem = get_cur_block();
652 set_cur_block(block);
653 block->attr.block.graph_arr[pos] = default_initialize_local_variable(irg, mode, pos - 1);
656 block->attr.block.graph_arr[pos] = new_Unknown(mode);
658 return block->attr.block.graph_arr[pos];
660 phi0 = new_rd_Phi0(irg, block, mode);
661 block->attr.block.graph_arr[pos] = phi0;
665 /* This loop goes to all predecessor blocks of the block the Phi node
666 is in and there finds the operands of the Phi node by calling
667 get_r_value_internal. */
668 for (i = 1; i <= ins; ++i) {
669 ir_node *cf_pred = block->in[i];
670 ir_node *prevCfOp = skip_Proj(cf_pred);
672 if (is_Bad(prevCfOp)) {
673 /* In case a Cond has been optimized we would get right to the start block
674 with an invalid definition. */
675 nin[i-1] = new_Bad();
678 prevBlock = prevCfOp->in[0]; /* go past control flow op to prev block */
680 if (!is_Bad(prevBlock)) {
681 nin[i-1] = get_r_value_internal(prevBlock, pos, mode);
683 nin[i-1] = new_Bad();
687 /* We want to pass the Phi0 node to the constructor: this finds additional
688 optimization possibilities.
689 The Phi0 node either is allocated in this function, or it comes from
690 a former call to get_r_value_internal(). In this case we may not yet
691 exchange phi0, as this is done in mature_immBlock(). */
693 phi0_all = block->attr.block.graph_arr[pos];
694 if (! is_Phi0(phi0_all) ||
695 get_irn_arity(phi0_all) != 0 ||
696 get_nodes_block(phi0_all) != block)
702 /* After collecting all predecessors into the array nin a new Phi node
703 with these predecessors is created. This constructor contains an
704 optimization: If all predecessors of the Phi node are identical it
705 returns the only operand instead of a new Phi node. */
706 res = new_rd_Phi_in(current_ir_graph, block, mode, nin, ins, phi0_all);
708 /* In case we allocated a Phi0 node at the beginning of this procedure,
709 we need to exchange this Phi0 with the real Phi. */
712 block->attr.block.graph_arr[pos] = res;
719 * This function returns the last definition of a value. In case
720 * this value was last defined in a previous block, Phi nodes are
721 * inserted. If the part of the firm graph containing the definition
722 * is not yet constructed, a dummy Phi node is returned.
724 * @param block the current block
725 * @param pos the value number of the value searched
726 * @param mode the mode of this value (needed for Phi construction)
728 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
731 /* There are 4 cases to treat.
733 1. The block is not mature and we visit it the first time. We can not
734 create a proper Phi node, therefore a Phi0, i.e., a Phi without
735 predecessors is returned. This node is added to the linked list (block
736 attribute "phis") of the containing block to be completed when this block is
737 matured. (Completion will add a new Phi and turn the Phi0 into an Id
740 2. The value is already known in this block, graph_arr[pos] is set and we
741 visit the block the first time. We can return the value without
742 creating any new nodes.
744 3. The block is mature and we visit it the first time. A Phi node needs
745 to be created (phi_merge). If the Phi is not needed, as all it's
746 operands are the same value reaching the block through different
747 paths, it's optimized away and the value itself is returned.
749 4. The block is mature, and we visit it the second time. Now two
750 subcases are possible:
751 * The value was computed completely the last time we were here. This
752 is the case if there is no loop. We can return the proper value.
753 * The recursion that visited this node and set the flag did not
754 return yet. We are computing a value in a loop and need to
755 break the recursion. This case only happens if we visited
756 the same block with phi_merge before, which inserted a Phi0.
757 So we return the Phi0.
760 /* case 4 -- already visited. */
761 if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) {
762 /* As phi_merge allocates a Phi0 this value is always defined. Here
763 is the critical difference of the two algorithms. */
764 assert(block->attr.block.graph_arr[pos]);
765 return block->attr.block.graph_arr[pos];
768 /* visited the first time */
769 set_irn_visited(block, get_irg_visited(current_ir_graph));
771 /* Get the local valid value */
772 res = block->attr.block.graph_arr[pos];
774 /* case 2 -- If the value is actually computed, return it. */
778 if (block->attr.block.is_matured) { /* case 3 */
780 /* The Phi has the same amount of ins as the corresponding block. */
781 int ins = get_irn_arity(block);
783 NEW_ARR_A(ir_node *, nin, ins);
785 /* Phi merge collects the predecessors and then creates a node. */
786 res = phi_merge(block, pos, mode, nin, ins);
788 } else { /* case 1 */
789 /* The block is not mature, we don't know how many in's are needed. A Phi
790 with zero predecessors is created. Such a Phi node is called Phi0
791 node. The Phi0 is then added to the list of Phi0 nodes in this block
792 to be matured by mature_immBlock later.
793 The Phi0 has to remember the pos of it's internal value. If the real
794 Phi is computed, pos is used to update the array with the local
796 res = new_rd_Phi0(current_ir_graph, block, mode);
797 res->attr.phi.u.pos = pos;
798 res->attr.phi.next = block->attr.block.phis;
799 block->attr.block.phis = res;
802 assert(is_ir_node(res) && "phi_merge() failed to construct a definition");
804 /* The local valid value is available now. */
805 block->attr.block.graph_arr[pos] = res;
808 } /* get_r_value_internal */
810 /* ************************************************************************** */
813 * Finalize a Block node, when all control flows are known.
814 * Acceptable parameters are only Block nodes.
816 void mature_immBlock(ir_node *block)
822 assert(is_Block(block));
823 if (!get_Block_matured(block)) {
824 ir_graph *irg = current_ir_graph;
826 ins = ARR_LEN(block->in) - 1;
827 /* Fix block parameters */
828 block->attr.block.backedge = new_backedge_arr(irg->obst, ins);
830 /* An array for building the Phi nodes. */
831 NEW_ARR_A(ir_node *, nin, ins);
833 /* Traverse a chain of Phi nodes attached to this block and mature
835 for (n = block->attr.block.phis; n; n = next) {
836 inc_irg_visited(irg);
837 next = n->attr.phi.next;
838 exchange(n, phi_merge(block, n->attr.phi.u.pos, n->mode, nin, ins));
841 block->attr.block.is_matured = 1;
843 /* Now, as the block is a finished Firm node, we can optimize it.
844 Since other nodes have been allocated since the block was created
845 we can not free the node on the obstack. Therefore we have to call
847 Unfortunately the optimization does not change a lot, as all allocated
848 nodes refer to the unoptimized node.
849 We can call optimize_in_place_2(), as global cse has no effect on blocks. */
850 block = optimize_in_place_2(block);
851 IRN_VERIFY_IRG(block, irg);
853 } /* mature_immBlock */
855 ir_node *new_d_Phi(dbg_info *db, int arity, ir_node **in, ir_mode *mode)
857 return new_bd_Phi(db, current_ir_graph->current_block, arity, in, mode);
860 ir_node *new_d_Const(dbg_info *db, tarval *con)
862 return new_bd_Const(db, con);
865 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
867 return new_bd_Const_long(db, mode, value);
868 } /* new_d_Const_long */
870 ir_node *new_d_Const_type(dbg_info *db, tarval *con, ir_type *tp)
872 return new_bd_Const_type(db, con, tp);
873 } /* new_d_Const_type */
876 ir_node *new_d_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
879 assert(is_Cond(arg));
880 arg->attr.cond.default_proj = max_proj;
881 res = new_d_Proj(db, arg, mode_X, max_proj);
883 } /* new_d_defaultProj */
885 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr, ir_entity *ent)
886 /* GL: objptr was called frame before. Frame was a bad choice for the name
887 as the operand could as well be a pointer to a dynamic object. */
889 return new_bd_Sel(db, current_ir_graph->current_block,
890 store, objptr, 0, NULL, ent);
891 } /* new_d_simpleSel */
893 ir_node *new_d_SymConst_type(dbg_info *db, ir_mode *mode, symconst_symbol value, symconst_kind kind, ir_type *tp)
895 return new_bd_SymConst_type(db, get_irg_start_block(current_ir_graph), mode,
897 } /* new_d_SymConst_type */
899 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value, symconst_kind kind)
901 return new_bd_SymConst_type(db, get_irg_start_block(current_ir_graph), mode,
902 value, kind, firm_unknown_type);
903 } /* new_d_SymConst */
905 ir_node *new_d_Sync(dbg_info *db, int arity, ir_node *in[])
907 return new_rd_Sync(db, current_ir_graph->current_block, arity, in);
910 ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[], ir_asm_constraint *inputs,
911 int n_outs, ir_asm_constraint *outputs, int n_clobber,
912 ident *clobber[], ident *text)
914 return new_bd_ASM(db, current_ir_graph->current_block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
917 /* ********************************************************************* */
918 /* Comfortable interface with automatic Phi node construction. */
919 /* (Uses also constructors of ?? interface, except new_Block. */
920 /* ********************************************************************* */
922 /* Block construction */
923 /* immature Block without predecessors */
924 ir_node *new_d_immBlock(dbg_info *db)
928 assert(get_irg_phase_state(current_ir_graph) == phase_building);
929 /* creates a new dynamic in-array as length of in is -1 */
930 res = new_ir_node(db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
932 res->attr.block.is_matured = 0;
933 res->attr.block.is_dead = 0;
934 res->attr.block.irg.irg = current_ir_graph;
935 res->attr.block.backedge = NULL;
936 res->attr.block.in_cg = NULL;
937 res->attr.block.cg_backedge = NULL;
938 res->attr.block.extblk = NULL;
939 res->attr.block.region = NULL;
940 res->attr.block.entity = NULL;
942 set_Block_block_visited(res, 0);
944 /* Create and initialize array for Phi-node construction. */
945 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
946 current_ir_graph->n_loc);
947 memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
949 /* Immature block may not be optimized! */
950 IRN_VERIFY_IRG(res, current_ir_graph);
953 } /* new_d_immBlock */
955 ir_node *new_immBlock(void)
957 return new_d_immBlock(NULL);
960 /* add an edge to a jmp/control flow node */
961 void add_immBlock_pred(ir_node *block, ir_node *jmp)
963 int n = ARR_LEN(block->in) - 1;
965 assert(is_Block(block) && "Error: Must be a Block");
966 assert(!block->attr.block.is_matured && "Error: Block already matured!\n");
967 assert(is_ir_node(jmp));
969 ARR_APP1(ir_node *, block->in, jmp);
971 hook_set_irn_n(block, n, jmp, NULL);
972 } /* add_immBlock_pred */
974 /* changing the current block */
975 void set_cur_block(ir_node *target)
977 current_ir_graph->current_block = target;
978 } /* set_cur_block */
980 /* ************************ */
981 /* parameter administration */
983 /* get a value from the parameter array from the current block by its index */
984 ir_node *get_d_value(dbg_info *db, int pos, ir_mode *mode)
986 ir_graph *irg = current_ir_graph;
987 assert(get_irg_phase_state(irg) == phase_building);
988 inc_irg_visited(irg);
993 return get_r_value_internal(irg->current_block, pos + 1, mode);
996 /* get a value from the parameter array from the current block by its index */
997 ir_node *get_value(int pos, ir_mode *mode)
999 return get_d_value(NULL, pos, mode);
1003 * helper function for guess_mode: recursively look for a definition for
1004 * local variable @p pos, returns its mode if found.
1006 static ir_mode *guess_recursively(ir_node *block, int pos)
1012 if (irn_visited(block))
1014 mark_irn_visited(block);
1016 /* already have a defintion -> we can simply look at its mode */
1017 value = block->attr.block.graph_arr[pos];
1019 return get_irn_mode(value);
1021 /* now we try to guess, by looking at the predecessor blocks */
1022 n_preds = get_irn_arity(block);
1023 for (i = 0; i < n_preds; ++i) {
1024 ir_node *pred_block = get_Block_cfgpred_block(block, i);
1025 ir_mode *mode = guess_recursively(pred_block, pos);
1030 /* no way to guess */
1034 ir_mode *ir_guess_mode(int pos)
1036 ir_graph *irg = current_ir_graph;
1037 ir_node *block = irg->current_block;
1038 ir_node *value = block->attr.block.graph_arr[pos+1];
1041 /* already have a defintion -> we can simply look at its mode */
1043 return get_irn_mode(value);
1045 ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
1046 inc_irg_visited(current_ir_graph);
1047 mode = guess_recursively(block, pos+1);
1048 ir_free_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
1053 /* set a value at position pos in the parameter array from the current block */
1054 void set_value(int pos, ir_node *value)
1056 ir_graph *irg = current_ir_graph;
1057 assert(get_irg_phase_state(irg) == phase_building);
1059 assert(pos+1 < irg->n_loc);
1060 assert(is_ir_node(value));
1061 irg->current_block->attr.block.graph_arr[pos + 1] = value;
1064 /* Find the value number for a node in the current block.*/
1065 int find_value(ir_node *value)
1068 ir_node *bl = current_ir_graph->current_block;
1070 for (i = ARR_LEN(bl->attr.block.graph_arr) - 1; i >= 1; --i)
1071 if (bl->attr.block.graph_arr[i] == value)
1076 /* get the current store */
1077 ir_node *get_store(void)
1079 ir_graph *irg = current_ir_graph;
1081 assert(get_irg_phase_state(irg) == phase_building);
1082 /* GL: one could call get_value instead */
1083 inc_irg_visited(irg);
1084 return get_r_value_internal(irg->current_block, 0, mode_M);
1087 /* set the current store: handles automatic Sync construction for Load nodes */
1088 void set_store(ir_node *store)
1090 ir_node *load, *pload, *pred, *in[2];
1092 assert(get_irg_phase_state(current_ir_graph) == phase_building);
1093 /* Beware: due to dead code elimination, a store might become a Bad node even in
1094 the construction phase. */
1095 assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
1097 if (get_opt_auto_create_sync()) {
1098 /* handle non-volatile Load nodes by automatically creating Sync's */
1099 load = skip_Proj(store);
1100 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
1101 pred = get_Load_mem(load);
1103 if (is_Sync(pred)) {
1104 /* a Load after a Sync: move it up */
1105 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
1107 set_Load_mem(load, get_memop_mem(mem));
1108 add_Sync_pred(pred, store);
1111 pload = skip_Proj(pred);
1112 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
1113 /* a Load after a Load: create a new Sync */
1114 set_Load_mem(load, get_Load_mem(pload));
1118 store = new_Sync(2, in);
1123 current_ir_graph->current_block->attr.block.graph_arr[0] = store;
1126 void keep_alive(ir_node *ka)
1128 add_End_keepalive(get_irg_end(current_ir_graph), ka);
1131 /* --- Useful access routines --- */
1132 /* Returns the current block of the current graph. To set the current
1133 block use set_cur_block. */
1134 ir_node *get_cur_block(void)
1136 return get_irg_current_block(current_ir_graph);
1137 } /* get_cur_block */
1139 /* Returns the frame type of the current graph */
1140 ir_type *get_cur_frame_type(void)
1142 return get_irg_frame_type(current_ir_graph);
1143 } /* get_cur_frame_type */
1146 /* ********************************************************************* */
1149 /* call once for each run of the library */
1150 void ir_set_uninitialized_local_variable_func(
1151 uninitialized_local_variable_func_t *func)
1153 default_initialize_local_variable = func;
1156 void irg_finalize_cons(ir_graph *irg)
1158 set_irg_phase_state(irg, phase_high);
1161 void irp_finalize_cons(void)
1164 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
1165 irg_finalize_cons(get_irp_irg(i));
1167 irp->phase_state = phase_high;
1170 ir_node *new_Start(void)
1172 return new_d_Start(NULL);
1174 ir_node *new_End(void)
1176 return new_d_End(NULL);
1178 ir_node *new_Const(tarval *con)
1180 return new_d_Const(NULL, con);
1183 ir_node *new_Const_long(ir_mode *mode, long value)
1185 return new_d_Const_long(NULL, mode, value);
1188 ir_node *new_Const_type(tarval *con, ir_type *tp)
1190 return new_d_Const_type(NULL, con, tp);
1193 ir_node *new_SymConst_type(ir_mode *mode, symconst_symbol value, symconst_kind kind, ir_type *type)
1195 return new_d_SymConst_type(NULL, mode, value, kind, type);
1197 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
1199 return new_d_SymConst(NULL, mode, value, kind);
1201 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
1203 return new_d_simpleSel(NULL, store, objptr, ent);
1205 ir_node *new_Phi(int arity, ir_node **in, ir_mode *mode)
1207 return new_d_Phi(NULL, arity, in, mode);
1209 ir_node *new_Sync(int arity, ir_node *in[])
1211 return new_d_Sync(NULL, arity, in);
1213 ir_node *new_defaultProj(ir_node *arg, long max_proj)
1215 return new_d_defaultProj(NULL, arg, max_proj);
1217 ir_node *new_Bad(void)
1219 return get_irg_bad(current_ir_graph);
1221 ir_node *new_NoMem(void)
1223 return get_irg_no_mem(current_ir_graph);
1225 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
1226 int n_outs, ir_asm_constraint *outputs,
1227 int n_clobber, ident *clobber[], ident *text)
1229 return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
1232 /* create a new anchor node */
1233 ir_node *new_Anchor(ir_graph *irg)
1235 ir_node *in[anchor_last];
1237 memset(in, 0, sizeof(in));
1238 res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last, in);
1240 /* hack to get get_irn_irg working: set block to ourself and allow
1241 * get_Block_irg for anchor */
1242 res->attr.irg.irg = irg;