Implement access functions for machine nodes with machine operands
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 4 Apr 2006 16:40:19 +0000 (16:40 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Tue, 4 Apr 2006 16:40:19 +0000 (16:40 +0000)
ir/be/Makefile.in
ir/be/bemachnode.c [new file with mode: 0644]
ir/be/bemachnode.h [new file with mode: 0644]

index f24a475..a97d29a 100644 (file)
@@ -28,7 +28,7 @@ SOURCES +=    Makefile.in besched.h belistsched.h belistsched.c \
        bechordal_draw.h beirgmod.c beirgmod.h benode.c benode_t.h \
        bessadestr.c beifg_std.c bespill.c bespillbelady.c bespillilp.c beuses.c \
        belower.c belower.h beraextern.c beabi.c beabi.h beabi_t.h \
-       benodesets.c benodesets.h
+       benodesets.c benodesets.h bemachnode.c bemachnode.h
 
 
 include $(topdir)/MakeRules
diff --git a/ir/be/bemachnode.c b/ir/be/bemachnode.c
new file mode 100644 (file)
index 0000000..d9c05d0
--- /dev/null
@@ -0,0 +1,113 @@
+#include "bemachnode.h"
+#include "irnode_t.h"
+
+typedef ir_node *** mirn_handle;
+
+/** Helper: fills in the array for machine ops */
+static int fill_arr(ir_node *op, mirn_handle res) {
+       ir_node **ins = get_irn_in(op);
+       int i, j, l = ARR_LEN(ins);
+
+       for (i = j = 0; i <= l; ++i) {
+               if (is_irn_machine_operand(ins[i]))
+                       j += fill_arr(ins[i], &res[j]);
+               else
+                       res[j++] = &ins[i];
+       }
+       return j;
+}
+
+/*
+ * Returns the machine handle for a machine node with machine operands.
+ * The order of the predecessors in this handle is not guaranteed, except that
+ * lists of operands as predecessors of Block or arguments of a Call are
+ * consecutive.
+ */
+mirn_handle get_mirn_in(ir_node *n) {
+       ir_node **ins = get_irn_in(n);
+       mirn_handle res = NULL;
+       int i, j, l = ARR_LEN(ins);
+       int lr = l + 8;
+
+       res = NEW_ARR_F(ir_node **, lr);
+
+       for (i = j = 0; i <= l; ++i) {
+               if (is_irn_machine_operand(ins[i]))
+                       j += fill_arr(ins[i], &res[j]);
+               else
+                       res[j++] = &ins[i];
+       }
+
+       assert(j > lr && "to many machine predecessors");
+
+       return res;
+}
+
+/* Frees a machine handle. */
+void free_mirn_in(mirn_handle h) {
+       DEL_ARR_F(h);
+}
+
+/* Get the pos-th predecessor of a machine node represented by it's
+    handle. */
+ir_node *get_mirn_n(mirn_handle h, int pos) {
+       assert(-1 <= pos && pos < ARR_LEN(h) - 1);
+       return *(h[pos + 1]);
+}
+
+/* Get the pos-th predecessor of a machine node. */
+ir_node *_get_mirn_n(ir_node *n, int pos) {
+       mirn_handle h = get_mirn_in(n);
+       ir_node *res = get_mirn_n(h, pos);
+       free_mirn_in(h);
+       return res;
+}
+
+/* Set the pos-th predecessor of a machine node represented by it's
+    handle. */
+void set_mirn_n(mirn_handle h, int pos, ir_node *n) {
+       assert(-1 <= pos && pos < ARR_LEN(h) - 1);
+       *(h[pos + 1]) = n;
+}
+
+/* Set the pos-th predecessor of a machine node. */
+void _set_mirn_n(ir_node *irn, int pos, ir_node *n) {
+       mirn_handle h = get_mirn_in(irn);
+       set_mirn_n(h, pos, n);
+       free_mirn_in(h);
+}
+
+/* Returns the arity of a machine node represented by it's
+    handle. */
+int get_mirn_arity(mirn_handle h) {
+       return ARR_LEN(h) - 1;
+}
+
+/** Helper: calculate the arity for a machine ops */
+static int arrity_of_op(ir_node *op) {
+       ir_node **ins = get_irn_in(op);
+       int i, j, l = ARR_LEN(ins);
+
+       for (i = j = 0; i <= l; ++i) {
+               if (is_irn_machine_operand(ins[i]))
+                       j += arrity_of_op(ins[i]);
+               else
+                       ++j;
+       }
+       return j;
+}
+
+/* Returns the arity of a machine node. */
+int _get_mirn_arity(ir_node *n) {
+       ir_node **ins = get_irn_in(n);
+       int i, j, l = ARR_LEN(ins);
+
+       for (i = j = 0; i <= l; ++i) {
+               if (is_irn_machine_operand(ins[i]))
+                       j += arrity_of_op(ins[i]);
+               else
+                       ++j;
+       }
+
+       return j;
+}
diff --git a/ir/be/bemachnode.h b/ir/be/bemachnode.h
new file mode 100644 (file)
index 0000000..64a61b5
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * Support for machine nodes with machine operands.
+ *
+ * @author Michael Beck
+ */
+#ifndef _BEMACHNODES_H
+#define _BEMACHNODES_H
+
+#include "firm_types.h"
+
+/*
+ * Machine nodes can have machine operands as inputs.
+ * Machine operands are trees of other machine operands.
+ * The leafs of machine operands are normal Firm nodes
+ * or a machine operand with arity 0.
+ *
+ * The arity of a machine node is the number of leafs
+ * that are NOT machine operands.
+ *
+ * For instance Add(x, Const) have the arity 1 if Const is a
+ * machine operand, Add(x, ADR(b, i)) have arity 3.
+ *
+ * We simulate the the normal concept of get_irn_n/set_irn_n.
+ * Instead of the node machine handle are used which are just
+ * caches for the leaf positions of a machine node.
+ * This means, it is only possible to manipulate the leafs!
+ * Do not mix _mirn_ and _irn_ calls or terrible things can happen :-)
+ *
+ * Note further that currently the number of ins for a machine
+ * instruction is limited to 8 + arity of Firm node which means
+ * up to 8 registers can be added due to machine operands.
+ *
+ * Moreover machine handles must be destroyed yet...
+ *
+ * The convenience functions create the handle and drop it at the end.
+ * as operands are seldom, they have a complexity of O(#predecessors)
+ * which is near to O(1) for most node but use them seldom ...
+ */
+
+/**
+ * The machine handle. A cache to access and set
+ * the predecessors (leafs) of a machine node.
+ */
+typedef ir_node *** mirn_handle;
+
+/**
+ * Returns the machine handle for a machine node with machine operands.
+ * The order of the predecessors in this handle is not guaranteed, except that
+ * lists of operands as predecessors of Block or arguments of a Call are
+ * consecutive.
+ */
+mirn_handle get_mirn_in(ir_node *n);
+
+/** Frees a machine handle. */
+void free_mirn_in(mirn_handle h);
+
+/** Get the pos-th predecessor of a machine node represented by it's
+    handle.. */
+ir_node *get_mirn_n(mirn_handle h, int pos);
+
+/** Convenience: Get the pos-th predecessor of a machine node. */
+ir_node *_get_mirn_n(ir_node *n, int pos);
+
+/** Set the n-th predecessor of a machine node represented by it's
+    handle.. */
+void set_mirn_n(mirn_handle h, int pos, ir_node *n);
+
+/* Convenience: Set the pos-th predecessor of a machine node. */
+void _set_mirn_n(ir_node *irn, int pos, ir_node *n);
+
+/** Returns the arity (in terms of inputs) of a machine node represented by it's
+    handle. */
+int get_mirn_arity(mirn_handle h);
+
+/* Convenience: Returns the arity of a machine node. */
+int _get_mirn_arity(ir_node *n);
+
+#endif /* _BEMACHNODES_H */