/*
 * Copyright (C) 1995-2010 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief   Various irnode constructors. Automatic construction of SSA
 *          representation.
 * @author  Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Boris Boesler,
 *          Michael Beck
 */

/**
 *  @file
 *
 *  documentation no more supported since 2001
 *
 *  IR node construction.
 *
 *    This file documents all datatypes and constructors needed to
 *    build a FIRM representation of a procedure.  The constructors are
 *    also implemented in this file.
 *
 *    The documentation also gives a short manual how to use the library.
 *
 *    For extensive documentation of FIRM see UKA Techreport 1999-14.
 *
 *
 *    Three kinds of nodes
 *    --------------------
 *
 *      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.
 *        They represent operations on the data of the program and control flow
 *        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.  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.
 *
 *    Implementation of the FIRM operations: ir_node
 *    ----------------------------------------------
 *
 *      Ir_nodes represent operations on the data of the program and control flow
 *      operations.  Examples of ir_nodes:  Add, Jmp, Cmp
 *
 *      FIRM is a dataflow graph.  A dataflow graph is a directed graph,
 *      so that every node has incoming and outgoing edges.  A node is
 *      executable if every input at its incoming edges is available.
 *      Execution of the dataflow graph is started at the Start node which
 *      has no incoming edges and ends when the End node executes, even if
 *      there are still executable or not executed nodes.  (Is this true,
 *      or must all executable nodes be executed?)  (There are exceptions
 *      to the dataflow paradigma that all inputs have to be available
 *      before a node can execute: Phi, Block.  See UKA Techreport
 *      1999-14.)
 *
 *      The implementation of FIRM differs from the view as a dataflow
 *      graph.  To allow fast traversion of the graph edges are
 *      implemented as C-pointers.  Inputs to nodes are not ambiguous, the
 *      results can be used by several other nodes.  Each input can be
 *      implemented as a single pointer to a predecessor node, outputs
 *      need to be lists of pointers to successors.  Therefore a node
 *      contains pointers to its predecessors so that the implementation is a
 *      dataflow graph with reversed edges.  It has to be traversed bottom
 *      up.
 *
 *      All nodes of the IR have the same basic structure.  They are
 *      distinguished by a field containing the opcode.
 *
 *      The fields of an ir_node:
 *
 *      kind             A firm_kind tag containing k_ir_node.  This is useful for
 *                       dynamically checking the type of a node.
 *
 *      *op              This ir_op gives the opcode as a tag and a string
 *                       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 its
 *                       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.
 *
 *      **in             An array with pointers to the node's predecessors.
 *
 *      *link            A pointer to an ir_node.  With this pointer all Phi nodes
 *                       are attached to a Block, i.e. a Block points to its
 *                       first Phi node, this node points to the second Phi node
 *                       in the Block and so forth.  Used in mature_immBlock
 *                       to find all Phi nodes to be matured.  It's also used to
 *                       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.
 *
 *    The struct ir_op
 *    ----------------
 *                       Not yet documented. See irop.h.
 *
 *    The struct ir_mode
 *    ------------------
 *                       Not yet documented. See irmode.h.
 *
 *    GLOBAL VARIABLES -- now also fields of ir_graph.
 *    ================
 *
 *    current_ir_graph   Points to the current ir_graph.  All constructors for
 *                       nodes add nodes to this graph.
 *
 *    ir_visited         An int used as flag to traverse the ir_graph.
 *
 *    block_visited      An int used as a flag to traverse block nodes in the
 *                       graph.
 *
 *                       Others not yet documented.
 *
 *
 *
 *    CONSTRUCTOR FOR IR_GRAPH --> see irgraph.h
 *    ========================
 *
 *
 *    PROCEDURE TO CONSTRUCT AN IR GRAPH --> see also Firm tutorial
 *    ==================================
 *
 *    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_<Node> 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_<Node> constructors and set_cur_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_<Node>
 *      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-14).  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.  Often 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 held 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
 *    set_cur_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), its 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_immBlock_pred(block,
 *    cfnode) predecessors can be added to the block.  If all predecessors are
 *    added to the block mature_immBlock(b) needs to be called.  Calling mature_immBlock
 *    early improves the efficiency of the Phi node construction algorithm.
 *    But if several  blocks are constructed at once, mature_immBlock 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_immBlock_pred(this_block, cf_pred1);
 *    add_immBlock_pred(this_block, cf_pred2);
 *    mature_immBlock(this_block);
 *    a_val = get_value(42, mode_Iu);
 *    mem = get_store();
 *    div = new_Div(mem, a_val, a_val, mode_Iu);
 *    mem = new_Proj(div, mode_M, pn_Div_M);   * for the numbers for Proj see docu *
 *    res = new_Proj(div, mode_Iu, pn_Div_res);
 *    set_store(mem);
 *    set_value(res, 42);
 *    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.
 *
 *    IR_NODES AND CONSTRUCTORS FOR IR_NODES
 *    =======================================
 *
 *    All ir_nodes are defined by a common data structure.  They are distinguished
 *    by their opcode and differ in the number of their attributes.
 *
 *    Const nodes are always added to the start block.
 *    All other constructors add the created node to the current_block.
 *    swich_block(block) allows to set the current block to block.
 *
 *    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 parameters to the constructor
 *     - the inputs of the Firm node
 *     - the outputs of the Firm node
 *     - attributes to the node
 *
 *    ------------
 *
 *    COPING WITH DATA OBJECTS
 *    ========================
 *
 *    Two kinds of data objects have to be distinguished for generating
 *    FIRM.  First there are local variables other than arrays that are
 *    known to be alias free.  Second there are all other data objects.
 *    For the first a common SSA representation is built, the second
 *    are modeled by saving them to memory.  The memory is treated as
 *    a single local variable, the alias problem is hidden in the
 *    content of this variable.
 *
 *    All values known in a Block are listed in the block's attribute,
 *    block.**graph_arr which is used to automatically insert Phi nodes.
 *    The following two functions can be used to add a newly computed value
 *    to the array, or to get the producer of a value, i.e., the current
 *    live value.
 *
 *    inline void set_value (int pos, ir_node *value)
 *    -----------------------------------------------
 *
 *    Has to be called for every assignment to a local variable.  It
 *    adds the value to the array of used values at position pos.  Pos
 *    has to be a unique identifier for an entry in the procedure's
 *    definition table.  It can be used to access the value again.
 *    Requires current_block to be set correctly.
 *
 *    ir_node *get_value (int pos, ir_mode *mode)
 *    -------------------------------------------
 *
 *    Returns the node defining the value referred to by pos. If the
 *    value is not defined in this block a Phi node is generated and
 *    all definitions reaching this Phi node are collected.  It can
 *    happen that the algorithm allocates an unnecessary Phi node,
 *    e.g. if there is only one definition of this value, but this
 *    definition reaches the currend block on several different
 *    paths.  This Phi node will be eliminated if optimizations are
 *    turned on right after its creation.
 *    Requires current_block to be set correctly.
 *
 *    There are two special routines for the global store:
 */
