- removed Psi nodes, Mux nodes are used again ...
[libfirm] / ir / ir / irgraph_t.h
index 06761e1..af9bf68 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
 #include "irgraph.h"
 
 #include "firm_common_t.h"
-#include "irtypeinfo.h"
+#include "irtypes.h"
 #include "irprog.h"
 #include "pseudo_irg.h"
 #include "type_t.h"
 #include "entity_t.h"
 #include "iredgekinds.h"
-#include "irmemory.h"
 
 #include "irloop.h"
-#include "execution_frequency.h"
 
 #include "obst.h"
 #include "pset.h"
 #include "set.h"
 
-/** Prefix that is added to every frame type. */
+/** Suffix that is added to every frame type. */
 #define FRAME_TP_SUFFIX "frame_tp"
 
 /**
- * Edge info to put into an irg.
+ * Initializes the graph construction module.
  */
-typedef struct _irg_edge_info_t {
-         set      *edges;         /**< a set containing all edges of a graph. */
-         unsigned activated : 1;  /**< set if edges are activated for the graph. */
-} irg_edge_info_t;
-
-typedef irg_edge_info_t irg_edges_info_t[EDGE_KIND_LAST];
+void firm_init_irgraph(void);
 
 /**
- * Index constants for nodes that can be accessed through the graph itself.
+ * Set the number of locals for a given graph.
+ *
+ * @param irg    the graph
+ * @param n_loc  number of locals
  */
-enum irg_anchors {
-       anchor_start_block = 0,  /**< block the start node will belong to */
-       anchor_start,            /**< start node of this ir_graph */
-       anchor_end_block,        /**< block the end node will belong to */
-       anchor_end,              /**< end node of this ir_graph */
-       anchor_end_reg,          /**< end node of this ir_graph */
-       anchor_end_except,       /**< end node of this ir_graph */
-       anchor_frame,            /**< method's frame */
-       anchor_globals,          /**< pointer to the data segment containing all
-                                     globals as well as global procedures. */
-       anchor_tls,              /**< pointer to the thread local storage containing all
-                                     thread local data. */
-       anchor_initial_mem,      /**< initial memory of this graph */
-       anchor_args,             /**< methods arguments */
-       anchor_value_param_base, /**< method value param base */
-       anchor_bad,              /**< bad node of this ir_graph, the one and
-                                     only in this graph */
-       anchor_no_mem,           /**< NoMem node of this ir_graph, the one and only in this graph */
-       anchor_max
-};
-
-/** A callgraph entry for callees. */
-typedef struct cg_callee_entry {
-       ir_graph  *irg;        /**< The called irg. */
-       ir_node  **call_list;  /**< The list of all calls to the irg. */
-       int        max_depth;  /**< Maximum depth of all Call nodes to irg. */
-} cg_callee_entry;
+void irg_set_nloc(ir_graph *res, int n_loc);
 
 /**
- * An ir_graph holds all information for a procedure.
+ * Internal constructor that does not add to irp_irgs or the like.
  */
