From patchwork Tue Oct 29 05:02:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Law X-Patchwork-Id: 286730 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A2D402C019C for ; Tue, 29 Oct 2013 16:02:54 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=bDyz651VM0b+lNPiuWidytMLMRZ45aSm55BLTiy4V7QPVR 7GB6DiTmoBe+ok+2Q4qYVgp0GqXXAwQ+FyJjcgLyuF1EhVOgP+Wngr6UaUvqT1Iz ccTzrzFTxmR23lSdtBr5WnVySCH9pLAJ1toynZZu17O4Igf20qeohJRz6m1gc= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=n/vn/HFRN72yPbykFay4TDrG59s=; b=OisgUQH/VfA73OOPDskw nnqMuakYyRsm5nx+qxVIwJqIhm2HyHW9zQ9cgujT0RJRoXMiUf2gjSfBKqUSCHw+ xefUvED89VmRTiFRE759dUZlR1aNsjV1pZKOSxu9BxYK67DF2U4zkCMVEyStlBnO RnMcIfOzqittt1wBrzPUNwo= Received: (qmail 20970 invoked by alias); 29 Oct 2013 05:02:48 -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 20957 invoked by uid 89); 29 Oct 2013 05:02:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 29 Oct 2013 05:02:46 +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 r9T52jot002908 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 29 Oct 2013 01:02:45 -0400 Received: from stumpy.slc.redhat.com (ovpn-113-93.phx2.redhat.com [10.3.113.93]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r9T52iAG020808 for ; Tue, 29 Oct 2013 01:02:44 -0400 Message-ID: <526F4174.9080300@redhat.com> Date: Mon, 28 Oct 2013 23:02:44 -0600 From: Jeff Law User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0 MIME-Version: 1.0 To: gcc-patches Subject: [PATCH][RFA] Improvements to infer_nonnull_range X-IsSubscribed: yes Based on a suggestion from Marc, I want to use infer_nonnull_range in the erroneous path isolation optimization. In the process of doing that, I found a few deficiencies in infer_nonnull_range that need to be addressed. First, infer_nonnull_range_p doesn't infer ranges from a GIMPLE_RETURN if the current function is marked as returns_nonnull. That's fixed in the relatively obvious way. Second, infer_nonnull_range_p, when presented with an arglist where the non-null attribute applies to all pointer arguments, it won't bother to determine if OP is actually one of the arguments :( It just assumes that OP is in the argument list. Opps. Third, I want to be able to call infer_nonnull_range with OP being 0B. That lets me use infer_nonnull_range to look for explicit null pointer dereferences, explicit uses of null in a return statement in functions that can't return non-null and explicit uses of null arguments when those arguments can't be null. Sadly, to make that work we need to use operand_equal_p rather than simple pointer comparisons to see if OP shows up in STMT. Finally, for detecting explicit null pointers, infer_nonnull_range calls count_ptr_derefs. count_ptr_derefs counts things in two ways. One with a FOR_EACH_SSA_TREE_OPERAND, then again with simple walks of the tree structures. Not surprisingly if we're looking for an explicit 0B, then the loop over the operands finds nothing, but walking the tree structures does. And the checking assert triggers. This change removes the assert and instead sets *num_uses_p to a sane value. I don't have testcases for this stuff that are independent of the erroneous path isolation optimization. However, each is triggered by tests I'll include in the the erroneous path isolation patch. Bootstrapped and regression tested on x86_64-unknown-linux-gnu. OK for the trunk? jeff * tree-ssa.c (count_ptr_derefs): Use operand_equal_p rather than testing pointer equality. Remove invalid assert. Clamp minimum value for *num_uses_p at *num_loads_p + *num_stores_p. * tree-vrp.c (infer_nonnull_range): Verify OP is in the argument list and the argument corresponding to OP is a pointer type. Use operand_equal_p rather than pointer equality when testing if OP is on the nonnull list. Handle GIMPLE_RETURN statements too. diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 0b743d1..d29665b 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -265,7 +265,8 @@ count_ptr_derefs (tree *tp, int *walk_subtrees, void *data) return NULL_TREE; } - if (TREE_CODE (*tp) == MEM_REF && TREE_OPERAND (*tp, 0) == count_p->ptr) + if (TREE_CODE (*tp) == MEM_REF + && operand_equal_p (TREE_OPERAND (*tp, 0), count_p->ptr, 0)) { if (wi_p->is_lhs) count_p->num_stores++; @@ -326,7 +327,11 @@ count_uses_and_derefs (tree ptr, gimple stmt, unsigned *num_uses_p, *num_loads_p = count.num_loads; } - gcc_assert (*num_uses_p >= *num_loads_p + *num_stores_p); + /* This can happen if PTR refers to something other than an SSA_NAME. + In that case we will find no uses as the FOR_EACH_SSA_TREE_OPERAND + only iterates over the SSA_NAMEs in a statement. */ + if (*num_uses_p < *num_loads_p + *num_stores_p) + *num_uses_p = *num_loads_p + *num_stores_p; } diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index d3a07f3..bbcb34c 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4509,21 +4509,38 @@ infer_nonnull_range (gimple stmt, tree op) return false; /* If "nonnull" applies to all the arguments, then ARG - is non-null. */ + is non-null if it's in the argument list. */ if (TREE_VALUE (attrs) == NULL_TREE) - return true; + { + for (unsigned int i = 0; i < gimple_call_num_args (stmt); i++) + { + if (operand_equal_p (op, gimple_call_arg (stmt, i), 0) + && POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (stmt, i)))) + return true; + } + return false; + } /* Now see if op appears in the nonnull list. */ for (tree t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t)) { int idx = TREE_INT_CST_LOW (TREE_VALUE (t)) - 1; tree arg = gimple_call_arg (stmt, idx); - if (op == arg) + if (operand_equal_p (op, arg, 0)) return true; } } } + /* If this function is marked as returning non-null, then we can + infer OP is non-null if it is used in the return statement. */ + if (gimple_code (stmt) == GIMPLE_RETURN + && gimple_return_retval (stmt) + && operand_equal_p (gimple_return_retval (stmt), op, 0) + && lookup_attribute ("returns_nonnull", + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) + return true; + return false; }