#ifndef FIRM_IR_IRCONS_H
#define FIRM_IR_IRCONS_H

#include "firm_types.h"
#include "begin.h"
#include "irnode.h"

/** @addtogroup Const
 * @{
 */

/**
 * Constructor for a Const node.
 *
 * Adds the node to the start block.
 *
 * Constructor for a Const node. The constant represents a target
 * value.  Sets the type information to type_unknown.  (No more
 * supported: If tv is entity derives a somehow useful type.)
 *
 * @param *db    A pointer for debug information.
 * @param *irg   The IR graph the node  belongs to.
 * @param *mode  The mode of the operands and results.
 * @param value  A value from which the tarval is made.
 */
FIRM_API ir_node *new_rd_Const_long(dbg_info *db, ir_graph *irg,
                                    ir_mode *mode, long value);

/** Constructor for a Const node.
 *
 * Adds the node to the start block.
 *
 * Constructor for a Const node. The constant represents a target
 * value.  Sets the type information to type_unknown.  (No more
 * supported: If tv is entity derives a somehow useful type.)
 *
 * @param *irg   The IR graph the node  belongs to.
 * @param *mode  The mode of the operands and the results.
 * @param value  A value from which the tarval is made.
 */
FIRM_API ir_node *new_r_Const_long(ir_graph *irg, ir_mode *mode, long value);

