This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Allow ipa-split to handle DECL_BY_REFERENCE retvals


Hi,
this patch enables handing of DECL_BY_REFERENCE in ipa-split.  It is relative to ipa-split
with the patch allowing structure returns I posted earlier.
The problem here is that we need to enable return slot optimization for the call
and we need to produce *<retval> = fncall.part () since retval is pointer.
(I hope this is valid gimple as call is store to non-register)

Bootstrapped/regtested x86_64-linux, seems sane?

Honza

	* ipa-split.c (split_function): For aggregate values set return_slot_opt;
	when passing DECL_BY_REFERENCE produce *<retval> = fncall.part ()
	(execute_split_functions): Do not care about DECL_BY_REFERENCE.
*** /home/jh/pretty-ipa2/gcc/ipa-split.c	Thu Jul  1 16:09:51 2010
--- ipa-split.c	Thu Jul  1 16:01:59 2010
*************** split_function (struct split_point *spli
*** 949,954 ****
--- 949,961 ----
    call = gimple_build_call_vec (node->decl, args_to_pass);
    gimple_set_block (call, DECL_INITIAL (current_function_decl));
  
+   /* We avoid address being taken on any variable used by split part,
+      so return slot optimization is always possible.  Moreover this is
+      required to make DECL_BY_REFERENCE work.  */
+   if (aggregate_value_p (DECL_RESULT (current_function_decl),
+ 			 TREE_TYPE (current_function_decl)))
+     gimple_call_set_return_slot_opt (call, true);
+ 
    /* Update return value.  This is bit tricky.  When we do not return,
       do nothing.  When we return we might need to update return_bb
       or produce a new return statement.  */
*************** split_function (struct split_point *spli
*** 1002,1008 ****
  		      update_stmt (gsi_stmt (bsi));
  		    }
  		}
! 	      gimple_call_set_lhs (call, retval);
  	    }
            gsi_insert_after (&gsi, call, GSI_NEW_STMT);
  	}
--- 1010,1019 ----
  		      update_stmt (gsi_stmt (bsi));
  		    }
  		}
! 	      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
! 	        gimple_call_set_lhs (call, build_simple_mem_ref (retval));
! 	      else
! 	        gimple_call_set_lhs (call, retval);
  	    }
            gsi_insert_after (&gsi, call, GSI_NEW_STMT);
  	}
*************** split_function (struct split_point *spli
*** 1021,1027 ****
  		retval = create_tmp_reg (TREE_TYPE (retval), NULL);
  	      if (is_gimple_reg (retval))
  		retval = make_ssa_name (retval, call);
! 	      gimple_call_set_lhs (call, retval);
  	    }
            gsi_insert_after (&gsi, call, GSI_NEW_STMT);
  	  ret = gimple_build_return (retval);
--- 1032,1041 ----
  		retval = create_tmp_reg (TREE_TYPE (retval), NULL);
  	      if (is_gimple_reg (retval))
  		retval = make_ssa_name (retval, call);
! 	      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
! 	        gimple_call_set_lhs (call, build_simple_mem_ref (retval));
! 	      else
! 	        gimple_call_set_lhs (call, retval);
  	    }
            gsi_insert_after (&gsi, call, GSI_NEW_STMT);
  	  ret = gimple_build_return (retval);
*************** execute_split_functions (void)
*** 1085,1097 ****
  	fprintf (dump_file, "Not splitting: nested function.\n");
        return 0;
      }
-   /* FIXME: Should be easy to support.  */
-   if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
-     {
-       if (dump_file)
- 	fprintf (dump_file, "Not splitting: returns value by reference.\n");
-       return 0;
-     }
  
    /* See if it makes sense to try to split.
       It makes sense to split if we inline, that is if we have direct calls to
--- 1099,1104 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]