local_optimize() now kills unrteachable code if dominance info is available.
[libfirm] / ir / ir / irnode.h
index c00e982..48d41bd 100644 (file)
@@ -20,6 +20,7 @@
 # include "irop.h"
 # include "irmode.h"
 # include "type.h"
+# include "irextbb.h"
 # include "dbginfo.h"
 
 /**
@@ -160,12 +161,26 @@ ir_graph     *get_irn_irg      (const ir_node *node);
    of node cast to long. */
 long          get_irn_node_nr  (const ir_node *node);
 
-/** Returns the pinned state of a node. */
+/** Returns the pinned state of a node.
+ *
+ *  Returns whether the node _always_ must be pinned.
+ *  I.e., the node is not floating after global cse.
+ *
+ * @returns Either state op_pin_state_pinned or op_pin_state_floats.
+ */
 op_pin_state get_irn_pinned    (const ir_node *node);
 
 /** Set pin state for nodes with op pin state op_pin_state_exc_pinned */
 void set_irn_pinned(ir_node *node, op_pin_state state);
 
+/** Returns whether the node is currently pinned.
+ *
+ * If get_irn_pinned returns op_pin_state_floats and the graph the
+ * node belongs to is in state op_poin_state_floats then this function
+ * returns 'floats', else 'pinned'.
+ */
+op_pin_state is_irn_pinned_in_irg (const ir_node *node);
+
 /**
  * irnode constructor.
  * Create a new irnode in irg, with an op, mode, arity and
@@ -174,6 +189,7 @@ void set_irn_pinned(ir_node *node, op_pin_state state);
  *
  * @param db    Debug info.
  * @param irg   IR-graph on with this new node should be constructed.
+ * @param block The block the new node belongs to
  * @param op    The opcode of the new node.
  * @param mode  The mode of the new node.
  * @param arity The arity of the new node, may be <0 if yet.
@@ -188,13 +204,17 @@ new_ir_node (dbg_info *db,
          int arity,
          ir_node *in[]);
 
-/** Return the block the node belongs to.
+/**
+ * Return the block the node belongs to.  This is only
+ * possible for pinned nodes or if the graph is in pinned state.
+ * Otherwise the block may be incorrect.  This condition is
+ * now checked by an assertion.
  *
  * This works for all except Block.  It can return Blocks or the Bad node.
  *
  * To express the difference to access routines that work for all
  * nodes we use infix "nodes" and do not name this function
- * get_irn_block. */
+ * get_irn_block(). */
 ir_node  *get_nodes_block (const ir_node *node);
 
 /** Sets the Block of a node. */
@@ -204,6 +224,7 @@ void      set_nodes_block (ir_node *node, ir_node *block);
  * @function get_irn_block()
  * @see get_nodes_block()
  */
+
 /**
  * Projection numbers for result of Start node: use for Proj nodes!
  */
@@ -244,6 +265,18 @@ ir_node **get_Block_cfgpred_arr (ir_node *node);
 int       get_Block_n_cfgpreds (ir_node *node);
 ir_node  *get_Block_cfgpred (ir_node *node, int pos);
 void      set_Block_cfgpred (ir_node *node, int pos, ir_node *pred);
+/** Get the predecessor block.
+ *
+ *  Returns the block corresonding to the predecessor pos of block.
+ *
+ *  There are several ambiguities we resolve with this function:
+ *  - The direct predecessor can be a Proj, which is not pinned.
+ *    We walk from the predecessor to the next pinned node
+ *    (skip_Proj) and return the block that node is in.
+ *  - If we encounter the Bad node, this function does not return
+ *    Start, but the Bad node.
+ */
+ir_node  *get_Block_cfgpred_block(ir_node *node, int pos);
 bool      get_Block_matured (ir_node *node);
 void      set_Block_matured (ir_node *node, bool matured);
 
@@ -251,6 +284,11 @@ void      set_Block_matured (ir_node *node, bool matured);
  *  @see also: get_irn_visited() inc_irg_visited() inc_irg_block_visited()*/
 unsigned long get_Block_block_visited (ir_node *node);
 void      set_Block_block_visited (ir_node *node, unsigned long visit);
+
+/**
+ * Marks a block as dead but do not replace it with a Bad node.
+ * Dead blocks are removed in the con
+ */
 ir_node  *set_Block_dead(ir_node *block);
 int       is_Block_dead(const ir_node *block);
 
@@ -273,6 +311,11 @@ ir_node  *get_Block_cg_cfgpred(ir_node * node, int pos);
 /* frees the memory. */
 void      remove_Block_cg_cfgpred_arr(ir_node * node);
 
+/** returns the extended basic block a block belongs to */
+ir_extblk *get_Block_extbb(const ir_node *block);
+/** sets the extended basic block a block belongs to */
+void set_Block_extbb(ir_node *block, ir_extblk *extblk);
+
 /** Return the number of Keep alive node. */
 int  get_End_n_keepalives(ir_node *end);
 
@@ -290,6 +333,11 @@ void set_End_keepalive(ir_node *end, int pos, ir_node *ka);
    free_End() frees these data structures. */
 void free_End (ir_node *end);
 
