From patchwork Thu Jun 5 20:12:30 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 356591 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 EC9BE140087 for ; Fri, 6 Jun 2014 06:12:47 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=lMpel6yskdMSwvbE5BAUGmO/nc8ebH1/ydoYdYw4nB+3s2esnJ 3WqxnTkybdOJgJa9x9Vd6a6xq3pdBoChj1VK2fpif0M5JnrUvsGyhysxjWtzZoo8 zmVXOtvwpUtxhYkPf+cZls48Qh2Bq7MZGwsheKDVvlQ/FTKijcWjtyJkQ= 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:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=RMNsXr07alAWz2bB11szGIPZLss=; b=lQ73fp9JIo4/AatyXDkC FDDXf+xc4TLO8Dl0MjvQ6phWd2gJQJoFgIHQ3OBXWVf+zWyL9tKSd5iTnW5GWbZI ZhyWDKMPTeneaHLaqMAOxjsNTXkdqpCHHeA9p8ML0UOXVERU/ZdNx2WTiUxjWmpk gpvf7x1nbA2zxExfvn/wpOM= Received: (qmail 665 invoked by alias); 5 Jun 2014 20:12:40 -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 648 invoked by uid 89); 5 Jun 2014 20:12:38 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-we0-f170.google.com Received: from mail-we0-f170.google.com (HELO mail-we0-f170.google.com) (74.125.82.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 05 Jun 2014 20:12:35 +0000 Received: by mail-we0-f170.google.com with SMTP id u57so1775977wes.29 for ; Thu, 05 Jun 2014 13:12:32 -0700 (PDT) X-Received: by 10.194.157.226 with SMTP id wp2mr83254829wjb.58.1401999152086; Thu, 05 Jun 2014 13:12:32 -0700 (PDT) Received: from localhost ([2.26.169.52]) by mx.google.com with ESMTPSA id en6sm17314598wib.11.2014.06.05.13.12.30 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jun 2014 13:12:31 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, vmakarov@redhat.com, rdsandiford@googlemail.com Cc: vmakarov@redhat.com Subject: RFA: Small tweak to ira-lives.c:single_reg_class Date: Thu, 05 Jun 2014 21:12:30 +0100 Message-ID: <87zjhr9kup.fsf@talisman.default> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 I'm about to post a series of patches that reworks the handling of standard constraints. As part of that I needed to make single_reg_class handle "extra" constraints in a similar way to the standard ones. It's not a particularly worthwhile change in itself -- not enough to justify this long essay -- but I split it out because it's the only part of the series that changes codegen. The function looks like this: case 'i': if (CONSTANT_P (op) || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const))) return NO_REGS; break; case 'n': if (CONST_SCALAR_INT_P (op) || (equiv_const != NULL_RTX && CONST_SCALAR_INT_P (equiv_const))) return NO_REGS; break; case 's': if ((CONSTANT_P (op) && !CONST_SCALAR_INT_P (op)) || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const) && !CONST_SCALAR_INT_P (equiv_const))) return NO_REGS; break; case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': if ((CONST_INT_P (op) && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, constraints)) || (equiv_const != NULL_RTX && CONST_INT_P (equiv_const) && CONST_OK_FOR_CONSTRAINT_P (INTVAL (equiv_const), c, constraints))) return NO_REGS; break; case 'E': case 'F': if (CONST_DOUBLE_AS_FLOAT_P (op) || (GET_CODE (op) == CONST_VECTOR && GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT) || (equiv_const != NULL_RTX && (CONST_DOUBLE_AS_FLOAT_P (equiv_const) || (GET_CODE (equiv_const) == CONST_VECTOR && (GET_MODE_CLASS (GET_MODE (equiv_const)) == MODE_VECTOR_FLOAT))))) return NO_REGS; break; case 'G': case 'H': if ((CONST_DOUBLE_AS_FLOAT_P (op) && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, constraints)) || (equiv_const != NULL_RTX && CONST_DOUBLE_AS_FLOAT_P (equiv_const) && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const, c, constraints))) return NO_REGS; /* ??? what about memory */ case 'r': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': case 'j': case 'k': case 'l': case 'q': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'W': case 'Y': case 'Z': next_cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, constraints)); if (cl == NO_REGS ? ira_class_singleton[next_cl][GET_MODE (op)] < 0 : (ira_class_singleton[cl][GET_MODE (op)] != ira_class_singleton[next_cl][GET_MODE (op)])) return NO_REGS; cl = next_cl; break; [...] default: return NO_REGS; So for known constant contraints we check whether OP or its equivalent constant satisfies the constraint and return NO_REGS if so. I'd like to extend this behaviour to the extra constraints, since some targets match constants (often symbolic or unspec-based constants) there too. The code that checks next_cl effectively assumes that the constraint is always a register constraint. If it's something else, next_cl will be NO_REGS, which isn't a singleton class, so we'll return NO_REGS regardless of what type of constraint we're matching or what OP is. (In principle this includes register constraints that are disabled on the current subtarget, since they'll have a next_cl of NO_REGS too.) In order to handle extra constant constraints as described above, we'd need to ignore cases where next_cl itself is NO_REGS. This brings me on to memory and address constraints... The comment says: /* ??? what about memory */ At the moment we return NO_REGS for target-independent memory constraints like "m", "o" and "g", because of the default case. The handling of next_cl means that we effectively do the same for extra memory constraints, since next_cl is always NO_REGS for them. That seems reasonable to me and I'm not trying to change it here. The patch just makes the current choice explicit by checking for extra memory constraints. Likewise we return NO_REGS for 'p' and (indirectly) for extra address constraints. This too makes sense, since I don't think we support a singleton BASE_REG_CLASS. Again the patch makes that explicit. So all in all, the patch only really affects two cases: extra constant constraints and the (probably rare) situation that there is a singleton register constraint alongside disabled/NO_REGS register constraints. The former does occur on Alpha and MIPS. E.g.: (define_insn "*call_osf_1" [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s")) (match_operand 1)) (use (reg:DI 29)) (clobber (reg:DI 26))] "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ jsr $26,($27),0\;ldgp $29,0($26) bsr $26,$%0..ng jsr $26,%0\;ldgp $29,0($26)" [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) Here "c" is a singleton register class (the ABI-defined indirect call register). "s" is the standard constraint for symbolic addresses and "R" is an extra constant constraint. If the call address is a register, single_reg_class currently returns NO_REGS because of the way that "R" is handled via next_cl==NO_REGS. After the patch it returns the singleton register class for "c" instead. I think this is the right behaviour, since indirect calls really do require a single register; the other constraints are for direct calls instead. It looks like there's a missing break after the 'G' and 'H' handling. Tested on x86_64-linux-gnu. I also did an assembly comparison for a range of targets and Alpha and MIPS seemed to be the only ones affected. OK to install? Sorry for the long write-up... Thanks, Richard gcc/ * ira-lives.c (single_reg_class): Add missing break. Return NO_REGS for extra address and memory constraints, not just 'p' and TARGET_MEM_CONSTRAINT. Likewise if the operand is a constant or equivalent to a constant and if it matches an extra constraint. Ignore other non-register operands. Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c 2014-06-04 22:15:23.527995920 +0100 +++ gcc/ira-lives.c 2014-06-04 22:15:50.765243138 +0100 @@ -839,7 +839,8 @@ single_reg_class (const char *constraint && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (equiv_const, c, constraints))) return NO_REGS; - /* ??? what about memory */ + break; + case 'r': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': case 'j': case 'k': case 'l': @@ -848,9 +849,22 @@ single_reg_class (const char *constraint case 'A': case 'B': case 'C': case 'D': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'W': case 'Y': case 'Z': +#ifdef EXTRA_CONSTRAINT_STR + /* ??? Is rejecting memory the best thing to do? */ + if (EXTRA_MEMORY_CONSTRAINT (c, constraints) + || EXTRA_ADDRESS_CONSTRAINT (c, constraints)) + return NO_REGS; + if (EXTRA_CONSTRAINT_STR (op, c, constraints) + || (equiv_const != NULL_RTX + && CONSTANT_P (equiv_const) + && EXTRA_CONSTRAINT_STR (equiv_const, c, constraints))) + return NO_REGS; +#endif next_cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, constraints)); + if (next_cl == NO_REGS) + break; if (cl == NO_REGS ? ira_class_singleton[next_cl][GET_MODE (op)] < 0 : (ira_class_singleton[cl][GET_MODE (op)]