/**
 * @see new_rd_Const_long()
 *
 * @param *db    A pointer for debug information.
 * @param *mode  The mode of the operands and results.
 * @param value  A value from which the tarval is made.
 */
FIRM_API ir_node *new_d_Const_long(dbg_info *db, ir_mode *mode, long value);

/**
 * Make a const from a long.
 * This is just convenience for the usual
 * <code>
 * new_Const(mode, tarval_from_long(mode, ...))
 * </code>
 * pain.
 * @param mode The mode for the const.
 * @param value The value of the constant.
 * @return A new const node.
 */
FIRM_API ir_node *new_Const_long(ir_mode *mode, long value);

/** @} */

/** addtogroup SymConst
 * @{
 */

/** Constructor for a SymConst node.
 *
 *  This is the constructor for a symbolic constant.
 *    There are several kinds of symbolic constants:
 *    - symconst_type_size  The symbolic constant represents the size of a type.
 *                          The type of which the constant represents the size
 *                          is given explicitly.
 *    - symconst_type_align The symbolic constant represents the alignment of a
 *                          type.  The type of which the constant represents the
 *                          size is given explicitly.
 *    - symconst_addr_ent   The symbolic constant represents the address of an
 *                          entity (variable or method).  The variable is given
 *                          explicitly by a firm entity.
 *    - symconst_ofs_ent    The symbolic constant represents the offset of an
 *                          entity in its owner type.
 *    - symconst_enum_const The symbolic constant is a enumeration constant of
 *                          an enumeration type.
 *
 *    Inputs to the node:
 *      No inputs except the block it belongs to.
 *    Outputs of the node.
 *      An unsigned integer (I_u) or a pointer (P).
 *
 *    Mention union in declaration so that the firmjni generator recognizes that
 *    it can not cast the argument to an int.
 *
 * @param *db     A pointer for debug information.
 * @param *irg    The IR graph the node  belongs to.
 * @param mode    The mode for the SymConst.
 * @param value   A type, ident, entity or enum constant depending on the
 *                SymConst kind.
 * @param kind    The kind of the symbolic constant, see the list above
 */
FIRM_API ir_node *new_rd_SymConst(dbg_info *db, ir_graph *irg, ir_mode *mode,
                                  union symconst_symbol value,
                                  symconst_kind kind);

/** Constructor for a SymConst addr_ent node.
 *
 * Same as new_rd_SymConst, except that the constructor is tailored for
 * symconst_addr_ent.
 * Adds the SymConst to the start block of irg.
 */
FIRM_API ir_node *new_rd_SymConst_addr_ent(dbg_info *db, ir_graph *irg,
                                           ir_mode *mode, ir_entity *symbol);

/** Constructor for a SymConst ofs_ent node.
 *
 * Same as new_rd_SymConst, except that the constructor is tailored for
 * symconst_ofs_ent.
 * Adds the SymConst to the start block of irg.
 */
FIRM_API ir_node *new_rd_SymConst_ofs_ent(dbg_info *db, ir_graph *irg,
                                          ir_mode *mode, ir_entity *symbol);

/** Constructor for a SymConst size node.
 *
 * Same as new_rd_SymConst, except that the constructor is tailored for
 * symconst_type_size.
 * Adds the SymConst to the start block of irg.
 */
FIRM_API ir_node *new_rd_SymConst_size(dbg_info *db, ir_graph *irg,
                                       ir_mode *mode, ir_type *symbol);

/** Constructor for a SymConst size node.
 *
 * Same as new_rd_SymConst, except that the constructor is tailored for
 * symconst_type_align.
 * Adds the SymConst to the start block of irg.
 */
