Commit 39cb5226 authored by Matthias Braun's avatar Matthias Braun
Browse files

- Bigger refactoring and cleanup in backend:

	* benodes store the out register requirements in backend_info now
	  (this is work towards killing the register_requirement callbacks)
	* ir_graph has a pointer to beirg now
	* Other cleanups

[r26540]
parent 65a67751
...@@ -119,9 +119,8 @@ typedef enum { ...@@ -119,9 +119,8 @@ typedef enum {
beo_RegParams, beo_RegParams,
beo_FrameAddr, beo_FrameAddr,
beo_Barrier, beo_Barrier,
beo_Unwind,
/* last backend node number */ /* last backend node number */
beo_Last = beo_Unwind, beo_Last = beo_Barrier,
/* first unfixed number. Dynamic node numbers start here */ /* first unfixed number. Dynamic node numbers start here */
iro_MaxOpcode iro_MaxOpcode
} ir_opcode; } ir_opcode;
......
...@@ -280,17 +280,13 @@ static void TEMPLATE_done(void *self) { ...@@ -280,17 +280,13 @@ static void TEMPLATE_done(void *self) {
} }
static unsigned TEMPLATE_get_n_reg_class(void)
static unsigned TEMPLATE_get_n_reg_class(const void *self)
{ {
(void) self;
return N_CLASSES; return N_CLASSES;
} }
static const arch_register_class_t *TEMPLATE_get_reg_class(const void *self, static const arch_register_class_t *TEMPLATE_get_reg_class(unsigned i)
unsigned i)
{ {
(void) self;
assert(i < N_CLASSES); assert(i < N_CLASSES);
return &TEMPLATE_reg_classes[i]; return &TEMPLATE_reg_classes[i];
} }
...@@ -303,10 +299,8 @@ static const arch_register_class_t *TEMPLATE_get_reg_class(const void *self, ...@@ -303,10 +299,8 @@ static const arch_register_class_t *TEMPLATE_get_reg_class(const void *self,
* @param mode The mode in question. * @param mode The mode in question.
* @return A register class which can hold values of the given mode. * @return A register class which can hold values of the given mode.
*/ */
const arch_register_class_t *TEMPLATE_get_reg_class_for_mode(const void *self, const arch_register_class_t *TEMPLATE_get_reg_class_for_mode(const ir_mode *mode)
const ir_mode *mode)
{ {
(void) self;
if (mode_is_float(mode)) if (mode_is_float(mode))
return &TEMPLATE_reg_classes[CLASS_TEMPLATE_floating_point]; return &TEMPLATE_reg_classes[CLASS_TEMPLATE_floating_point];
else else
...@@ -486,10 +480,9 @@ static const ilp_sched_selector_t *TEMPLATE_get_ilp_sched_selector( ...@@ -486,10 +480,9 @@ static const ilp_sched_selector_t *TEMPLATE_get_ilp_sched_selector(
/** /**
* Returns the necessary byte alignment for storing a register of given class. * Returns the necessary byte alignment for storing a register of given class.
*/ */
static int TEMPLATE_get_reg_class_alignment(const void *self, static int TEMPLATE_get_reg_class_alignment(const arch_register_class_t *cls)
const arch_register_class_t *cls) { {
ir_mode *mode = arch_register_class_mode(cls); ir_mode *mode = arch_register_class_mode(cls);
(void) self;
return get_mode_size_bytes(mode); return get_mode_size_bytes(mode);
} }
...@@ -514,9 +507,8 @@ static const backend_params *TEMPLATE_get_backend_params(void) { ...@@ -514,9 +507,8 @@ static const backend_params *TEMPLATE_get_backend_params(void) {
} }
static const be_execution_unit_t ***TEMPLATE_get_allowed_execution_units( static const be_execution_unit_t ***TEMPLATE_get_allowed_execution_units(
const void *self, const ir_node *irn) const ir_node *irn)
{ {
(void) self;
(void) irn; (void) irn;
/* TODO */ /* TODO */
assert(0); assert(0);
...@@ -539,17 +531,14 @@ static ir_graph **TEMPLATE_get_backend_irg_list(const void *self, ...@@ -539,17 +531,14 @@ static ir_graph **TEMPLATE_get_backend_irg_list(const void *self,
return NULL; return NULL;
} }
static asm_constraint_flags_t TEMPLATE_parse_asm_constraint(const void *self, static asm_constraint_flags_t TEMPLATE_parse_asm_constraint(const char **c)
const char **c)
{ {
(void) self;
(void) c; (void) c;
return ASM_CONSTRAINT_FLAG_INVALID; return ASM_CONSTRAINT_FLAG_INVALID;
} }
static int TEMPLATE_is_valid_clobber(const void *self, const char *clobber) static int TEMPLATE_is_valid_clobber(const char *clobber)
{ {
(void) self;
(void) clobber; (void) clobber;
return 0; return 0;
} }
......
...@@ -854,7 +854,7 @@ static ir_node *gen_Load(ir_node *node) { ...@@ -854,7 +854,7 @@ static ir_node *gen_Load(ir_node *node) {
if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) { if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) {
/* add a result proj and a Keep to produce a pseudo use */ /* add a result proj and a Keep to produce a pseudo use */
ir_node *proj = new_r_Proj(block, new_load, mode_Iu, pn_arm_Load_res); ir_node *proj = new_r_Proj(block, new_load, mode_Iu, pn_arm_Load_res);
be_new_Keep(arch_get_irn_reg_class_out(proj), block, 1, &proj); be_new_Keep(block, 1, &proj);
} }
return new_load; return new_load;
......
...@@ -669,17 +669,14 @@ static void arm_done(void *self) { ...@@ -669,17 +669,14 @@ static void arm_done(void *self) {
* here to speed up register allocation (and makes dumps * here to speed up register allocation (and makes dumps
* smaller and more readable). * smaller and more readable).
*/ */
static unsigned arm_get_n_reg_class(const void *self) { static unsigned arm_get_n_reg_class(void) {
(void) self;
return N_CLASSES; return N_CLASSES;
} }
/** /**
* Return the register class with requested index. * Return the register class with requested index.
*/ */
static const arch_register_class_t *arm_get_reg_class(const void *self, static const arch_register_class_t *arm_get_reg_class(unsigned i) {
unsigned i) {
(void) self;
assert(i < N_CLASSES); assert(i < N_CLASSES);
return &arm_reg_classes[i]; return &arm_reg_classes[i];
} }
...@@ -690,8 +687,7 @@ static const arch_register_class_t *arm_get_reg_class(const void *self, ...@@ -690,8 +687,7 @@ static const arch_register_class_t *arm_get_reg_class(const void *self,
* @param mode The mode in question. * @param mode The mode in question.
* @return A register class which can hold values of the given mode. * @return A register class which can hold values of the given mode.
*/ */
const arch_register_class_t *arm_get_reg_class_for_mode(const void *self, const ir_mode *mode) { const arch_register_class_t *arm_get_reg_class_for_mode(const ir_mode *mode) {
(void) self;
if (mode_is_float(mode)) if (mode_is_float(mode))
return &arm_reg_classes[CLASS_arm_fpa]; return &arm_reg_classes[CLASS_arm_fpa];
else else
...@@ -970,15 +966,14 @@ static const ilp_sched_selector_t *arm_get_ilp_sched_selector(const void *self) ...@@ -970,15 +966,14 @@ static const ilp_sched_selector_t *arm_get_ilp_sched_selector(const void *self)
/** /**
* Returns the necessary byte alignment for storing a register of given class. * Returns the necessary byte alignment for storing a register of given class.
*/ */
static int arm_get_reg_class_alignment(const void *self, const arch_register_class_t *cls) { static int arm_get_reg_class_alignment(const arch_register_class_t *cls)
(void) self; {
(void) cls; (void) cls;
/* ARM is a 32 bit CPU, no need for other alignment */ /* ARM is a 32 bit CPU, no need for other alignment */
return 4; return 4;
} }
static const be_execution_unit_t ***arm_get_allowed_execution_units(const void *self, const ir_node *irn) { static const be_execution_unit_t ***arm_get_allowed_execution_units(const ir_node *irn) {
(void) self;
(void) irn; (void) irn;
/* TODO */ /* TODO */
panic("Unimplemented arm_get_allowed_execution_units()"); panic("Unimplemented arm_get_allowed_execution_units()");
...@@ -1040,17 +1035,15 @@ static int arm_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j) { ...@@ -1040,17 +1035,15 @@ static int arm_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j) {
return 1; return 1;
} }
static asm_constraint_flags_t arm_parse_asm_constraint(const void *self, const char **c) static asm_constraint_flags_t arm_parse_asm_constraint(const char **c)
{ {
/* asm not supported */ /* asm not supported */
(void) self;
(void) c; (void) c;
return ASM_CONSTRAINT_FLAG_INVALID; return ASM_CONSTRAINT_FLAG_INVALID;
} }
static int arm_is_valid_clobber(const void *self, const char *clobber) static int arm_is_valid_clobber(const char *clobber)
{ {
(void) self;
(void) clobber; (void) clobber;
return 0; return 0;
} }
......
...@@ -815,7 +815,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp) ...@@ -815,7 +815,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
/* create the Keep for the caller save registers */ /* create the Keep for the caller save registers */
in = (ir_node **) obstack_finish(obst); in = (ir_node **) obstack_finish(obst);
keep = be_new_Keep(NULL, bl, n, in); keep = be_new_Keep(bl, n, in);
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
const arch_register_t *reg = get_irn_link(in[i]); const arch_register_t *reg = get_irn_link(in[i]);
be_node_set_reg_class_in(keep, i, reg->reg_class); be_node_set_reg_class_in(keep, i, reg->reg_class);
...@@ -1208,7 +1208,7 @@ static void process_ops_in_block(ir_node *bl, void *data) ...@@ -1208,7 +1208,7 @@ static void process_ops_in_block(ir_node *bl, void *data)
if (curr_sp != env->init_sp && if (curr_sp != env->init_sp &&
!(is_Proj(curr_sp) && be_is_Call(get_Proj_pred(curr_sp)))) { !(is_Proj(curr_sp) && be_is_Call(get_Proj_pred(curr_sp)))) {
nodes[0] = curr_sp; nodes[0] = curr_sp;
keep = be_new_Keep(env->arch_env->sp->reg_class, bl, 1, nodes); keep = be_new_Keep(bl, 1, nodes);
pmap_insert(env->keep_map, bl, keep); pmap_insert(env->keep_map, bl, keep);
} }
} }
...@@ -1353,10 +1353,10 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm ...@@ -1353,10 +1353,10 @@ static ir_node *create_barrier(be_abi_irg_t *env, ir_node *bl, ir_node **mem, pm
obstack_free(&env->obst, in); obstack_free(&env->obst, in);
for (n = 0; n < n_regs; ++n) { for (n = 0; n < n_regs; ++n) {
ir_node *pred = rm[n].irn; ir_node *pred = rm[n].irn;
const arch_register_t *reg = rm[n].reg; const arch_register_t *reg = rm[n].reg;
arch_register_type_t add_type = 0; arch_register_type_t add_type = 0;
ir_node *proj; ir_node *proj;
/* stupid workaround for now... as not all nodes report register /* stupid workaround for now... as not all nodes report register
* requirements. */ * requirements. */
......
...@@ -215,8 +215,9 @@ void be_register_isa_if(const char *name, const arch_isa_if_t *isa); ...@@ -215,8 +215,9 @@ void be_register_isa_if(const char *name, const arch_isa_if_t *isa);
struct arch_register_t { struct arch_register_t {
const char *name; /**< The name of the register. */ const char *name; /**< The name of the register. */
const arch_register_class_t *reg_class; /**< The class the register belongs to. */ const arch_register_class_t *reg_class; /**< The class the register belongs to. */
unsigned index; /**< The index of the register in the class. */ unsigned index; /**< The index of the register in the class. */
arch_register_type_t type; /**< The type of the register. */ arch_register_type_t type; /**< The type of the register. */
const arch_register_req_t *single_req;
}; };
static inline const arch_register_class_t * static inline const arch_register_class_t *
...@@ -237,9 +238,9 @@ const char *_arch_register_get_name(const arch_register_t *reg) ...@@ -237,9 +238,9 @@ const char *_arch_register_get_name(const arch_register_t *reg)
return reg->name; return reg->name;
} }
#define arch_register_get_class(reg) _arch_register_get_class(reg) #define arch_register_get_class(reg) _arch_register_get_class(reg)
#define arch_register_get_index(reg) _arch_register_get_index(reg) #define arch_register_get_index(reg) _arch_register_get_index(reg)
#define arch_register_get_name(reg) _arch_register_get_name(reg) #define arch_register_get_name(reg) _arch_register_get_name(reg)
/** /**
* Convenience macro to check for register type. * Convenience macro to check for register type.
...@@ -255,13 +256,14 @@ const char *_arch_register_get_name(const arch_register_t *reg) ...@@ -255,13 +256,14 @@ const char *_arch_register_get_name(const arch_register_t *reg)
* Like general purpose or floating point. * Like general purpose or floating point.
*/ */
struct arch_register_class_t { struct arch_register_class_t {
unsigned index; /**< index of this register class */ unsigned index; /**< index of this register class */
const char *name; /**< The name of the register class.*/ const char *name; /**< The name of the register class.*/
unsigned n_regs; /**< Number of registers in this unsigned n_regs; /**< Number of registers in this
class. */ class. */
ir_mode *mode; /**< The mode of the register class.*/ ir_mode *mode; /**< The mode of the register class.*/
const arch_register_t *regs; /**< The array of registers. */ const arch_register_t *regs; /**< The array of registers. */
arch_register_class_flags_t flags; /**< register class flags. */ arch_register_class_flags_t flags; /**< register class flags. */
const arch_register_req_t *class_req;
}; };
/** return the number of registers in this register class */ /** return the number of registers in this register class */
...@@ -572,14 +574,14 @@ struct arch_isa_if_t { ...@@ -572,14 +574,14 @@ struct arch_isa_if_t {
* Get the the number of register classes in the isa. * Get the the number of register classes in the isa.
* @return The number of register classes. * @return The number of register classes.
*/ */
unsigned (*get_n_reg_class)(const void *self); unsigned (*get_n_reg_class)(void);
/** /**
* Get the i-th register class. * Get the i-th register class.
* @param i The number of the register class. * @param i The number of the register class.
* @return The register class. * @return The register class.
*/ */
const arch_register_class_t *(*get_reg_class)(const void *self, unsigned i); const arch_register_class_t *(*get_reg_class)(unsigned i);
/** /**
* Get the register class which shall be used to store a value of a given mode. * Get the register class which shall be used to store a value of a given mode.
...@@ -587,7 +589,7 @@ struct arch_isa_if_t { ...@@ -587,7 +589,7 @@ struct arch_isa_if_t {
* @param mode The mode in question. * @param mode The mode in question.
* @return A register class which can hold values of the given mode. * @return A register class which can hold values of the given mode.
*/ */
const arch_register_class_t *(*get_reg_class_for_mode)(const void *self, const ir_mode *mode); const arch_register_class_t *(*get_reg_class_for_mode)(const ir_mode *mode);
/** /**
* Get the ABI restrictions for procedure calls. * Get the ABI restrictions for procedure calls.
...@@ -627,7 +629,7 @@ struct arch_isa_if_t { ...@@ -627,7 +629,7 @@ struct arch_isa_if_t {
* @param cls The register class. * @param cls The register class.
* @return The alignment in bytes. * @return The alignment in bytes.
*/ */
int (*get_reg_class_alignment)(const void *self, const arch_register_class_t *cls); int (*get_reg_class_alignment)(const arch_register_class_t *cls);
/** /**
* A "static" function, returns the frontend settings * A "static" function, returns the frontend settings
...@@ -650,7 +652,7 @@ struct arch_isa_if_t { ...@@ -650,7 +652,7 @@ struct arch_isa_if_t {
* NULL * NULL
* }; * };
*/ */
const be_execution_unit_t ***(*get_allowed_execution_units)(const void *self, const ir_node *irn); const be_execution_unit_t ***(*get_allowed_execution_units)(const ir_node *irn);
/** /**
* Return the abstract machine for this isa. * Return the abstract machine for this isa.
...@@ -671,41 +673,41 @@ struct arch_isa_if_t { ...@@ -671,41 +673,41 @@ struct arch_isa_if_t {
/** /**
* mark node as rematerialized * mark node as rematerialized
*/ */
void (*mark_remat)(const void *self, ir_node *node); void (*mark_remat)(ir_node *node);
/** /**
* parse an assembler constraint part and set flags according to its nature * parse an assembler constraint part and set flags according to its nature
* advances the *c pointer to point to the last parsed character (so if you * advances the *c pointer to point to the last parsed character (so if you
* parse a single character don't advance c) * parse a single character don't advance c)
*/ */
asm_constraint_flags_t (*parse_asm_constraint)(const void *self, const char **c); asm_constraint_flags_t (*parse_asm_constraint)(const char **c);
/** /**
* returns true if the string is a valid clobbered (register) in this * returns true if the string is a valid clobbered (register) in this
* backend * backend
*/ */
int (*is_valid_clobber)(const void *self, const char *clobber); int (*is_valid_clobber)(const char *clobber);
}; };
#define arch_env_done(env) ((env)->impl->done(env)) #define arch_env_done(env) ((env)->impl->done(env))
#define arch_env_handle_intrinsics(env) \ #define arch_env_handle_intrinsics(env) \
do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0) do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0)
#define arch_env_get_n_reg_class(env) ((env)->impl->get_n_reg_class(env)) #define arch_env_get_n_reg_class(env) ((env)->impl->get_n_reg_class())
#define arch_env_get_reg_class(env,i) ((env)->impl->get_reg_class(env, i)) #define arch_env_get_reg_class(env,i) ((env)->impl->get_reg_class(i))
#define arch_env_get_reg_class_for_mode(env,mode) ((env)->impl->get_reg_class_for_mode((env), (mode))) #define arch_env_get_reg_class_for_mode(env,mode) ((env)->impl->get_reg_class_for_mode((mode)))
#define arch_env_get_call_abi(env,tp,abi) ((env)->impl->get_call_abi((env), (tp), (abi))) #define arch_env_get_call_abi(env,tp,abi) ((env)->impl->get_call_abi((env), (tp), (abi)))
#define arch_env_get_code_generator_if(env) ((env)->impl->get_code_generator_if((env))) #define arch_env_get_code_generator_if(env) ((env)->impl->get_code_generator_if((env)))
#define arch_env_get_list_sched_selector(env,selector) ((env)->impl->get_list_sched_selector((env), (selector))) #define arch_env_get_list_sched_selector(env,selector) ((env)->impl->get_list_sched_selector((env), (selector)))
#define arch_env_get_ilp_sched_selector(env) ((env)->impl->get_ilp_sched_selector(env)) #define arch_env_get_ilp_sched_selector(env) ((env)->impl->get_ilp_sched_selector(env))
#define arch_env_get_reg_class_alignment(env,cls) ((env)->impl->get_reg_class_alignment((env), (cls))) #define arch_env_get_reg_class_alignment(env,cls) ((env)->impl->get_reg_class_alignment((cls)))
#define arch_env_get_params(env) ((env)->impl->get_params()) #define arch_env_get_params(env) ((env)->impl->get_params())
#define arch_env_get_allowed_execution_units(env,irn) ((env)->impl->get_allowed_execution_units((env), (irn))) #define arch_env_get_allowed_execution_units(env,irn) ((env)->impl->get_allowed_execution_units((irn)))
#define arch_env_get_machine(env) ((env)->impl->get_machine(env)) #define arch_env_get_machine(env) ((env)->impl->get_machine(env))
#define arch_env_get_backend_irg_list(env,irgs) ((env)->impl->get_backend_irg_list((env), (irgs))) #define arch_env_get_backend_irg_list(env,irgs) ((env)->impl->get_backend_irg_list((env), (irgs)))
#define arch_env_parse_asm_constraint(env,c) ((env)->impl->parse_asm_constraint((env), (c)) #define arch_env_parse_asm_constraint(env,c) ((env)->impl->parse_asm_constraint((c))
#define arch_env_is_valid_clobber(env,clobber) ((env)->impl->is_valid_clobber((env), (clobber)) #define arch_env_is_valid_clobber(env,clobber) ((env)->impl->is_valid_clobber((clobber))
#define arch_env_mark_remat(env,node) \ #define arch_env_mark_remat(env,node) \
do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((env), (node)); } while(0) do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((node)); } while(0)
/** /**
* ISA base class. * ISA base class.
......
...@@ -516,7 +516,8 @@ static ir_node **create_block_schedule_greedy(ir_graph *irg, ir_exec_freq *execf ...@@ -516,7 +516,8 @@ static ir_node **create_block_schedule_greedy(ir_graph *irg, ir_exec_freq *execf
coalesce_blocks(&env); coalesce_blocks(&env);
start_entry = finish_block_schedule(&env); start_entry = finish_block_schedule(&env);
block_list = create_blocksched_array(&env, start_entry, env.blockcount, get_irg_obstack(irg)); block_list = create_blocksched_array(&env, start_entry, env.blockcount,
be_get_birg_obst(irg));
DEL_ARR_F(env.edges); DEL_ARR_F(env.edges);
obstack_free(&obst, NULL); obstack_free(&obst, NULL);
...@@ -713,7 +714,9 @@ static ir_node **create_block_schedule_ilp(ir_graph *irg, ir_exec_freq *execfreq ...@@ -713,7 +714,9 @@ static ir_node **create_block_schedule_ilp(ir_graph *irg, ir_exec_freq *execfreq
coalesce_blocks_ilp(&env); coalesce_blocks_ilp(&env);
start_entry = finish_block_schedule(&env.env); start_entry = finish_block_schedule(&env.env);
block_list = create_blocksched_array(&env.env, start_entry, env.env.blockcount, get_irg_obstack(irg)); block_list = create_blocksched_array(&env.env, start_entry,
env.env.blockcount,
be_get_birg_obst(irg));
DEL_ARR_F(env.ilpedges); DEL_ARR_F(env.ilpedges);
free_lpp(env.lpp); free_lpp(env.lpp);
......
...@@ -333,7 +333,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env, ...@@ -333,7 +333,7 @@ static ir_node *pre_process_constraints(be_chordal_alloc_env_t *alloc_env,
* since ignore-nodes are not Perm'ed. * since ignore-nodes are not Perm'ed.
*/ */
if (op->has_constraints && is_Proj(proj) && get_Proj_pred(proj) == perm) { if (op->has_constraints && is_Proj(proj) && get_Proj_pred(proj) == perm) {
be_set_constr_limited(perm, BE_OUT_POS(get_Proj_proj(proj)), op->req); be_set_constr_out(perm, get_Proj_proj(proj), op->req);
} }
} }
......
...@@ -46,8 +46,8 @@ void be_info_new_node(ir_node *node) ...@@ -46,8 +46,8 @@ void be_info_new_node(ir_node *node)
if (is_Proj(node)) // Projs need no be info, their tuple holds all information if (is_Proj(node)) // Projs need no be info, their tuple holds all information
return; return;
obst = get_irg_obstack(current_ir_graph); obst = be_get_birg_obst(current_ir_graph);
info = OALLOCZ(obst, backend_info_t); info = OALLOCZ(obst, backend_info_t);
if (is_Phi(node)) { if (is_Phi(node)) {
info->out_infos = NEW_ARR_D(reg_out_info_t, obst, 1); info->out_infos = NEW_ARR_D(reg_out_info_t, obst, 1);
...@@ -59,36 +59,39 @@ void be_info_new_node(ir_node *node) ...@@ -59,36 +59,39 @@ void be_info_new_node(ir_node *node)
static void new_Phi_copy_attr(const ir_node *old_node, ir_node *new_node) static void new_Phi_copy_attr(const ir_node *old_node, ir_node *new_node)
{ {
struct obstack *obst = get_irg_obstack(get_irn_irg(new_node));
backend_info_t *old_info = be_get_info(old_node); backend_info_t *old_info = be_get_info(old_node);
backend_info_t *new_info = be_get_info(new_node); backend_info_t *new_info = be_get_info(new_node);
*new_info = *old_info;
old_phi_copy_attr(old_node, new_node); old_phi_copy_attr(old_node, new_node);
new_info->out_infos = DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
} }
int be_info_equal(const ir_node *node1, const ir_node *node2) int be_infos_equal(const backend_info_t *info1, const backend_info_t *info2)
{ {
backend_info_t *info1 = be_get_info(node1);
backend_info_t *info2 = be_get_info(node2);
int len = ARR_LEN(info1->out_infos); int len = ARR_LEN(info1->out_infos);
int i; int i;
if (ARR_LEN(info2->out_infos) != len) if (ARR_LEN(info2->out_infos) != len)
return 0; return false;
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
const reg_out_info_t *out1 = &info1->out_infos[i]; const reg_out_info_t *out1 = &info1->out_infos[i];
const reg_out_info_t *out2 = &info2->out_infos[i]; const reg_out_info_t *out2 = &info2->out_infos[i];
if (out1->reg != out2->reg) if (out1->reg != out2->reg)
return 0; return false;
if (!reg_reqs_equal(out1->req, out2->req)) if (!reg_reqs_equal(out1->req, out2->req))
return 0; return false;
} }
/* TODO: in reqs */ return true;
}
return 1; 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)</