+/** Return the target address of an IJmp */
+ir_node *get_IJmp_target(ir_node *ijmp);
+
+/** Sets the target address of an IJmp */
+void set_IJmp_target(ir_node *ijmp, ir_node *tgt);
 
 /* We distinguish three kinds of Cond nodes.  These can be distinguished
    by the mode of the selector operand and an internal flag of type cond_kind.
@@ -299,10 +347,10 @@ void free_End (ir_node *end);
    is recognized by the boolean selector.
    The switch Cond has as selector an unsigned integer.  It produces as result
    an n+1 Tuple (cf0, ... , cfn) of control flows.
-   We differ two flavours of this Cond.  The first, the dense Cond, passes
+   We differ two flavors of this Cond.  The first, the dense Cond, passes
    control along output i if the selector value is i, 0 <= i <= n.  If the
    selector value is >n it passes control along output n.
-   The second Cond flavor diffirences in the treatment of cases not specified in
+   The second Cond flavor differences in the treatment of cases not specified in
    the source program.  It magically knows about the existence of Proj nodes.
    It only passes control along output i, 0 <= i <= n, if a node Proj(Cond, i)
    exists.  Else it passes control along output n (even if this Proj does not
@@ -357,7 +405,7 @@ typedef enum {
   CNST_NULL     =  0, /**< The node is a const(0). */
   CNST_ONE      = +1, /**< The node is a const(1). */
   CNST_ALL_ONE  = -1, /**< The node is a const(11111...). */
-  CNST_OTHER    =  2, /**< The tarvel of the const has another value. */
+  CNST_OTHER    =  2, /**< The tarval of the const has another value. */
   CNST_SYMCONST =  3, /**< The node is symconst. */
   CNST_NO_CONST =  4  /**< The node is no const at all. */
 } cnst_classify_t;
@@ -397,8 +445,9 @@ typedef enum {
                           Type_or_id_p is entity *. */
 } symconst_kind;
 