FIRM_API ir_node *new_rd_SymConst_align(dbg_info *db, ir_graph *irg,
                                        ir_mode *mode, ir_type *symbol);

/** Constructor for a SymConst node.
 *
 *  This is the constructor for a symbolic constant.
 *    There are several kinds of symbolic constants:
 *    - symconst_type_size  The symbolic constant represents the size of a type.
 *                          The type of which the constant represents the size
 *                          is given explicitly.
 *    - symconst_type_align The symbolic constant represents the alignment of a
 *                          type.  The type of which the constant represents the
 *                          size is given explicitly.
 *    - symconst_addr_ent   The symbolic constant represents the address of an
 *                          entity (variable or method).  The variable is given
 *                          explicitly by a firm entity.
 *    - symconst_ofs_ent    The symbolic constant represents the offset of an
 *                          entity in its owner type.
 *    - symconst_enum_const The symbolic constant is a enumeration constant of
 *                          an enumeration type.
 *
 *    Inputs to the node:
 *      No inputs except the block it belongs to.
 *    Outputs of the node.
 *      An unsigned integer (I_u) or a pointer (P).
 *
 *    Mention union in declaration so that the firmjni generator recognizes that
 *    it can not cast the argument to an int.
 *
 * @param *irg    The IR graph the node  belongs to.
 * @param mode    The mode for the SymConst.
 * @param value   A type, ident, entity or enum constant depending on the
 *                SymConst kind.
 * @param kind    The kind of the symbolic constant, see the list above
 */
FIRM_API ir_node *new_r_SymConst(ir_graph *irg, ir_mode *mode,
                                 union symconst_symbol value,
                                 symconst_kind kind);

/** Constructor for an SymConst node
 *
 *  This is the constructor for a symbolic constant.
 *    There are several kinds of symbolic constants:
 *    - symconst_type_size  The symbolic constant represents the size of a type.
 *                          The type of which the constant represents the size
 *                          is given explicitly.
 *    - symconst_type_align The symbolic constant represents the alignment of a
 *                          type.  The type of which the constant represents the
 *                          size is given explicitly.
 *    - symconst_addr_ent   The symbolic constant represents the address of an
 *                          entity (variable or method).  The variable is given
 *                          explicitly by a firm entity.
 *    - symconst_ofs_ent    The symbolic constant represents the offset of an
 *                          entity in its owner type.
 *    - symconst_enum_const The symbolic constant is a enumeration constant of
 *                          an enumeration type.
 *
 *    Inputs to the node:
 *      No inputs except the block it belongs to.
 *    Outputs of the node.
 *      An unsigned integer (I_u) or a pointer (P).
 *
 *    Mention union in declaration so that the firmjni generator recognizes that
 *    it can not cast the argument to an int.
 *
 * @param *db     A pointer for debug information.
 * @param mode    The mode for the SymConst.
 * @param value   A type, ident, entity or enum constant depending on the
 *                SymConst kind.
 * @param kind    The kind of the symbolic constant, see the list above
 */
FIRM_API ir_node *new_d_SymConst(dbg_info *db, ir_mode *mode,
                                 union symconst_symbol value,
                                 symconst_kind kind);

/** Constructor for a SymConst node.
 *
 *  This is the constructor for a symbolic constant.
 *    There are several kinds of symbolic constants:
 *    - symconst_type_size  The symbolic constant represents the size of a type.
 *                          The type of which the constant represents the size
 *                          is given explicitly.
 *    - symconst_type_align The symbolic constant represents the alignment of a
 *                          type.  The type of which the constant represents the
 *                          size is given explicitly.
 *    - symconst_addr_ent   The symbolic constant represents the address of an
 *                          entity (variable or method).  The variable is given
 *                          explicitly by a firm entity.
 *    - symconst_ofs_ent    The symbolic constant represents the offset of an
 *                          entity in its owner type.
 *    - symconst_enum_const The symbolic constant is a enumeration constant of
 *                          an enumeration type.
 *
 *    Inputs to the node:
 *      No inputs except the block it belongs to.
 *    Outputs of the node.
 *      An unsigned integer (I_u) or a pointer (P).
 *
 *    Mention union in declaration so that the firmjni generator recognizes that
 *    it can not cast the argument to an int.
 *
 * @param mode    The mode for the SymConst.
 * @param value   A type, ident, entity or enum constant depending on the
 *                SymConst kind.
 * @param kind    The kind of the symbolic constant, see the list above
 */