-struct ir_graph {
-       firm_kind         kind;        /**< Always set to k_ir_graph. */
-       /* --  Basics of the representation -- */
-       ir_entity  *ent;               /**< The entity of this procedure, i.e.,
-                                           the type of the procedure and the
-                                           class it belongs to. */
-       ir_type *frame_type;           /**< A class type representing the stack frame.
-                                           Can include "inner" methods. */
-       ir_node *anchors[anchor_max];  /**< List of anchor nodes. */
-       ir_node **proj_args;           /**< Projs of the methods arguments. */
-       struct obstack *obst;          /**< The obstack where all of the ir_nodes live. */
-       ir_node *current_block;        /**< Current block for newly gen_*()-erated ir_nodes. */
-       struct obstack *extbb_obst;    /**< The obstack for extended basic block info. */
-
-       unsigned last_node_idx;        /**< The last IR node index for this graph. */
-
-       /* -- Fields for graph properties -- */
-       irg_inline_property inline_property;     /**< How to handle inlineing. */
-       unsigned additional_properties;          /**< Additional graph properties. */
-
-       /* -- Fields indicating different states of irgraph -- */
-       irg_phase_state phase_state;       /**< Compiler phase. */
-       op_pin_state irg_pinned_state;     /**< Flag for status of nodes. */
-       irg_outs_state outs_state;         /**< Out edges. */
-       irg_dom_state dom_state;           /**< Dominator state information. */
-       irg_dom_state pdom_state;          /**< Post Dominator state information. */
-       ir_typeinfo_state typeinfo_state;        /**< Validity of type information. */
-       irg_callee_info_state callee_info_state; /**< Validity of callee information. */
-       irg_loopinfo_state loopinfo_state;       /**< State of loop information. */
-       ir_class_cast_state class_cast_state;    /**< Kind of cast operations in code. */
-       irg_extblk_info_state extblk_state;      /**< State of extended basic block info. */
-       exec_freq_state execfreq_state;          /**< Execution frequency state. */
-       ir_address_taken_computed_state adr_taken_state;  /**< Address taken state. */
-       unsigned mem_disambig_opt;               /**< Options for the memory disambiguator. */
-       unsigned fp_model;                       /**< floating point model of the graph. */
-
-       /* -- Fields for construction -- */
-#if USE_EXPLICIT_PHI_IN_STACK
-       struct Phi_in_stack *Phi_in_stack; /**< Needed for automatic Phi construction. */
-#endif
-       int n_loc;                         /**< Number of local variables in this
-                                               procedure including procedure parameters. */
-       void **loc_descriptions;           /**< Storage for local variable descriptions. */
-
-       /* -- Fields for optimizations / analysis information -- */
-       pset *value_table;                 /**< Hash table for global value numbering (cse)
-                                               for optimizing use in iropt.c */
-       ir_node **outs;                    /**< Space for the out arrays. */
-
-       ir_loop *loop;                     /**< The outermost loop for this graph. */
-       void *link;                        /**< A void* field to link any information to
-                                               the node. */
-
-       ir_graph **callers;                /**< For callgraph analysis: list of caller graphs. */
-       unsigned char *caller_isbe;        /**< For callgraph analysis: set if backedge. */
-       cg_callee_entry **callees;         /**< For callgraph analysis: list of callee calls */
-       unsigned char *callee_isbe;        /**< For callgraph analysis: set if backedge. */
-       int        callgraph_loop_depth;         /**< For callgraph analysis */
-       int        callgraph_recursion_depth;    /**< For callgraph analysis */
-       double     method_execution_frequency;   /**< For callgraph analysis */
-
-       ir_loop   *l;                            /**< For callgraph analysis. */
-
-       /* -- Fields for Walking the graph -- */
-       unsigned long visited;             /**< this flag is an identifier for
-                         ir walk. it will be incremented
-                         every time someone walks through
-                         the graph */
-       unsigned long block_visited;       /**< same as visited, for a complete block */
-
-       unsigned estimated_node_count;     /**< estimated number of nodes in this graph,
-                                               updated after every walk */
-       irg_edges_info_t edge_info;        /**< edge info for automatic outs */
-       ir_node **idx_irn_map;             /**< Array mapping node indexes to nodes. */
-
-#ifdef DEBUG_libfirm
-       int             n_outs;            /**< Size wasted for outs */
-       long graph_nr;                     /**< a unique graph number for each graph to make output
-                                               readable. */
-#endif
-
-#ifndef NDEBUG
-       unsigned using_visited       : 1;  /**< set to 1 if we are currently using the visited flag */
-       unsigned using_block_visited : 1;  /**< set to 1 if we are currently using the block_visited flag */
-       unsigned using_irn_link      : 1;  /**< set to 1 if we are currently using the irn_link fields */
-#endif
-};
+ir_graph *new_r_ir_graph(ir_entity *ent, int n_loc);
 
 /**
- * Initializes the graph construction module
+ * Make a rudimentary ir graph for the constant code.
+ * Must look like a correct irg, spare everything else.
  */
-void firm_init_irgraph(void);
-
-/* Internal constructor that does not add to irp_irgs or the like. */
-ir_graph *new_r_ir_graph (ir_entity *ent, int n_loc);
-
-/** Make a rudimentary ir graph for the constant code.
-   Must look like a correct irg, spare everything else. */
 ir_graph *new_const_code_irg(void);
 
+/**
+ * Create a new graph that is a copy of a given one.
+ * Uses the link fields of the original graphs.
+ *
+ * @param irg  The graph that must be copied.
+ */
+ir_graph *create_irg_copy(ir_graph *irg);
+
 /**
  * Set the op_pin_state_pinned state of a graph.
  *
  * @param irg     the IR graph
  * @param p       new pin state
  */
-INLINE void
-set_irg_pinned (ir_graph *irg, op_pin_state p);
+void set_irg_pinned(ir_graph *irg, op_pin_state p);
 
 /** Returns the obstack associated with the graph. */
 struct obstack *get_irg_obstack(const ir_graph *irg);
@@ -216,13 +101,6 @@ int node_is_in_irgs_storage(ir_graph *irg, ir_node *n);
 /* inline functions for graphs                                       */
 /*-------------------------------------------------------------------*/
 
