-
- /* check, if it's a param sel and if have not seen this entity immediatly before */
- if (ptr == param_base && ctx->value_param_list != ent) {
- set_entity_link(ent, ctx->value_param_list);
- ctx->value_param_list = ent;
- }
- }
- }
-}
-
-/**
- * Check if a value parameter is transmitted as a register.
- * This might happen if the address of an parameter is taken which is
- * transmitted in registers.
- *
- * Note that on some architectures this case must be handled specially
- * because the place of the backing store is determined by their ABI.
- *
- * In the default case we move the entity to the frame type and create
- * a backing store into the first block.
- */
-static void fix_address_of_parameter_access(be_abi_irg_t *env, ir_entity *value_param_list) {
- be_abi_call_t *call = env->call;
- ir_graph *irg = env->birg->irg;
- ir_entity *ent, *next_ent, *new_list;
- ir_type *frame_tp;
- DEBUG_ONLY(firm_dbg_module_t *dbg = env->dbg;)
-
- new_list = NULL;
- for (ent = value_param_list; ent; ent = next_ent) {
- int i = get_struct_member_index(get_entity_owner(ent), ent);
- be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
-
- next_ent = get_entity_link(ent);
- if (arg->in_reg) {
- DBG((dbg, LEVEL_2, "\targ #%d need backing store\n", i));
- set_entity_link(ent, new_list);
- new_list = ent;
- }
- }
- if (new_list) {
- /* ok, change the graph */
- ir_node *start_bl = get_irg_start_block(irg);
- ir_node *first_bl = NULL;
- ir_node *frame, *imem, *nmem, *store, *mem, *args, *args_bl;
- const ir_edge_t *edge;
- optimization_state_t state;
- int offset;
-
- foreach_block_succ(start_bl, edge) {
- ir_node *succ = get_edge_src_irn(edge);
- if (start_bl != succ) {
- first_bl = succ;
- break;
- }
- }
- assert(first_bl);
- /* we had already removed critical edges, so the following
- assertion should be always true. */
- assert(get_Block_n_cfgpreds(first_bl) == 1);
-
- /* now create backing stores */
- frame = get_irg_frame(irg);
- imem = get_irg_initial_mem(irg);
-
- save_optimization_state(&state);
- set_optimize(0);
- nmem = new_r_Proj(irg, first_bl, get_irg_start(irg), mode_M, pn_Start_M);
- restore_optimization_state(&state);
-
- /* reroute all edges to the new memory source */
- edges_reroute(imem, nmem, irg);
-
- store = NULL;
- mem = imem;
- args = get_irg_args(irg);
- args_bl = get_nodes_block(args);
- for (ent = new_list; ent; ent = get_entity_link(ent)) {
- int i = get_struct_member_index(get_entity_owner(ent), ent);
- ir_type *tp = get_entity_type(ent);
- ir_mode *mode = get_type_mode(tp);
- ir_node *addr;
-
- /* address for the backing store */
- addr = be_new_FrameAddr(env->isa->sp->reg_class, irg, first_bl, frame, ent);
-
- if (store)
- mem = new_r_Proj(irg, first_bl, store, mode_M, pn_Store_M);
-
- /* the backing store itself */
- store = new_r_Store(irg, first_bl, mem, addr,
- new_r_Proj(irg, args_bl, args, mode, i));