FIRM_API ir_node *new_SymConst(ir_mode *mode, union symconst_symbol value,
                               symconst_kind kind);

/** @} */

/** @addtogroup Conv
 * @{
 */

/** Constructor for a strictConv node.
 *
 * @param db    A pointer for debug information.
 * @param block The IR block the node belongs to.
 * @param op    The operand.
 * @param mode  The mode of this the operand muss be converted .
 */
FIRM_API ir_node *new_rd_strictConv(dbg_info *db, ir_node *block,
                                    ir_node *op, ir_mode *mode);

/** Constructor for a strictConv node.
 *
 * @param block The IR block the node belongs to.
 * @param op    The operand.
 * @param mode  The mode of this the operand muss be converted .
 */
FIRM_API ir_node *new_r_strictConv(ir_node *block, ir_node *op, ir_mode *mode);

/** Constructor for a strict Conv node.
 *
 * @param db    A pointer for debug information.
 * @param op    The operand.
 * @param mode  The mode of this the operand muss be converted .
 */
FIRM_API ir_node *new_d_strictConv(dbg_info *db, ir_node *op, ir_mode *mode);

/** Constructor for a strict Conv node.
 *
 * @param op    The operand.
 * @param mode  The mode of this the operand muss be converted .
 */
FIRM_API ir_node *new_strictConv(ir_node *op, ir_mode *mode);

/** @} */

/** @addtogroup Sel
 * @{
 */

/** Constructor for a simpleSel node.
 *
 *  This is a shortcut for the new_rd_Sel() constructor.  To be used for
 *  Sel nodes that do not select from an array, i.e., have no index
 *  inputs.  It adds the two parameters 0, NULL.
 *
 * @param   *db        A pointer for debug information.
 * @param   *block     The IR block the node belongs to.
 * @param   *store     The memory in which the object the entity should be
 *                     selected from is allocated.
 * @param   *objptr    The object from that the Sel operation selects a
 *                     single attribute out.
 * @param   *ent       The entity to select.
 */
FIRM_API ir_node *new_rd_simpleSel(dbg_info *db, ir_node *block, ir_node *store,
                                   ir_node *objptr, ir_entity *ent);

/** Constructor for a simpleSel node.
 *
 *  This is a shortcut for the new_d_Sel() constructor.  To be used for
 *  Sel nodes that do not select from an array, i.e., have no index
 *  inputs.  It adds the two parameters 0, NULL.
 *
 * @param *block     The IR block the node belongs to.
 * @param *store     The memory in which the object the entity should be selected
 *                   from is allocated.
 * @param *objptr    The object from that the Sel operation selects a
 *                   single attribute out.
 * @param *ent       The entity to select.
 * @ingroup Sel
 */
FIRM_API ir_node *new_r_simpleSel(ir_node *block, ir_node *store,
                                  ir_node *objptr, ir_entity *ent);

/** Constructor for a simpleSel node.
 *
 *  This is a shortcut for the new_d_Sel() constructor.  To be used for
 *  Sel nodes that do not select from an array, i.e., have no index
 *  inputs.  It adds the two parameters 0, NULL.
 *
 * @param   *db        A pointer for debug information.
 * @param   *store     The memory in which the object the entity should be
 *                     selected from is allocated.
 * @param   *objptr    The object from that the Sel operation selects a
 *                     single attribute out.
 * @param   *ent       The entity to select.
 */
FIRM_API ir_node *new_d_simpleSel(dbg_info *db, ir_node *store, ir_node *objptr,
                                  ir_entity *ent);

