X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Fircons.h;h=b00434f901b96a857e7a0c4d48e0e089e5cd4419;hb=5f8ddee6b08c8040c0a304a347d65045c1141d52;hp=6088d7dde5588bf35a51954874c649070955fb63;hpb=b2e11274ee969200b5e3e5135d05c4845de3a39f;p=libfirm diff --git a/ir/ir/ircons.h b/ir/ir/ircons.h index 6088d7dde..b00434f90 100644 --- a/ir/ir/ircons.h +++ b/ir/ir/ircons.h @@ -9,7 +9,7 @@ /** !!! -*** Ideas for improvement: +*** Ideas for imrovement: *** Handle construction of exceptions more comfortable: Add new constructors that pass the exception region (or better the @@ -21,7 +21,6 @@ it is always unambiguous. **/ - /** *** IRCONS @@ -62,23 +61,23 @@ The following nodes are Projs from the start node, held in ir_graph for simple access: - *frame The ir_node producing the pointer to the stack frame of the - procedure as output. This is the Proj node on the third - output of the start node. This output of the start node - is tagged as pns_frame_base. In FIRM most lokal + *frame The ir_node producing the pointer to the stack frame of + the procedure as output. This is the Proj node on the + third output of the start node. This output of the start + node is tagged as pns_frame_base. In FIRM most lokal variables are modeled as data flow edges. Static allocated arrays can not be represented as dataflow edges. Therefore FIRM has to represent them in the stack frame. - *globals This models a pointer to a space in the memory where _all_ - global things are held. Select from this pointer with a Sel - node the pointer to a global variable / procedure / compiler - known function... . + *globals This models a pointer to a space in the memory where + _all_ global things are held. Select from this pointer + with a Sel node the pointer to a global variable / + procedure / compiler known function... . - *args The ir_node that produces the arguments of the method as it's - result. This is a Proj node on the fourth output of the start - node. This output is tagged as pns_args. + *args The ir_node that produces the arguments of the method as + it's result. This is a Proj node on the fourth output of + the start node. This output is tagged as pns_args. *bad The bad node is an auxiliary node. It is needed only once, so there is this globally reachable node. @@ -87,25 +86,29 @@ *obst An obstack that contains all nodes. - *current_block A pointer to the current block. Any node created with one - of the node constructors (new_) are assigned to this - block. It can be set with switch_block(block). Only needed - for ir construction. + *current_block A pointer to the current block. Any node created with + one of the node constructors (new_) are assigned + to this block. It can be set with switch_block(block). + Only needed for ir construction. - params/n_loc An int giving the number of local variables in this procedure. - This is neede for ir construction. Name will be changed. + params/n_loc An int giving the number of local variables in this + procedure. This is neede for ir construction. Name will + be changed. - *value_table This pset is used for global value numbering for optimizing - use in iropt.c. + *value_table This hash table (pset) is used for global value numbering + for optimizing use in iropt.c. *Phi_in_stack; a stack needed for automatic Phi construction, needed only during ir construction. + visited A int used as flag to traverse the ir_graph. + + block_visited A int used as a flag to traverse block nodes in the graph. Three kinds of nodes -------------------- - There are three kinds of nodes known to the ir: enties, + There are three kinds of nodes known to the ir: entities, types, and ir_nodes + ir_nodes are the actual nodes of the FIRM intermediate representation. @@ -113,11 +116,13 @@ operations. + entity ==> implemented in entity.h - Refers to a single entity of the compiled program, e.g. a field of a class or - a method. + Refers to a single entity of the compiled program, e.g. a field of a + class or a method. If a method or variable can not be assigned to + a method or class or the like, it is a global object. + types ==> implemented in type.h - With types type information is represented. There are several type nodes. + With types type information is represented. There are several type + nodes. Implementation of the FIRM operations: ir_node ---------------------------------------------- @@ -158,10 +163,10 @@ and the number of attributes of an ir_node. There is one statically allocated struct ir_op for each opcode. - *mode The ir_mode of the operation represented by this firm node. - The mode of the operation is the mode of it's result. A Firm - mode is a datatype as known to the target, not a type of the - source language. + *mode The ir_mode of the operation represented by this firm + node. The mode of the operation is the mode of it's + result. A Firm mode is a datatype as known to the target, + not a type of the source language. visit A flag for traversing the ir. @@ -175,8 +180,8 @@ annotate a node with a better, optimized version of it. attr An attr struct containing the attributes of the nodes. The - attributes depend on the opcode of the node. The number of - these attributes is given in op. + attributes depend on the opcode of the node. The number + of these attributes is given in op. The struct ir_op ---------------- @@ -189,18 +194,18 @@ GLOBAL VARIABLES ================ - current_ir_graph Points to the current ir_graph. All constructors for nodes - add nodes to this graph. + current_ir_graph Points to the current ir_graph. All constructors for + nodes add nodes to this graph. - ir_visited A int used as flag to traverse the ir_graph. + ir_visited An int used as flag to traverse the ir_graph. - block_visited A int used as a flag to traverse block nodes in the graph. + block_visited An int used as a flag to traverse block nodes in the + graph. Others not yet documented. - CONSTRUCTOR FOR IR_GRAPH ======================== @@ -222,7 +227,7 @@ procedure: * The start block containing a start node and Proj nodes for it's - four results (X, M, P, T). + five results (X, M, P, P, T). * The end block containing an end node. This block is not matured after executing new_ir_graph as predecessors need to be added to it. (Maturing a block means fixing it's number of predecessors.) @@ -235,6 +240,156 @@ There is no path from end to start in the graph after calling ir_graph. + PROCEDURE TO CONSTRUCT AN IR GRAPH + ================================== + + This library supplies several interfaces to construct a FIRM graph for + a program: + * A "comfortable" interface generating SSA automatically. Automatically + computed predecessors of nodes need not be specified in the constructors. + (new_ constructurs and a set of additional routines.) + * A less comfortable interface where all predecessors except the block + an operation belongs to need to be specified. SSA must be constructed + by hand. (new_ constructors and switch_block()). This interface + is called "block oriented". It automatically calles the local optimizations + for each new node. + * An even less comfortable interface where the block needs to be specified + explicitly. This is called the "raw" interface. (new_r_ + constructors). These nodes are not optimized. + + To use the functionality of the comfortable interface correctly the Front + End needs to follow certain protocols. This is explained in the following. + To build a correct IR with the other interfaces study the semantics of + the firm node (See tech-reprot UKA 1999-44). For the construction of + types and entities see the documentation in those modules. + + First the Frontend needs to decide which variables and values used in + a procedure can be represented by dataflow edges. These are variables + that need not be saved to memory as they cause no side effects visible + out of the procedure. In general these are all compiler generated + variables and simple local variables of the procedure as integers, + reals and pointers. The frontend has to count and number these variables. + + First an ir_graph needs to be constructed with new_ir_graph. The + constructor gets the number of local variables. The graph is hold in the + global variable irg. + + Now the construction of the procedure can start. Several basic blocks can + be constructed in parallel, but the code within each block needs to + be constructed (almost) in program order. + + A global variable holds the current basic block. All (non block) nodes + generated are added to this block. The current block can be set with + switch_block(block). If several blocks are constructed in parallel block + switches need to be performed constantly. + + To generate a Block node (with the comfortable interface) it's predecessor + control flow nodes need not be known. In case of cyclic control flow these + can not be known when the block is constructed. With add_in_edge(block, + cfnode) predecessors can be added to the block. If all predecessors are + added to the block mature_block(b) needs to be called. Calling mature_block + early improves the efficiency of the Phi node construction algorithm. + But if several blocks are constructed at once, mature_block must only + be called after performing all set_values and set_stores in the block! + (See documentation of new_immBlock constructor.) + + The constructors of arithmetic nodes require that their predecessors + are mentioned. Sometimes these are available in the Frontend as the + predecessors have just been generated by the frontend. If they are local + values the predecessors can be obtained from the library with a call to + get_value(local_val_nr). (local_val_nr needs to be administered by + the Frontend.) A call to get_value triggers the generation of Phi nodes. + If an arithmetic operation produces a local value this value needs to be + passed to the library by set_value(node, local_val_nr). + In straight line code these two operations just remember and return the + pointer to nodes producing the value. If the value passes block boundaries + Phi nodes can be inserted. + Similar routines exist to manage the Memory operands: set_store and + get_store. + + Several nodes produce more than one result. An example is the Div node. + Such nodes return tuples of values. From these individual values can be + extracted by proj nodes. + + The following example illustrates the construction of a simple basic block + with two predecessors stored in variables cf_pred1 and cf_pred2, containing + the code + a = a div a; + and finally jumping to an other block. The variable a got the local_val_nr + 42 by the frontend. + + ir_node *this_block, *cf_pred1, *cf_pred2, *a_val, *mem, *div, *res, *cf_op; + + this_block = new_immBlock(); + add_in_edge(this_block, cf_pred1); + add_in_edge(this_block, cf_pred2); + mature_block(this_block); + a_val = get_value(17, mode_I); + mem = get_store(); + div = new_Div(mem, a_val, a_val); + mem = new_Proj(div, mode_M, 0); * for the numbers for Proj see docu * + res = new_Proj(div, mode_I, 2); + set_store(mem); + set_value(res, 17); + cf_op = new_Jmp(); + + For further information look at the documentation of the nodes and + constructors and at the paragraph COPING WITH DATA OBJECTS at the + end of this documentation. + + The comfortable interface contains the following routines further explained + below: + + ir_node *new_immBlock (void); + ir_node *new_Start (void); + ir_node *new_End (void); + ir_node *new_Jmp (void); + ir_node *new_Cond (ir_node *c); + ir_node *new_Return (ir_node *store, int arity, ir_node **in); + ir_node *new_Raise (ir_node *store, ir_node *obj); + ir_node *new_Const (ir_mode *mode, tarval *con); + ir_node *new_SymConst (type_or_id *value, symconst_kind kind); + ir_node *new_simpleSel (ir_node *store, ir_node *objptr, entity *ent); + ir_node *new_Sel (ir_node *store, ir_node *objptr, int arity, + ir_node **in, entity *ent); + ir_node *new_Call (ir_node *store, ir_node *callee, int arity, + ir_node **in, type_method *type); + ir_node *new_Add (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Sub (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Minus (ir_node *op, ir_mode *mode); + ir_node *new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Quot (ir_node *memop, ir_node *op1, ir_node *op2); + ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2); + ir_node *new_Div (ir_node *memop, ir_node *op1, ir_node *op2); + ir_node *new_Mod (ir_node *memop, ir_node *op1, ir_node *op2); + ir_node *new_Abs (ir_node *op, ir_mode *mode); + ir_node *new_And (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Or (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Eor (ir_node *op1, ir_node *op2, ir_mode *mode); + ir_node *new_Not (ir_node *op, ir_mode *mode); + ir_node *new_Shl (ir_node *op, ir_node *k, ir_mode *mode); + ir_node *new_Shr (ir_node *op, ir_node *k, ir_mode *mode); + ir_node *new_Shrs (ir_node *op, ir_node *k, ir_mode *mode); + ir_node *new_Rot (ir_node *op, ir_node *k, ir_mode *mode); + ir_node *new_Cmp (ir_node *op1, ir_node *op2); + ir_node *new_Conv (ir_node *op, ir_mode *mode); + ir_node *new_Load (ir_node *store, ir_node *addr); + ir_node *new_Store (ir_node *store, ir_node *addr, ir_node *val); + ir_node *new_Alloc (ir_node *store, ir_node *size, type *alloc_type, + where_alloc where); + ir_node *new_Free (ir_node *store, ir_node *ptr, ir_node *size, + type *free_type); + ir_node *new_Proj (ir_node *arg, ir_mode *mode, long proj); + + void add_in_edge (ir_node *block, ir_node *jmp); + void mature_block (ir_node *block); + void switch_block (ir_node *target); + ir_node *get_value (int pos, ir_mode *mode); + void set_value (int pos, ir_node *value); + ir_node *get_store (void); + void set_store (ir_node *store); + + IR_NODES AND CONSTRUCTORS FOR IR_NODES ======================================= @@ -249,19 +404,18 @@ Watch for my inconsistent use of input and predecessor (dataflow view) and `the node points to' (implementation view). - The following description of the nodes lists four properties them if these are - of interest: + The following description of the nodes lists four properties them if these + are of interest: - the parameters to the constructor - the inputs of the Firm node - the outputs of the Firm node - attributes to the node - BASIC BLOCKS ------------ - ir_node *new_Block (void) - -------------------------- + ir_node *new_immBlock (void) + ---------------------------- Creates a new block. Sets current_block to itself. When a new block is created it cannot be known how many predecessors this block will have in the @@ -278,7 +432,10 @@ of this block are called after maturing it and before calling get_value in some block that is control flow dependent on this block, the construction is correct. - Example for faulty ir construction: + + Example for faulty ir construction: (draw the graph on a paper and you'll + get it ;-) + block_before_loop = new_block(); set_value(x); mature_block(block_before_loop); @@ -299,7 +456,8 @@ get_value(loop_body, x); // gets the Phi in loop_header set_value(loop_header, x); // sets the value the above get_value should - // have returned!!! + // have returned!!! + Mature_block also fixes the number of inputs to the Phi nodes. Mature_block should be called as early as possible, as afterwards the generation of Phi nodes is more efficient. @@ -310,17 +468,24 @@ Possible predecessors: Start, Jmp, Cond, Raise or Return or any node possibly causing an exception. (Often the real predecessors are Projs.) Output: - Mode R, all nodes belonging to this block should consume this output. + Mode BB (R), all nodes belonging to this block should consume this output. As they are strict (except Block and Phi node) it is a necessary condition - that the block node executed before any other node in this block - executes. + that the block node executed before any other node in this block executes. Attributes: block.matured Indicates whether the block is mature. - block.closed ??? block.**graph_arr This attribute contains all local values valid in this block. This is needed to build the Phi nodes and removed - if the graph is complete. + if the graph is complete. This field is used by the + internal construction algorithm and should not be accessed + from outside. + + + ir_node *new_Block (int arity, ir_node **in) + -------------------------------------------- + + Creates a new Block with the given list of predecessors. This block + is mature. CONTROL FLOW OPERATIONS @@ -333,8 +498,8 @@ ir_node *new_Start (void) ------------------------- - Creates a start node. Not actually needed public. Created - by new_ir_graph. + Creates a start node. Not actually needed public. There is only one such + node in each procedure which is automatically created by new_ir_graph. Inputs: No inputs except the block it belogns to. @@ -345,20 +510,21 @@ mode X, points to the first block to be executed. * pns_global_store mode M, the global store - * pns_frame_base mode P, a pointer to the base of the procedures stack frame. - * pns_globals mode P, a pointer to the part of the memory containing _all_ - global things. + * pns_frame_base mode P, a pointer to the base of the procedures + stack frame. + * pns_globals mode P, a pointer to the part of the memory containing + _all_ global things. * pns_args mode T, a tuple containing all arguments of the procedure. ir_node *new_End (void) ----------------------- - Creates an end node. Not actually needed public. Created by - new_ir_graph. + Creates an end node. Not actually needed public. There is only one such + node in each procedure which is automatically created by new_ir_graph. Inputs: - No inputs except the block it belogns to. + No inputs except the block it belongs to. Output: No output. @@ -445,15 +611,17 @@ ir_node *new_SymConst (type *type, symconst_kind kind) ------------------------------------------------------------ - There are two kinds of symbolic constants: + There are three kinds of symbolic constants: type_tag The symbolic constant represents a type tag. size The symbolic constant represents the size of a class. - link_info Information for the linker. + link_info Information for the linker, e.g. the name of a global + variable. Parameters - kind The kind of the symbolic constant: type_tag or size. - *type Points to the type the tag stands for or to the type - whose size is represented by the constant. + kind The kind of the symbolic constant: type_tag, size or link_info. + *type_or_id Points to the type the tag stands for or to the type + whose size is represented by the constant or to an ident + representing the linkage info. Inputs: No inputs except the block it belogns to. @@ -465,10 +633,11 @@ - type_tag - size - linkage_ptr_info - If the attr.i.num is type_tag of size, the node contains an attribute - attr.i.*type A pointer to a type_class. + If the attr.i.num is type_tag or size, the node contains an attribute + attr.i.*type, a pointer to a type_class. The mode of the node is mode_i. if it is linkage_ptr_info it contains - attr.i.*ptrinfo A ident holding information for the linker. + attr.i.*ptrinfo, an ident holding information for the linker. The mode + of the node is mode_p. THE SELECT NODE --------------- @@ -481,8 +650,8 @@ a method. Parameters: - *store The memory in which the object the entity should be selected from - is allocated. + *store The memory in which the object the entity should be selected + from is allocated. *frame The pointer to the object. *sel The entity to select. @@ -537,11 +706,11 @@ Creates a procedure call. Parameters - *store The actual store. Why not also the stack frame? + *store The actual store. *callee A pointer to the called procedure. arity The number of procedure parameters. **in An array with the pointers to the parameters. - This array is copied in the constructor. + The constructor copies this array. *type Type information of the procedure called. Inputs: @@ -725,7 +894,6 @@ Parameters: *store The current memory. *addr A pointer to the variable to be read in this memory. - *mode The mode of the loaded value. Inputs: The memory and a pointer to a variable in this memory. @@ -914,41 +1082,21 @@ # ifndef _IRCONS_H_ # define _IRCONS_H_ -# include "irgmod.h" +# include "common.h" +# include "irgraph.h" +# include "irnode.h" # include "irmode.h" # include "entity.h" # include "tv.h" -# include "common.h" -# include "irop.h" -# include "irgraph.h" # include "type.h" -# include "pdeq.h" -# include "irvrfy.h" - -/* irnode constructor */ -/* Create a new irnode in irg, with an op, mode, arity and */ -/* some incoming irnodes. */ -/* If arity is negative, a node with a dynamic array is created. */ -/* inline ir_node *new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, - ir_mode *mode, int arity, ir_node **in); -*/ -/** These headers need not to be here. They are never used by the - public. - That's not completely true. They need not be seen by a frontend, - but they might be useful for optimizations changing the IR. **/ - -#if USE_EXPICIT_PHI_IN_STACK -/* A stack needed for the automatic Phi node construction in constructor - Phi_in. */ -typedef struct Phi_in_stack { - ir_node **stack; - int pos; -} Phi_in_stack; -#endif - -/* privat interfaces */ -/* more detailed construction */ +/***************************************************************************/ +/* The raw interface */ +/***************************************************************************/ + +/* Constructs a Block with a fixed number of predecessors. + Does not set current_block. Can not be used with automatic + Phi node construction. */ ir_node *new_r_Block (ir_graph *irg, int arity, ir_node **in); ir_node *new_r_Start (ir_graph *irg, ir_node *block); ir_node *new_r_End (ir_graph *irg, ir_node *block); @@ -961,12 +1109,13 @@ ir_node *new_r_Raise (ir_graph *irg, ir_node *block, ir_node *new_r_Const (ir_graph *irg, ir_node *block, ir_mode *mode, tarval *con); ir_node *new_r_SymConst (ir_graph *irg, ir_node *block, - type_or_id *value, symconst_kind symkind); + type_or_id_p value, symconst_kind symkind); ir_node *new_r_Sel (ir_graph *irg, ir_node *block, ir_node *store, ir_node *objptr, int n_index, ir_node **index, entity *ent); ir_node *new_r_Call (ir_graph *irg, ir_node *block, ir_node *store, - ir_node *callee, int arity, ir_node **in, type_method *type); + ir_node *callee, int arity, ir_node **in, + type_method *type); ir_node *new_r_Add (ir_graph *irg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode); ir_node *new_r_Sub (ir_graph *irg, ir_node *block, @@ -975,14 +1124,14 @@ ir_node *new_r_Minus (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode); ir_node *new_r_Mul (ir_graph *irg, ir_node *block, ir_node *op1, ir_node *op2, ir_mode *mode); -ir_node *new_r_Quot (ir_graph *irg, ir_node *block, ir_node *memop, - ir_node *op1, ir_node *op2); +ir_node *new_r_Quot (ir_graph *irg, ir_node *block, + ir_node *memop, ir_node *op1, ir_node *op2); ir_node *new_r_DivMod (ir_graph *irg, ir_node *block, ir_node *memop, ir_node *op1, ir_node *op2); -ir_node *new_r_Div (ir_graph *irg, ir_node *block, ir_node *memop, - ir_node *op1, ir_node *op2); -ir_node *new_r_Mod (ir_graph *irg, ir_node *block, ir_node *memop, - ir_node *op1, ir_node *op2); +ir_node *new_r_Div (ir_graph *irg, ir_node *block, + ir_node *memop, ir_node *op1, ir_node *op2); +ir_node *new_r_Mod (ir_graph *irg, ir_node *block, + ir_node *memop, ir_node *op1, ir_node *op2); ir_node *new_r_Abs (ir_graph *irg, ir_node *block, ir_node *op, ir_mode *mode); ir_node *new_r_And (ir_graph *irg, ir_node *block, @@ -1020,16 +1169,23 @@ ir_node *new_r_Proj (ir_graph *irg, ir_node *block, ir_node *arg, ir_mode *mode, long proj); ir_node *new_r_Tuple (ir_graph *irg, ir_node *block, int arity, ir_node **in); -ir_node *new_r_Id (ir_graph *irg, ir_node *block, - ir_node *val, ir_mode *mode); -ir_node *new_r_Bad (ir_node *block); +ir_node *new_r_Id (ir_graph *irg, ir_node *block, + ir_node *val, ir_mode *mode); +ir_node *new_r_Bad (); +/*************************************************************************/ +/* The block oriented interface */ +/*************************************************************************/ -/* public interfaces */ -/* normal constructors */ +/* Sets the current block in which the following constructors place the + nodes they construct. */ +void switch_block (ir_node *target); -ir_node *new_Block (void); +/* Constructs a Block with a fixed number of predecessors. + Does set current_block. Can be used with automatic Phi + node construction. */ +ir_node *new_Block(int arity, ir_node **in); ir_node *new_Start (void); ir_node *new_End (void); ir_node *new_Jmp (void); @@ -1037,7 +1193,7 @@ ir_node *new_Cond (ir_node *c); ir_node *new_Return (ir_node *store, int arity, ir_node **in); ir_node *new_Raise (ir_node *store, ir_node *obj); ir_node *new_Const (ir_mode *mode, tarval *con); -ir_node *new_SymConst (type_or_id *value, symconst_kind kind); +ir_node *new_SymConst (type_or_id_p value, symconst_kind kind); ir_node *new_simpleSel (ir_node *store, ir_node *objptr, entity *ent); ir_node *new_Sel (ir_node *store, ir_node *objptr, int arity, ir_node **in, entity *ent); @@ -1075,12 +1231,45 @@ ir_node *new_Tuple (int arity, ir_node **in); ir_node *new_Id (ir_node *val, ir_mode *mode); ir_node *new_Bad (void); - -#if USE_EXPICIT_PHI_IN_STACK -Phi_in_stack *new_Phi_in_stack(); -#endif - -/* initialize ir construction */ +/***********************************************************************/ +/* The comfortable interface. */ +/* Supports automatic Phi node construction. */ +/* All routines of the block oriented interface except new_Block are */ +/* needed also. */ +/***********************************************************************/ + +/** Block construction **/ +/* immature Block without predecessors */ +ir_node *new_immBlock (void); + +/* Add a control flow edge to an immature block. */ +void add_in_edge (ir_node *immblock, ir_node *jmp); + +/* fixes the number of predecessors of a block. */ +void mature_block (ir_node *block); + +/** Parameter administration **/ +/* Read a value from the array with the local variables. Use this + function to obtain the last definition of the value associated with + pos. Pos may not exceed the value passed as n_loc to new_ir_graph. */ +ir_node *get_value (int pos, ir_mode *mode); + +/* Write a value in the array with the local variables. Use this function + to remember a new definition of the value associated with pos. Pos may + not exceed the value passed as n_loc to new_ir_graph. */ +void set_value (int pos, ir_node *value); + +/* Read a store. + Use this function to get the most recent version of the store (type M). + Internally it does the same as get_value. */ +ir_node *get_store (void); + +/* Write a store. */ +void set_store (ir_node *store); + +/***********************************************************************/ +/* initialize ir construction */ +/***********************************************************************/ void init_cons (void);