Commit 07ce9818 authored by Matthias Braun's avatar Matthias Braun
Browse files

save input requirements in be_info without complicated callback

[r27995]
parent 9f018140
......@@ -94,33 +94,6 @@ TEMPLATE_attr_t *get_TEMPLATE_attr(ir_node *node)
return (TEMPLATE_attr_t *)get_irn_generic_attr(node);
}
/**
* Returns the argument register requirements of a TEMPLATE node.
*/
const arch_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node)
{
const TEMPLATE_attr_t *attr = get_TEMPLATE_attr_const(node);
return attr->in_req;
}
/**
* Returns the argument register requirement at position pos of an TEMPLATE node.
*/
const arch_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos)
{
const TEMPLATE_attr_t *attr = get_TEMPLATE_attr_const(node);
return attr->in_req[pos];
}
/**
* Sets the IN register requirements at position pos.
*/
void set_TEMPLATE_req_in(ir_node *node, const arch_register_req_t *req, int pos)
{
TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
attr->in_req[pos] = req;
}
/**
* Initializes the nodes attributes.
*/
......@@ -131,12 +104,11 @@ static void init_TEMPLATE_attributes(ir_node *node, arch_irn_flags_t flags,
{
ir_graph *irg = get_irn_irg(node);
struct obstack *obst = get_irg_obstack(irg);
TEMPLATE_attr_t *attr = get_TEMPLATE_attr(node);
backend_info_t *info;
(void) execution_units;
arch_irn_set_flags(node, flags);
attr->in_req = in_reqs;
arch_set_in_register_reqs(node, in_reqs);
info = be_get_info(node);
info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
......@@ -159,5 +131,23 @@ static int TEMPLATE_compare_attr(ir_node *a, ir_node *b)
return 0;
}
static void TEMPLATE_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
struct obstack *obst = get_irg_obstack(irg);
const void *attr_old = get_irn_generic_attr_const(old_node);
void *attr_new = get_irn_generic_attr(new_node);
backend_info_t *old_info = be_get_info(old_node);
backend_info_t *new_info = be_get_info(new_node);
/* copy the attributes */
memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));
/* copy out flags */
new_info->out_infos =
DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
new_info->in_reqs = old_info->in_reqs;
}
/* Include the generated constructor functions */
#include "gen_TEMPLATE_new_nodes.c.inl"
......@@ -34,21 +34,6 @@ TEMPLATE_attr_t *get_TEMPLATE_attr(ir_node *node);
const TEMPLATE_attr_t *get_TEMPLATE_attr_const(const ir_node *node);
/**
* Returns the argument register requirements of an TEMPLATE node.
*/
const arch_register_req_t **get_TEMPLATE_in_req_all(const ir_node *node);
/**
* Returns the argument register requirements of an TEMPLATE node.
*/
const arch_register_req_t *get_TEMPLATE_in_req(const ir_node *node, int pos);
/**
* Sets the IN register requirements at position pos.
*/
void set_TEMPLATE_req_in(ir_node *node, const arch_register_req_t *req, int pos);
/* Include the generated headers */
#include "gen_TEMPLATE_new_nodes.h"
......
......@@ -32,9 +32,6 @@ typedef struct TEMPLATE_attr_t TEMPLATE_attr_t;
struct TEMPLATE_attr_t
{
tarval *value;
const arch_register_req_t **in_req; /**< register requirements for arguments */
const arch_register_req_t **out_req; /**< register requirements for results */
};
#endif
......@@ -122,6 +122,9 @@ $mode_fp = "mode_E"; # mode used by floatingpoint registers
C => "${arch}_emit_immediate(node);"
);
$default_attr_type = "TEMPLATE_attr_t";
$default_copy_attr = "TEMPLATE_copy_attr";
%nodes = (
# Integer nodes
......
......@@ -85,7 +85,6 @@ static int TEMPLATE_get_sp_bias(const ir_node *irn)
/* fill register allocator interface */
static const arch_irn_ops_t TEMPLATE_irn_ops = {
get_TEMPLATE_in_req,
TEMPLATE_classify,
TEMPLATE_get_frame_entity,
TEMPLATE_set_frame_offset,
......
......@@ -108,33 +108,6 @@ const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node)
return sym_attr;
}
/**
* Returns the argument register requirements of a amd64 node.
*/
const arch_register_req_t **get_amd64_in_req_all(const ir_node *node)
{
const amd64_attr_t *attr = get_amd64_attr_const(node);
return attr->in_req;
}
/**
* Returns the argument register requirement at position pos of an amd64 node.
*/
const arch_register_req_t *get_amd64_in_req(const ir_node *node, int pos)
{
const amd64_attr_t *attr = get_amd64_attr_const(node);
return attr->in_req[pos];
}
/**
* Sets the IN register requirements at position pos.
*/
void set_amd64_req_in(ir_node *node, const arch_register_req_t *req, int pos)
{
amd64_attr_t *attr = get_amd64_attr(node);
attr->in_req[pos] = req;
}
/**
* Initializes the nodes attributes.
*/
......@@ -151,7 +124,7 @@ static void init_amd64_attributes(ir_node *node, arch_irn_flags_t flags,
(void) execution_units;
arch_irn_set_flags(node, flags);
attr->in_req = in_reqs;
arch_set_in_register_reqs(node, in_reqs);
info = be_get_info(node);
info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
......@@ -211,6 +184,7 @@ static void amd64_copy_attr(ir_graph *irg, const ir_node *old_node,
/* copy out flags */
new_info->out_infos =
DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
new_info->in_reqs = old_info->in_reqs;
}
/* Include the generated constructor functions */
......
......@@ -51,21 +51,6 @@ amd64_attr_t *get_amd64_attr(ir_node *node);
const amd64_attr_t *get_amd64_attr_const(const ir_node *node);
const amd64_SymConst_attr_t *get_amd64_SymConst_attr_const(const ir_node *node);
/**
* Returns the argument register requirements of an amd64 node.
*/
const arch_register_req_t **get_amd64_in_req_all(const ir_node *node);
/**
* Returns the argument register requirements of an amd64 node.
*/
const arch_register_req_t *get_amd64_in_req(const ir_node *node, int pos);
/**
* Sets the IN register requirements at position pos.
*/
void set_amd64_req_in(ir_node *node, const arch_register_req_t *req, int pos);
/* Include the generated headers */
#include "gen_amd64_new_nodes.h"
......
......@@ -33,8 +33,6 @@ typedef struct amd64_SymConst_attr_t amd64_SymConst_attr_t;
struct amd64_attr_t
{
except_attr exc; /**< the exception attribute. MUST be the first one. */
const arch_register_req_t **in_req; /**< register requirements for arguments */
const arch_register_req_t **out_req; /**< register requirements for results */
ir_mode *ls_mode; /**< Stores the "input" mode */
struct amd64_attr_data_bitfield {
unsigned ins_permuted : 1; /**< inputs of node have been permuted
......
......@@ -111,7 +111,6 @@ static int amd64_get_sp_bias(const ir_node *irn)
/* fill register allocator interface */
static const arch_irn_ops_t amd64_irn_ops = {
get_amd64_in_req,
amd64_classify,
amd64_get_frame_entity,
amd64_set_frame_offset,
......
......@@ -288,24 +288,6 @@ const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node)
return get_irn_generic_attr_const(node);
}
void set_arm_in_req_all(ir_node *node, const arch_register_req_t **reqs)
{
arm_attr_t *attr = get_arm_attr(node);
attr->in_req = reqs;
}
const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos)
{
const arm_attr_t *attr = get_arm_attr_const(node);
return attr->in_req[pos];
}
void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos)
{
arm_attr_t *attr = get_arm_attr(node);
attr->in_req[pos] = req;
}
tarval *get_fConst_value(const ir_node *node)
{
const arm_fConst_attr_t *attr = get_arm_fConst_attr_const(node);
......@@ -367,7 +349,7 @@ static void init_arm_attributes(ir_node *node, int flags,
(void) execution_units;
arch_irn_set_flags(node, flags);
attr->in_req = in_reqs;
arch_set_in_register_reqs(node, in_reqs);
attr->is_load_store = false;
info = be_get_info(node);
......@@ -603,6 +585,7 @@ static void arm_copy_attr(ir_graph *irg, const ir_node *old_node,
/* copy out flags */
new_info->out_infos =
DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
new_info->in_reqs = old_info->in_reqs;
}
......
......@@ -65,18 +65,6 @@ const arm_cmp_attr_t *get_arm_cmp_attr_const(const ir_node *node);
arm_farith_attr_t *get_arm_farith_attr(ir_node *node);
const arm_farith_attr_t *get_arm_farith_attr_const(const ir_node *node);
void set_arm_in_req_all(ir_node *node, const arch_register_req_t **reqs);
/**
* Returns the argument register requirements of an arm node.
*/
const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos);
/**
* Sets the IN register requirements at position pos.
*/
void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos);
/**
* Return the tarval of a fConst
*/
......
......@@ -64,7 +64,6 @@ enum fpa_immediates {
/** Generic ARM node attributes. */
typedef struct arm_attr_t {
except_attr exc; /**< the exception attribute. MUST be the first one. */
const arch_register_req_t **in_req; /**< register requirements for arguments */
bool is_load_store : 1; /**< if set, this is a load or store instruction */
} arm_attr_t;
......
......@@ -2000,7 +2000,7 @@ static ir_node *gen_Call(ir_node *node)
pmap_insert(node_to_stack, node, incsp);
}
set_arm_in_req_all(res, in_req);
arch_set_in_register_reqs(res, in_req);
/* create output register reqs */
arch_set_out_register_req(res, 0, arch_no_register_req);
......
......@@ -119,7 +119,6 @@ static int arm_get_sp_bias(const ir_node *irn)
/* fill register allocator interface */
static const arch_irn_ops_t arm_irn_ops = {
get_arm_in_req,
arm_classify,
arm_get_frame_entity,
arm_set_stack_bias,
......
......@@ -72,16 +72,16 @@ static inline const arch_irn_ops_t *get_irn_ops(const ir_node *irn)
const arch_register_req_t *arch_get_register_req(const ir_node *irn, int pos)
{
if (is_Proj(irn)) {
ir_node *pred = get_Proj_pred(irn);
long pn = get_Proj_proj(irn);
assert(pos == -1);
pos = -1-get_Proj_proj(irn);
irn = get_Proj_pred(irn);
return arch_get_out_register_req(pred, pn);
}
if (pos < 0) {
return arch_get_out_register_req(irn, -pos-1);
} else {
const arch_irn_ops_t *ops = get_irn_ops_simple(irn);
return ops->get_irn_reg_req_in(irn, pos);
return arch_get_in_register_req(irn, pos);
}
}
......
......@@ -383,16 +383,6 @@ struct arch_inverse_t {
struct arch_irn_ops_t {
/**
* Get the register requirements for a given operand.
* @param irn The node.
* @param pos The operand's position
* @return The register requirements for the selected operand.
* The pointer returned is never NULL.
*/
const arch_register_req_t *(*get_irn_reg_req_in)(const ir_node *irn,
int pos);
/**
* Classify the node.
* @param irn The node.
......@@ -812,8 +802,10 @@ static inline bool arch_irn_consider_in_reg_alloc(
static inline const arch_register_req_t *arch_get_in_register_req(
const ir_node *node, int pos)
{
const arch_irn_ops_t *ops = get_irn_ops_simple(node);
return ops->get_irn_reg_req_in(node, pos);
const backend_info_t *info = be_get_info(node);
if (info->in_reqs == NULL)
return arch_no_register_req;
return info->in_reqs[pos];
}
/**
......@@ -836,6 +828,20 @@ static inline void arch_set_out_register_req(ir_node *node, int pos,
info->out_infos[pos].req = req;
}
static inline void arch_set_in_register_reqs(ir_node *node,
const arch_register_req_t **in_reqs)
{
backend_info_t *info = be_get_info(node);
info->in_reqs = in_reqs;
}
static inline const arch_register_req_t **arch_get_in_register_reqs(
const ir_node *node)
{
backend_info_t *info = be_get_info(node);
return info->in_reqs;
}
/**
* Iterate over all values defined by an instruction.
* Only looks at values in a certain register class where the requirements
......
......@@ -75,14 +75,24 @@ static void new_Phi_copy_attr(ir_graph *irg, const ir_node *old_node,
old_phi_copy_attr(irg, old_node, new_node);
}
int be_infos_equal(const backend_info_t *info1, const backend_info_t *info2)
int be_nodes_equal(ir_node *node1, ir_node *node2)
{
int len = ARR_LEN(info1->out_infos);
int i;
const backend_info_t *info1 = be_get_info(node1);
const backend_info_t *info2 = be_get_info(node2);
int len = ARR_LEN(info1->out_infos);
int arity = get_irn_arity(node1);
int i;
if (ARR_LEN(info2->out_infos) != len)
return false;
assert(arity == get_irn_arity(node2));
for (i = 0; i < arity; ++i) {
if (info1->in_reqs[i] != info2->in_reqs[i])
return false;
}
for (i = 0; i < len; ++i) {
const reg_out_info_t *out1 = &info1->out_infos[i];
const reg_out_info_t *out2 = &info2->out_infos[i];
......@@ -95,13 +105,6 @@ int be_infos_equal(const backend_info_t *info1, const backend_info_t *info2)
return true;
}
int be_nodes_equal(const ir_node *node1, const ir_node *node2)
{
backend_info_t *info1 = be_get_info(node1);
backend_info_t *info2 = be_get_info(node2);
return be_infos_equal(info1, info2);
}
static void init_walker(ir_node *node, void *data)
{
(void) data;
......
......@@ -65,7 +65,6 @@ void be_info_new_node(ir_node *node);
void be_info_duplicate(const ir_node *old_node, ir_node *new_node);
int be_info_initialized(const ir_graph *irg);
int be_nodes_equal(const ir_node *node1, const ir_node *node2);
int be_infos_equal(const backend_info_t *info1, const backend_info_t *info2);
int be_nodes_equal(ir_node *node1, ir_node *node2);
#endif
......@@ -58,18 +58,8 @@
#include "beirgmod.h"
typedef struct {
const arch_register_req_t *in_req;
} be_reg_data_t;
/** The generic be nodes attribute type. */
typedef struct {
be_reg_data_t *reg_data;
} be_node_attr_t;
/** The be_Return nodes attribute type. */
typedef struct {
be_node_attr_t node_attr; /**< base attributes of every be node. */
int num_ret_vals; /**< number of return values */
unsigned pop; /**< number of bytes that should be popped */
int emit_pop; /**< if set, emit pop bytes, even if pop = 0 */
......@@ -77,7 +67,6 @@ typedef struct {
/** The be_IncSP attribute type. */
typedef struct {
be_node_attr_t node_attr; /**< base attributes of every be node. */
int offset; /**< The offset by which the stack shall be
expanded/shrinked. */
int align; /**< whether stack should be aligned after the
......@@ -86,23 +75,20 @@ typedef struct {
/** The be_Frame attribute type. */
typedef struct {
be_node_attr_t node_attr; /**< base attributes of every be node. */
ir_entity *ent;
int offset;
} be_frame_attr_t;
/** The be_Call attribute type. */
typedef struct {
be_node_attr_t node_attr; /**< base attributes of every be node. */
ir_entity *ent; /**< called entity if this is a static call. */
unsigned pop;
ir_type *call_tp; /**< call type, copied from the original Call */
} be_call_attr_t;
typedef struct {
be_node_attr_t node_attr; /**< base attributes of every be node. */
ir_entity **in_entities;
ir_entity **out_entities;
ir_entity **in_entities;
ir_entity **out_entities;
} be_memperm_attr_t;
ir_op *op_be_Spill;
......@@ -123,32 +109,6 @@ ir_op *op_be_Barrier;
static const ir_op_ops be_node_op_ops;
/**
* Compare two be node attributes.
*
* @return zero if both attributes are identically
*/
static int node_cmp_attr(ir_node *a, ir_node *b)
{
const be_node_attr_t *a_attr = get_irn_generic_attr_const(a);
const be_node_attr_t *b_attr = get_irn_generic_attr_const(b);
int i, len = ARR_LEN(a_attr->reg_data);
if (len != ARR_LEN(b_attr->reg_data))
return 1;
if (!be_nodes_equal(a, b))
return 1;
for (i = len - 1; i >= 0; --i) {
if (!reg_reqs_equal(a_attr->reg_data[i].in_req,
b_attr->reg_data[i].in_req))
return 1;
}
return 0;
}
/**
* Compare the attributes of two be_FrameAddr nodes.
*
......@@ -162,7 +122,7 @@ static int FrameAddr_cmp_attr(ir_node *a, ir_node *b)
if (a_attr->ent != b_attr->ent || a_attr->offset != b_attr->offset)
return 1;
return node_cmp_attr(a, b);
return be_nodes_equal(a, b);
}
/**
......@@ -182,7 +142,7 @@ static int Return_cmp_attr(ir_node *a, ir_node *b)
if (a_attr->emit_pop != b_attr->emit_pop)
return 1;
return node_cmp_attr(a, b);
return be_nodes_equal(a, b);
}
/**
......@@ -198,7 +158,7 @@ static int IncSP_cmp_attr(ir_node *a, ir_node *b)
if (a_attr->offset != b_attr->offset)
return 1;
return node_cmp_attr(a, b);
return be_nodes_equal(a, b);
}
/**
......@@ -215,7 +175,7 @@ static int Call_cmp_attr(ir_node *a, ir_node *b)
a_attr->call_tp != b_attr->call_tp)
return 1;
return node_cmp_attr(a, b);
return be_nodes_equal(a, b);
}
static arch_register_req_t *allocate_reg_req(const ir_node *node)
......@@ -230,10 +190,9 @@ static arch_register_req_t *allocate_reg_req(const ir_node *node)
void be_set_constr_in(ir_node *node, int pos, const arch_register_req_t *req)
{
const be_node_attr_t *attr = get_irn_generic_attr_const(node);
be_reg_data_t *rd = &attr->reg_data[pos];
assert(pos < ARR_LEN(attr->reg_data));
rd->in_req = req;
backend_info_t *info = be_get_info(node);
assert(pos < get_irn_arity(node));
info->in_reqs[pos] = req;
}
void be_set_constr_out(ir_node *node, int pos, const arch_register_req_t *req)
......@@ -249,20 +208,20 @@ static void *init_node_attr(ir_node *node, int n_inputs, int n_outputs)
{
ir_graph *irg = get_irn_irg(node);
struct obstack *obst = be_get_be_obst(irg);
be_node_attr_t *a = get_irn_generic_attr(node);
backend_info_t *info = be_get_info(node);
memset(a, 0, sizeof(get_op_attr_size(get_irn_op(node))));
const arch_register_req_t **in_reqs;
if (n_inputs >= 0) {
int i;
a->reg_data = NEW_ARR_D(be_reg_data_t, obst, n_inputs);
assert(n_inputs == get_irn_arity(node));
in_reqs = OALLOCN(obst, const arch_register_req_t*, n_inputs);
for (i = 0; i < n_inputs; ++i) {
a->reg_data[i].in_req = arch_no_register_req;
in_reqs[i] = arch_no_register_req;
}
} else {
a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
in_reqs = NEW_ARR_F(const arch_register_req_t*, 0);
}
info->in_reqs = in_reqs;
if (n_outputs >= 0) {
int i;
......@@ -275,7 +234,7 @@ static void *init_node_attr(ir_node *node, int n_inputs, int n_outputs)
info->out_infos = NEW_ARR_F(reg_out_info_t, 0);
}
return a;
return get_irn_generic_attr(node);
}
static void add_register_req_out(ir_node *node)
......@@ -289,11 +248,8 @@ static void add_register_req_out(ir_node *node)
static void add_register_req_in(ir_node *node)
{
be_node_attr_t *a = get_irn_generic_attr(node);
be_reg_data_t regreq;
memset(&regreq, 0, sizeof(regreq));
regreq.in_req = arch_no_register_req;
ARR_APP1(be_reg_data_t, a->reg_data, regreq);
backend_info_t *info = be_get_info(node);
ARR_APP1(const arch_register_req_t*, info->in_reqs, arch_no_register_req);
}
ir_node *be_new_Spill(const arch_register_class_t *cls,
......@@ -398,14 +354,13 @@ ir_node *be_new_Perm(const arch_register_class_t *cls, ir_node *block,
void be_Perm_reduce(ir_node *perm, int new_size, int *map)
{
int arity = get_irn_arity(perm);
be_reg_data_t *old_data = ALLOCAN(be_reg_data_t, arity);
reg_out_info_t *old_infos = ALLOCAN(reg_out_info_t, arity);
be_node_attr_t *attr = get_irn_generic_attr(perm);