}
-ir_node *be_new_Spill(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *to_spill)
+ir_node *be_new_Spill(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
+ ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *to_spill)
{
be_frame_attr_t *a;
+ ir_node *in[2];
ir_node *res;
- res = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 1, &to_spill);
+ in[0] = frame;
+ in[1] = to_spill;
+ res = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
a = init_node_attr(res, 2);
a->ent = NULL;
a->offset = 0;
+ be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
be_node_set_reg_class(res, be_pos_Spill_val, cls);
return res;
}
-ir_node *be_new_Reload(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *mem, ir_mode *mode)
+ir_node *be_new_Reload(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
+ ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *mem, ir_mode *mode)
{
- ir_node *res = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 1, &mem);
+ ir_node *in[2];
+ ir_node *res;
+
+ in[0] = frame;
+ in[1] = mem;
+ res = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);
+
init_node_attr(res, 2);
be_node_set_reg_class(res, -1, cls);
+ be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
return res;
}
return get_irn_n(irn, be_pos_Reload_mem);
}
+ir_node *be_get_Reload_frame(const ir_node *irn)
+{
+ assert(be_is_Reload(irn));
+ return get_irn_n(irn, be_pos_Reload_frame);
+}
+
ir_node *be_get_Spill_val(const ir_node *irn)
{
assert(be_is_Spill(irn));
return get_irn_n(irn, be_pos_Spill_val);
}
+ir_node *be_get_Spill_frame(const ir_node *irn)
+{
+ assert(be_is_Spill(irn));
+ return get_irn_n(irn, be_pos_Spill_frame);
+}
ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
{
ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
{
- ir_node *bl = get_nodes_block(irn);
- ir_graph *irg = get_irn_irg(bl);
- const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, irn, -1);
+ ir_node *bl = get_nodes_block(irn);
+ ir_graph *irg = get_irn_irg(bl);
+ ir_node *frame = get_irg_frame(irg);
+ const arch_register_class_t *cls = arch_get_irn_reg_class(arch_env, irn, -1);
+ const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
ir_node *spill;
-
- spill = be_new_Spill(cls, irg, bl, irn);
+ spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
return spill;
}
ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *insert, ir_mode *mode, ir_node *spill)
{
ir_node *reload;
- ir_node *bl = is_Block(insert) ? insert : get_nodes_block(insert);
- ir_graph *irg = get_irn_irg(bl);
+ ir_node *bl = is_Block(insert) ? insert : get_nodes_block(insert);
+ ir_graph *irg = get_irn_irg(bl);
+ ir_node *frame = get_irg_frame(irg);
+ const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
assert(be_is_Spill(spill) || (is_Phi(spill) && get_irn_mode(spill) == mode_M));
- reload = be_new_Reload(cls, irg, bl, spill, mode);
+ reload = be_new_Reload(cls, cls_frame, irg, bl, frame, spill, mode);
- if(is_Block(insert)) {
+ if (is_Block(insert)) {
insert = sched_skip(insert, 0, sched_skip_cf_predicator, (void *) arch_env);
sched_add_after(insert, reload);
}
{
int out_pos = pos;
- if(pos < 0) {
- if(get_irn_mode(irn) == mode_T)
+ if (pos < 0) {
+ if (get_irn_mode(irn) == mode_T)
return NULL;
- out_pos = redir_proj((const ir_node **) &irn, pos);
+ out_pos = redir_proj((const ir_node **)&irn, pos);
assert(is_be_node(irn));
return put_out_reg_req(req, irn, out_pos);
}
else {
- return is_be_node(irn) ? put_in_reg_req(req, irn, pos) : NULL;
+ if (is_be_node(irn)) {
+ /*
+ For spills and reloads, we return "none" as requirement for frame pointer,
+ so every input is ok. Some backends need this (e.g. STA). We use an arbitrary
+ large number as pos, so put_in_reg_req will return "none" as requirement.
+ */
+ if ((be_is_Spill(irn) && pos == be_pos_Spill_frame) ||
+ (be_is_Reload(irn) && pos == be_pos_Reload_frame))
+ return put_in_reg_req(req, irn, INT_MAX);
+ else
+ return put_in_reg_req(req, irn, pos);
+ }
+ return NULL;
}
return req;
* Position numbers for the be_Spill inputs.
*/
enum {
- be_pos_Spill_val = 0
+ be_pos_Spill_frame = 0,
+ be_pos_Spill_val = 1
};
/**
* Make a new Spill node.
*/
-ir_node *be_new_Spill(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *node_to_spill);
+ir_node *be_new_Spill(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
+ ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *to_spill);
/**
* Position numbers for the be_Reload inputs.
*/
enum {
- be_pos_Reload_mem = 0
+ be_pos_Reload_frame = 0,
+ be_pos_Reload_mem = 1
};
/**
* Make a new Reload node.
*/
-ir_node *be_new_Reload(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *spill_node, ir_mode *mode);
+ir_node *be_new_Reload(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
+ ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *mem, ir_mode *mode);
/**
* Position numbers for the be_Copy inputs.
int be_get_frame_offset(const ir_node *irn);
ir_node* be_get_Reload_mem(const ir_node *irn);
+ir_node *be_get_Reload_frame(const ir_node *irn);
ir_node* be_get_Spill_val(const ir_node *irn);
+ir_node *be_get_Spill_frame(const ir_node *irn);
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity* ent);
ir_entity *be_get_MemPerm_in_entity(const ir_node *irn, int n);