From patchwork Wed Dec 16 13:53:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 557472 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B89091402BC for ; Thu, 17 Dec 2015 00:54:06 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ZBpaZe2I; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=IF5L4xLr6aP2drSRQiv6tv9o9h7DfC9hKoGuAXDYKk5IwC5JwW avxOLA7+Uh2eZ6lmjyiBa8L7L37fVo/DCLjnCdJYTS7DVRAN2IMbAya/EQKezXGr y65Pp51CFMkMYGzd/GOWsbPEP0eVDkpmMMdMbxOVgGMpqNdGQh3z3uCXc= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=bcn75FDE/HEwoX7j1rq4VxOtFws=; b=ZBpaZe2I8OA2O1yXOgWg JQ5VBmjOhCR4eTfGwCu3oe90JX0FD78THHatry6hwQEGXb+NSkvqzswbi9N8DMH0 gl3B1P8uUiigb6iLpsLU8WZgiF5br+W0UfeqXDlZe8RTKucytaqEBCdP6yfvdbKI 92gPy3F84OgHf/iBk0HmCZk= Received: (qmail 37993 invoked by alias); 16 Dec 2015 13:53:57 -0000 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 Received: (qmail 37982 invoked by uid 89); 16 Dec 2015 13:53:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.9 required=5.0 tests=BAYES_50, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 X-HELO: mail-qk0-f179.google.com Received: from mail-qk0-f179.google.com (HELO mail-qk0-f179.google.com) (209.85.220.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 16 Dec 2015 13:53:55 +0000 Received: by mail-qk0-f179.google.com with SMTP id t125so63790146qkh.3 for ; Wed, 16 Dec 2015 05:53:54 -0800 (PST) X-Received: by 10.55.21.156 with SMTP id 28mr57504972qkv.7.1450274032740; Wed, 16 Dec 2015 05:53:52 -0800 (PST) Received: from ?IPv6:2601:181:c000:c497:a2a8:cdff:fe3e:b48? ([2601:181:c000:c497:a2a8:cdff:fe3e:b48]) by smtp.googlemail.com with ESMTPSA id f32sm2630572qga.1.2015.12.16.05.53.51 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 16 Dec 2015 05:53:52 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: [PTX] simplify calling struct Message-ID: <56716CEF.9060709@acm.org> Date: Wed, 16 Dec 2015 08:53:51 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 PTX's machine_function structure squirrels away the function type to calculate the presence of varadic args later, rather than calculate it immediately. It also uses an rtx field as a boolean. This patch reorganizes it with less verbose names and more apt types. I also noticed that nvptx_hard_regno_mode_ok wasn't being used, so that's deleted. nathan 2015-12-16 Nathan Sidwell * config/nvptx/nvptx-protos.h (nvptx_hard_regno_mode_ok): Delete. * config/nvptx/nvptx.h (struct machine_function): Reimplement. Adjust all users. * config/nvptx/nvptx.c (nvptx_declare_function_name): Move stack and frame array generation earlier. (nvptx_call_args): Reimplement. (nvptx_expand_call): Adjust. (nvptx_hard_reno_mode_ok): Delete. (nvptx_reorg): Revert scan of hard regs. Index: config/nvptx/nvptx-protos.h =================================================================== --- config/nvptx/nvptx-protos.h (revision 231689) +++ config/nvptx/nvptx-protos.h (working copy) @@ -41,7 +41,6 @@ extern const char *nvptx_ptx_type_from_m extern const char *nvptx_output_mov_insn (rtx, rtx); extern const char *nvptx_output_call_insn (rtx_insn *, rtx, rtx); extern const char *nvptx_output_return (void); -extern bool nvptx_hard_regno_mode_ok (int, machine_mode); extern rtx nvptx_maybe_convert_symbolic_operand (rtx); #endif #endif Index: config/nvptx/nvptx.c =================================================================== --- config/nvptx/nvptx.c (revision 231689) +++ config/nvptx/nvptx.c (working copy) @@ -147,7 +147,7 @@ static struct machine_function * nvptx_init_machine_status (void) { struct machine_function *p = ggc_cleared_alloc (); - p->ret_reg_mode = VOIDmode; + p->return_mode = VOIDmode; return p; } @@ -487,7 +487,7 @@ nvptx_strict_argument_naming (cumulative static rtx nvptx_libcall_value (machine_mode mode, const_rtx) { - if (cfun->machine->start_call == NULL_RTX) + if (!cfun->machine->doing_call) /* Pretend to return in a hard reg for early uses before pseudos can be generated. */ return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM); @@ -506,7 +506,7 @@ nvptx_function_value (const_tree type, c if (outgoing) { - cfun->machine->ret_reg_mode = mode; + cfun->machine->return_mode = mode; return gen_rtx_REG (mode, NVPTX_RETURN_REGNUM); } @@ -678,14 +678,14 @@ write_return_type (std::stringstream &s, optimization-level specific, so no caller can make use of this data, but more importantly for us, we must ensure it doesn't change the PTX prototype. */ - mode = (machine_mode) cfun->machine->ret_reg_mode; + mode = (machine_mode) cfun->machine->return_mode; if (mode == VOIDmode) return return_in_mem; - /* Clear ret_reg_mode to inhibit copy of retval to non-existent + /* Clear return_mode to inhibit copy of retval to non-existent retval parameter. */ - cfun->machine->ret_reg_mode = VOIDmode; + cfun->machine->return_mode = VOIDmode; } else mode = promote_return (mode); @@ -989,7 +989,18 @@ nvptx_declare_function_name (FILE *file, fprintf (file, "%s", s.str().c_str()); - if (regno_reg_rtx[OUTGOING_STATIC_CHAIN_REGNUM] != const0_rtx) + /* Declare a local var for outgoing varargs. */ + if (cfun->machine->has_varadic) + init_frame (file, STACK_POINTER_REGNUM, + UNITS_PER_WORD, crtl->outgoing_args_size); + + /* Declare a local variable for the frame. */ + HOST_WIDE_INT sz = get_frame_size (); + if (sz || cfun->machine->has_chain) + init_frame (file, FRAME_POINTER_REGNUM, + crtl->stack_alignment_needed / BITS_PER_UNIT, sz); + + if (cfun->machine->has_chain) fprintf (file, "\t.reg.u%d %s;\n", GET_MODE_BITSIZE (Pmode), reg_names[OUTGOING_STATIC_CHAIN_REGNUM]); @@ -1010,17 +1021,6 @@ nvptx_declare_function_name (FILE *file, } } - /* Declare a local var for outgoing varargs. */ - if (cfun->machine->has_call_with_varargs) - init_frame (file, STACK_POINTER_REGNUM, - UNITS_PER_WORD, crtl->outgoing_args_size); - - /* Declare a local variable for the frame. */ - HOST_WIDE_INT sz = get_frame_size (); - if (sz || cfun->machine->has_call_with_sc) - init_frame (file, FRAME_POINTER_REGNUM, - crtl->stack_alignment_needed / BITS_PER_UNIT, sz); - /* Emit axis predicates. */ if (cfun->machine->axis_predicate[0]) nvptx_init_axis_predicate (file, @@ -1036,7 +1036,7 @@ nvptx_declare_function_name (FILE *file, const char * nvptx_output_return (void) { - machine_mode mode = (machine_mode)cfun->machine->ret_reg_mode; + machine_mode mode = (machine_mode)cfun->machine->return_mode; if (mode != VOIDmode) fprintf (asm_out_file, "\tst.param%s\t[%s_out], %s;\n", @@ -1076,20 +1076,28 @@ nvptx_get_drap_rtx (void) argument to the next call. */ static void -nvptx_call_args (rtx arg, tree funtype) +nvptx_call_args (rtx arg, tree fntype) { - if (cfun->machine->start_call == NULL_RTX) + if (!cfun->machine->doing_call) { - cfun->machine->call_args = NULL; - cfun->machine->funtype = funtype; - cfun->machine->start_call = const0_rtx; + cfun->machine->doing_call = true; + cfun->machine->is_varadic = false; + cfun->machine->num_args = 0; + + if (fntype && stdarg_p (fntype)) + { + cfun->machine->is_varadic = true; + cfun->machine->has_varadic = true; + cfun->machine->num_args++; + } } - if (arg == pc_rtx) - return; - rtx_expr_list *args_so_far = cfun->machine->call_args; - if (REG_P (arg)) - cfun->machine->call_args = alloc_EXPR_LIST (VOIDmode, arg, args_so_far); + if (REG_P (arg) && arg != pc_rtx) + { + cfun->machine->num_args++; + cfun->machine->call_args = alloc_EXPR_LIST (VOIDmode, arg, + cfun->machine->call_args); + } } /* Implement the corresponding END_CALL_ARGS hook. Clear and free the @@ -1098,7 +1106,7 @@ nvptx_call_args (rtx arg, tree funtype) static void nvptx_end_call_args (void) { - cfun->machine->start_call = NULL_RTX; + cfun->machine->doing_call = false; free_EXPR_LIST_list (&cfun->machine->call_args); } @@ -1111,16 +1119,10 @@ nvptx_end_call_args (void) void nvptx_expand_call (rtx retval, rtx address) { - int nargs = 0; rtx callee = XEXP (address, 0); - rtx pat, t; - rtvec vec; rtx varargs = NULL_RTX; unsigned parallel = 0; - for (t = cfun->machine->call_args; t; t = XEXP (t, 1)) - nargs++; - if (!call_insn_operand (callee, Pmode)) { callee = force_reg (Pmode, callee); @@ -1133,7 +1135,7 @@ nvptx_expand_call (rtx retval, rtx addre if (decl != NULL_TREE) { if (DECL_STATIC_CHAIN (decl)) - cfun->machine->has_call_with_sc = true; + cfun->machine->has_chain = true; tree attr = get_oacc_fn_attrib (decl); if (attr) @@ -1154,35 +1156,31 @@ nvptx_expand_call (rtx retval, rtx addre } } - if (cfun->machine->funtype - && stdarg_p (cfun->machine->funtype)) + unsigned nargs = cfun->machine->num_args; + if (cfun->machine->is_varadic) { varargs = gen_reg_rtx (Pmode); emit_move_insn (varargs, stack_pointer_rtx); - cfun->machine->has_call_with_varargs = true; } - vec = rtvec_alloc (nargs + 1 + (varargs ? 1 : 0)); - pat = gen_rtx_PARALLEL (VOIDmode, vec); + rtvec vec = rtvec_alloc (nargs + 1); + rtx pat = gen_rtx_PARALLEL (VOIDmode, vec); int vec_pos = 0; - + + rtx call = gen_rtx_CALL (VOIDmode, address, const0_rtx); rtx tmp_retval = retval; - t = gen_rtx_CALL (VOIDmode, address, const0_rtx); - if (retval != NULL_RTX) + if (retval) { if (!nvptx_register_operand (retval, GET_MODE (retval))) tmp_retval = gen_reg_rtx (GET_MODE (retval)); - t = gen_rtx_SET (tmp_retval, t); + call = gen_rtx_SET (tmp_retval, call); } - XVECEXP (pat, 0, vec_pos++) = t; + XVECEXP (pat, 0, vec_pos++) = call; /* Construct the call insn, including a USE for each argument pseudo register. These will be used when printing the insn. */ for (rtx arg = cfun->machine->call_args; arg; arg = XEXP (arg, 1)) - { - rtx this_arg = XEXP (arg, 0); - XVECEXP (pat, 0, vec_pos++) = gen_rtx_USE (VOIDmode, this_arg); - } + XVECEXP (pat, 0, vec_pos++) = gen_rtx_USE (VOIDmode, XEXP (arg, 0)); if (varargs) XVECEXP (pat, 0, vec_pos++) = gen_rtx_USE (VOIDmode, varargs); @@ -1477,18 +1475,6 @@ nvptx_legitimate_address_p (machine_mode return false; } } - -/* Implement HARD_REGNO_MODE_OK. We barely use hard regs, but we want - to ensure that the return register's mode isn't changed. */ - -bool -nvptx_hard_regno_mode_ok (int regno, machine_mode mode) -{ - if (regno != NVPTX_RETURN_REGNUM - || cfun == NULL || cfun->machine->ret_reg_mode == VOIDmode) - return true; - return mode == cfun->machine->ret_reg_mode; -} /* Machinery to output constant initializers. When beginning an initializer, we decide on a fragment size (which is visible in ptx @@ -3773,7 +3759,7 @@ nvptx_reorg (void) /* Mark unused regs as unused. */ int max_regs = max_reg_num (); - for (int i = 0; i < max_regs; i++) + for (int i = LAST_VIRTUAL_REGISTER + 1; i < max_regs; i++) if (REG_N_SETS (i) == 0 && REG_N_REFS (i) == 0) regno_reg_rtx[i] = const0_rtx; Index: config/nvptx/nvptx.h =================================================================== --- config/nvptx/nvptx.h (revision 231689) +++ config/nvptx/nvptx.h (working copy) @@ -220,14 +220,15 @@ struct nvptx_args { #if defined HOST_WIDE_INT struct GTY(()) machine_function { - rtx_expr_list *call_args; - rtx start_call; - tree funtype; - bool has_call_with_varargs; - bool has_call_with_sc; - HOST_WIDE_INT outgoing_stdarg_size; - int ret_reg_mode; /* machine_mode not defined yet. */ - rtx axis_predicate[2]; + rtx_expr_list *call_args; /* Arg list for the current call. */ + bool doing_call; /* Within a CALL_ARGS ... CALL_ARGS_END sequence. */ + bool is_varadic; /* This call is varadic */ + bool has_varadic; /* Current function has a varadic call. */ + bool has_chain; /* Current function has outgoing static chain. */ + int num_args; /* Number of args of current call. */ + int return_mode; /* Return mode of current fn. + (machine_mode not defined yet.) */ + rtx axis_predicate[2]; /* Neutering predicates. */ }; #endif