new access routine
[libfirm] / ir / ir / irnode.c
index 018670a..94cbf54 100644 (file)
@@ -19,7 +19,7 @@
 #include "irnode_t.h"
 #include "irgraph_t.h"
 #include "irmode_t.h"
-#include "typegmod_t.h"
+#include "typegmod.h"
 #include "array.h"
 #include "irbackedge_t.h"
 #include "irdump.h"
@@ -152,20 +152,32 @@ is_ir_node (void *thing) {
 
 /* returns the number of predecessors without the block predecessor. */
 INLINE int
-get_irn_arity (const ir_node *node) {
+get_irn_intra_arity (const ir_node *node) {
   assert(node);
-  if (interprocedural_view) { /* handle Filter and Block specially */
-    if (get_irn_opcode(node) == iro_Filter) {
-      assert(node->attr.filter.in_cg);
-      return ARR_LEN(node->attr.filter.in_cg) - 1;
-    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
-      return ARR_LEN(node->attr.block.in_cg) - 1;
-    }
-    /* else fall through */
-  }
   return ARR_LEN(node->in) - 1;
 }
 
+/* returns the number of predecessors without the block predecessor. */
+INLINE int
+get_irn_inter_arity (const ir_node *node) {
+  assert(node);
+  if (get_irn_opcode(node) == iro_Filter) {
+    assert(node->attr.filter.in_cg);
+    return ARR_LEN(node->attr.filter.in_cg) - 1;
+  } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
+    return ARR_LEN(node->attr.block.in_cg) - 1;
+  }
+  return get_irn_intra_arity(node);
+}
+
+/* returns the number of predecessors without the block predecessor. */
+INLINE int
+get_irn_arity (const ir_node *node) {
+  assert(node);
+  if (interprocedural_view) return get_irn_inter_arity(node);
+  return get_irn_intra_arity(node);
+}
+
 /* Returns the array with ins. This array is shifted with respect to the
    array accessed by get_irn_n: The block operand is at position 0 not -1.
    (@@@ This should be changed.)
@@ -212,6 +224,24 @@ set_irn_in (ir_node *node, int arity, ir_node **in) {
   memcpy((*arr) + 1, in, sizeof(ir_node *) * arity);
 }
 
+INLINE ir_node *
+get_irn_intra_n (ir_node *node, int n) {
+  return (node->in[n + 1] = skip_nop(node->in[n + 1]));
+}
+
+INLINE ir_node*
+get_irn_inter_n (ir_node *node, int n) {
+  /* handle Filter and Block specially */
+  if (get_irn_opcode(node) == iro_Filter) {
+    assert(node->attr.filter.in_cg);
+    return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1]));
+  } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
+    return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1]));
+  }
+
+  return get_irn_intra_n (node, n);
+}
+
 /* to iterate through the predecessors without touching the array */
 /* To iterate over the operands iterate from 0 to i < get_irn_arity(),
    to iterate includind the Block predecessor iterate from i = -1 to
@@ -219,24 +249,17 @@ set_irn_in (ir_node *node, int arity, ir_node **in) {
    If it is a block, the entry -1 is NULL. */
 INLINE ir_node *
 get_irn_n (ir_node *node, int n) {
-  /* debug @@@
+  /* debug @@@ */
   if (-1 > n || get_irn_arity(node) <= n) {
     printf("pos: %d, arity: %d ", n, get_irn_arity(node));
     DDMN(node);
-    } */
+    } /**/
   assert(node); assert(-1 <= n && n < get_irn_arity(node));
-  if (interprocedural_view) { /* handle Filter and Block specially */
-    if (get_irn_opcode(node) == iro_Filter) {
-      assert(node->attr.filter.in_cg);
-      return (node->attr.filter.in_cg[n + 1] = skip_nop(node->attr.filter.in_cg[n + 1]));
-    } else if (get_irn_opcode(node) == iro_Block && node->attr.block.in_cg) {
-      return (node->attr.block.in_cg[n + 1] = skip_nop(node->attr.block.in_cg[n + 1]));
-    }
-    /* else fall through */
-  }
-  return (node->in[n + 1] = skip_nop(node->in[n + 1]));
+  if (interprocedural_view)  return get_irn_inter_n (node, n);
+  return get_irn_intra_n (node, n);
 }
 
