From 3ee41de347cf368cbc333441f75d1f62ed26a40a Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 4 Apr 2006 16:40:19 +0000 Subject: [PATCH] Implement access functions for machine nodes with machine operands --- ir/be/Makefile.in | 2 +- ir/be/bemachnode.c | 113 +++++++++++++++++++++++++++++++++++++++++++++ ir/be/bemachnode.h | 78 +++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 ir/be/bemachnode.c create mode 100644 ir/be/bemachnode.h diff --git a/ir/be/Makefile.in b/ir/be/Makefile.in index f24a47513..a97d29a6c 100644 --- a/ir/be/Makefile.in +++ b/ir/be/Makefile.in @@ -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 index 000000000..d9c05d08a --- /dev/null +++ b/ir/be/bemachnode.c @@ -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 index 000000000..64a61b566 --- /dev/null +++ b/ir/be/bemachnode.h @@ -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 */ -- 2.20.1