/** Constructor for a simpelSel node.
 *
 *  This is a shortcut for the new_Sel() constructor.  To be used for
 *  Sel nodes that do not select from an array, i.e., have no index
 *  inputs.  It adds the two parameters 0, NULL.
 *
 * @param   *store     The memory in which the object the entity should be selected from is allocated.
 * @param   *objptr    The object from that the Sel operation selects a single attribute out.
 * @param   *ent       The entity to select.
 */
FIRM_API ir_node *new_simpleSel(ir_node *store, ir_node *objptr,
                                ir_entity *ent);

/** @} */

/** @addtogroup Div
 * @{
 */

/** Constructor for a remainderless Div node.
 *
 * @param   *db    A pointer for debug information.
 * @param   *block The IR block the node belongs to.
 * @param   *memop The store needed to model exceptions
 * @param   *op1   The first operand.
 * @param   *op2   The second operand.
 * @param   *mode  The mode of the result.
 * @param   state  The pinned state.
 */
FIRM_API ir_node *new_rd_DivRL(dbg_info *db, ir_node *block, ir_node *memop,
                               ir_node *op1, ir_node *op2, ir_mode *mode,
                               op_pin_state state);

/** Constructor for a remainderless Div node.
 *
 * @param *block The IR block the node belongs to.
 * @param *memop The store needed to model exceptions
 * @param *op1   The first operand.
 * @param *op2   The second operand.
 * @param *mode  The mode of the result.
 * @param state  The pinned state.
 */
FIRM_API ir_node *new_r_DivRL(ir_node *block, ir_node *memop,
                              ir_node *op1, ir_node *op2, ir_mode *mode,
                              op_pin_state state);

/** Constructor for a remainderless Div node.
 *
 * Adds the node to the block in current_ir_block.
 *
 * @param   *db    A pointer for debug information.
 * @param   *memop The store needed to model exceptions
 * @param   *op1   The first operand.
 * @param   *op2   The second operand.
 * @param   *mode  The mode of the result.
 * @param   state  The pinned state.
 */
FIRM_API ir_node *new_d_DivRL(dbg_info *db, ir_node *memop,
                              ir_node *op1, ir_node *op2, ir_mode *mode,
                              op_pin_state state);

/** Constructor for a remainderless Div node.
 *
 * Adds the node to the block in current_ir_block.
 *
 * @param   *memop The store needed to model exceptions
 * @param   *op1   The first operand.
 * @param   *op2   The second operand.
 * @param   *mode  The mode of the result.
 * @param   state  The pinned state.
 */
FIRM_API ir_node *new_DivRL(ir_node *memop, ir_node *op1, ir_node *op2,
                            ir_mode *mode, op_pin_state state);

/** @} */

/** @addtogroup ASM
 * @{
 */

/** Constructor for an ASM pseudo node.
 *
 * @param *db         A pointer for debug information.
 * @param *block      The block the node belong to.
 * @param arity       The number of data inputs to the node.
 * @param *in         The array of length arity of data inputs.
 * @param *inputs     The array of length arity of input constraints.
 * @param n_outs      The number of data outputs to the node.
 * @param *outputs    The array of length n_outs of output constraints.
 * @param n_clobber   The number of clobbered registers.
 * @param *clobber    The array of length n_clobber of clobbered registers.
 * @param *asm_text   The assembler text.
 */
FIRM_API ir_node *new_rd_ASM(dbg_info *db, ir_node *block,
                            int arity, ir_node *in[], ir_asm_constraint *inputs,
                            size_t n_outs, ir_asm_constraint *outputs,
                            size_t n_clobber, ident *clobber[],
                            ident *asm_text);

/** Constructor for an ASM pseudo node.
 *
 * @param *block      The block the node belong to.
 * @param arity       The number of data inputs to the node.
 * @param *in         The array of length arity of data inputs.
 * @param *inputs     The array of length arity of input constraints.
 * @param n_outs      The number of data outputs to the node.
 * @param *outputs    The array of length n_outs of output constraints.
 * @param n_clobber   The number of clobbered registers.
 * @param *clobber    The array of length n_clobber of clobbered registers.
 * @param *asm_text   The assembler text.
 */
