From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19387 invoked by alias); 17 Aug 2011 14:52:50 -0000 Received: (qmail 19376 invoked by uid 22791); 17 Aug 2011 14:52:48 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-fx0-f47.google.com (HELO mail-fx0-f47.google.com) (209.85.161.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 17 Aug 2011 14:52:33 +0000 Received: by fxg11 with SMTP id 11so793299fxg.20 for ; Wed, 17 Aug 2011 07:52:31 -0700 (PDT) Received: by 10.223.120.134 with SMTP id d6mr1491370far.112.1313592751594; Wed, 17 Aug 2011 07:52:31 -0700 (PDT) Received: from richards-thinkpad.stglab.manchester.uk.ibm.com (gbibp9ph1--blueice3n2.emea.ibm.com [195.212.29.84]) by mx.google.com with ESMTPS id d1sm955580fai.4.2011.08.17.07.52.30 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 17 Aug 2011 07:52:31 -0700 (PDT) From: Richard Sandiford To: gcc@gcc.gnu.org Mail-Followup-To: gcc@gcc.gnu.org, richard.sandiford@linaro.org Subject: Just what are rtx costs? Date: Wed, 17 Aug 2011 14:52:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2011-08/txt/msg00306.txt.bz2 I've been working on some patches to make insn_rtx_cost take account of the cost of SET_DESTs as well as SET_SRCs. But I'm slowly beginning to realise that I don't understand what rtx costs are supposed to represent. AIUI the rules have historically been: 1) Registers have zero cost. 2) Constants have a cost relative to that of registers. By extension, constants have zero cost if they are as cheap as a register. 3) With an outer code of SET, actual operations have the cost of the associated instruction. E.g. the cost of a PLUS is the cost of an addition instruction. 4) With other outer codes, actual operations have the cost of the combined instruction, if available, or the cost of a separate instruction otherwise. E.g. the cost of a NEG inside an AND might be zero on targets that support BIC-like instructions, and COSTS_N_INSNS (1) on most others. Memories seem a bit more vague. I think most ports handle them like (2), but I'm not sure whether all RISCy ports do. I'd wrongly assumed that rtx costs were only used for rvalues. However, several places actually take the rtx cost of a SET. Specifically: * auto-inc-dec.c (attempt_change) * cfgloopanal.c (seq_cost) * loop-invariant.c (create_new_invariant) * postreload.c (move2add_use_add2_insn, move2add_use_add3_insn) (reload_cse_move2add) (What confused me is that these places still pass "SET" as the outer code. "INSN" would be more accurate.) By default, the cost of a SET is: COSTS_N_INSNS (1) + rtx_cost (SET_DEST (x), SET, speed) + rtx_cost (SET_SRC (x), SET, speed) But it seems like there's some double-counting for complex SET_SRCs here. The cost of the instruction is already included in the SET_SRC, so adding COSTS_N_INSNS (1) is overkill. COSTS_N_INSNS (1) does seem necessary for register, constant, subreg and (possibly) memory SET_SRCs though. Some targets' cost hooks do handle SETs. Others have a default case that assumes any unhandled operation is expensive, so even register sets end up getting this treatment. (I notice ARM is inconsistent: Thumb-1 handles SETs explicitly, but the default ARM and Thumb-2 costs assume that SET itself has a cost of COSTS_N_INSNS (4).) insn_rtx_cost instead uses: cost = set_src_cost (SET_SRC (set), speed); return cost > 0 ? cost : COSTS_N_INSNS (1); This ignores SET_DEST (the problem I'm trying to fix). It also means that constants that are slightly more expensive than a register -- somewhere in the range [0, COSTS_N_INSNS (1)] -- end up seeming cheaper than registers. So it doesn't look like we're consistent here, and that some rejigging might be needed. As others have said, it would be nice if costs could be extracted from the .md file, but that's more work than I have time for now. Is it worth changing the costs anyway? One approach I'm trying is to make sure that every target that doesn't explicitly handle SET does nothing with it. (Targets that do handle SET remain unchanged.) Then, if we see a SET whose SET_SRC is a register, constant, memory or subreg, we give it cost: COSTS_N_INSNS (1) + rtx_cost (SET_DEST (x), SET, speed) + rtx_cost (SET_SRC (x), SET, speed) as now. In other cases we give it a cost of: rtx_cost (SET_DEST (x), SET, speed) + rtx_cost (SET_SRC (x), SET, speed) But that hardly seems clean either. Perhaps we should instead make the SET_SRC always include the cost of the SET, even for registers, constants and the like. Thoughts? (The patches I've been working on also tell rtx_costs -- and the target hook -- whether the operand is an lvalue. That means that stores can have a different cost from loads.) Richard