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
25 * Michael Beck, Matthias Braun
31 #include "irgraph_t.h"
41 #include "irbackedge_t.h"
43 #include "iredges_t.h"
47 #include "gen_ir_cons.c.inl"
50 * Language dependent variable initialization callback.
52 static uninitialized_local_variable_func_t *default_initialize_local_variable = NULL;
55 * Creates a Phi node with all predecessors. Calling this constructor
56 * is only allowed if the corresponding block is mature.
58 ir_node *new_rd_Phi(dbg_info *db, ir_node *block, int arity, ir_node **in,
61 ir_graph *irg = get_irn_irg(block);
62 ir_node *res = new_ir_node(db, irg, block, op_Phi, mode, arity, in);
63 res->attr.phi.u.backedge = new_backedge_arr(irg->obst, arity);
65 res = optimize_node(res);
66 irn_verify_irg(res, irg);
68 /* Memory Phis in endless loops must be kept alive.
69 As we can't distinguish these easily we keep all of them alive. */
70 if (is_Phi(res) && mode == mode_M)
71 add_End_keepalive(get_irg_end(irg), res);
75 ir_node *new_rd_Const(dbg_info *db, ir_graph *irg, ir_tarval *con)
77 ir_node *block = get_irg_start_block(irg);
78 ir_mode *mode = get_tarval_mode(con);
79 ir_node *res = new_ir_node(db, irg, block, op_Const, mode, 0, NULL);
80 res->attr.con.tarval = con;
82 res = optimize_node (res);
83 irn_verify_irg(res, irg);
88 ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg, ir_mode *mode,
91 return new_rd_Const(db, irg, new_tarval_from_long(value, mode));
94 ir_node *new_rd_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
99 arg->attr.cond.default_proj = max_proj;
100 res = new_rd_Proj(db, arg, mode_X, max_proj);
104 ir_node *new_rd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[],
105 ir_asm_constraint *inputs, int n_outs,
106 ir_asm_constraint *outputs, int n_clobber,
107 ident *clobber[], ident *text)
109 ir_graph *irg = get_irn_irg(block);
110 ir_node *res = new_ir_node(db, irg, block, op_ASM, mode_T, arity, in);
112 res->attr.assem.pin_state = op_pin_state_pinned;
113 res->attr.assem.input_constraints
114 = NEW_ARR_D(ir_asm_constraint, irg->obst, arity);
115 res->attr.assem.output_constraints
116 = NEW_ARR_D(ir_asm_constraint, irg->obst, n_outs);
117 res->attr.assem.clobbers = NEW_ARR_D(ident *, irg->obst, n_clobber);
118 res->attr.assem.text = text;
120 memcpy(res->attr.assem.input_constraints, inputs, sizeof(inputs[0]) * arity);
121 memcpy(res->attr.assem.output_constraints, outputs, sizeof(outputs[0]) * n_outs);
122 memcpy(res->attr.assem.clobbers, clobber, sizeof(clobber[0]) * n_clobber);
124 res = optimize_node(res);
125 irn_verify_irg(res, irg);
129 ir_node *new_rd_simpleSel(dbg_info *db, ir_node *block, ir_node *store,
130 ir_node *objptr, ir_entity *ent)
132 return new_rd_Sel(db, block, store, objptr, 0, NULL, ent);
135 ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
136 symconst_symbol value, symconst_kind symkind)
138 ir_node *block = get_irg_start_block(irg);
139 ir_node *res = new_ir_node(db, irg, block, op_SymConst, mode, 0, NULL);
140 res->attr.symc.kind = symkind;
141 res->attr.symc.sym = value;
143 res = optimize_node(res);
144 irn_verify_irg(res, irg);
148 ir_node *new_rd_SymConst_addr_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol)
151 sym.entity_p = symbol;
152 return new_rd_SymConst(db, irg, mode, sym, symconst_addr_ent);
155 ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_entity *symbol)
158 sym.entity_p = symbol;
159 return new_rd_SymConst(db, irg, mode, sym, symconst_ofs_ent);
162 ir_node *new_rd_SymConst_type_tag(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
166 return new_rd_SymConst(db, irg, mode, sym, symconst_type_tag);
169 ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
173 return new_rd_SymConst(db, irg, mode, sym, symconst_type_size);
176 ir_node *new_rd_SymConst_align(dbg_info *db, ir_graph *irg, ir_mode *mode, ir_type *symbol)
180 return new_rd_SymConst(db, irg, mode, sym, symconst_type_align);
183 ir_node *new_r_Const(ir_graph *irg, ir_tarval *con)
185 return new_rd_Const(NULL, irg, con);
187 ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value)
189 return new_rd_Const_long(NULL, irg, mode, value);
191 ir_node *new_r_SymConst(ir_graph *irg, ir_mode *mode, symconst_symbol value,
192 symconst_kind symkind)
194 return new_rd_SymConst(NULL, irg, mode, value, symkind);
196 ir_node *new_r_simpleSel(ir_node *block, ir_node *store, ir_node *objptr,
199 return new_rd_Sel(NULL, block, store, objptr, 0, NULL, ent);
201 ir_node *new_r_Phi(ir_node *block, int arity, ir_node **in, ir_mode *mode)
203 return new_rd_Phi(NULL, block, arity, in, mode);
205 ir_node *new_r_defaultProj(ir_node *arg, long max_proj)
207 return new_rd_defaultProj(NULL, arg, max_proj);
209 ir_node *new_r_ASM(ir_node *block,
210 int arity, ir_node *in[], ir_asm_constraint *inputs,
211 int n_outs, ir_asm_constraint *outputs,
212 int n_clobber, ident *clobber[], ident *text)
214 return new_rd_ASM(NULL, block, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
217 /* ***********************************************************************/
218 /* Methods necessary for automatic Phi node creation */
220 ir_node *phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins)
221 ir_node *get_r_value_internal (ir_node *block, int pos, ir_mode *mode);
222 ir_node *new_rd_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode)
223 ir_node *new_rd_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode, ir_node **in, int ins)
225 Call Graph: ( A ---> B == A "calls" B)
227 get_value mature_immBlock
235 get_r_value_internal |
239 new_rd_Phi0 new_rd_Phi_in
241 * *************************************************************************** */
243 /** Creates a Phi node with 0 predecessors. */
244 static inline ir_node *new_rd_Phi0(ir_node *block, ir_mode *mode)
246 ir_graph *irg = get_irn_irg(block);
247 ir_node *res = new_ir_node(NULL, irg, block, op_Phi, mode, 0, NULL);
248 irn_verify_irg(res, irg);
253 * Internal constructor of a Phi node by a phi_merge operation.
255 * @param block the block in which the Phi will be constructed
256 * @param mode the mod eof the Phi node
257 * @param in the input array of the phi node
258 * @param n_in number of elements in the input array
259 * @param phi0 in non-NULL: the Phi0 node in the same block that represents
260 * the value for which the new Phi is constructed
262 static ir_node *new_rd_Phi_in(ir_node *block, ir_mode *mode,
263 int n_in, ir_node **in, ir_node *phi0)
266 ir_node *res, *known;
267 ir_graph *irg = get_irn_irg(block);
269 /* Allocate a new node on the obstack. The allocation copies the in
271 res = new_ir_node(NULL, irg, block, op_Phi, mode, n_in, in);
272 res->attr.phi.u.backedge = new_backedge_arr(irg->obst, n_in);
274 /* This loop checks whether the Phi has more than one predecessor.
275 If so, it is a real Phi node and we break the loop. Else the
276 Phi node merges the same definition on several paths and therefore
278 Note: We MUST consider Bad nodes, else we might get data flow cycles in dead loops! */
280 for (i = n_in - 1; i >= 0; --i) {
283 in[i] = skip_Id(in[i]); /* increases the number of freed Phis. */
285 /* Optimize self referencing Phis: We can't detect them yet properly, as
286 they still refer to the Phi0 they will replace. So replace right now. */
287 if (phi0 && in[i] == phi0)
290 if (in[i] == res || in[i] == known)
299 /* i < 0: there is at most one predecessor, we don't need a phi node. */
302 edges_node_deleted(res, current_ir_graph);
303 obstack_free(current_ir_graph->obst, res);
305 /* If pred is a phi node we want to optimize it: If loops are matured in a bad
306 order, an enclosing Phi know may get superfluous. */
307 res = optimize_in_place_2(known);
309 exchange(known, res);
314 /* A undefined value, e.g., in unreachable code. */
315 res = new_r_Bad(irg);
318 res = optimize_node(res); /* This is necessary to add the node to the hash table for cse. */
319 irn_verify_irg(res, irg);
320 /* Memory Phis in endless loops must be kept alive.
321 As we can't distinguish these easily we keep all of them alive. */
322 if (is_Phi(res) && mode == mode_M)
323 add_End_keepalive(get_irg_end(irg), res);
329 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode);
332 * Computes the predecessors for the real phi node, and then
333 * allocates and returns this node. The routine called to allocate the
334 * node might optimize it away and return a real value.
335 * This function must be called with an in-array of proper size.
337 static ir_node *phi_merge(ir_node *block, int pos, ir_mode *mode,
338 int n_ins, ir_node **ins)
340 ir_graph *irg = get_irn_irg(block);
341 ir_node *prevBlock, *res, *phi0, *phi0_all;
344 /* If this block has no value at pos create a Phi0 and remember it
345 in graph_arr to break recursions.
346 Else we may not set graph_arr as there a later value is remembered. */
348 if (block->attr.block.graph_arr[pos] == NULL) {
350 if (block == get_irg_start_block(irg)) {
351 /* Collapsing to Bad tarvals is no good idea.
352 So we call a user-supplied routine here that deals with this
353 case as appropriate for the given language. Sorrily the only
354 help we can give here is the position.
356 Even if all variables are defined before use, it can happen that
357 we get to the start block, if a Cond has been replaced by a tuple
358 (bad, jmp). In this case we call the function needlessly,
359 eventually generating an non existent error.
360 However, this SHOULD NOT HAPPEN, as bad control flow nodes are
361 intercepted before recurring.
363 if (default_initialize_local_variable != NULL) {
364 ir_node *rem = get_r_cur_block(irg);
366 set_r_cur_block(irg, block);
367 block->attr.block.graph_arr[pos] = default_initialize_local_variable(irg, mode, pos - 1);
368 set_r_cur_block(irg, rem);
370 block->attr.block.graph_arr[pos] = new_r_Unknown(irg, mode);
372 return block->attr.block.graph_arr[pos];
374 phi0 = new_rd_Phi0(block, mode);
375 block->attr.block.graph_arr[pos] = phi0;
379 /* This loop goes to all predecessor blocks of the block the Phi node
380 is in and there finds the operands of the Phi node by calling
381 get_r_value_internal. */
382 for (i = 1; i <= n_ins; ++i) {
383 ir_node *cf_pred = block->in[i];
384 ir_node *prevCfOp = skip_Proj(cf_pred);
386 if (is_Bad(prevCfOp)) {
387 /* In case a Cond has been optimized we would get right to the start block
388 with an invalid definition. */
389 ins[i-1] = new_r_Bad(irg);
392 prevBlock = prevCfOp->in[0]; /* go past control flow op to prev block */
394 if (!is_Bad(prevBlock)) {
395 ins[i-1] = get_r_value_internal(prevBlock, pos, mode);
397 ins[i-1] = new_r_Bad(irg);
401 /* We want to pass the Phi0 node to the constructor: this finds additional
402 optimization possibilities.
403 The Phi0 node either is allocated in this function, or it comes from
404 a former call to get_r_value_internal(). In this case we may not yet
405 exchange phi0, as this is done in mature_immBlock(). */
407 phi0_all = block->attr.block.graph_arr[pos];
408 if (! is_Phi0(phi0_all) ||
409 get_irn_arity(phi0_all) != 0 ||
410 get_nodes_block(phi0_all) != block)
416 /* After collecting all predecessors into the array ins a new Phi node
417 with these predecessors is created. This constructor contains an
418 optimization: If all predecessors of the Phi node are identical it
419 returns the only operand instead of a new Phi node. */
420 res = new_rd_Phi_in(block, mode, n_ins, ins, phi0_all);
422 /* In case we allocated a Phi0 node at the beginning of this procedure,
423 we need to exchange this Phi0 with the real Phi. */
426 block->attr.block.graph_arr[pos] = res;
433 * This function returns the last definition of a value. In case
434 * this value was last defined in a previous block, Phi nodes are
435 * inserted. If the part of the firm graph containing the definition
436 * is not yet constructed, a dummy Phi node is returned.
438 * @param block the current block
439 * @param pos the value number of the value searched
440 * @param mode the mode of this value (needed for Phi construction)
442 static ir_node *get_r_value_internal(ir_node *block, int pos, ir_mode *mode)
445 /* There are 4 cases to treat.
447 1. The block is not mature and we visit it the first time. We can not
448 create a proper Phi node, therefore a Phi0, i.e., a Phi without
449 predecessors is returned. This node is added to the linked list (block
450 attribute "phis") of the containing block to be completed when this block is
451 matured. (Completion will add a new Phi and turn the Phi0 into an Id
454 2. The value is already known in this block, graph_arr[pos] is set and we
455 visit the block the first time. We can return the value without
456 creating any new nodes.
458 3. The block is mature and we visit it the first time. A Phi node needs
459 to be created (phi_merge). If the Phi is not needed, as all it's
460 operands are the same value reaching the block through different
461 paths, it's optimized away and the value itself is returned.
463 4. The block is mature, and we visit it the second time. Now two
464 subcases are possible:
465 * The value was computed completely the last time we were here. This
466 is the case if there is no loop. We can return the proper value.
467 * The recursion that visited this node and set the flag did not
468 return yet. We are computing a value in a loop and need to
469 break the recursion. This case only happens if we visited
470 the same block with phi_merge before, which inserted a Phi0.
471 So we return the Phi0.
474 /* case 4 -- already visited. */
475 if (irn_visited(block)) {
476 /* As phi_merge allocates a Phi0 this value is always defined. Here
477 is the critical difference of the two algorithms. */
478 assert(block->attr.block.graph_arr[pos]);
479 return block->attr.block.graph_arr[pos];
482 /* visited the first time */
483 mark_irn_visited(block);
485 /* Get the local valid value */
486 res = block->attr.block.graph_arr[pos];
488 /* case 2 -- If the value is actually computed, return it. */
492 if (block->attr.block.is_matured) { /* case 3 */
494 /* The Phi has the same amount of ins as the corresponding block. */
495 int n_in = get_irn_arity(block);
497 NEW_ARR_A(ir_node *, in, n_in);
499 /* Phi merge collects the predecessors and then creates a node. */
500 res = phi_merge(block, pos, mode, n_in, in);
501 } else { /* case 1 */
502 /* The block is not mature, we don't know how many in's are needed. A Phi
503 with zero predecessors is created. Such a Phi node is called Phi0
504 node. The Phi0 is then added to the list of Phi0 nodes in this block
505 to be matured by mature_immBlock later.
506 The Phi0 has to remember the pos of it's internal value. If the real
507 Phi is computed, pos is used to update the array with the local
509 res = new_rd_Phi0(block, mode);
510 res->attr.phi.u.pos = pos;
511 res->attr.phi.next = block->attr.block.phis;
512 block->attr.block.phis = res;
515 assert(is_ir_node(res) && "phi_merge() failed to construct a definition");
517 /* The local valid value is available now. */
518 block->attr.block.graph_arr[pos] = res;
523 /* ************************************************************************** */
526 * Finalize a Block node, when all control flows are known.
527 * Acceptable parameters are only Block nodes.
529 void mature_immBlock(ir_node *block)
535 assert(is_Block(block));
536 if (!get_Block_matured(block)) {
537 ir_graph *irg = current_ir_graph;
539 ins = ARR_LEN(block->in) - 1;
540 /* Fix block parameters */
541 block->attr.block.backedge = new_backedge_arr(irg->obst, ins);
543 /* An array for building the Phi nodes. */
544 NEW_ARR_A(ir_node *, nin, ins);
546 /* Traverse a chain of Phi nodes attached to this block and mature
548 for (n = block->attr.block.phis; n; n = next) {
549 inc_irg_visited(irg);
550 next = n->attr.phi.next;
551 exchange(n, phi_merge(block, n->attr.phi.u.pos, n->mode, ins, nin));
554 block->attr.block.is_matured = 1;
556 /* Now, as the block is a finished Firm node, we can optimize it.
557 Since other nodes have been allocated since the block was created
558 we can not free the node on the obstack. Therefore we have to call
560 Unfortunately the optimization does not change a lot, as all allocated
561 nodes refer to the unoptimized node.
562 We can call optimize_in_place_2(), as global cse has no effect on blocks. */
563 block = optimize_in_place_2(block);
564 irn_verify_irg(block, irg);
568 ir_node *new_d_Phi(dbg_info *db, int arity, ir_node **in, ir_mode *mode)
570 assert(get_irg_phase_state(current_ir_graph) == phase_building);
571 return new_rd_Phi(db, current_ir_graph->current_block, arity, in, mode);
574 ir_node *new_d_Const(dbg_info *db, ir_tarval *con)
576 assert(get_irg_phase_state(current_ir_graph) == phase_building);
577 return new_rd_Const(db, current_ir_graph, con);
580 ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value)
582 assert(get_irg_phase_state(current_ir_graph) == phase_building);
583 return new_rd_Const_long(db, current_ir_graph, mode, value);
586 ir_node *new_d_defaultProj(dbg_info *db, ir_node *arg, long max_proj)
589 assert(is_Cond(arg) || is_Bad(arg));
590 assert(get_irg_phase_state(current_ir_graph) == phase_building);
592 arg->attr.cond.default_proj = max_proj;
593 res = new_d_Proj(db, arg, mode_X, max_proj);
597 ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
600 assert(get_irg_phase_state(current_ir_graph) == phase_building);
601 return new_rd_Sel(db, current_ir_graph->current_block,
602 store, objptr, 0, NULL, ent);
605 ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode, symconst_symbol value,
608 assert(get_irg_phase_state(current_ir_graph) == phase_building);
609 return new_rd_SymConst(db, current_ir_graph, mode, value, kind);
612 ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[],
613 ir_asm_constraint *inputs,
614 int n_outs, ir_asm_constraint *outputs, int n_clobber,
615 ident *clobber[], ident *text)
617 assert(get_irg_phase_state(current_ir_graph) == phase_building);
618 return new_rd_ASM(db, current_ir_graph->current_block, arity, in, inputs,
619 n_outs, outputs, n_clobber, clobber, text);
622 ir_node *new_rd_immBlock(dbg_info *dbgi, ir_graph *irg)
626 assert(get_irg_phase_state(irg) == phase_building);
627 /* creates a new dynamic in-array as length of in is -1 */
628 res = new_ir_node(dbgi, irg, NULL, op_Block, mode_BB, -1, NULL);
630 res->attr.block.is_matured = 0;
631 res->attr.block.is_dead = 0;
632 res->attr.block.irg.irg = irg;
633 res->attr.block.backedge = NULL;
634 res->attr.block.in_cg = NULL;
635 res->attr.block.cg_backedge = NULL;
636 res->attr.block.extblk = NULL;
637 res->attr.block.region = NULL;
638 res->attr.block.entity = NULL;
640 set_Block_block_visited(res, 0);
642 /* Create and initialize array for Phi-node construction. */
643 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
644 memset(res->attr.block.graph_arr, 0, sizeof(ir_node*) * irg->n_loc);
646 /* Immature block may not be optimized! */
647 irn_verify_irg(res, irg);
652 ir_node *new_r_immBlock(ir_graph *irg)
654 return new_rd_immBlock(NULL, irg);
657 ir_node *new_d_immBlock(dbg_info *dbgi)
659 return new_rd_immBlock(dbgi, current_ir_graph);
662 ir_node *new_immBlock(void)
664 return new_rd_immBlock(NULL, current_ir_graph);
667 void add_immBlock_pred(ir_node *block, ir_node *jmp)
669 int n = ARR_LEN(block->in) - 1;
671 assert(is_Block(block) && "Error: Must be a Block");
672 assert(!block->attr.block.is_matured && "Error: Block already matured!\n");
673 assert(is_ir_node(jmp));
675 ARR_APP1(ir_node *, block->in, jmp);
677 hook_set_irn_n(block, n, jmp, NULL);
680 void set_cur_block(ir_node *target)
682 current_ir_graph->current_block = target;
685 void set_r_cur_block(ir_graph *irg, ir_node *target)
687 irg->current_block = target;
690 ir_node *get_r_cur_block(ir_graph *irg)
692 return irg->current_block;
695 ir_node *get_cur_block(void)
697 return get_r_cur_block(current_ir_graph);
700 ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode)
702 assert(get_irg_phase_state(irg) == phase_building);
703 inc_irg_visited(irg);
707 return get_r_value_internal(irg->current_block, pos + 1, mode);
710 ir_node *get_value(int pos, ir_mode *mode)
712 return get_r_value(current_ir_graph, pos, mode);
716 * helper function for guess_mode: recursively look for a definition for
717 * local variable @p pos, returns its mode if found.
719 static ir_mode *guess_recursively(ir_node *block, int pos)
725 if (irn_visited(block))
727 mark_irn_visited(block);
729 /* already have a defintion -> we can simply look at its mode */
730 value = block->attr.block.graph_arr[pos];
732 return get_irn_mode(value);
734 /* now we try to guess, by looking at the predecessor blocks */
735 n_preds = get_irn_arity(block);
736 for (i = 0; i < n_preds; ++i) {
737 ir_node *pred_block = get_Block_cfgpred_block(block, i);
738 ir_mode *mode = guess_recursively(pred_block, pos);
743 /* no way to guess */
747 ir_mode *ir_guess_mode(int pos)
749 ir_graph *irg = current_ir_graph;
750 ir_node *block = irg->current_block;
751 ir_node *value = block->attr.block.graph_arr[pos+1];
754 /* already have a defintion -> we can simply look at its mode */
756 return get_irn_mode(value);
758 ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
759 inc_irg_visited(current_ir_graph);
760 mode = guess_recursively(block, pos+1);
761 ir_free_resources(current_ir_graph, IR_RESOURCE_IRN_VISITED);
766 void set_r_value(ir_graph *irg, int pos, ir_node *value)
768 assert(get_irg_phase_state(irg) == phase_building);
770 assert(pos+1 < irg->n_loc);
771 assert(is_ir_node(value));
772 irg->current_block->attr.block.graph_arr[pos + 1] = value;
775 void set_value(int pos, ir_node *value)
777 set_r_value(current_ir_graph, pos, value);
780 int find_value(ir_node *value)
783 ir_node *bl = current_ir_graph->current_block;
785 for (i = ARR_LEN(bl->attr.block.graph_arr) - 1; i >= 1; --i)
786 if (bl->attr.block.graph_arr[i] == value)
791 ir_node *get_r_store(ir_graph *irg)
793 assert(get_irg_phase_state(irg) == phase_building);
794 inc_irg_visited(irg);
795 return get_r_value_internal(irg->current_block, 0, mode_M);
798 ir_node *get_store(void)
800 return get_r_store(current_ir_graph);
803 void set_r_store(ir_graph *irg, ir_node *store)
805 ir_node *load, *pload, *pred, *in[2];
807 assert(get_irg_phase_state(irg) == phase_building);
808 /* Beware: due to dead code elimination, a store might become a Bad node even in
809 the construction phase. */
810 assert((get_irn_mode(store) == mode_M || is_Bad(store)) && "storing non-memory node");
812 if (get_opt_auto_create_sync()) {
813 /* handle non-volatile Load nodes by automatically creating Sync's */
814 load = skip_Proj(store);
815 if (is_Load(load) && get_Load_volatility(load) == volatility_non_volatile) {
816 pred = get_Load_mem(load);
819 /* a Load after a Sync: move it up */
820 ir_node *mem = skip_Proj(get_Sync_pred(pred, 0));
822 set_Load_mem(load, get_memop_mem(mem));
823 add_Sync_pred(pred, store);
826 pload = skip_Proj(pred);
827 if (is_Load(pload) && get_Load_volatility(pload) == volatility_non_volatile) {
828 /* a Load after a Load: create a new Sync */
829 set_Load_mem(load, get_Load_mem(pload));
833 store = new_r_Sync(irg->current_block, 2, in);
838 irg->current_block->attr.block.graph_arr[0] = store;
841 void set_store(ir_node *store)
843 set_r_store(current_ir_graph, store);
846 void keep_alive(ir_node *ka)
848 add_End_keepalive(get_irg_end(current_ir_graph), ka);
851 void ir_set_uninitialized_local_variable_func(
852 uninitialized_local_variable_func_t *func)
854 default_initialize_local_variable = func;
857 void irg_finalize_cons(ir_graph *irg)
859 set_irg_phase_state(irg, phase_high);
862 void irp_finalize_cons(void)
865 for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
866 irg_finalize_cons(get_irp_irg(i));
868 irp->phase_state = phase_high;
871 ir_node *new_Const(ir_tarval *con)
873 return new_d_Const(NULL, con);
876 ir_node *new_Const_long(ir_mode *mode, long value)
878 return new_d_Const_long(NULL, mode, value);
881 ir_node *new_SymConst(ir_mode *mode, symconst_symbol value, symconst_kind kind)
883 return new_d_SymConst(NULL, mode, value, kind);
885 ir_node *new_simpleSel(ir_node *store, ir_node *objptr, ir_entity *ent)
887 return new_d_simpleSel(NULL, store, objptr, ent);
889 ir_node *new_Phi(int arity, ir_node **in, ir_mode *mode)
891 return new_d_Phi(NULL, arity, in, mode);
893 ir_node *new_defaultProj(ir_node *arg, long max_proj)
895 return new_d_defaultProj(NULL, arg, max_proj);
897 ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
898 int n_outs, ir_asm_constraint *outputs,
899 int n_clobber, ident *clobber[], ident *text)
901 return new_d_ASM(NULL, arity, in, inputs, n_outs, outputs, n_clobber, clobber, text);
904 ir_node *new_r_Anchor(ir_graph *irg)
906 ir_node *in[anchor_last];
908 memset(in, 0, sizeof(in));
909 res = new_ir_node(NULL, irg, NULL, op_Anchor, mode_ANY, anchor_last, in);
910 res->attr.anchor.irg.irg = irg;
912 /* hack to get get_irn_irg working: set block to ourself and allow
913 * get_Block_irg for anchor */
919 ir_node *new_r_Block_noopt(ir_graph *irg, int arity, ir_node *in[])
921 ir_node *res = new_ir_node(NULL, irg, NULL, op_Block, mode_BB, arity, in);
922 res->attr.block.irg.irg = irg;
923 res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
924 set_Block_matured(res, 1);
925 /* Create and initialize array for Phi-node construction. */
926 if (get_irg_phase_state(irg) == phase_building) {
927 res->attr.block.graph_arr = NEW_ARR_D(ir_node *, irg->obst, irg->n_loc);
928 memset(res->attr.block.graph_arr, 0, irg->n_loc * sizeof(ir_node*));
930 irn_verify_irg(res, irg);