-extern int firm_interprocedural_view;
-
-static INLINE int
-_get_interprocedural_view(void) {
-       return firm_interprocedural_view;
-}
-
 static INLINE int
 _is_ir_graph(const void *thing) {
        return (get_kind(thing) == k_ir_graph);
@@ -231,143 +109,145 @@ _is_ir_graph(const void *thing) {
 /** Returns the start block of a graph. */
 static INLINE ir_node *
 _get_irg_start_block(const ir_graph *irg) {
-       return irg->anchors[anchor_start_block];
+       return get_irn_intra_n(irg->anchor, anchor_start_block);
 }
 
 static INLINE void
 _set_irg_start_block(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_start_block] = node;
+       set_irn_n(irg->anchor, anchor_start_block, node);
 }
 
 static INLINE ir_node *
 _get_irg_start(const ir_graph *irg) {
-       return irg->anchors[anchor_start];
+       return get_irn_intra_n(irg->anchor, anchor_start);
 }
 
 static INLINE void
 _set_irg_start(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_start] = node;
+       set_irn_n(irg->anchor, anchor_start, node);
 }
 
 static INLINE ir_node *
 _get_irg_end_block(const ir_graph *irg) {
-  return irg->anchors[anchor_end_block];
+       return get_irn_intra_n(irg->anchor, anchor_end_block);
 }
 
 static INLINE void
 _set_irg_end_block(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_end_block] = node;
+       set_irn_n(irg->anchor, -1, node);
+       set_irn_n(irg->anchor, anchor_end_block, node);
 }
 
 static INLINE ir_node *
 _get_irg_end(const ir_graph *irg) {
-       return irg->anchors[anchor_end];
+       return get_irn_intra_n(irg->anchor, anchor_end);
 }
 
 static INLINE void
 _set_irg_end(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_end] = node;
+       set_irn_n(irg->anchor, anchor_end, node);
 }
 
 static INLINE ir_node *
 _get_irg_end_reg(const ir_graph *irg) {
-       return irg->anchors[anchor_end_reg];
+       return get_irn_intra_n(irg->anchor, anchor_end_reg);
+}
+
+static INLINE void
+_set_irg_end_reg(ir_graph *irg, ir_node *node) {
+       set_irn_n(irg->anchor, anchor_end_reg, node);
 }
 
 static INLINE ir_node *
-_get_irg_end_except (const ir_graph *irg) {
-       return irg->anchors[anchor_end_except];
+_get_irg_end_except(const ir_graph *irg) {
+       return get_irn_intra_n(irg->anchor, anchor_end_except);
+}
+
+static INLINE void
+_set_irg_end_except(ir_graph *irg, ir_node *node) {
+       set_irn_n(irg->anchor, anchor_end_except, node);
 }
 
 static INLINE ir_node *
-_get_irg_frame(const ir_graph *irg) {
-       return irg->anchors[anchor_frame];
+_get_irg_initial_exec(const ir_graph *irg) {
+       return get_irn_intra_n(irg->anchor, anchor_initial_exec);
 }
 
 static INLINE void
-_set_irg_frame(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_frame] = node;
+_set_irg_initial_exec(ir_graph *irg, ir_node *node) {
+       set_irn_n(irg->anchor, anchor_initial_exec, node);
 }
 
 static INLINE ir_node *
-_get_irg_globals(const ir_graph *irg) {
-       return irg->anchors[anchor_globals];
+_get_irg_frame(const ir_graph *irg) {
+       return get_irn_intra_n(irg->anchor, anchor_frame);
 }
 
 static INLINE void
-_set_irg_globals(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_globals] = node;
+_set_irg_frame(ir_graph *irg, ir_node *node) {
+       set_irn_n(irg->anchor, anchor_frame, node);
 }
 
 static INLINE ir_node *
 _get_irg_tls(const ir_graph *irg) {
-       return irg->anchors[anchor_tls];
+       return get_irn_intra_n(irg->anchor, anchor_tls);
 }
 
 static INLINE void
 _set_irg_tls(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_tls] = node;
+       set_irn_n(irg->anchor, anchor_tls, node);
 }
 
 static INLINE ir_node *
 _get_irg_initial_mem(const ir_graph *irg) {
-       return irg->anchors[anchor_initial_mem];
+       return get_irn_intra_n(irg->anchor, anchor_initial_mem);
 }
 
 static INLINE void
 _set_irg_initial_mem(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_initial_mem] = node;
+       set_irn_n(irg->anchor, anchor_initial_mem, node);
 }
 
 static INLINE ir_node *
 _get_irg_args(const ir_graph *irg) {
-       return irg->anchors[anchor_args];
+       return get_irn_intra_n(irg->anchor, anchor_args);
 }
 
 static INLINE void
 _set_irg_args(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_args] = node;
+       set_irn_n(irg->anchor, anchor_args, node);
 }
 
 static INLINE ir_node *
 _get_irg_value_param_base(const ir_graph *irg) {
-       return irg->anchors[anchor_value_param_base];
+       return get_irn_intra_n(irg->anchor, anchor_value_param_base);
 }
 
 static INLINE void
 _set_irg_value_param_base(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_value_param_base] = node;