FIRM_API ir_node *new_r_ASM(ir_node *block,
                            int arity, ir_node *in[], ir_asm_constraint *inputs,
                            size_t n_outs, ir_asm_constraint *outputs,
                            size_t n_clobber, ident *clobber[],
                            ident *asm_text);

/** Constructor for an ASM pseudo node.
 *
 * @param *db         A pointer for debug information.
 * @param arity       The number of data inputs to the node.
 * @param *in         The array of length arity of data inputs.
 * @param *inputs     The array of length arity of input constraints.
 * @param n_outs      The number of data outputs to the node.
 * @param *outputs    The array of length n_outs of output constraints.
 * @param n_clobber   The number of clobbered registers.
 * @param *clobber    The array of length n_clobber of clobbered registers.
 * @param *asm_text   The assembler text.
 * @ingroup ASM
 */
FIRM_API ir_node *new_d_ASM(dbg_info *db, int arity, ir_node *in[],
                            ir_asm_constraint *inputs,
                            size_t n_outs, ir_asm_constraint *outputs,
                            size_t n_clobber, ident *clobber[],
                            ident *asm_text);

/** Constructor for an ASM pseudo node.
 *
 * @param arity       The number of data inputs to the node.
 * @param *in         The array of length arity of data inputs.
 * @param *inputs     The array of length arity of input constraints.
 * @param n_outs      The number of data outputs to the node.
 * @param *outputs    The array of length n_outs of output constraints.
 * @param n_clobber   The number of clobbered registers.
 * @param *clobber    The array of length n_clobber of clobbered registers.
 * @param *asm_text   The assembler text.
 * @ingroup ASM
 */
FIRM_API ir_node *new_ASM(int arity, ir_node *in[], ir_asm_constraint *inputs,
                          size_t n_outs, ir_asm_constraint *outputs,
                          size_t n_clobber, ident *clobber[], ident *asm_text);

/** @} */

/**
 * @ingroup ir_graph
 * @defgroup ir_cons Construction Support
 * @{
 */

/**
 * Global variable holding the graph which is currently constructed.
 */
FIRM_API ir_graph *current_ir_graph;

/**
 * Returns graph which is currently constructed
 */
FIRM_API ir_graph *get_current_ir_graph(void);

/**
 * Sets graph which is currently constructed
 */
FIRM_API void set_current_ir_graph(ir_graph *graph);

/** Create an immature Block.
 *
 * An immature Block has an unknown number of predecessors.  Predecessors
 * can be added with add_immBlock_pred().  Once all predecessors are
 * added the block must be matured.
 *
 * Adds the block to the graph in current_ir_graph.
 * This constructor can only be used if the graph is in state_building.
 */
FIRM_API ir_node *new_d_immBlock(dbg_info *db);
/** Create an immature Block.
 *
 * An immature Block has an unknown number of predecessors.  Predecessors
 * can be added with add_immBlock_pred().  Once all predecessors are
 * added the block must be matured.
 *
 * Adds the block to the graph in current_ir_graph.
 * This constructor can only be used if the graph is in state_building.
 */
FIRM_API ir_node *new_immBlock(void);
/** Create an immature Block.
 *
 * An immature Block has an unknown number of predecessors.  Predecessors
 * can be added with add_immBlock_pred().  Once all predecessors are
 * added the block must be matured.
 *
 * This constructor can only be used if the graph is in state_building.
 */
FIRM_API ir_node *new_r_immBlock(ir_graph *irg);
/** Create an immature Block.
 *
 * An immature Block has an unknown number of predecessors.  Predecessors
 * can be added with add_immBlock_pred().  Once all predecessors are
 * added the block must be matured.
 *
 * This constructor can only be used if the graph is in state_building.
 */
FIRM_API ir_node *new_rd_immBlock(dbg_info *db, ir_graph *irg);

/** Add a control flow edge to an immature block. */
FIRM_API void add_immBlock_pred(ir_node *immblock, ir_node *jmp);

