Added exception markings to graph and cfg dumps --flo
[libfirm] / ir / ir / ircons.h
index 8472af6..0d50efe 100644 (file)
@@ -7,6 +7,7 @@
 ** ircons.h ir node construction
 */
 
+/* $Id$ */
 
 /** !!!
 *** Ideas for imrovement:
  *    ------------------
  *                       Not yet documented. See irmode.h.
  *
- *    GLOBAL VARIABLES
+ *    GLOBAL VARIABLES -- now also fields of ir_graph.
  *    ================
  *
  *    current_ir_graph   Points to the current ir_graph.  All constructors for
  *
  *
  *
- *    CONSTRUCTOR FOR IR_GRAPH
+ *    CONSTRUCTOR FOR IR_GRAPH --> see irgraph.h
  *    ========================
  *
- *    ir_graph *new_ir_graph (entity *ent, int params);
- *    -------------------------------------------------
- *
- *    This constructor generates the basic infrastructure needed to
- *    represent a procedure in FIRM.
- *
- *    The parameters of new_ir_graph are:
- *
- *      *ent             A pointer to an entity representing the procedure.
- *
- *      params           An integer giving the number of local variables in the
- *                       procedure.
  *
- *    It allocates an ir_graph and sets current_ir_graph to point to this
- *    graph.  Further it allocates the following nodes needed for every
- *    procedure:
- *
- *    * The start block containing a start node and Proj nodes for it's
- *      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.)
- *    * The current block, which is empty and also not matured.
- *
- *    Further it enters the global store into the datastructure of the start
- *    block that contanis all valid values in this block (set_store()).  This
- *    datastructure is used to build the Phi nodes and removed after completion
- *    of the graph.
- *    There is no path from end to start in the graph after calling ir_graph.
- *
- *
- *    PROCEDURE TO CONSTRUCT AN IR GRAPH
+ *    PROCEDURE TO CONSTRUCT AN IR GRAPH --> see also Firm tutorial
  *    ==================================
  *
  *    This library supplies several interfaces to construct a FIRM graph for
  *    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
+ *    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.  In general these are all compiler generated
+ *    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.
  *
  *    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);
+ *    a_val = get_value(42, 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);
+ *    set_value(res, 42);
  *    cf_op = new_Jmp();
  *
  *    For further information look at the documentation of the nodes and
  *    void set_value (int pos, ir_node *value);
  *    ir_node *get_store (void);
  *    void set_store (ir_node *store);
- *
+ *    keep_alive (ir_node ka)
  *
  *    IR_NODES AND CONSTRUCTORS FOR IR_NODES
  *    =======================================
  *
  *      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
  *      size      The symbolic constant represents the size of a class.
  *      link_info Information for the linker, e.g. the name of a global
  *                variable.
+ *    To represent a pointer to an entity that is represented by an entity
+ *    datastructure don't use
+ *      new_SymConst((type_or_id*)get_entity_ld_ident(ent), linkage_ptr_info);.
+ *    Use a real const instead:
+ *      new_Const(mode_p, tarval_p_from_entity(ent));
+ *    This makes the Constant independent of name changes of the entity due to
+ *    mangling.
  *
  *    Parameters
  *      kind        The kind of the symbolic constant: type_tag, size or link_info.
  *    ir_node *new_Minus (ir_node *op, ir_mode *mode)
  *    -----------------------------------------------
  *
- *    This constructor is for unary Minus operations on floating point
- *    values.  Such a Minus can trap if it is implemented as a Sub from
- *    zero due to rounding errors.
+ *    Unary Minus operations on floating point values.
  *
  *    ir_node *new_Mul (ir_node *op1, ir_node *op2, ir_mode *mode)
  *    ------------------------------------------------------------
  *    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)
  *    -------------------------------------------
  *    definition reaches the currend block on several different
  *    paths.  This Phi node will be eliminated if optimizations are
  *    turned on right after it's creation.
- *
+ *    Requires current_block to be set correctly.
  *
  *    There are two special routines for the global store:
  *
  *
  *    Adds the store to the array of known values at a reserved
  *    position.
+ *    Requires current_block to be set correctly.
  *
  *    inline ir_node *get_store (void)
  *    --------------------------------
  *
  *    Returns the node defining the actual store.
+ *    Requires current_block to be set correctly.
+ *
+ *
+ *    inline void keep_alive (ir_node *ka)
+ *    ------------------------------------
+ *
+ *    Keep this node alive because it is (might be) not in the control
+ *    flow from Start to End.  Adds the node to the list in the end
+ *    node.
+ *
  *****
  */
 
 # include "entity.h"
 # include "tv.h"
 # include "type.h"