-/** SymConst attributes
-    This union contains the symbolic information represented by the node  */
+/** SymConst attribute.
+ *
+ *  This union contains the symbolic information represented by the node.  */
 union symconst_symbol {
   type   *type_p;
   ident  *ident_p;
@@ -470,6 +519,7 @@ typedef enum {
                  an exception */
   pn_Call_max       = 5   /**< number of projections from a Call */
 } pn_Call;   /* Projection numbers for Call. */
+#define pn_Call_M pn_Call_M_regular
 
 ir_node *get_Call_mem (ir_node *node);
 void     set_Call_mem (ir_node *node, ir_node *mem);
@@ -602,7 +652,8 @@ void     set_Div_mem (ir_node *node, ir_node *mem);
 typedef enum {
   pn_Div_M,           /**< Memory result.    */
   pn_Div_X_except,    /**< Execution result if exception occurred. */
-  pn_Div_res          /**< Result of computation. */
+  pn_Div_res,         /**< Result of computation. */
+  pn_Div_max          /**< number of projections from a Div */
 } pn_Div;  /* Projection numbers for Div. */
 
 ir_node *get_Mod_left (ir_node *node);
@@ -667,18 +718,18 @@ typedef enum {
   pn_Cmp_Uge   = pn_Cmp_Uo|pn_Cmp_Eq|pn_Cmp_Gt, /**< unordered, greater or equal */
   pn_Cmp_Ne    = pn_Cmp_Uo|pn_Cmp_Lt|pn_Cmp_Gt, /**< unordered, less or greater = not equal */
   pn_Cmp_True  = 15                             /**< true */
-  /* not_mask = Leg*/   /* bits to flip to negate comparison * @@ hack for jni interface */
+  /* not_mask = Leg*/   /* bits to flip to negate comparison * @@ hack for JNI interface */
 } pn_Cmp;   /* Projection numbers for Cmp */
 /* #define not_mask pn_Cmp_Leg */
 
 /** returns the pnc name from an pnc constant */
 const char *get_pnc_string(int pnc);
 
-/** Calculates the negated pnc condition. */
-int         get_negated_pnc(int pnc);
+/** Calculates the negated (Complement(R)) pnc condition. */
+int         get_negated_pnc(int pnc, ir_mode *mode);
 
-/** Calculates the swapped pnc condition, i.e., "<" --> ">" */
-int         get_swapped_pnc(int pnc);
+/** Calculates the inversed (R^-1) pnc condition, i.e., "<" --> ">" */
+int         get_inversed_pnc(int pnc);
 
 ir_node *get_Cmp_left (ir_node *node);
 void     set_Cmp_left (ir_node *node, ir_node *left);
@@ -810,7 +861,7 @@ void           set_Store_volatility (ir_node *node, ent_volatility volatility);
  * Projection numbers for Alloc: use for Proj nodes!
  */
 typedef enum {
-  pn_Alloc_M,          /**< Memory result. */
+  pn_Alloc_M,         /**< Memory result. */
   pn_Alloc_X_except,  /**< Execution result if exception occurred. */
   pn_Alloc_res,       /**< Result of allocation. */
   pn_Alloc_max        /**< number of projections from an Alloc */
@@ -855,10 +906,10 @@ void      set_Sync_pred (ir_node *node, int pos, ir_node *pred);
 type     *get_Proj_type (ir_node *node);
 
 /** Return the predecessor of a Proj node. */
-ir_node  *get_Proj_pred (ir_node *node);
+ir_node  *get_Proj_pred (const ir_node *node);
 void      set_Proj_pred (ir_node *node, ir_node *pred);
 /** Return the projection number of a Proj node. */
-long      get_Proj_proj (ir_node *node);
+long      get_Proj_proj (const ir_node *node);
 void      set_Proj_proj (ir_node *node, long proj);
 
 ir_node **get_Tuple_preds_arr (ir_node *node);
@@ -899,11 +950,15 @@ void     set_Mux_true  (ir_node *node, ir_node *ir_true);
 ir_node *skip_Proj (ir_node *node);
 /** returns operand of node if node is a Id */
 ir_node *skip_Id  (ir_node *node);   /* Same as skip_nop. */
-/* returns corresponding operand of Tuple if node is a Proj from
+/** returns corresponding operand of Tuple if node is a Proj from
    a Tuple. */
 ir_node *skip_Tuple (ir_node *node);
 /** returns operand of node if node is a Cast */
 ir_node *skip_Cast  (ir_node *node);
+/** returns operand of node if node is a Confirm */
+ir_node *skip_Confirm  (ir_node *node);
+/** Skip all high-level Operations. */
+ir_node *skip_HighLevel(ir_node *node);
 /** returns true if irn is a Const node. */
 int                     is_Const(const ir_node *node);
 /** returns true if node is a Bad node. */
@@ -933,13 +988,34 @@ ir_node *get_fragile_op_mem(ir_node *node);
 
 /** Returns true if the operation is a forking control flow
  *  operation: Cond. */
-int is_forking_op(const ir_node *node);
+int is_irn_forking(const ir_node *node);
 
 /** Return the type associated with the value produced by n
  *  if the node remarks this type as it is the case for
  *  Cast, Const, SymConst and some Proj nodes. */
 type *get_irn_type(ir_node *n);
 
+/** Returns non-zero for constant-like nodes. */
+int is_irn_constlike(const ir_node *node);
+
+/**
+ * A type to express conditional jump predictions.
+ */
+typedef enum {
+  COND_JMP_PRED_NONE,        /**< No jump prediction. Default. */
+  COND_JMP_PRED_TRUE,        /**< The True case is predicted. */
+  COND_JMP_PRED_FALSE        /**< The False case is predicted. */
+} cond_jmp_predicate;
+
+/** Gets the string representation of the jump prediction .*/
+const char *get_cond_jmp_predicate_name(cond_jmp_predicate pred);
+
+/** Returns the conditional jump prediction of a Cond node. */
+cond_jmp_predicate get_Cond_jmp_pred(ir_node *cond);
+
+/** Sets a new conditional jump prediction. */
+void set_Cond_jmp_pred(ir_node *cond, cond_jmp_predicate pred);
+
 /**
  * Access custom node data.
  * The data must have been registered with
@@ -970,6 +1046,11 @@ type *get_irn_type(ir_node *n);
  */
 unsigned register_additional_node_data(unsigned size);
 
+/**
+ * Return a pointer to the node attributes.
+ * Needed for user-defined nodes.
+ */
+void *get_irn_generic_attr(ir_node *node);
 
 /*-----------------------------------------------------------------*/
 /** Debug aides                                                   **/
@@ -999,7 +1080,11 @@ void    dump_irn(ir_node *n);
 /** Output the firm kind of the node */
 #define DDMK(X)  printf("%s(l.%i) %s: %p\n",                 __MYFUNC__, __LINE__,  print_firm_kind(X), (void *)(X));
 /** Output information about a node */
-#define DDMN(X)  printf("%s(l.%i) %s%s: %ld (%p)\n",         __MYFUNC__, __LINE__,  get_irn_opname(X), get_mode_name(get_irn_mode(X)), get_irn_node_nr(X), (void *)(X))
+
+/*#define DDMN(X)  printf("%s(l.%i) %s%s: %ld (%p)\n",         __MYFUNC__, __LINE__,  get_irn_opname(X), get_mode_name(get_irn_mode(X)), get_irn_node_nr(X), (void *)(X))*/
+int dump_node_opcode(FILE *F, ir_node *n);
+#define DDMN(X)  do { printf("%s(l.%i) ", __MYFUNC__, __LINE__); dump_node_opcode(stdout, X); printf(": %ld (%p)\n", get_irn_node_nr(X), (void *)(X)); } while (0)
+
 /** Output information about a node and its block */
 #define DDMNB(X) printf("%s%s: %ld (in block %ld)\n", get_irn_opname(X),  get_mode_name(get_irn_mode(X)), get_irn_node_nr(X), get_irn_node_nr(get_nodes_block(X)))
 /** Output information about a type */