*** empty log message ***
[libfirm] / ir / ir / irnode.c
index fcae463..a9fccc2 100644 (file)
@@ -5,10 +5,22 @@
 **
 */
 
-#include "irnode.h"
-//#include "irnode2.h"
+#include "irnode_t.h"
+#include "irgraph_t.h"
+#include "ident_t.h"
+#include "irmode_t.h"
 #include "array.h"
 
+#ifdef DEBUG_libfirm
+#include "irprog.h"
+#endif
+
+/* some constants fixing the positions of nodes predecessors
+   in the in array */
+#define CALL_PARAM_OFFSET 2
+#define SEL_INDEX_OFFSET 2
+#define RETURN_RESULT_OFFSET 1  /* mem is not a result */
+
 static char *pnc_name_arr [] = {"False", "Eq", "Lt", "Le",
                                "Gt", "Ge", "Lg", "Leg", "Uo",
                                "Ue", "Ul", "Ule", "Ug", "Uge",
@@ -47,8 +59,6 @@ static char *pns_name_arr [] = {"initial_exec", "global_store",
 
 static char *symconst_name_arr [] = {"type_tag", "size", "linkage_ptr_info"};
 
-
-
 void
 init_irnode (void)
 {
@@ -70,7 +80,7 @@ new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
   res->kind = k_ir_node;
   res->op = op;
   res->mode = mode;
-  res->visit = 0;
+  res->visited = 0;
   res->link = NULL;
   if (arity < 0) {
     res->in = NEW_ARR_F (ir_node *, 1);
@@ -79,9 +89,21 @@ new_ir_node (ir_graph *irg, ir_node *block, ir_op *op, ir_mode *mode,
     memcpy (&res->in[1], in, sizeof (ir_node *) * arity);
   }
   res->in[0] = block;
+
+#ifdef DEBUG_libfirm
+  res->node_nr = get_irp_new_node_nr();
+#endif
+
   return res;
 }
 
+/* Copies all attributes stored in the old node to the new node.
+   Assumes both have the same opcode and sufficient size. */
+void
+copy_attrs (ir_node *old, ir_node *new) {
+  assert (get_irn_opcode(old) == get_irn_opcode(new));
+  memcpy (&new->attr, &old->attr, get_op_attr_size(get_irn_op(old)));
+}
 
 /* IR-Nodes with attributes */
 int
@@ -95,7 +117,7 @@ ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
     return printed;
   }
 
-  XPF1 ("%I", get_irn_op(np)->name);
+  XPF1 ("%I", get_irn_opident(np));
 
   switch (get_irn_opcode (np)) {       /* node label */
   case iro_Const:
@@ -144,12 +166,16 @@ ir_node_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
 inline int
 get_irn_arity (ir_node *node)
 {
-  // printf("called for node %s\n", ID_TO_STR(node->op->name));
-  // if (get_irn_opcode(node) == iro_Block) return (ARR_LEN((node)->in));
+  assert(node);
   return (ARR_LEN((node)->in)-1);
 }
 
-/* returns the array with ins */
+/* 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.)
+   The order of the predecessors in this array is not guaranteed, except that
+   lists of operands as predecessors of Block or arguments of a Call are
+   consecutive. */
 inline ir_node **
 get_irn_in (ir_node *node)
 {
@@ -161,12 +187,12 @@ get_irn_in (ir_node *node)
 /* To iterate over the operands iterate from 0 to i < get_irn_arity(),
    to iterate includind the Block predecessor iterate from i = -1 to
    i < get_irn_arity.
-   Don't know how to iterate if it is a block ?? */
+   If it is a block, the entry -1 is NULL. */
 inline ir_node *
 get_irn_n (ir_node *node, int n)
 {
   assert (node);
-  // assert (get_irn_arity (node) > n);
+  assert (get_irn_arity (node) > n);
   return skip_nop(node->in[n+1]);
 }
 
@@ -192,6 +218,14 @@ get_irn_modecode (ir_node *node)
   return node->mode->code;
 }
 
+
+inline ident *
+get_irn_modeident (ir_node *node)
+{
+  assert(node);
+  return node->mode->name;
+}
+
 inline ir_op *
 get_irn_op (ir_node *node)
 {
@@ -214,6 +248,33 @@ get_irn_opcode (ir_node *node)
   return node->op->code;
 }
 
+inline const char *
+get_irn_opname (ir_node *node)
+{
+  assert(node);
+  return id_to_str(node->op->name);
+}
+
+inline ident *
+get_irn_opident (ir_node *node)
+{
+  assert(node);
+  return node->op->name;
+}
+
+inline unsigned long
+get_irn_visited (ir_node *node)
+{
+  assert (node);
+  return node->visited;
+}
+
+inline void
+set_irn_visited (ir_node *node, unsigned long visited)
+{
+  assert (node);
+  node->visited = visited;
+}
 inline void
 set_irn_link (ir_node *node, ir_node *link) {
   assert (node);
@@ -226,6 +287,15 @@ get_irn_link (ir_node *node) {
   return node->link;
 }
 
+#ifdef DEBUG_libfirm
+/* Outputs a unique number for this node */
+inline long
+get_irn_node_nr(ir_node *node) {
+  assert(node);
+  return node->node_nr;
+}
+#endif
+
 inline tarval *
 get_irn_const_attr (ir_node *node)
 {
@@ -304,6 +374,18 @@ set_nodes_Block (ir_node *node, ir_node *block) {
   set_irn_n(node, -1, block);
 }
 
+/* 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
+   array itself. Therefore writing to this array might obstruct the ir. */
+inline ir_node **
+get_Block_cfgpred_arr (ir_node *node)
+{
+  assert ((node->op == op_Block));
+  return (ir_node **)&(get_irn_in(node)[1]);
+}
+
+
 inline int
 get_Block_n_cfgpreds (ir_node *node) {
   assert ((node->op == op_Block));
@@ -341,15 +423,15 @@ set_Block_matured (ir_node *node, bool matured) {
   node->attr.block.matured = matured;
 }
 inline unsigned long
-get_Block_block_visit (ir_node *node) {
+get_Block_block_visited (ir_node *node) {
   assert (node->op == op_Block);
-  return node->attr.block.block_visit;
+  return node->attr.block.block_visited;
 }
 
 inline void
-set_Block_block_visit (ir_node *node, unsigned long visit) {
+set_Block_block_visited (ir_node *node, unsigned long visit) {
   assert (node->op == op_Block);
-  node->attr.block.block_visit = visit;
+  node->attr.block.block_visited = visit;
 }
 
 inline ir_node *
@@ -378,7 +460,7 @@ set_Cond_selector (ir_node *node, ir_node *selector) {
 
 inline ir_node *
 get_Return_mem (ir_node *node) {
-  assert (node->op == op_Cond);
+  assert (node->op == op_Return);
   return get_irn_n(node, 0);
 }
 
@@ -388,10 +470,20 @@ set_Return_mem (ir_node *node, ir_node *mem) {
   set_irn_n(node, 0, mem);
 }
 
+inline ir_node **
+get_Return_res_arr (ir_node *node)
+{
+  assert ((node->op == op_Return));
+  if (get_Return_n_res(node) > 0)
+    return (ir_node **)&(get_irn_in(node)[1 + RETURN_RESULT_OFFSET]);
+  else
+    return NULL;
+}
+
 inline int
 get_Return_n_res (ir_node *node) {
   assert (node->op == op_Return);
-  return (get_irn_arity(node) - 1);
+  return (get_irn_arity(node) - RETURN_RESULT_OFFSET);
 }
 
 /*
@@ -404,13 +496,14 @@ set_Return_n_res (ir_node *node, int results) {
 inline ir_node *
 get_Return_res (ir_node *node, int pos) {
   assert (node->op == op_Return);
-  return get_irn_n(node, pos+1);
+  assert (get_Return_n_res(node) > pos);
+  return get_irn_n(node, pos + RETURN_RESULT_OFFSET);
 }
 
 inline void
 set_Return_res (ir_node *node, int pos, ir_node *res){
-  assert (node->op == op_Raise);
-  set_irn_n(node, pos+1, res);
+  assert (node->op == op_Return);
+  set_irn_n(node, pos + RETURN_RESULT_OFFSET, res);
 }
 
 inline ir_node *
@@ -481,8 +574,6 @@ get_SymConst_ptrinfo (ir_node *node) {
   assert (   (node->op == op_SymConst)
           && (get_SymConst_kind(node) == linkage_ptr_info));
   return node->attr.i.tori.ptrinfo;
-
-
 }
 
 inline void
@@ -492,6 +583,18 @@ set_SymConst_ptrinfo (ir_node *node, ident *ptrinfo) {
   node->attr.i.tori.ptrinfo = ptrinfo;
 }
 
+inline type_or_id_p
+get_SymConst_type_or_id (ir_node *node) {
+  assert (node->op == op_SymConst);
+  return &(node->attr.i.tori);
+}
+
+inline void
+set_SymConst_type_or_id (ir_node *node, type_or_id_p tori) {
+  assert (node->op == op_SymConst);
+  memcpy (&(node->attr.i.tori), tori, sizeof(type_or_id));
+}
+
 inline ir_node *
 get_Sel_mem (ir_node *node) {
   assert (node->op == op_Sel);
@@ -516,10 +619,20 @@ set_Sel_ptr (ir_node *node, ir_node *ptr) {
   set_irn_n(node, 1, ptr);
 }
 
+inline ir_node **
+get_Sel_index_arr (ir_node *node)
+{
+  assert ((node->op == op_Sel));
+  if (get_Sel_n_index(node) > 0)
+    return (ir_node **)& get_irn_in(node)[SEL_INDEX_OFFSET + 1];
+  else
+    return NULL;
+}
+
 inline int
 get_Sel_n_index (ir_node *node) {
   assert (node->op == op_Sel);
-  return (get_irn_arity(node) - 2);
+  return (get_irn_arity(node) - SEL_INDEX_OFFSET);
 }
 
 /*
@@ -532,13 +645,13 @@ set_Sel_n_index (ir_node *node, int n_index) {
 inline ir_node *
 get_Sel_index (ir_node *node, int pos) {
   assert (node->op == op_Sel);
-  return get_irn_n(node, pos+2);
+  return get_irn_n(node, pos + SEL_INDEX_OFFSET);
 }
 
 inline void
 set_Sel_index (ir_node *node, int pos, ir_node *index) {
   assert (node->op == op_Sel);
-  set_irn_n(node, pos+2, index);
+  set_irn_n(node, pos + SEL_INDEX_OFFSET, index);
 }
 
 inline entity *
@@ -553,14 +666,14 @@ set_Sel_entity (ir_node *node, entity *ent) {
   node->attr.s.ent = ent;
 }
 
-inline linkage_type *
+inline linkage_type
 get_Sel_linkage_type (ir_node *node) {
   assert (node->op == op_Sel);
   return node->attr.s.ltyp;
 }
 
 inline void
-set_Sel_linkage_type (ir_node *node, linkage_type *lt) {
+set_Sel_linkage_type (ir_node *node, linkage_type lt) {
   assert (node->op == op_Sel);
   node->attr.s.ltyp = lt;
 }
@@ -589,10 +702,21 @@ set_Call_ptr (ir_node *node, ir_node *ptr) {
   set_irn_n(node, 1, ptr);
 }
 
+inline ir_node **
+get_Call_param_arr (ir_node *node) {
+  assert (node->op == op_Call);
+  return (ir_node **)&get_irn_in(node)[CALL_PARAM_OFFSET + 1];
+}
+
 inline int
-get_Call_arity (ir_node *node) {
+get_Call_n_params (ir_node *node)  {
   assert (node->op == op_Call);
-  return (get_irn_arity(node) - 2);
+  return (get_irn_arity(node) - CALL_PARAM_OFFSET);
+}
+
+inline int
+get_Call_arity (ir_node *node) {
+  return get_Call_n_params(node);
 }
 
 /* inline void
@@ -604,13 +728,13 @@ set_Call_arity (ir_node *node, ir_node *arity) {
 inline ir_node *
 get_Call_param (ir_node *node, int pos) {
   assert (node->op == op_Call);
-  return get_irn_n(node, pos+1);
+  return get_irn_n(node, pos + CALL_PARAM_OFFSET);
 }
 
 inline void
 set_Call_param (ir_node *node, int pos, ir_node *param) {
   assert (node->op == op_Call);
-  set_irn_n(node, pos+1, param);
+  set_irn_n(node, pos + CALL_PARAM_OFFSET, param);
 }
 
 inline type_method *
@@ -1302,6 +1426,12 @@ set_Conv_op (ir_node *node, ir_node *op) {
   set_irn_n(node, 0, op);
 }
 
+inline ir_node **
+get_Phi_preds_arr (ir_node *node) {
+  assert (node->op == op_Phi);
+  return (ir_node **)&(get_irn_in(node)[1]);
+}
+
 inline int
 get_Phi_n_preds (ir_node *node) {
   assert (node->op == op_Phi);
@@ -1406,7 +1536,7 @@ get_Alloc_size (ir_node *node) {
 }
 
 inline void
-set_Allco_size (ir_node *node, ir_node *size) {
+set_Alloc_size (ir_node *node, ir_node *size) {
   assert (node->op == op_Alloc);
   set_irn_n(node, 1, size);
 }
@@ -1484,6 +1614,12 @@ set_Free_type (ir_node *node, type *type) {
   node->attr.f = type;
 }
 
+inline ir_node **
+get_Sync_preds_arr (ir_node *node) {
+  assert (node->op == op_Sync);
+  return (ir_node **)&(get_irn_in(node)[1]);
+}
+
 inline int
 get_Sync_n_preds (ir_node *node) {
   assert (node->op == op_Sync);
@@ -1533,6 +1669,12 @@ set_Proj_proj (ir_node *node, long proj) {
   node->attr.proj = proj;
 }
 
+inline ir_node **
+get_Tuple_preds_arr (ir_node *node) {
+  assert (node->op == op_Tuple);
+  return (ir_node **)&(get_irn_in(node)[1]);
+}
+
 inline int
 get_Tuple_n_preds (ir_node *node) {
   assert (node->op == op_Tuple);
@@ -1587,8 +1729,12 @@ skip_Proj (ir_node *node) {
 inline ir_node *
 skip_nop (ir_node *node) {
   /* don't assert node !!! */
-  if (node && (node->op == op_Id)) {
-    return get_Id_pred(node);
+
+  if (node && (node->op == op_Id) && (node != get_Id_pred(node))) {
+    /* Don't use get_Id_pred:  We get into an endless loop for
+       self-referencing Ids. */
+    assert (get_irn_arity (node) > 0);
+    return node->in[0+1];
   } else {
     return node;
   }