+# include "dbginfo.h"
 
 /***************************************************************************/
 /* 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_rd_Block  (dbg_info *db, ir_graph *irg,  int arity, ir_node **in);
+ir_node *new_rd_Start  (dbg_info *db, ir_graph *irg, ir_node *block);
+ir_node *new_rd_End    (dbg_info *db, ir_graph *irg, ir_node *block);
+ir_node *new_rd_Jmp    (dbg_info *db, ir_graph *irg, ir_node *block);
+ir_node *new_rd_Cond   (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *c);
+ir_node *new_rd_Return (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *store, int arity, ir_node **in);
+ir_node *new_rd_Raise  (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *store, ir_node *obj);
+ir_node *new_rd_Const  (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_mode *mode, tarval *con);
+ir_node *new_rd_SymConst (dbg_info *db, ir_graph *irg, ir_node *block,
+                       type_or_id_p value, symconst_kind symkind);
+ir_node *new_rd_Sel    (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+                       ir_node *objptr, int n_index, ir_node **index,
+                      entity *ent);
+ir_node *new_rd_Call   (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+                      ir_node *callee, int arity, ir_node **in,
+                      type *type);
+ir_node *new_rd_Add    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Sub    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Minus  (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op,  ir_mode *mode);
+ir_node *new_rd_Mul    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Quot   (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_rd_DivMod (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_rd_Div    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_rd_Mod    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_rd_Abs    (dbg_info *db, ir_graph *irg, ir_node *block,
+                       ir_node *op, ir_mode *mode);
+ir_node *new_rd_And    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Or     (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Eor    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_rd_Not    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_mode *mode);
+ir_node *new_rd_Cmp    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op1, ir_node *op2);
+ir_node *new_rd_Shl    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_node *k, ir_mode *mode);
+ir_node *new_rd_Shr    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_node *k, ir_mode *mode);
+ir_node *new_rd_Shrs   (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_node *k, ir_mode *mode);
+ir_node *new_rd_Rot    (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_node *k, ir_mode *mode);
+ir_node *new_rd_Conv   (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *op, ir_mode *mode);
+ir_node *new_rd_Phi    (dbg_info *db, ir_graph *irg, ir_node *block, int arity,
+                      ir_node **in, ir_mode *mode);
+ir_node *new_rd_Load   (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *store, ir_node *adr);
+ir_node *new_rd_Store  (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *store, ir_node *adr, ir_node *val);
+ir_node *new_rd_Alloc  (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+                      ir_node *size, type *alloc_type, where_alloc where);
+ir_node *new_rd_Free   (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+                      ir_node *ptr, ir_node *size, type *free_type);
+ir_node *new_rd_Sync   (dbg_info *db, ir_graph *irg, ir_node *block, int arity, ir_node **in);
+ir_node *new_rd_Proj   (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *arg,
+                      ir_mode *mode, long proj);
+ir_node *new_rd_defaultProj (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *arg,
+                           long max_proj);
+ir_node *new_rd_Tuple  (dbg_info *db, ir_graph *irg, ir_node *block,
+                      int arity, ir_node **in);
+ir_node *new_rd_Id     (dbg_info *db, ir_graph *irg, ir_node *block,
+                      ir_node *val, ir_mode *mode);
+ir_node *new_rd_Bad    ();
+
+/***************************************************************************/
+/* The raw interface without debug support                                 */
+/***************************************************************************/
+
+/* Constructs a Block with a fixed number of predecessors.
+   Does not set current_block.  Can not be used with automatic
+   Phi node costruction. */
 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);