/** Finalize a Block node, when all control flows are known. */
FIRM_API void mature_immBlock(ir_node *block);

/**
 * Sets the current block in which the following constructors place the
 * nodes they construct.
 *
 * @param target  The new current block.
 */
FIRM_API void set_cur_block(ir_node *target);
/**
 * Sets current block of a given graph.
 * @see set_cur_block()
 */
FIRM_API void set_r_cur_block(ir_graph *irg, ir_node *target);

/** Returns the current block of the current graph. */
FIRM_API ir_node *get_cur_block(void);
/** Returns current block of a given graph */
FIRM_API ir_node *get_r_cur_block(ir_graph *irg);

/** Returns the current value of a local variable.
 *
 * Use this function to obtain the last definition of the local variable
 * associated with pos.  Pos may not exceed the value passed as n_loc
 * to new_ir_graph.  This call automatically inserts Phi nodes.
 *
 * @param  pos   The position/id of the local variable.
 * @param *mode  The mode of the value to get.
 */
FIRM_API ir_node *get_value(int pos, ir_mode *mode);
/** Returns the current value of a local variable in given graph
 * @see get_value() */
FIRM_API ir_node *get_r_value(ir_graph *irg, int pos, ir_mode *mode);

/**
 * Try to guess the mode of a local variable.
 * This is done by recursively going up the control flow graph until
 * we find a definition for the variable. The mode of the first found
 * definition is returned. NULL in case no definition is found.
 *
 * @param  pos   The position/id of the local variable.
 */
FIRM_API ir_mode *ir_guess_mode(int pos);
/**
 * Try to guess the mode of a local variable in a given graph.
 */
FIRM_API ir_mode *ir_r_guess_mode(ir_graph *irg, int pos);

/** Remark a new definition of a variable.
 *
 * 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.  This call is needed to automatically inserts Phi
 * nodes.
 *
 * @param  pos   The position/id of the local variable.
 * @param *value The new value written to the local variable.
 */
FIRM_API void set_value(int pos, ir_node *value);
/** Sets current value of a variable in a given graph */
FIRM_API void set_r_value(ir_graph *irg, int pos, ir_node *value);

/**
 * Find the value number for a node in the current block.
 *
 * @param value  the searched value
 *
 * @return the value number of the value or -1 if this value has
 * no value number in the current block.
 */
FIRM_API int find_value(ir_node *value);
/**
 * Find value number for a node in the current block of a given graph
 * @see find_value()
 */
FIRM_API int r_find_value(ir_graph *irg, ir_node *value);

/** Returns the current memory state.
 *
 * Use this function to obtain the last definition of the memory
 * state.  This call automatically inserts Phi nodes for the memory
 * state value.
 */
FIRM_API ir_node *get_store(void);
/** Returns current memory state for a given graph
 * @see get_store() */
FIRM_API ir_node *get_r_store(ir_graph *irg);

/** Remark a new definition of the memory state.
 *
 * Use this function to remember a new definition of the memory state.
 * This call is needed to automatically inserts Phi nodes.
 *
 * @param *store The new memory state.
 */
FIRM_API void set_store(ir_node *store);
/** Sets current memory state for a given graph
 * @see set_store() */
FIRM_API void set_r_store(ir_graph *irg, ir_node *store);

/** keep this node alive even if End is not control-reachable from it
 *
 * @param ka The node to keep alive.
 */
FIRM_API void keep_alive(ir_node *ka);

/** Puts the graph into state "phase_high" */
FIRM_API void irg_finalize_cons(ir_graph *irg);

/** Puts the program and all graphs into state phase_high.
 *
 * This also remarks, the construction of types is finished,
 * e.g., that no more subtypes will be added.  */
FIRM_API void irp_finalize_cons(void);

/**
 * Register a new callback for the case that the value of an uninitialized
 * variable is requested.
 */
FIRM_API void ir_set_uninitialized_local_variable_func(
		uninitialized_local_variable_func_t *func);

/** @} */

#include "end.h"

#endif
