From patchwork Tue Mar 15 11:22:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 86941 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 96401B700B for ; Tue, 15 Mar 2011 22:22:15 +1100 (EST) Received: (qmail 4434 invoked by alias); 15 Mar 2011 11:22:13 -0000 Received: (qmail 4424 invoked by uid 22791); 15 Mar 2011 11:22:11 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_FN, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 15 Mar 2011 11:22:05 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p2FBM4RH016469 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 15 Mar 2011 07:22:04 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p2FBM3DG017728 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 15 Mar 2011 07:22:03 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p2FBM2nr008567; Tue, 15 Mar 2011 12:22:02 +0100 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p2FBM2ma008565; Tue, 15 Mar 2011 12:22:02 +0100 Date: Tue, 15 Mar 2011 12:22:02 +0100 From: Jakub Jelinek To: Richard Henderson , Cary Coutant , Jason Merrill Cc: gcc-patches@gcc.gnu.org, Roland McGrath Subject: [PATCH] Adjustment to DW_TAG_GNU_call_site patch for ICF debug Message-ID: <20110315112202.GY30899@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi! Here is the http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01795.html patch updated to current trunk, bootstrapped/regtested on x86_64-linux and i686-linux. Ok for trunk? 2011-03-15 Jakub Jelinek * calls.c (emit_call_1): Set MEM_EXPR on call's MEM. * var-tracking.c (prepare_call_arguments): Use MEM_EXPR on call's MEM. Handle functions returning aggregate through a hidden first pointer. For virtual calls add clobbered pc to call arguments chain. * dwarf2out.c (gen_subprogram_die): Emit DW_AT_GNU_call_site_target_clobbered if DW_AT_GNU_call_site_target can't be emitted. Jakub --- gcc/calls.c.jj 2010-12-22 10:17:25.000000000 +0100 +++ gcc/calls.c 2010-12-22 14:09:52.000000000 +0100 @@ -256,7 +256,7 @@ emit_call_1 (rtx funexp, tree fntree ATT CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED) { rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size); - rtx call_insn; + rtx call_insn, call, funmem; int already_popped = 0; HOST_WIDE_INT n_popped = targetm.calls.return_pops_args (fndecl, funtype, stack_size); @@ -271,6 +271,12 @@ emit_call_1 (rtx funexp, tree fntree ATT if (GET_CODE (funexp) != SYMBOL_REF) funexp = memory_address (FUNCTION_MODE, funexp); + funmem = gen_rtx_MEM (FUNCTION_MODE, funexp); + if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL) + set_mem_expr (funmem, fndecl); + else if (fntree) + set_mem_expr (funmem, build_fold_indirect_ref (CALL_EXPR_FN (fntree))); + #if defined (HAVE_sibcall_pop) && defined (HAVE_sibcall_value_pop) if ((ecf_flags & ECF_SIBCALL) && HAVE_sibcall_pop && HAVE_sibcall_value_pop @@ -283,13 +289,11 @@ emit_call_1 (rtx funexp, tree fntree ATT if possible, for the sake of frame pointer elimination. */ if (valreg) - pat = GEN_SIBCALL_VALUE_POP (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - n_pop); + pat = GEN_SIBCALL_VALUE_POP (valreg, funmem, rounded_stack_size_rtx, + next_arg_reg, n_pop); else - pat = GEN_SIBCALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_SIBCALL_POP (funmem, rounded_stack_size_rtx, next_arg_reg, + n_pop); emit_call_insn (pat); already_popped = 1; @@ -316,12 +320,11 @@ emit_call_1 (rtx funexp, tree fntree ATT if possible, for the sake of frame pointer elimination. */ if (valreg) - pat = GEN_CALL_VALUE_POP (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_CALL_VALUE_POP (valreg, funmem, rounded_stack_size_rtx, + next_arg_reg, n_pop); else - pat = GEN_CALL_POP (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, n_pop); + pat = GEN_CALL_POP (funmem, rounded_stack_size_rtx, next_arg_reg, + n_pop); emit_call_insn (pat); already_popped = 1; @@ -334,13 +337,12 @@ emit_call_1 (rtx funexp, tree fntree ATT && HAVE_sibcall && HAVE_sibcall_value) { if (valreg) - emit_call_insn (GEN_SIBCALL_VALUE (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), + emit_call_insn (GEN_SIBCALL_VALUE (valreg, funmem, rounded_stack_size_rtx, next_arg_reg, NULL_RTX)); else - emit_call_insn (GEN_SIBCALL (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, + emit_call_insn (GEN_SIBCALL (funmem, rounded_stack_size_rtx, + next_arg_reg, GEN_INT (struct_value_size))); } else @@ -350,13 +352,10 @@ emit_call_1 (rtx funexp, tree fntree ATT if (HAVE_call && HAVE_call_value) { if (valreg) - emit_call_insn (GEN_CALL_VALUE (valreg, - gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, - NULL_RTX)); + emit_call_insn (GEN_CALL_VALUE (valreg, funmem, rounded_stack_size_rtx, + next_arg_reg, NULL_RTX)); else - emit_call_insn (GEN_CALL (gen_rtx_MEM (FUNCTION_MODE, funexp), - rounded_stack_size_rtx, next_arg_reg, + emit_call_insn (GEN_CALL (funmem, rounded_stack_size_rtx, next_arg_reg, GEN_INT (struct_value_size))); } else @@ -366,6 +365,19 @@ emit_call_1 (rtx funexp, tree fntree ATT /* Find the call we just emitted. */ call_insn = last_call_insn (); + /* Some target create a fresh MEM instead of reusing the one provided + above. Set its MEM_EXPR. */ + call = PATTERN (call_insn); + if (GET_CODE (call) == PARALLEL) + call = XVECEXP (call, 0, 0); + if (GET_CODE (call) == SET) + call = SET_SRC (call); + if (GET_CODE (call) == CALL + && MEM_P (XEXP (call, 0)) + && MEM_EXPR (XEXP (call, 0)) == NULL_TREE + && MEM_EXPR (funmem) != NULL_TREE) + set_mem_expr (XEXP (call, 0), MEM_EXPR (funmem)); + /* Put the register usage information there. */ add_function_usage_to (call_insn, call_fusage); --- gcc/var-tracking.c.jj 2010-12-22 15:09:56.000000000 +0100 +++ gcc/var-tracking.c 2010-12-23 10:11:00.000000000 +0100 @@ -5557,7 +5557,9 @@ prepare_call_arguments (basic_block bb, rtx link, x; rtx prev, cur, next; rtx call = PATTERN (insn); - tree type = NULL_TREE, t; + rtx this_arg = NULL_RTX; + tree type = NULL_TREE, t, fndecl = NULL_TREE; + tree obj_type_ref = NULL_TREE; CUMULATIVE_ARGS args_so_far; memset (&args_so_far, 0, sizeof (args_so_far)); @@ -5565,27 +5567,91 @@ prepare_call_arguments (basic_block bb, call = XVECEXP (call, 0, 0); if (GET_CODE (call) == SET) call = SET_SRC (call); - if (GET_CODE (call) == CALL - && MEM_P (XEXP (call, 0)) - && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) - { - rtx symbol = XEXP (XEXP (call, 0), 0); - if (SYMBOL_REF_DECL (symbol) - && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL - && TYPE_ARG_TYPES (TREE_TYPE (SYMBOL_REF_DECL (symbol)))) + if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0))) + { + if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) + { + rtx symbol = XEXP (XEXP (call, 0), 0); + if (SYMBOL_REF_DECL (symbol)) + fndecl = SYMBOL_REF_DECL (symbol); + } + if (fndecl == NULL_TREE) + fndecl = MEM_EXPR (XEXP (call, 0)); + if (fndecl + && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE + && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE) + fndecl = NULL_TREE; + if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl))) + type = TREE_TYPE (fndecl); + if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL) + { + if (TREE_CODE (fndecl) == INDIRECT_REF + && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF) + obj_type_ref = TREE_OPERAND (fndecl, 0); + fndecl = NULL_TREE; + } + if (type) { - type = TREE_TYPE (SYMBOL_REF_DECL (symbol)); for (t = TYPE_ARG_TYPES (type); t && t != void_list_node; t = TREE_CHAIN (t)) if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t)))) break; - if (t == NULL || t == void_list_node) + if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE) type = NULL; else - INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX, - SYMBOL_REF_DECL (symbol), - list_length (TYPE_ARG_TYPES (type))); + { + int nargs = list_length (TYPE_ARG_TYPES (type)); + link = CALL_INSN_FUNCTION_USAGE (insn); +#ifndef PCC_STATIC_STRUCT_RETURN + if (aggregate_value_p (TREE_TYPE (type), type) + && targetm.calls.struct_value_rtx (type, 0) == 0) + { + tree struct_addr = build_pointer_type (TREE_TYPE (type)); + enum machine_mode mode = TYPE_MODE (struct_addr); + rtx reg; + INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX, fndecl, + nargs + 1); + reg = targetm.calls.function_arg (&args_so_far, mode, + struct_addr, true); + targetm.calls.function_arg_advance (&args_so_far, mode, + struct_addr, true); + if (reg == NULL_RTX) + { + for (; link; link = XEXP (link, 1)) + if (GET_CODE (XEXP (link, 0)) == USE + && MEM_P (XEXP (XEXP (link, 0), 0))) + { + link = XEXP (link, 1); + break; + } + } + } +#endif + else + INIT_CUMULATIVE_ARGS (args_so_far, type, NULL_RTX, fndecl, + nargs); + if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node) + { + enum machine_mode mode; + t = TYPE_ARG_TYPES (type); + mode = TYPE_MODE (TREE_VALUE (t)); + this_arg = targetm.calls.function_arg (&args_so_far, mode, + TREE_VALUE (t), true); + if (this_arg && !REG_P (this_arg)) + this_arg = NULL_RTX; + else if (this_arg == NULL_RTX) + { + for (; link; link = XEXP (link, 1)) + if (GET_CODE (XEXP (link, 0)) == USE + && MEM_P (XEXP (XEXP (link, 0), 0))) + { + this_arg = XEXP (XEXP (link, 0), 0); + break; + } + } + } + } } } t = type ? TYPE_ARG_TYPES (type) : NULL_TREE; @@ -5733,6 +5799,20 @@ prepare_call_arguments (basic_block bb, } } } + if (this_arg) + { + enum machine_mode mode + = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref))); + rtx clobbered = gen_rtx_MEM (mode, this_arg); + HOST_WIDE_INT token + = tree_low_cst (OBJ_TYPE_REF_TOKEN (obj_type_ref), 0); + if (token) + clobbered = plus_constant (clobbered, token * GET_MODE_SIZE (mode)); + clobbered = gen_rtx_MEM (mode, clobbered); + x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered); + call_arguments + = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments); + } } /* Callback for cselib_record_sets_hook, that records as micro --- gcc/dwarf2out.c.jj 2010-12-22 12:32:47.000000000 +0100 +++ gcc/dwarf2out.c 2010-12-23 09:40:43.000000000 +0100 @@ -19418,7 +19418,7 @@ gen_subprogram_die (tree decl, dw_die_re for (ca_loc = call_arg_locations; ca_loc; ca_loc = ca_loc->next) { dw_die_ref die = NULL; - rtx tloc = NULL_RTX; + rtx tloc = NULL_RTX, tlocc = NULL_RTX; rtx arg, next_arg; for (arg = NOTE_VAR_LOCATION (ca_loc->call_arg_loc_note); @@ -19447,6 +19447,13 @@ gen_subprogram_die (tree decl, dw_die_re tloc = XEXP (XEXP (arg, 0), 1); continue; } + else if (GET_CODE (XEXP (XEXP (arg, 0), 0)) == CLOBBER + && XEXP (XEXP (XEXP (arg, 0), 0), 0) == pc_rtx) + { + gcc_assert (ca_loc->symbol_ref == NULL_RTX); + tlocc = XEXP (XEXP (arg, 0), 1); + continue; + } if (REG_P (XEXP (XEXP (arg, 0), 0))) reg = reg_loc_descriptor (XEXP (XEXP (arg, 0), 0), VAR_INIT_STATUS_INITIALIZED); @@ -19480,13 +19487,23 @@ gen_subprogram_die (tree decl, dw_die_re if (die == NULL && (ca_loc->symbol_ref || tloc)) die = gen_call_site_die (decl, subr_die, ca_loc); - if (die != NULL && tloc != NULL_RTX) + if (die != NULL && (tloc != NULL_RTX || tlocc != NULL_RTX)) { - dw_loc_descr_ref tval - = mem_loc_descriptor (tloc, VOIDmode, - VAR_INIT_STATUS_INITIALIZED); + dw_loc_descr_ref tval = NULL; + + if (tloc != NULL_RTX) + tval = mem_loc_descriptor (tloc, VOIDmode, + VAR_INIT_STATUS_INITIALIZED); if (tval) add_AT_loc (die, DW_AT_GNU_call_site_target, tval); + else if (tlocc != NULL_RTX) + { + tval = mem_loc_descriptor (tlocc, VOIDmode, + VAR_INIT_STATUS_INITIALIZED); + if (tval) + add_AT_loc (die, DW_AT_GNU_call_site_target_clobbered, + tval); + } } if (die != NULL) {