Alternative fix for const functions with aggregate return
authorMatthias Braun <matze@braunis.de>
Mon, 5 Sep 2011 12:07:17 +0000 (14:07 +0200)
committerMatthias Braun <matze@braunis.de>
Tue, 6 Sep 2011 11:57:04 +0000 (13:57 +0200)
They really are const before lowering. So only mark the function
as non-const after lowering

This reverts commit 72c631f337f78b20460c508bd8af37fe67a5af37.

ir/lower/lower_calls.c
ir/opt/funccall.c

index f557ec4..9e57bef 100644 (file)
@@ -98,6 +98,7 @@ static ir_type *lower_mtp(compound_call_lowering_flags flags, ir_type *mtp)
        size_t    nn_ress;
        size_t    nn_params;
        size_t    i;
+       mtp_additional_properties mtp_properties;
 
        if (!is_Method_type(mtp))
                return mtp;
@@ -159,10 +160,14 @@ static ir_type *lower_mtp(compound_call_lowering_flags flags, ir_type *mtp)
 
        set_method_variadicity(lowered, get_method_variadicity(mtp));
 
-       /* associate the lowered type with the original one for easier access */
        set_method_calling_convention(lowered, get_method_calling_convention(mtp) | cc_compound_ret);
-       set_method_additional_properties(lowered, get_method_additional_properties(mtp));
+       mtp_properties = get_method_additional_properties(mtp);
+       /* after lowering the call is not const anymore, since it writes to the
+        * memory for the return value passed to it */
+       mtp_properties &= ~mtp_property_const;
+       set_method_additional_properties(lowered, mtp_properties);
 
+       /* associate the lowered type with the original one for easier access */
        set_lowered_type(mtp, lowered);
        pmap_insert(lowered_mtps, mtp, lowered);
 
@@ -486,9 +491,14 @@ static void add_hidden_param(ir_graph *irg, size_t n_com, ir_node **ins,
                n = (ir_node*)get_irn_link(p);
 
                ins[idx] = get_CopyB_dst(p);
-               mem      = get_CopyB_mem(p);
                blk      = get_nodes_block(p);
 
+               /* use the memory output of the call and not the input of the CopyB
+                * otherwise stuff breaks if the call was mtp_property_const, because
+                * then the copyb skips the call. But after lowering the call is not
+                * const anymore, and its memory has to be used */
+               mem = new_r_Proj(entry->call, mode_M, pn_Call_M);
+
                /* get rid of the CopyB */
                turn_into_tuple(p, pn_CopyB_max+1);
                set_Tuple_pred(p, pn_CopyB_M,         mem);
index 3307833..256e32c 100644 (file)
@@ -71,23 +71,6 @@ static unsigned *busy_set;
  */
 #define mtp_temporary  mtp_property_inherited
 
-static bool has_compound_return_type(ir_node *node)
-{
-       ir_type *mtp   = get_Call_type(node);
-       size_t   n_res = get_method_n_ress(mtp);
-       size_t   i;
-
-       for (i = 0; i < n_res; ++i) {
-               ir_type *rtp = get_method_res_type(mtp, i);
-
-               if (is_compound_type(rtp)) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
 /**
  * Walker: Collect all calls to const and pure functions
  * to lists. Collect all Proj(Call) nodes into a Proj list.
@@ -105,16 +88,6 @@ static void collect_const_and_pure_calls(ir_node *node, void *env)
 
                /* set the link to NULL for all non-const/pure calls */
                set_irn_link(call, NULL);
-
-               /* If the backend's calling convention handles compound return types
-                * via a hidden pointer argument, it is incorrect to regard this
-                * call as a call to a const/pure function.
-                * TODO:  This might be overly conservative if the backend uses
-                *        a different calling convention, e.g., for small structs. */
-               if (has_compound_return_type(node)) {
-                       return;
-               }
-
                ptr = get_Call_ptr(call);
                if (is_Global(ptr)) {
                        ent = get_Global_entity(ptr);