X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Fircons.c;h=ea1573d8540d35800b1b8f4d9f65e655399f2825;hb=eed0e43a82a6da6d60cf9d2e67f2394ca9f34e8d;hp=83746c40c49d0ee6d7e33c35795ca59a6d3ce8a8;hpb=efbeaff549fcc6015da255ed4d453a95937ff0fd;p=libfirm diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index 83746c40c..ea1573d85 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -10,45 +10,62 @@ */ # include "ircons.h" -# include "array.h" +# include "common.h" +# include "irvrfy.h" +# include "irop.h" # include "iropt.h" +# include "irgmod.h" +# include "array.h" /* memset belongs to string.h */ # include "string.h" +# include "irnode.h" +#if USE_EXPICIT_PHI_IN_STACK +/* A stack needed for the automatic Phi node construction in constructor + Phi_in. */ +struct Phi_in_stack { + ir_node **stack; + int pos; +}; +#endif + +/*********************************************** */ +/** privat interfaces, for professional use only */ + +/* Constructs a Block with a fixed number of predecessors.*/ -/* irnode constructor */ -/* create a new irnode in irg, with an op, mode, arity and */ -/* some incoming irnodes */ -/* this constructor is used in every specified irnode constructor */ inline ir_node * -new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode, - int arity, ir_node **in) +new_r_Block (ir_graph *irg, int arity, ir_node **in) { ir_node *res; - int node_size = offsetof (ir_node, attr) + op->attr_size; - res = (ir_node *) obstack_alloc (irg->obst, node_size); + res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, arity, in); - res->kind = k_ir_node; - res->op = op; - res->mode = mode; - res->visit = 0; - res->link = NULL; - if (arity < 0) { - res->in = NEW_ARR_F (ir_node *, 1); - } else { - res->in = NEW_ARR_D (ir_node *, irg->obst, (arity+1)); - memcpy (&res->in[1], in, sizeof (ir_node *) * arity); - } - res->in[0] = block; + irn_vrfy (res); return res; } +ir_node * +new_r_Start (ir_graph *irg, ir_node *block) +{ + ir_node *res; + res = new_ir_node (irg, block, op_Start, mode_T, 0, NULL); + irn_vrfy (res); + return res; +} -/*********************************************** */ -/** privat interfaces, for professional use only */ +ir_node * +new_r_End (ir_graph *irg, ir_node *block) +{ + ir_node *res; + + res = new_ir_node (irg, block, op_End, mode_X, -1, NULL); + + irn_vrfy (res); + return res; +} /* Creates a Phi node with 0 predecessors */ inline ir_node * @@ -60,7 +77,7 @@ new_r_Phi0 (ir_graph *irg, ir_node *block, ir_mode *mode) /* GL I'm not sure whether we should optimize this guy. * res = optimize (res); ??? */ - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -77,7 +94,7 @@ new_r_Phi (ir_graph *irg, ir_node *block, int arity, ir_node **in, ir_mode *mode res = new_ir_node (irg, block, op_Phi, mode, arity, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -98,7 +115,6 @@ new_Phi_in_stack() { return res; } - void free_to_Phi_in_stack(ir_node *phi) { assert(get_irn_opcode(phi) == iro_Phi); @@ -129,7 +145,7 @@ alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode, assert (res->kind == k_ir_node); assert (res->op == op_Phi); res->mode = mode; - res->visit = 0; + res->visited = 0; res->link = NULL; assert (arity >= 0); /* ???!!! How to free the old in array?? */ @@ -144,7 +160,6 @@ alloc_or_pop_from_Phi_in_stack(ir_graph *irg, ir_node *block, ir_mode *mode, #endif - /* Creates a Phi node with a given, fixed array **in of predecessors. If the Phi node is unnecessary, as the same value reaches the block through all control flow paths, it is eliminated and the value @@ -183,8 +198,9 @@ new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode, #else res = known = new_ir_node (irg, block, op_Phi, mode, ins, in); #endif - /* The in-array can contain NULLs. These were returned by get_r_value_internal - if it reached the same block/definition on a second path. + /* The in-array can contain NULLs. These were returned by + get_r_value_internal if it reached the same block/definition on a + second path. The NULLs are replaced by the node itself to simplify the test in the next loop. */ for (i=0; i < ins; ++i) @@ -214,7 +230,7 @@ new_r_Phi_in (ir_graph *irg, ir_node *block, ir_mode *mode, res = known; } else { res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); } /* return the pointer to the Phi node. This node might be deallocated! */ @@ -228,7 +244,7 @@ new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con) res = new_ir_node (irg, block, op_Const, mode, 0, NULL); res->attr.con = con; res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); #if 0 res = local_optimize_newby (res); @@ -244,19 +260,26 @@ new_r_Id (ir_graph *irg, ir_node *block, ir_node *val, ir_mode *mode) ir_node *res; res = new_ir_node (irg, block, op_Id, mode, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } ir_node * -new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj) +new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, + long proj) { ir_node *in[1] = {arg}; ir_node *res; res = new_ir_node (irg, block, op_Proj, mode, 1, in); res->attr.proj = proj; + + assert(res); + assert(get_Proj_pred(res)); + assert(get_nodes_Block(get_Proj_pred(res))); + res = optimize (res); - ir_vrfy (res); + + irn_vrfy (res); return res; } @@ -268,7 +291,7 @@ new_r_Conv (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode) ir_node *res; res = new_ir_node (irg, block, op_Conv, mode, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -280,7 +303,7 @@ new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in) res = new_ir_node (irg, block, op_Tuple, mode_T, arity, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -292,7 +315,7 @@ new_r_Add (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Add, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -304,7 +327,7 @@ new_r_Sub (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Sub, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -316,7 +339,7 @@ new_r_Minus (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Minus, mode, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -328,7 +351,7 @@ new_r_Mul (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Mul, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -338,9 +361,9 @@ new_r_Quot (ir_graph *irg, ir_node *block, { ir_node *in[3] = {memop, op1, op2}; ir_node *res; - res = new_ir_node (irg, block, op_Quot, mode_T, 2, in); + res = new_ir_node (irg, block, op_Quot, mode_T, 3, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -350,9 +373,9 @@ new_r_DivMod (ir_graph *irg, ir_node *block, { ir_node *in[3] = {memop, op1, op2}; ir_node *res; - res = new_ir_node (irg, block, op_DivMod, mode_T, 2, in); + res = new_ir_node (irg, block, op_DivMod, mode_T, 3, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -362,9 +385,9 @@ new_r_Div (ir_graph *irg, ir_node *block, { ir_node *in[3] = {memop, op1, op2}; ir_node *res; - res = new_ir_node (irg, block, op_Div, mode_T, 2, in); + res = new_ir_node (irg, block, op_Div, mode_T, 3, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -374,9 +397,9 @@ new_r_Mod (ir_graph *irg, ir_node *block, { ir_node *in[3] = {memop, op1, op2}; ir_node *res; - res = new_ir_node (irg, block, op_Mod, mode_T, 2, in); + res = new_ir_node (irg, block, op_Mod, mode_T, 3, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -388,7 +411,7 @@ new_r_And (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_And, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -400,7 +423,7 @@ new_r_Or (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Or, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -412,7 +435,7 @@ new_r_Eor (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Eor, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -424,7 +447,7 @@ new_r_Not (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Not, mode, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -436,7 +459,7 @@ new_r_Shl (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Shl, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -448,7 +471,7 @@ new_r_Shr (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Shr, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -460,7 +483,7 @@ new_r_Shrs (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Shrs, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -472,7 +495,7 @@ new_r_Rot (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Rot, mode, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -484,7 +507,7 @@ new_r_Abs (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Abs, mode, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -496,7 +519,7 @@ new_r_Cmp (ir_graph *irg, ir_node *block, ir_node *res; res = new_ir_node (irg, block, op_Cmp, mode_T, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -507,7 +530,7 @@ new_r_Jmp (ir_graph *irg, ir_node *block) ir_node *res; res = new_ir_node (irg, block, op_Jmp, mode_X, 0, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -518,7 +541,7 @@ new_r_Cond (ir_graph *irg, ir_node *block, ir_node *c) ir_node *res; res = new_ir_node (irg, block, op_Cond, mode_T, 1, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -540,7 +563,7 @@ new_r_Call (ir_graph *irg, ir_node *block, ir_node *store, set_Call_type(res, type); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -553,18 +576,12 @@ new_r_Return (ir_graph *irg, ir_node *block, int r_arity; r_arity = arity+1; - NEW_ARR_A (ir_node *, r_in, r_arity); - r_in[0] = store; - memcpy (&r_in[1], in, sizeof (ir_node *) * arity); - res = new_ir_node (irg, block, op_Return, mode_X, r_arity, r_in); - res = optimize (res); - - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -576,7 +593,7 @@ new_r_Raise (ir_graph *irg, ir_node *block, ir_node *store, ir_node *obj) res = new_ir_node (irg, block, op_Raise, mode_X, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -589,7 +606,7 @@ new_r_Load (ir_graph *irg, ir_node *block, res = new_ir_node (irg, block, op_Load, mode_T, 2, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -602,7 +619,7 @@ new_r_Store (ir_graph *irg, ir_node *block, res = new_ir_node (irg, block, op_Store, mode_T, 3, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -618,7 +635,7 @@ new_r_Alloc (ir_graph *irg, ir_node *block, ir_node *store, res->attr.a.type = alloc_type; res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -633,7 +650,7 @@ new_r_Free (ir_graph *irg, ir_node *block, ir_node *store, res->attr.f = free_type; res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -656,7 +673,7 @@ new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr, res->attr.s.ent = ent; res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -678,7 +695,7 @@ new_r_SymConst (ir_graph *irg, ir_node *block, type_or_id *value, res->attr.i.tori.typ = (type *)value; } res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } @@ -690,13 +707,12 @@ new_r_Sync (ir_graph *irg, ir_node *block, int arity, ir_node **in) res = new_ir_node (irg, block, op_Sync, mode_M, arity, in); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } - ir_node * -new_r_Bad (ir_node *block) +new_r_Bad () { return current_ir_graph->bad; } @@ -714,11 +730,10 @@ new_Start (void) op_Start, mode_T, 0, NULL); res = optimize (res); - ir_vrfy (res); + irn_vrfy (res); return res; } - ir_node * new_End (void) { @@ -728,9 +743,9 @@ new_End (void) op_End, mode_X, -1, NULL); res = optimize (res); - ir_vrfy (res); - return res; + irn_vrfy (res); + return res; } ir_node * @@ -741,10 +756,11 @@ new_Block (void) res = new_ir_node (current_ir_graph, NULL, op_Block, mode_R, -1, NULL); current_ir_graph->current_block = res; res->attr.block.matured = 0; - set_Block_block_visit(res, 0); + set_Block_block_visited(res, 0); - // res = optimize (res); /* GL: only optimize if mature!!!! */ - ir_vrfy (res); + /* forget this optimization. use this only if mature !!!! + res = optimize (res); */ + irn_vrfy (res); /** create a new dynamic array, which stores all parameters in irnodes */ /** using the same obstack as the whole irgraph */ @@ -757,6 +773,192 @@ new_Block (void) return res; } +inline ir_node * +get_r_value_internal (ir_node *block, int pos, ir_mode *mode); + +/** This function computes the predecessors for a real Phi node, and then + allocates and returns this node. The routine called to allocate the + node might optimize it away and return a real value, or even a pointer + to a deallocated Phi node on top of the obstack! + This function is called with an in-array of proper size. **/ +static inline ir_node * +phi_merge (ir_node *block, int pos, ir_mode *mode, ir_node **nin, int ins) +{ + ir_node *prevBlock, *res; + int i; + + /* This loop goes to all predecessor blocks of the block the Phi node is in + and there finds the operands of the Phi node by calling + get_r_value_internal. */ + for (i = 1; i <= ins; ++i) { + assert (block->in[i]); + prevBlock = block->in[i]->in[0]; /* go past control flow op to prev block */ + assert (prevBlock); + nin[i-1] = get_r_value_internal (prevBlock, pos, mode); + } + + /* After collecting all predecessors into the array nin a new Phi node + with these predecessors is created. This constructor contains an + optimization: If all predecessors of the Phi node are identical it + returns the only operand instead of a new Phi node. If the value + passes two different control flow edges without being defined, and + this is the second path treated, a pointer to the node that will be + allocated for the first path (recurstion) is returned. We already + know the address of this node, as it is the next node to be allocated + and will be placed on top of the obstack. (The obstack is a _stack_!) */ + res = new_r_Phi_in (current_ir_graph, block, mode, nin, ins); + + /* Now we now the value "pos" and can enter it in the array with + all known local variables. Attention: this might be a pointer to + a node, that later will be allocated!!! See new_r_Phi_in. + If this is called in mature, after some set_value in the same block, + the proper value must not be overwritten: + The call order + get_value (makes Phi0, put's it into graph_arr) + set_value (overwrites Phi0 in graph_arr) + mature_block (upgrades Phi0, puts it again into graph_arr, overwriting + the proper value.) + fails. */ + if (!block->attr.block.graph_arr[pos]) { + block->attr.block.graph_arr[pos] = res; + } else { + // printf(" value already computed by %s\n", + // id_to_str(block->attr.block.graph_arr[pos]->op->name)); + } + + return res; +} + +/* This function returns the last definition of a variable. In case + this variable was last defined in a previous block, Phi nodes are + inserted. If the part of the firm graph containing the definition + is not yet constructed, a dummy Phi node is returned. */ +inline ir_node * +get_r_value_internal (ir_node *block, int pos, ir_mode *mode) +{ + ir_node *res; + /* There are 4 cases to treat. + + 1. The block is not mature and we visit it the first time. We can not + create a proper Phi node, therefore a Phi0, i.e., a Phi without + predecessors is returned. This node is added to the linked list (field + "link") of the containing block to be completed when this block is + matured. (Comlpletion will add a new Phi and turn the Phi0 into a Id + node.) + + 2. The value is already known in this block, graph_arr[pos] is set and we + visit the block the first time. We can return the value without + creating any new nodes. + + 3. The block is mature and we visit it the first time. A Phi node needs + to be created (phi_merge). If the Phi is not needed, as all it's + operands are the same value reaching the block through different + paths, it's optimizes away and the value itself is returned. + + 4. The block is mature, and we visit it the second time. Now two + subcases are possible: + * The value was computed completely the last time we were here. + This is the case if there is no loop. We can return the proper value. + * The recursion that visited this node and set the flag did not + return yet. We are computing a value in a loop and need to + break the recursion without knowing the result yet. + There is no simple check for the second subcase. Therefore we check + for a second visit and treat all such cases as the second subcase. + Anyways, the basic situation is the same: we reached a block + on two paths without finding a definition of the value: No Phi + nodes are needed on both paths. + We return this information "Two paths, no Phi needed" by a very tricky + implementation that relies on the fact that an obstack is a stack and + will return a node with the same address on different allocations. + Look also at phi_merge and get_r_phi_in to understand this. + */ + + /* case 4 -- already visited. */ + if (get_irn_visited(block) == get_irg_visited(current_ir_graph)) return NULL; + + /* visited the first time */ + set_irn_visited(block, get_irg_visited(current_ir_graph)); + + /* Get the local valid value */ + res = block->attr.block.graph_arr[pos]; + + /* case 2 -- If the value is actually computed, return it. */ + if (res) { return res;}; + + if (block->attr.block.matured) { /* case 3 */ + + /* The Phi has the same amount of ins as the corresponding block. */ + int ins = get_irn_arity(block); + ir_node **nin; + NEW_ARR_A (ir_node *, nin, ins); + + /* Phi merge collects the predecessors and then creates a node. */ + res = phi_merge (block, pos, mode, nin, ins); + + } else { /* case 1 */ + /* The block is not mature, we don't know how many in's are needed. A Phi + with zero predecessors is created. Such a Phi node is called Phi0 + node. (There is also an obsolete Phi0 opcode.) The Phi0 is then added + to the list of Phi0 nodes in this block to be matured by mature_block + later. + The Phi0 has to remember the pos of it's internal value. If the real + Phi is computed, pos is used to update the array with the local + values. */ + + res = new_r_Phi0 (current_ir_graph, block, mode); + res->attr.phi0_pos = pos; + res->link = block->link; + block->link = res; + } + + /* If we get here, the frontend missed a use-before-definition error */ + if (!res) { + /* Error Message */ + printf("Error: no value set\n"); + assert (mode->code >= irm_f && mode->code <= irm_p); + res = new_r_Const (current_ir_graph, block, mode, + tarval_mode_null[mode->code]); + } + + /* The local valid value is available now. */ + block->attr.block.graph_arr[pos] = res; + + return res; +} + +/** Finalize a Block node, when all control flows are known. */ +/** Acceptable parameters are only Block nodes. */ +void +mature_block (ir_node *block) +{ + + int ins; + ir_node *n, **nin; + ir_node *next; + + assert (get_irn_opcode(block) == iro_Block); + + if (!get_Block_matured(block)) { + + /* turn the dynamic in-array into a static one. */ + ins = ARR_LEN (block->in)-1; + NEW_ARR_A (ir_node *, nin, ins); + + /* Traverse a chain of Phi nodes attached to this block and mature + these, too. **/ + for (n = block->link; n; n=next) { + inc_irg_visited(current_ir_graph); + next = n->link; + exchange (n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins)); + } + + block->attr.block.matured = 1; + + block = optimize_in_place(block); + irn_vrfy(block); + } + +} ir_node * new_Phi (int arity, ir_node **in, ir_mode *mode) @@ -947,8 +1149,6 @@ new_Call (ir_node *store, ir_node *callee, int arity, ir_node **in, store, callee, arity, in, type); } -/* make M parameter in call explicit: -new_Return (ir_node* store, int arity, ir_node **in) */ ir_node * new_Return (ir_node* store, int arity, ir_node **in) { @@ -1029,30 +1229,65 @@ new_Bad (void) return current_ir_graph->bad; } -#if 0 -/************************/ -/* ir block constructor */ +/*************************************************************************/ +/* Comfortable interface with automatic Phi node construction. */ +/* (Uses also constructors of ?? interface, except new_Block. */ +/* add an adge to a jmp node */ +void +add_in_edge (ir_node *block, ir_node *jmp) +{ + if (block->attr.block.matured) { + printf("Error: Block already matured!\n"); + } + else { + assert (jmp != NULL); + ARR_APP1 (ir_node *, block->in, jmp); + } +} + +/* changing the current block */ +void +switch_block (ir_node *target) +{ + current_ir_graph->current_block = target; +} -/* GL: what's this good for? */ +/****************************/ +/* parameter administration */ -typedef struct ir_block { - char closed; - char matured; - /* -1 = error, 0 = OK */ -} ir_block; +/* get a value from the parameter array from the current block by its index */ +ir_node * +get_value (int pos, ir_mode *mode) +{ + inc_irg_visited(current_ir_graph); + return get_r_value_internal (current_ir_graph->current_block, pos + 1, mode); +} -ir_block * -new_ir_Block(void) +/* set a value at position pos in the parameter array from the current block */ +inline void +set_value (int pos, ir_node *value) { - ir_block *res; + current_ir_graph->current_block->attr.block.graph_arr[pos + 1] = value; +} - res->closed = -1; - res->matured = -1; +/* get the current store */ +inline ir_node * +get_store (void) +{ + /* GL: one could call get_value instead */ + inc_irg_visited(current_ir_graph); + return get_r_value_internal (current_ir_graph->current_block, 0, mode_M); +} - return res; +/* set the current store */ +inline void +set_store (ir_node *store) +{ + /* GL: one could call set_value instead */ + current_ir_graph->current_block->attr.block.graph_arr[0] = store; } -#endif +/*************************************************************************/ /* initialize */ /* call once for each run of the library */