+/**
+ * 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_graph *irg,
+ ent_pos_pair *value_param_list)
+{
+ be_abi_call_t *call = env->call;
+ const arch_env_t *arch_env = be_get_irg_arch_env(irg);
+ ent_pos_pair *entry, *new_list;
+ ir_type *frame_tp;
+ int i, n = ARR_LEN(value_param_list);
+
+ new_list = NULL;
+ for (i = 0; i < n; ++i) {
+ int pos = value_param_list[i].pos;
+ be_abi_call_arg_t *arg = get_call_arg(call, 0, pos, 1);
+
+ if (arg->in_reg) {
+ DBG((dbg, LEVEL_2, "\targ #%d need backing store\n", pos));
+ value_param_list[i].next = new_list;
+ new_list = &value_param_list[i];
+ }
+ }
+ if (new_list != NULL) {
+ /* ok, change the graph */
+ ir_node *start_bl = get_irg_start_block(irg);
+ ir_node *first_bl = get_first_block_succ(start_bl);
+ ir_node *frame, *imem, *nmem, *store, *mem, *args;
+ optimization_state_t state;
+ unsigned offset;
+
+ assert(first_bl && first_bl != start_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(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);
+
+ store = NULL;
+ mem = imem;
+ args = get_irg_args(irg);
+ for (entry = new_list; entry != NULL; entry = entry->next) {
+ int i = entry->pos;
+ ir_type *tp = get_entity_type(entry->ent);
+ ir_mode *mode = get_type_mode(tp);
+ ir_node *addr;
+
+ /* address for the backing store */
+ addr = be_new_FrameAddr(arch_env->sp->reg_class, first_bl, frame, entry->ent);
+
+ if (store)
+ mem = new_r_Proj(store, mode_M, pn_Store_M);
+
+ /* the backing store itself */
+ store = new_r_Store(first_bl, mem, addr,
+ new_r_Proj(args, mode, i), cons_none);
+ }
+ /* the new memory Proj gets the last Proj from store */
+ set_Proj_pred(nmem, store);
+ set_Proj_proj(nmem, pn_Store_M);
+
+ /* move all entities to the frame type */
+ frame_tp = get_irg_frame_type(irg);
+ offset = get_type_size_bytes(frame_tp);
+
+ /* we will add new entities: set the layout to undefined */
+ assert(get_type_state(frame_tp) == layout_fixed);
+ set_type_state(frame_tp, layout_undefined);
+ for (entry = new_list; entry != NULL; entry = entry->next) {
+ ir_entity *ent = entry->ent;
+
+ /* If the entity is still on the argument type, move it to the
+ * frame type.
+ * This happens if the value_param type was build due to compound
+ * params. */
+ if (get_entity_owner(ent) != frame_tp) {
+ ir_type *tp = get_entity_type(ent);
+ unsigned align = get_type_alignment_bytes(tp);
+
+ offset += align - 1;
+ offset &= ~(align - 1);
+ set_entity_owner(ent, frame_tp);
+ /* must be automatic to set a fixed layout */
+ set_entity_offset(ent, offset);
+ offset += get_type_size_bytes(tp);
+ }
+ }
+ set_type_size_bytes(frame_tp, offset);
+ /* fix the layout again */
+ set_type_state(frame_tp, layout_fixed);
+ }
+}