-}
-
-static INLINE ir_node **
-_get_irg_proj_args(const ir_graph *irg) {
-       return irg->proj_args;
-}
-
-static INLINE void
-_set_irg_proj_args(ir_graph *irg, ir_node **nodes) {
-       irg->proj_args = nodes;
+       set_irn_n(irg->anchor, anchor_value_param_base, node);
 }
 
 static INLINE ir_node *
 _get_irg_bad(const ir_graph *irg) {
-       return irg->anchors[anchor_bad];
+       return get_irn_intra_n(irg->anchor, anchor_bad);
 }
 
 static INLINE void
 _set_irg_bad(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_bad] = node;
+       set_irn_n(irg->anchor, anchor_bad, node);
 }
 
 static INLINE ir_node *
 _get_irg_no_mem(const ir_graph *irg) {
-       return irg->anchors[anchor_no_mem];
+       return get_irn_intra_n(irg->anchor, anchor_no_mem);
 }
 
 static INLINE void
 _set_irg_no_mem(ir_graph *irg, ir_node *node) {
-       irg->anchors[anchor_no_mem] = node;
+       set_irn_n(irg->anchor, anchor_no_mem, node);
 }
+
 static INLINE ir_node *
 _get_irg_current_block(const ir_graph *irg) {
        return irg->current_block;
@@ -619,7 +499,41 @@ get_idx_irn(ir_graph *irg, unsigned idx) {
        return irg->idx_irn_map[idx];
 }
 
+/**
+ * Return the number of anchors in this graph.
+ */
+static INLINE int
+get_irg_n_anchors(const ir_graph *irg) {
+       return get_irn_arity(irg->anchor);
+}
+
+/**
+ * Return anchor for given index
+ */
+static INLINE ir_node *
+get_irg_anchor(const ir_graph *irg, int idx) {
+       return get_irn_intra_n(irg->anchor, idx);
+}
+
+/**
+ * Set anchor for given index
+ */
+static INLINE void
+set_irg_anchor(ir_graph *irg, int idx, ir_node *irn) {
+       set_irn_n(irg->anchor, idx, irn);
+}
+
+#ifdef INTERPROCEDURAL_VIEW
+extern int firm_interprocedural_view;
+
+static INLINE int
+_get_interprocedural_view(void) {
+       return firm_interprocedural_view;
+}
+
 #define get_interprocedural_view()            _get_interprocedural_view()
+#endif
+
 #define is_ir_graph(thing)                    _is_ir_graph(thing)
 #define get_irg_start_block(irg)              _get_irg_start_block(irg)
 #define set_irg_start_block(irg, node)        _set_irg_start_block(irg, node)
@@ -630,11 +544,13 @@ get_idx_irn(ir_graph *irg, unsigned idx) {
 #define get_irg_end(irg)                      _get_irg_end(irg)
 #define set_irg_end(irg, node)                _set_irg_end(irg, node)
 #define get_irg_end_reg(irg)                  _get_irg_end_reg(irg)
+#define set_irg_end_reg(irg, node)            _set_irg_end_reg(irg, node)
 #define get_irg_end_except(irg)               _get_irg_end_except(irg)
+#define set_irg_end_except(irg, node)         _set_irg_end_except(irg, node)
+#define get_irg_initial_exec(irg)             _get_irg_initial_exec(irg)
+#define set_irg_initial_exec(irg, node)       _set_irg_initial_exec(irg, node)
 #define get_irg_frame(irg)                    _get_irg_frame(irg)
 #define set_irg_frame(irg, node)              _set_irg_frame(irg, node)
-#define get_irg_globals(irg)                  _get_irg_globals(irg)
-#define set_irg_globals(irg, node)            _set_irg_globals(irg, node)
 #define get_irg_tls(irg)                      _get_irg_tls(irg)
 #define set_irg_tls(irg, node)                _set_irg_tls(irg, node)
 #define get_irg_initial_mem(irg)              _get_irg_initial_mem(irg)
@@ -646,7 +562,7 @@ get_idx_irn(ir_graph *irg, unsigned idx) {
 #define get_irg_bad(irg)                      _get_irg_bad(irg)
 #define set_irg_bad(irg, node)                _set_irg_bad(irg, node)
 #define get_irg_no_mem(irg)                   _get_irg_no_mem(irg)
-#define set_irg_no_mem(irg, node)             _set_irg_no_mem(irg, node)
+#define set_irn_no_mem(irg, node)             _set_irn_no_mem(irg, node)
 #define get_irg_current_block(irg)            _get_irg_current_block(irg)
 #define set_irg_current_block(irg, node)      _set_irg_current_block(irg, node)
 #define get_irg_entity(irg)                   _get_irg_entity(irg)