Really fix the endless loop.
[libfirm] / ir / be / beabi.c
index cdc93db..818b871 100644 (file)
@@ -1555,14 +1555,15 @@ static ir_node *create_be_return(be_abi_irg_t *env, ir_node *irn, ir_node *bl, i
 typedef struct lower_frame_sels_env_t {
        be_abi_irg_t *env;
        ir_entity    *value_param_list;  /**< the list of all value param entities */
+       ir_entity    *value_param_tail;  /**< the tail of the list of all value param entities */
 } lower_frame_sels_env_t;
 
 /**
  * Walker: Replaces Sels of frame type and
  * value param type entities by FrameAddress.
+ * Links all used entities.
  */
-static void lower_frame_sels_walker(ir_node *irn, void *data)
-{
+static void lower_frame_sels_walker(ir_node *irn, void *data) {
        lower_frame_sels_env_t *ctx = data;
 
        if (is_Sel(irn)) {
@@ -1580,10 +1581,13 @@ static void lower_frame_sels_walker(ir_node *irn, void *data)
                        nw = be_new_FrameAddr(env->isa->sp->reg_class, irg, bl, frame, ent);
                        exchange(irn, nw);
 
-                       /* 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) {
+                       /* check, if it's a param sel and if have not seen this entity before */
+                       if (ptr == param_base &&
+                                       ent != ctx->value_param_tail &&
+                                       get_entity_link(ent) == NULL) {
                                set_entity_link(ent, ctx->value_param_list);
                                ctx->value_param_list = ent;
+                               if (ctx->value_param_tail == NULL) ctx->value_param_tail = ent;
                        }
                }
        }
@@ -1756,7 +1760,7 @@ static void modify_irg(be_abi_irg_t *env)
        ir_node *arg_tuple;
        ir_node *value_param_base;
        const ir_edge_t *edge;
-       ir_type *arg_type, *bet_type;
+       ir_type *arg_type, *bet_type, *tp;
        lower_frame_sels_env_t ctx;
        ir_entity **param_map;
 
@@ -1765,9 +1769,18 @@ static void modify_irg(be_abi_irg_t *env)
 
        DBG((dbg, LEVEL_1, "introducing abi on %+F\n", irg));
 
+       /* set the links of all frame entities to NULL, we use it
+          to detect if an entity is already linked in the value_param_list */
+       tp = get_method_value_param_type(method_type);
+       if (tp != NULL) {
+               for (i = get_struct_n_members(tp) - 1; i >= 0; --i)
+                       set_entity_link(get_struct_member(tp, i), NULL);
+       }
+
        /* Convert the Sel nodes in the irg to frame load/store/addr nodes. */
        ctx.env              = env;
        ctx.value_param_list = NULL;
+       ctx.value_param_tail = NULL;
        irg_walk_graph(irg, lower_frame_sels_walker, NULL, &ctx);
 
        /* value_param_base anchor is not needed anymore now */