From patchwork Mon Aug 18 15:55:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 381053 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 7F1EA140076 for ; Tue, 19 Aug 2014 01:56:12 +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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=UmK6xz7zgPGQeBi2e +Kqs1AmkHt5VRTVbY0kqJyIotTQQapS6dw5yhRmNo67c1qdvzB+3j0j8DEK0SuC0 mIEtYWho7rts/eF5ta+bMB89adMrbcLaWL4IzwOAqdIRk/v8CwwKBgdDZ5etGuEZ b7U+xL1NKTj1kXOQfb3aKYsjfU= 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=uNXXc6SpgaCpoA8NOxXNlzT ejKA=; b=x5LsJ4qDWWuXSbKbMacgh/p7x/hy4oPH8EPYncfB1nVd9XTs6mpCYzs zWiWLhhHz62r4m9f+VF9rDNdr+XCPYTqO+bLlCs+hpUbnJQIZqXjKOaWJSOl8vrC jTtbi81XQOvIJTtIMi8MwINN00rVPiW8x0Q48bE2XIBff30qdOJs= Received: (qmail 17095 invoked by alias); 18 Aug 2014 15:55:41 -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 17005 invoked by uid 89); 18 Aug 2014 15:55:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f51.google.com Received: from mail-pa0-f51.google.com (HELO mail-pa0-f51.google.com) (209.85.220.51) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 18 Aug 2014 15:55:34 +0000 Received: by mail-pa0-f51.google.com with SMTP id ey11so7871143pad.24 for ; Mon, 18 Aug 2014 08:55:27 -0700 (PDT) X-Received: by 10.68.68.131 with SMTP id w3mr36299528pbt.90.1408377327656; Mon, 18 Aug 2014 08:55:27 -0700 (PDT) Received: from msticlxl57.ims.intel.com (fmdmzpr03-ext.fm.intel.com. [192.55.54.38]) by mx.google.com with ESMTPSA id jr5sm16561487pbc.75.2014.08.18.08.55.25 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 18 Aug 2014 08:55:27 -0700 (PDT) Date: Mon, 18 Aug 2014 19:55:16 +0400 From: Ilya Enkovich To: Jeff Law Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH, Pointer Bounds Checker 23/x] Function split Message-ID: <20140818155516.GF29976@msticlxl57.ims.intel.com> References: <20140603070950.GA20877@msticlxl57.ims.intel.com> <538EC794.1030903@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <538EC794.1030903@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes On 04 Jun 01:15, Jeff Law wrote: > On 06/03/14 01:10, Ilya Enkovich wrote: > >Hi, > > > >This patch does not allow splitting in case bounds are returned until retutrned bounds are supported. It also propagates instrumentation marks for generated call and function. > > > >Bootstrapped and tested on linux-x86_64. > > > >Thanks, > >Ilya > >-- > >gcc/ > > > >2014-06-03 Ilya Enkovich > > > > * ipa-split.c: Include tree-chkp.h. > > (consider_split): Do not split when return bounds. > > (split_function): Propagate Pointer Bounds Checker > > instrumentation marks. > It's a hack. There's no reason we can't support this. So I'll > approve on the condition that you do look at removing this > limitation in the future. > > jeff > I did some work for function splitting and now patch cover more cases. Now returned bounds are supported but it is not allowed to split producers of returned pointer and its bounds. Is it OK? Thanks, Ilya --- 2014-08-15 Ilya Enkovich * ipa-split.c: Include tree-chkp.h. (find_retbnd): New. (consider_split): Do not split retbnd and retval producers. (split_function): Propagate Pointer Bounds Checker instrumentation marks and handle returned bounds. diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 2af3a93..f8ecaf7 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -110,6 +110,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "ipa-inline.h" #include "cfgloop.h" +#include "tree-chkp.h" /* Per basic block info. */ @@ -151,6 +152,7 @@ struct split_point best_split_point; static bitmap forbidden_dominators; static tree find_retval (basic_block return_bb); +static tree find_retbnd (basic_block return_bb); /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic variable, check it if it is present in bitmap passed via DATA. */ @@ -387,6 +389,7 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, unsigned int i; int incoming_freq = 0; tree retval; + tree retbnd; bool back_edge = false; if (dump_file && (dump_flags & TDF_DETAILS)) @@ -588,6 +591,32 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, else current->split_part_set_retval = true; + /* See if retbnd used by return bb is computed by header or split part. */ + retbnd = find_retbnd (return_bb); + if (retbnd) + { + bool split_part_set_retbnd + = (!SSA_NAME_IS_DEFAULT_DEF (retbnd) + && (bitmap_bit_p (current->split_bbs, + gimple_bb (SSA_NAME_DEF_STMT (retbnd))->index) + || gimple_bb (SSA_NAME_DEF_STMT (retbnd)) == return_bb)); + + /* If we have both return value and bounds then keep their definitions + in a single function. We use SSA names to link returned bounds and + value and therefore do not handle cases when result is passed by + reference (which should not be our case anyway since bounds are + returned for pointers only). */ + if ((DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)) + && current->split_part_set_retval) + || split_part_set_retbnd != current->split_part_set_retval) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + " Refused: split point splits return value and bounds\n"); + return; + } + } + /* split_function fixes up at most one PHI non-virtual PHI node in return_bb, for the return value. If there are other PHIs, give up. */ if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) @@ -710,6 +739,18 @@ find_retval (basic_block return_bb) return NULL; } +/* Given return basic block RETURN_BB, see where return bounds are really + stored. */ +static tree +find_retbnd (basic_block return_bb) +{ + gimple_stmt_iterator bsi; + for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); gsi_next (&bsi)) + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN) + return gimple_return_retbnd (gsi_stmt (bsi)); + return NULL; +} + /* Callback for walk_stmt_load_store_addr_ops. If T is non-SSA automatic variable, mark it as used in bitmap passed via DATA. Return true when access to T prevents splitting the function. */ @@ -1095,8 +1136,9 @@ split_function (struct split_point *split_point) gimple call; edge e; edge_iterator ei; - tree retval = NULL, real_retval = NULL; + tree retval = NULL, real_retval = NULL, retbnd = NULL; bool split_part_return_p = false; + bool with_bounds = chkp_function_instrumented_p (current_function_decl); gimple last_stmt = NULL; unsigned int i; tree arg, ddef; @@ -1245,6 +1287,12 @@ split_function (struct split_point *split_point) DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN; DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0; } + + /* If the original function is instrumented then it's + part is also instrumented. */ + if (with_bounds) + chkp_function_mark_instrumented (node->decl); + /* If the original function is declared inline, there is no point in issuing a warning for the non-inlinable part. */ DECL_NO_INLINE_WARNING_P (node->decl) = 1; @@ -1279,6 +1327,7 @@ split_function (struct split_point *split_point) args_to_pass[i] = arg; } call = gimple_build_call_vec (node->decl, args_to_pass); + gimple_call_set_with_bounds (call, with_bounds); gimple_set_block (call, DECL_INITIAL (current_function_decl)); args_to_pass.release (); @@ -1385,6 +1434,7 @@ split_function (struct split_point *split_point) if (return_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) { real_retval = retval = find_retval (return_bb); + retbnd = find_retbnd (return_bb); if (real_retval && split_point->split_part_set_retval) { @@ -1429,6 +1479,21 @@ split_function (struct split_point *split_point) } update_stmt (gsi_stmt (bsi)); } + + /* Replace retbnd with new one. */ + if (retbnd) + { + gimple_stmt_iterator bsi; + for (bsi = gsi_start_bb (return_bb); !gsi_end_p (bsi); + gsi_next (&bsi)) + if (gimple_code (gsi_stmt (bsi)) == GIMPLE_RETURN) + { + retbnd = copy_ssa_name (retbnd, call); + gimple_return_set_retbnd (gsi_stmt (bsi), retbnd); + update_stmt (gsi_stmt (bsi)); + break; + } + } } if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) { @@ -1450,6 +1515,15 @@ split_function (struct split_point *split_point) gsi_insert_after (&gsi, cpy, GSI_NEW_STMT); retval = tem; } + /* Build bndret call to obtain returned bounds. */ + if (retbnd) + { + tree fndecl + = targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDRET); + gimple bndret = gimple_build_call (fndecl, 1, retval); + gimple_call_set_lhs (bndret, retbnd); + gsi_insert_after (&gsi, bndret, GSI_NEW_STMT); + } gimple_call_set_lhs (call, retval); update_stmt (call); } @@ -1468,6 +1542,10 @@ split_function (struct split_point *split_point) { retval = DECL_RESULT (current_function_decl); + if (chkp_function_instrumented_p (current_function_decl) + && BOUNDED_P (retval)) + retbnd = create_tmp_reg (pointer_bounds_type_node, NULL); + /* We use temporary register to hold value when aggregate_value_p is false. Similarly for DECL_BY_REFERENCE we must avoid extra copy. */ @@ -1491,6 +1569,15 @@ split_function (struct split_point *split_point) gimple_call_set_lhs (call, retval); } gsi_insert_after (&gsi, call, GSI_NEW_STMT); + /* Build bndret call to obtain returned bounds. */ + if (retbnd) + { + tree fndecl + = targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDRET); + gimple bndret = gimple_build_call (fndecl, 1, retval); + gimple_call_set_lhs (bndret, retbnd); + gsi_insert_after (&gsi, bndret, GSI_NEW_STMT); + } ret = gimple_build_return (retval); gsi_insert_after (&gsi, ret, GSI_NEW_STMT); }