fix an intrinsic lower not reporting changes
[libfirm] / ir / lower / lower_dw.c
index 0db3f1d..936e07c 100644 (file)
@@ -139,6 +139,7 @@ struct lower_env_t {
 };
 
 static void lower_node(lower_env_t *env, ir_node *node);
+static bool mtp_must_be_lowered(lower_env_t *env, ir_type *mtp);
 
 /**
  * Create a method type for a Conv emulation from imode to omode.
@@ -1432,9 +1433,6 @@ static ir_type *lower_mtp(lower_env_t *env, ir_type *mtp)
        pmap_entry *entry;
        ir_type    *res, *value_type;
 
-       if (is_lowered_type(mtp))
-               return mtp;
-
        entry = pmap_find(lowered_type, mtp);
        if (! entry) {
                size_t i, orig_n_params, orig_n_res, n_param, n_res;
@@ -1599,29 +1597,21 @@ static void lower_Start(ir_node *node, ir_mode *mode, lower_env_t *env)
        ir_graph  *irg = get_irn_irg(node);
        ir_entity *ent = get_irg_entity(irg);
        ir_type   *tp  = get_entity_type(ent);
-       ir_type   *mtp;
        long      *new_projs;
        size_t    i, j, n_params;
        int       rem;
        ir_node   *proj, *args;
        (void) mode;
 
-       if (is_lowered_type(tp)) {
-               mtp = get_associated_type(tp);
-       } else {
-               mtp = tp;
-       }
-       assert(! is_lowered_type(mtp));
+       if (!mtp_must_be_lowered(env, tp)) return;
 
-       n_params = get_method_n_params(mtp);
-       if (n_params <= 0)
-               return;
+       n_params = get_method_n_params(tp);
 
        NEW_ARR_A(long, new_projs, n_params);
 
-       /* first check if we have parameters that must be fixed */
+       /* Calculate mapping of proj numbers in new_projs */
        for (i = j = 0; i < n_params; ++i, ++j) {
-               ir_type *ptp = get_method_param_type(mtp, i);
+               ir_type *ptp = get_method_param_type(tp, i);
 
                new_projs[i] = j;
                if (is_Primitive_type(ptp)) {
@@ -1632,18 +1622,17 @@ static void lower_Start(ir_node *node, ir_mode *mode, lower_env_t *env)
                                ++j;
                }
        }
-       if (i == j)
-               return;
 
-       mtp = lower_mtp(env, mtp);
-       set_entity_type(ent, mtp);
+       /* lower method type */
+       tp = lower_mtp(env, tp);
+       set_entity_type(ent, tp);
 
        /* switch off optimization for new Proj nodes or they might be CSE'ed
           with not patched one's */
        rem = get_optimize();
        set_optimize(0);
 
-       /* ok, fix all Proj's and create new ones */
+       /* fix all Proj's and create new ones */
        args = get_irg_args(irg);
        for (proj = (ir_node*)get_irn_link(node); proj;
             proj = (ir_node*)get_irn_link(proj)) {
@@ -1689,7 +1678,6 @@ static void lower_Start(ir_node *node, ir_mode *mode, lower_env_t *env)
 static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env)
 {
        ir_type  *tp = get_Call_type(node);
-       ir_type  *call_tp;
        ir_node  **in, *proj, *results;
        size_t   n_params, n_res;
        bool     need_lower = false;
@@ -1698,20 +1686,12 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env)
        long     *res_numbers = NULL;
        (void) mode;
 
-       if (is_lowered_type(tp)) {
-               call_tp = get_associated_type(tp);
-       } else {
-               call_tp = tp;
-       }
-
-       assert(! is_lowered_type(call_tp));
-
-       n_params = get_method_n_params(call_tp);
+       n_params = get_method_n_params(tp);
        for (p = 0; p < n_params; ++p) {
-               ir_type *tp = get_method_param_type(call_tp, p);
+               ir_type *ptp = get_method_param_type(tp, p);
 
-               if (is_Primitive_type(tp)) {
-                       ir_mode *mode = get_type_mode(tp);
+               if (is_Primitive_type(ptp)) {
+                       ir_mode *mode = get_type_mode(ptp);
 
                        if (mode == env->high_signed || mode == env->high_unsigned) {
                                need_lower = true;
@@ -1719,16 +1699,16 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env)
                        }
                }
        }
-       n_res = get_method_n_ress(call_tp);
+       n_res = get_method_n_ress(tp);
        if (n_res > 0) {
                NEW_ARR_A(long, res_numbers, n_res);
 
                for (i = j = 0; i < n_res; ++i, ++j) {
-                       ir_type *tp = get_method_res_type(call_tp, i);
+                       ir_type *ptp = get_method_res_type(tp, i);
 
                        res_numbers[i] = j;
-                       if (is_Primitive_type(tp)) {
-                               ir_mode *mode = get_type_mode(tp);
+                       if (is_Primitive_type(ptp)) {
+                               ir_mode *mode = get_type_mode(ptp);
 
                                if (mode == env->high_signed || mode == env->high_unsigned) {
                                        need_lower = true;
@@ -1742,10 +1722,10 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env)
                return;
 
        /* let's lower it */
-       call_tp = lower_mtp(env, call_tp);
-       set_Call_type(node, call_tp);
+       tp = lower_mtp(env, tp);
+       set_Call_type(node, tp);
 
-       NEW_ARR_A(ir_node *, in, get_method_n_params(call_tp) + 2);
+       NEW_ARR_A(ir_node *, in, get_method_n_params(tp) + 2);
 
        in[0] = get_Call_mem(node);
        in[1] = get_Call_ptr(node);
@@ -2233,9 +2213,8 @@ static void lower_node(lower_env_t *env, ir_node *node)
        unsigned      idx;
        node_entry_t *entry;
 
-       if (irn_visited(node))
+       if (irn_visited_else_mark(node))
                return;
-       mark_irn_visited(node);
 
        /* cycles are always broken at Phi and Block nodes. So we don't need special
         * magic in all the other lower functions */
@@ -2305,8 +2284,8 @@ static void lower_irg(lower_env_t *env, ir_graph *irg)
 
        if (mtp_must_be_lowered(env, mtp)) {
                ir_type *ltp = lower_mtp(env, mtp);
+               /* Do not update the entity type yet, this will be done by lower_Start! */
                env->flags |= MUST_BE_LOWERED;
-               set_entity_type(ent, ltp);
                env->l_mtp = ltp;
                env->value_param_tp = get_method_value_param_type(mtp);
        }