+
 INLINE void
 set_irn_n (ir_node *node, int n, ir_node *in) {
   assert(node && -1 <= n && n < get_irn_arity(node));
@@ -283,6 +306,13 @@ get_irn_modecode (const ir_node *node)
   return node->mode->code;
 }
 
+/** Gets the string representation of the mode .*/
+INLINE const char *
+get_irn_modename (const ir_node *node)
+{
+  assert(node);
+  return get_mode_name(node->mode);
+}
 
 INLINE ident *
 get_irn_modeident (const ir_node *node)
@@ -384,11 +414,11 @@ get_irn_node_nr(const ir_node *node) {
 #ifdef DEBUG_libfirm
   return node->node_nr;
 #else
-  return 0;
+  return (long)&node;
 #endif
 }
 
-INLINE tarval *
+INLINE const_attr
 get_irn_const_attr (ir_node *node)
 {
   assert (node->op == op_Const);
@@ -466,6 +496,42 @@ set_nodes_Block (ir_node *node, ir_node *block) {
   set_irn_n(node, -1, block);
 }
 
+/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
+ * from Start.  If so returns frame type, else Null. */
+type *is_frame_pointer(ir_node *n) {
+  if ((get_irn_op(n) == op_Proj) &&
+      (get_Proj_proj(n) == pn_Start_P_frame_base)) {
+    ir_node *start = get_Proj_pred(n);
+    if (get_irn_op(start) == op_Start) {
+      return get_irg_frame_type(get_irn_irg(start));
+    }
+  }
+  return NULL;
+}
+
+/* Test whether arbitrary node is globals pointer, i.e. Proj(pn_Start_P_globals)
+ * from Start.  If so returns global type, else Null. */
+type *is_globals_pointer(ir_node *n) {
+  if ((get_irn_op(n) == op_Proj) &&
+      (get_Proj_proj(n) == pn_Start_P_globals)) {
+    ir_node *start = get_Proj_pred(n);
+    if (get_irn_op(start) == op_Start) {
+      return get_glob_type();
+    }
+  }
+  return NULL;
+}
+
+/* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base)
+ * from Start.  If so returns 1, else 0. */
+int is_value_arg_pointer(ir_node *n) {
+  if ((get_irn_op(n) == op_Proj) &&
+      (get_Proj_proj(n) == pn_Start_P_value_arg_base) &&
+      (get_irn_op(get_Proj_pred(n)) == op_Start))
+    return 1;
+  return 0;
+}
+
 /* Returns an array with the predecessors of the Block. Depending on
    the implementation of the graph datastructure this can be a copy of
    the internal representation of predecessors as well as the internal
@@ -551,7 +617,7 @@ set_Block_graph_arr (ir_node *node, int pos, ir_node *value) {
   node->attr.block.graph_arr[pos+1] = value;
 }
 
-/* handler handling for Blocks */
+/* handler handling for Blocks * /
 void
 set_Block_handler (ir_node *block, ir_node *handler)  {
   assert ((block->op == op_Block));
@@ -565,7 +631,7 @@ get_Block_handler (ir_node *block) {
   return (block->attr.block.handler_entry);
 }
 
-/* handler handling for Nodes */
+/ * handler handling for Nodes * /
 void
 set_Node_handler (ir_node *node, ir_node *handler) {
   set_Block_handler (get_nodes_Block (node), handler);
@@ -576,7 +642,7 @@ get_Node_handler (ir_node *node) {
   return (get_Block_handler (get_nodes_Block (node)));
 }
 
-/* exc_t handling for Blocks */
+/ * exc_t handling for Blocks * /
 void set_Block_exc (ir_node *block, exc_t exc) {
   assert ((block->op == op_Block));
   block->attr.block.exc = exc;
@@ -584,11 +650,10 @@ void set_Block_exc (ir_node *block, exc_t exc) {
 
 exc_t get_Block_exc (ir_node *block) {
   assert ((block->op == op_Block));
-
   return (block->attr.block.exc);
 }
 
-/* exc_t handling for Nodes */
+/ * exc_t handling for Nodes * /
 void set_Node_exc (ir_node *node, exc_t exc) {
   set_Block_exc (get_nodes_Block (node), exc);
 }
@@ -596,6 +661,7 @@ void set_Node_exc (ir_node *node, exc_t exc) {
 exc_t get_Node_exc (ir_node *node) {
   return (get_Block_exc (get_nodes_Block (node)));
 }
+*/
 
 void set_Block_cg_cfgpred_arr(ir_node * node, int arity, ir_node ** in) {
   assert(node->op == op_Block);
@@ -645,15 +711,15 @@ void remove_Block_cg_cfgpred_arr(ir_node * node) {
 /* Start references the irg it is in. */
 INLINE ir_graph *
 get_Start_irg(ir_node *node) {
-  assert(node->op == op_Start);
-  return node->attr.start.irg;
+  return get_irn_irg(node);
 }
 
 INLINE void
 set_Start_irg(ir_node *node, ir_graph *irg) {
   assert(node->op == op_Start);
   assert(is_ir_graph(irg));
-  node->attr.start.irg = irg;
+  assert(0 && " Why set irg? ");
+  //node->attr.start.irg = irg;
 }
 
 INLINE int
@@ -683,19 +749,18 @@ set_End_keepalive(ir_node *end, int pos, ir_node *ka) {
 INLINE void
 free_End (ir_node *end) {
   assert (end->op == op_End);
+  end->kind = k_BAD;
   /* DEL_ARR_F(end->in);   GL @@@ tut nicht ! */
   end->in = NULL;   /* @@@ make sure we get an error if we use the
                       in array afterwards ... */
 }
 
-ir_graph *get_EndReg_irg (const ir_node *end) {
-  assert (end->op == op_EndReg);
-  return end->attr.end.irg;
+ir_graph *get_EndReg_irg (ir_node *end) {
+  return get_irn_irg(end);
 }
 
-ir_graph *get_EndExcept_irg  (const ir_node *end) {
-  assert (end->op == op_EndReg);
-  return end->attr.end.irg;
+ir_graph *get_EndExcept_irg  (ir_node *end) {
+  return get_irn_irg(end);
 }
 
 /*
@@ -827,15 +892,41 @@ set_Raise_exo_ptr (ir_node *node, ir_node *exo_ptr) {
 
 INLINE tarval *get_Const_tarval (ir_node *node) {
   assert (node->op == op_Const);
-  return get_irn_const_attr(node);
+  return node->attr.con.tv;
 }
 
 INLINE void
 set_Const_tarval (ir_node *node, tarval *con) {
   assert (node->op == op_Const);
-  node->attr.con = con;
+  node->attr.con.tv = con;
 }
 
+
+/* The source language type.  Must be an atomic type.  Mode of type must
+   be mode of node. For tarvals from entities type must be pointer to
+   entity type. */
+INLINE type *
+get_Const_type (ir_node *node) {
+  assert (node->op == op_Const);
+  return node->attr.con.tp;
+}
+
+INLINE void
+set_Const_type (ir_node *node, type *tp) {
+  assert (node->op == op_Const);
+  if (tp != unknown_type) {
+    assert (is_atomic_type(tp));
+    assert (get_type_mode(tp) == get_irn_mode(node));
+    assert (!tarval_is_entity(get_Const_tarval(node)) ||
+           (is_pointer_type(tp) &&
+            (get_pointer_points_to_type(tp) ==
+             get_entity_type(get_tarval_entity(get_Const_tarval(node))))));
+  }
+
+  node->attr.con.tp = tp;
+}
+
+
 INLINE symconst_kind
 get_SymConst_kind (const ir_node *node) {
   assert (node->op == op_SymConst);
@@ -1072,6 +1163,10 @@ set_Call_type (ir_node *node, type *tp) {
   node->attr.call.cld_tp = tp;
 }
 
+int Call_has_callees(ir_node *node) {
+  return (node->attr.call.callee_arr != NULL);
+}
+
 int get_Call_n_callees(ir_node * node) {
   assert(node->op == op_Call && node->attr.call.callee_arr);
   return ARR_LEN(node->attr.call.callee_arr);
@@ -1104,8 +1199,7 @@ void set_CallBegin_ptr (ir_node *node, ir_node *ptr) {
   set_irn_n(node, 0, ptr);
 }
 ir_graph * get_CallBegin_irg (ir_node *node) {
-  assert(node->op == op_CallBegin);
-  return node->attr.callbegin.irg;
+  return get_irn_irg(node);
 }
 ir_node * get_CallBegin_call (ir_node *node) {
   assert(node->op == op_CallBegin);
@@ -1807,6 +1901,11 @@ set_binop_right (ir_node *node, ir_node *right) {
   };
 }
 
+INLINE int is_Phi (ir_node *n) {
+  assert(n);
+  return ((get_irn_op(n) == op_Phi) ||
+         (get_irn_op(n) == op_Filter && interprocedural_view));
+}
 
 INLINE ir_node **
 get_Phi_preds_arr (ir_node *node) {
@@ -1816,7 +1915,7 @@ get_Phi_preds_arr (ir_node *node) {
 
 INLINE int
 get_Phi_n_preds (ir_node *node) {
-  assert (node->op == op_Phi);
+  assert (is_Phi(node));
   return (get_irn_arity(node));
 }
 
@@ -1828,13 +1927,13 @@ INLINE void set_Phi_n_preds (ir_node *node, int n_preds) {
 
 INLINE ir_node *
 get_Phi_pred (ir_node *node, int pos) {
-  assert (node->op == op_Phi);
+  assert (is_Phi(node));
   return get_irn_n(node, pos);
 }
 
 INLINE void
 set_Phi_pred (ir_node *node, int pos, ir_node *pred) {
-  assert (node->op == op_Phi);
+  assert (is_Phi(node));
   set_irn_n(node, pos, pred);
 }
 
@@ -2099,6 +2198,31 @@ set_Id_pred (ir_node *node, ir_node *pred) {
   set_irn_n(node, 0, pred);
 }
 
+INLINE ir_node *get_Confirm_value (ir_node *node) {
+  assert (node->op == op_Confirm);
+  return get_irn_n(node, 0);
+}
+INLINE void     set_Confirm_value (ir_node *node, ir_node *value) {
+  assert (node->op == op_Confirm);
+  set_irn_n(node, 0, value);
+}
+INLINE ir_node *get_Confirm_bound (ir_node *node) {
+  assert (node->op == op_Confirm);
+  return get_irn_n(node, 1);
+}
+INLINE void     set_Confirm_bound (ir_node *node, ir_node *bound) {
+  assert (node->op == op_Confirm);
+  set_irn_n(node, 0, bound);
+}
+INLINE pn_Cmp   get_Confirm_cmp   (ir_node *node) {
+  assert (node->op == op_Confirm);
+  return node->attr.confirm_cmp;
+}
+INLINE void     set_Confirm_cmp   (ir_node *node, pn_Cmp cmp) {
+  assert (node->op == op_Confirm);
+  node->attr.confirm_cmp = cmp;
+}
+
 
 INLINE ir_node *
 get_Filter_pred (ir_node *node) {
@@ -2155,17 +2279,10 @@ ir_node *get_Filter_cg_pred(ir_node *node, int pos) {
 
 INLINE ir_graph *
 get_irn_irg(ir_node *node) {
-  if (get_irn_op(node) == op_CallBegin) {
-    return node->attr.callbegin.irg;
-  } else if (get_irn_op(node) == op_EndReg ||
-            get_irn_op(node) == op_EndExcept) {
-    return node->attr.end.irg;
-  } else if (get_irn_op(node) == op_Start) {
-    return node->attr.start.irg;
-  } else {
-    assert(0 && "no irg attr");
-    return NULL;
-  }
+  if (get_irn_op(node) != op_Block)
+    node = get_nodes_block(node);
+  assert(get_irn_op(node) == op_Block);
+  return node->attr.block.irg;
 }
 
 
@@ -2253,6 +2370,13 @@ is_Block (ir_node *node) {
   return (get_irn_opcode(node) == iro_Block);
 }
 
+/* returns true if node is a Unknown node. */
+INLINE int
+is_Unknown (ir_node *node) {
+  assert(node);
+  return (get_irn_opcode(node) == iro_Unknown);
+}
+
 INLINE int
 is_Proj (const ir_node *node) {
   assert(node);
@@ -2273,17 +2397,7 @@ INLINE int is_ip_cfop(ir_node *node) {
 }
 
 ir_graph *get_ip_cfop_irg(ir_node *n) {
-  switch (get_irn_opcode(n)) {
-  case iro_EndReg:
-    return get_EndReg_irg(n);
-  case iro_EndExcept:
-    return get_EndExcept_irg(n);
-  case iro_CallBegin:
-    return get_CallBegin_irg(n);
-  default:
-    assert(is_ip_cfop(n));
-  }
-  return NULL; /* should never be reached */
+  return get_irn_irg(n);
 }
 
 /* Returns true if the operation can change the control flow because