@@ -1170,13 +1244,14 @@ ir_node *new_r_Free   (ir_graph *irg, ir_node *block, ir_node *store,
 ir_node *new_r_Sync   (ir_graph *irg, ir_node *block, int arity, ir_node **in);
 ir_node *new_r_Proj   (ir_graph *irg, ir_node *block, ir_node *arg,
                       ir_mode *mode, long proj);
+ir_node *new_r_defaultProj (ir_graph *irg, ir_node *block, ir_node *arg,
+                           long max_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    ();
 
-
 /*************************************************************************/
 /* The block oriented interface                                          */
 /*************************************************************************/
@@ -1185,6 +1260,65 @@ ir_node *new_r_Bad    ();
    nodes they construct. */
 void switch_block (ir_node *target);
 
+/* Constructs a Block with a fixed number of predecessors.
+   Does set current_block.  Can be used with automatic Phi
+   node construction. */
+
+
+ir_node *new_d_Block(dbg_info* db, int arity, ir_node **in);
+ir_node *new_d_Start  (dbg_info* db);
+ir_node *new_d_End    (dbg_info* db);
+ir_node *new_d_Jmp    (dbg_info* db);
+ir_node *new_d_Cond   (dbg_info* db, ir_node *c);
+ir_node *new_d_Return (dbg_info* db, ir_node *store, int arity, ir_node **in);
+ir_node *new_d_Raise  (dbg_info* db, ir_node *store, ir_node *obj);
+ir_node *new_d_Const  (dbg_info* db, ir_mode *mode, tarval *con);
+ir_node *new_d_SymConst (dbg_info* db, type_or_id_p value, symconst_kind kind);
+ir_node *new_d_simpleSel(dbg_info* db, ir_node *store, ir_node *objptr, entity *ent);
+ir_node *new_d_Sel    (dbg_info* db, ir_node *store, ir_node *objptr, int arity, ir_node **in,
+                     entity *ent);
+ir_node *new_d_Call   (dbg_info* db, ir_node *store, ir_node *callee, int arity, ir_node **in,
+                    type *type);
+ir_node *new_d_Add    (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Sub    (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Minus  (dbg_info* db, ir_node *op,  ir_mode *mode);
+ir_node *new_d_Mul    (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Quot   (dbg_info* db, ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_d_DivMod (dbg_info* db, ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_d_Div    (dbg_info* db, ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_d_Mod    (dbg_info* db, ir_node *memop, ir_node *op1, ir_node *op2);
+ir_node *new_d_Abs    (dbg_info* db, ir_node *op,                ir_mode *mode);
+ir_node *new_d_And    (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Or     (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Eor    (dbg_info* db, ir_node *op1, ir_node *op2, ir_mode *mode);
+ir_node *new_d_Not    (dbg_info* db, ir_node *op,                ir_mode *mode);
+ir_node *new_d_Shl    (dbg_info* db, ir_node *op,  ir_node *k,   ir_mode *mode);
+ir_node *new_d_Shr    (dbg_info* db, ir_node *op,  ir_node *k,   ir_mode *mode);
+ir_node *new_d_Shrs   (dbg_info* db, ir_node *op,  ir_node *k,   ir_mode *mode);
+ir_node *new_d_Rot    (dbg_info* db, ir_node *op,  ir_node *k,   ir_mode *mode);
+ir_node *new_d_Cmp    (dbg_info* db, ir_node *op1, ir_node *op2);
+ir_node *new_d_Conv   (dbg_info* db, ir_node *op, ir_mode *mode);
+ir_node *new_d_Phi    (dbg_info* db, int arity, ir_node **in, ir_mode *mode);
+ir_node *new_d_Load   (dbg_info* db, ir_node *store, ir_node *addr);
+ir_node *new_d_Store  (dbg_info* db, ir_node *store, ir_node *addr, ir_node *val);
+ir_node *new_d_Alloc  (dbg_info* db, ir_node *store, ir_node *size, type *alloc_type,
+                     where_alloc where);
+ir_node *new_d_Free   (dbg_info* db, ir_node *store, ir_node *ptr, ir_node *size,
+                    type *free_type);
+ir_node *new_d_Sync   (dbg_info* db, int arity, ir_node **in);
+ir_node *new_d_Proj   (dbg_info* db, ir_node *arg, ir_mode *mode, long proj);
+ir_node *new_d_defaultProj (dbg_info* db, ir_node *arg, long max_proj);
+ir_node *new_d_Tuple  (dbg_info* db, int arity, ir_node **in);
+ir_node *new_d_Id     (dbg_info* db, ir_node *val, ir_mode *mode);
+ir_node *new_d_Bad    (void);
+
+/*************************************************************************/
+/* The block oriented interface without debug support                    */
+/*************************************************************************/
+
+/* Needed from the interfase with debug support:
+void switch_block (ir_node *target);   */
+
 /* Constructs a Block with a fixed number of predecessors.
    Does set current_block.  Can be used with automatic Phi
    node construction. */
@@ -1197,7 +1331,7 @@ 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_p value, symconst_kind kind);
-ir_node *new_simpleSel (ir_node *store, ir_node *objptr, entity *ent);
+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,
@@ -1230,6 +1364,7 @@ ir_node *new_Free   (ir_node *store, ir_node *ptr, ir_node *size,
                     type *free_type);
 ir_node *new_Sync   (int arity, ir_node **in);
 ir_node *new_Proj   (ir_node *arg, ir_mode *mode, long proj);
+ir_node *new_defaultProj (ir_node *arg, long max_proj);
 ir_node *new_Tuple  (int arity, ir_node **in);
 ir_node *new_Id     (ir_node *val, ir_mode *mode);
 ir_node *new_Bad    (void);
@@ -1243,6 +1378,7 @@ ir_node *new_Bad    (void);
 
 /** Block construction **/
 /* immature Block without predecessors */
+ir_node *new_d_immBlock (dbg_info* db);
 ir_node *new_immBlock (void);
 
 /* Add a control flow edge to an immature block. */
@@ -1255,6 +1391,7 @@ void mature_block (ir_node *block);
 /* 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_d_value (dbg_info* db, int pos, ir_mode *mode);
 ir_node *get_value (int pos, ir_mode *mode);
 
 /* Write a value in the array with the local variables. Use this function
@@ -1270,10 +1407,24 @@ ir_node *get_store (void);
 /* Write a store. */
 void set_store (ir_node *store);
 
+/* keep this node alive even if End is not control-reachable from it */
+inline void keep_alive (ir_node *ka);
+
+/** Useful access routines **/
+/* Returns the current block of the current graph.  To set the current
+   block use switch_block(). */
+ir_node *get_cur_block();
+
+/* Returns the frame type of the current graph */
+type *get_cur_frame_type();
+
+
 /***********************************************************************/
-/* initialize ir construction                                          */
+/* initialize and finalize ir construction                             */
 /***********************************************************************/
-void init_cons (void);
+
+/* Puts the graph into state "phase_high" */
+void finalize_cons (ir_graph *irg);
 
 
 # endif /* _IRCONS_H_ */