From patchwork Thu Jul 9 23:08:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 50990 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 713E7213FD for ; Thu, 9 Jul 2015 23:08:57 +0000 (UTC) Received: by lagx9 with SMTP id x9sf78337766lag.2 for ; Thu, 09 Jul 2015 16:08:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mailing-list:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:sender :delivered-to:message-id:date:from:user-agent:mime-version:to:cc :subject:references:in-reply-to:content-type:x-original-sender :x-original-authentication-results; bh=OKvCAc8KG1TarVQKEsdT6LZtArF1ETx4KuZJcwf1UOE=; b=g5YD6Qfclcx5Z3qaS7b2zedVQ7XjK3BntM2/OfxyKbO5WHPWFOV56ERJ/R+kvoRuE3 hCbFsqFcSZQf66nwC9UDfSjS61aPF3Vo3m35dTOx3COaW+qNVCLDPdBI2OJyP6NxKmiO 9dqx4wTVOLNbt2xw8NnSlLDZK32IMhOhBV9yFdX/3wpTgz4m9F7yKGBDAJFfFQpJq/dy aYi4yJgvF9RkkzV/nZSGEFWSOcMw6yrvIaGIdcAy9ZTUIYLvZd7jCvrIcwOjftuR+bS9 Tbt+RAN+cYmEocfjs4CLzLWFNZdTFGmiMxH0V6AOhD46R0zFEtr7VVKkhz+wbGM2kaAZ 78kA== X-Gm-Message-State: ALoCoQl8Htx8iPR1D5UuWvZIIIN0/fi8Z5iIBe3qfSDTwSfqnVqy3p0YWkorcApCGGmITW3Wko5r X-Received: by 10.112.42.236 with SMTP id r12mr9277558lbl.2.1436483335967; Thu, 09 Jul 2015 16:08:55 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.163.65 with SMTP id yg1ls1060687lab.26.gmail; Thu, 09 Jul 2015 16:08:55 -0700 (PDT) X-Received: by 10.112.46.9 with SMTP id r9mr3345582lbm.53.1436483335818; Thu, 09 Jul 2015 16:08:55 -0700 (PDT) Received: from mail-lb0-x230.google.com (mail-lb0-x230.google.com. [2a00:1450:4010:c04::230]) by mx.google.com with ESMTPS id x10si6004375lbo.118.2015.07.09.16.08.55 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jul 2015 16:08:55 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::230 as permitted sender) client-ip=2a00:1450:4010:c04::230; Received: by lbbpo10 with SMTP id po10so83220571lbb.3 for ; Thu, 09 Jul 2015 16:08:55 -0700 (PDT) X-Received: by 10.152.1.66 with SMTP id 2mr15511469lak.56.1436483335631; Thu, 09 Jul 2015 16:08:55 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp972669lbb; Thu, 9 Jul 2015 16:08:53 -0700 (PDT) X-Received: by 10.66.228.73 with SMTP id sg9mr36205670pac.88.1436483333174; Thu, 09 Jul 2015 16:08:53 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id yo7si11252272pac.224.2015.07.09.16.08.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jul 2015 16:08:53 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-402574-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 45606 invoked by alias); 9 Jul 2015 23:08:40 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list 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 45597 invoked by uid 89); 9 Jul 2015 23:08:39 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f42.google.com Received: from mail-pa0-f42.google.com (HELO mail-pa0-f42.google.com) (209.85.220.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 09 Jul 2015 23:08:37 +0000 Received: by pacws9 with SMTP id ws9so159147278pac.0 for ; Thu, 09 Jul 2015 16:08:35 -0700 (PDT) X-Received: by 10.68.238.39 with SMTP id vh7mr36239401pbc.12.1436483315200; Thu, 09 Jul 2015 16:08:35 -0700 (PDT) Received: from [10.1.1.8] (58-6-183-210.dyn.iinet.net.au. [58.6.183.210]) by smtp.googlemail.com with ESMTPSA id o16sm7164581pdj.24.2015.07.09.16.08.31 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 09 Jul 2015 16:08:32 -0700 (PDT) Message-ID: <559EFEE5.6030006@linaro.org> Date: Fri, 10 Jul 2015 09:08:21 +1000 From: Kugan User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Jeff Law , Bernhard Reutner-Fischer CC: "gcc-patches@gcc.gnu.org" Subject: Re: [PR66726] Factor conversion out of COND_EXPR References: <55974BF2.3060603@linaro.org> <20150704085143.GA14895@nbbrfq.cc.univie.ac.at> <5597D24B.8010900@linaro.org> <559AF515.6010700@redhat.com> <559BCB15.9010209@linaro.org> <559BE505.5070802@redhat.com> In-Reply-To: <559BE505.5070802@redhat.com> X-IsSubscribed: yes X-Original-Sender: kugan.vivekanandarajah@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::230 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@gcc.gnu.org X-Google-Group-Id: 836684582541 On 08/07/15 00:41, Jeff Law wrote: > On 07/07/2015 06:50 AM, Kugan wrote: >> >> Thanks for the review. I have addressed your comments above in the >> attached patch. >> >> I have one question with respect to unary operation. For generic unary >> operation with INTEGER_CST, do we skip this or do we have to perform the >> inverse operation so that the conversion after PHI will restore it? Is >> there any easy way to do this safely? > I think we'd have to invert the operation -- some of which are trivial, > such as BIT_NOT_EXPR. > > NEGATE_EXPR is trivial once you filter out the cases where inversion > will create signed overflow (ie INT_MIN and like when arg1 is an > INTEGER_CST). > > Similarly ABS_EXPR is trivial once you filter out cases where arg1 is a > negative INTEGER_CST. > > If you want to try and handle those cases, I'm certainly comfortable > with that as a follow-up. Obviously we'll want to testcases for them, > including the cases where we don't want to make the transformation for > NEGATE_EXPR and ABS_EXPR. > > There may be other special cases we need to handle for other unary > operations. I haven't walked through the full list. Thanks Jeff for the review.As you said later, I will skip generic unary in this patch and work on that as an addition on top of this. > >> >> Bootstrapped and regression tested the attached patch on >> x86-64-none-linux-gnu with no new regressions. >> >> Thanks, >> Kugan >> >> >> p.txt >> >> >> diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c >> index 92b4ab0..1d6de9b 100644 >> --- a/gcc/tree-ssa-phiopt.c >> +++ b/gcc/tree-ssa-phiopt.c >> @@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see >> static unsigned int tree_ssa_phiopt_worker (bool, bool); >> static bool conditional_replacement (basic_block, basic_block, >> edge, edge, gphi *, tree, tree); >> +static bool factor_out_conditional_conversion (edge, edge, gphi *, >> tree, tree); >> static int value_replacement (basic_block, basic_block, >> edge, edge, gimple, tree, tree); >> static bool minmax_replacement (basic_block, basic_block, >> @@ -335,6 +336,17 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool >> do_hoist_loads) >> node. */ >> gcc_assert (arg0 != NULL && arg1 != NULL); >> >> + if (factor_out_conditional_conversion (e1, e2, phi, arg0, arg1)) >> + { >> + /* Update arg0 and arg1. */ >> + phis = phi_nodes (bb2); >> + phi = single_non_singleton_phi_for_edges (phis, e1, e2); >> + gcc_assert (phi); >> + arg0 = gimple_phi_arg_def (phi, e1->dest_idx); >> + arg1 = gimple_phi_arg_def (phi, e2->dest_idx); >> + gcc_assert (arg0 != NULL && arg1 != NULL); >> + } >> + > So small comment before this block of code indicating why we're > recomputing these values. Something like this perhaps: > > /* factor_out_conditional_conversion may create a new PHI in BB2 and > eliminate an existing PHI in BB2. Recompute values that may be > affected by that change. */ > > > Or something along those lines. Done. > > >> /* Do the replacement of conditional if it can be done. */ >> if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) >> cfgchanged = true; >> @@ -410,6 +422,133 @@ replace_phi_edge_with_variable (basic_block >> cond_block, >> bb->index); >> } >> >> +/* PR66726: Factor conversion out of COND_EXPR. If the arguments of >> the PHI >> + stmt are CONVERT_STMT, factor out the conversion and perform the >> conversion >> + to the result of PHI stmt. */ >> + >> +static bool >> +factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, >> + tree arg0, tree arg1) >> +{ >> + gimple arg0_def_stmt = NULL, arg1_def_stmt = NULL, new_stmt; >> + tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE; >> + tree temp, result; >> + gphi *newphi; >> + gimple_stmt_iterator gsi, gsi_for_def; >> + source_location locus = gimple_location (phi); >> + enum tree_code convert_code; >> + >> + /* Handle only PHI statements with two arguments. TODO: If all >> + other arguments to PHI are INTEGER_CST, we can handle more >> + than two arguments too. */ >> + if (gimple_phi_num_args (phi) != 2) >> + return false; > Similarly we can handle more than one SSA_NAME if their defining > statement all have the same unary operation. Might as well add that to > the comment too. While handling > 2 arguments is certainly possible, I > really wonder how often those cases occur in practice. > Comment added. I will work on the implementation after this patch. >> + >> + /* If arg0 is an SSA_NAME and the stmt which defines arg0 is >> + a conversion. */ >> + arg0_def_stmt = SSA_NAME_DEF_STMT (arg0); >> + if (!is_gimple_assign (arg0_def_stmt) >> + || (!gimple_assign_cast_p (arg0_def_stmt) >> + && (get_gimple_rhs_class (gimple_assign_rhs_code (arg0_def_stmt)) >> + != GIMPLE_UNARY_RHS))) > So what happens if arg0_def_stmt is a GIMPLE_UNARY_RHS other than a > NOP_EXPR or CONVERT_EXPR? I'd probably punt anything that is not a > gimple_assign_cast_p for the first iteration and follow-up with handling > of the other unary operations as a follow-up. > > > >> + return false; >> + >> + /* Use the LHS as new_arg0. */ > s/LHS/RHS/ > Done. >> + convert_code = gimple_assign_rhs_code (arg0_def_stmt); >> + new_arg0 = gimple_assign_rhs1 (arg0_def_stmt); >> + if (convert_code == VIEW_CONVERT_EXPR) >> + new_arg0 = TREE_OPERAND (new_arg0, 0); > Is this really right for VIEW_CONVERT_EXPR? Also, do we do the right > thing for FIX_TRUNC_EXPR? > I experimented with this and it seems to me that FIX_TRUNC_EXPR does not need this. I added an execution testcase for VIEW_CONVERT_EXPR. > >> + >> + /* If arg1 is an SSA_NAME and the stmt which defines arg0 is >> + a conversion. */ > s/arg0/arg1/ > > It's also the case that if arg1 is an SSA_NAME, then it must do the same > operation as we found in arg0's defining statement. I see that's > properly tested in the code, so just a minor comment updated needed. > >> + >> + /* Create a new PHI stmt. */ >> + result = PHI_RESULT (phi); >> + temp = make_ssa_name (TREE_TYPE (new_arg0), NULL); >> + newphi = create_phi_node (temp, gimple_bb (phi)); >> + >> + if (dump_file && (dump_flags & TDF_DETAILS)) >> + { >> + fprintf (dump_file, "PHI "); >> + print_generic_expr (dump_file, gimple_phi_result (phi), 0); >> + fprintf (dump_file, >> + " changed to factor conversion out from COND_EXPR.\n"); >> + fprintf (dump_file, "New stmt with CAST that defines "); >> + print_generic_expr (dump_file, result, 0); >> + fprintf (dump_file, ".\n"); >> + } >> + >> + /* Remove the old cast(s) that has single use. */ >> + if (arg0_def_stmt && has_single_use (arg0)) >> + { >> + gsi_for_def = gsi_for_stmt (arg0_def_stmt); >> + gsi_remove (&gsi_for_def, true); >> + } >> + >> + if (arg1_def_stmt && has_single_use (arg1)) >> + { >> + gsi_for_def = gsi_for_stmt (arg1_def_stmt); >> + gsi_remove (&gsi_for_def, true); >> + } > So I would move the have_single_use tests up higher and reject the > transformation if arg0/arg1 have > 1 use. The reason is if arg0/arg1 > have > 1 use, then this transformation actually increases the number of > expressions evaluated at runtime. Done. > > It'd probably be good to include a test when arg0 or arg1 are both > SSA_NAMEs and new_arg0 and new_arg1 have > 1 use to verify the > transformation does not apply in that case. > Done. Bootstrapped and regression tested on x86-64-none-linux-gnu with no new regressions. Is this OK for trunk? Thanks, Kugan diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr66726.c b/gcc/testsuite/g++.dg/tree-ssa/pr66726.c index e69de29..9b3bd8f 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr66726.c +++ b/gcc/testsuite/g++.dg/tree-ssa/pr66726.c @@ -0,0 +1,36 @@ + +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* Execution test for converting VIEW_CONVERT_EXPR. */ + +struct cpp_num { + bool f; +}; + +extern cpp_num __attribute__((noinline)) +foo (cpp_num lhs, + cpp_num rhs) +{ + lhs.f = lhs.f || rhs.f; + return lhs; +} + +cpp_num lhs, rhs, r; + +int main () +{ + + lhs.f = false; + rhs.f = false; + r = foo (lhs, rhs); + if (r.f) + __builtin_abort (); + + + lhs.f = false; + rhs.f = true; + r = foo (lhs, rhs); + if (!r.f) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66726-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66726-2.c index e69de29..ab43d48 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr66726-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66726-2.c @@ -0,0 +1,19 @@ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt1-details" } */ + +extern void bar (char, char); +int +foo (char b) +{ + char a; + a = b; + b = 'b'; + bar (a, b); + b = a; + if (b == 0) + a++; + return a + b; +} + +/* { dg-final { scan-tree-dump-times "factor conversion out" 0 "phiopt1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr66726.c b/gcc/testsuite/gcc.dg/tree-ssa/pr66726.c index e69de29..a4c7418 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr66726.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr66726.c @@ -0,0 +1,15 @@ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt1-details" } */ + +extern unsigned short mode_size[]; + +int +oof (int mode) +{ + return (64 < mode_size[mode] ? 64 : mode_size[mode]); +} + +/* { dg-final { scan-tree-dump-times "factor conversion out" 1 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "phiopt1" } } */ + diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 92b4ab0..766ec63 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see static unsigned int tree_ssa_phiopt_worker (bool, bool); static bool conditional_replacement (basic_block, basic_block, edge, edge, gphi *, tree, tree); +static bool factor_out_conditional_conversion (edge, edge, gphi *, tree, tree); static int value_replacement (basic_block, basic_block, edge, edge, gimple, tree, tree); static bool minmax_replacement (basic_block, basic_block, @@ -335,6 +336,19 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) node. */ gcc_assert (arg0 != NULL && arg1 != NULL); + if (factor_out_conditional_conversion (e1, e2, phi, arg0, arg1)) + { + /* factor_out_conditional_conversion may create a new PHI in + BB2 and eliminate an existing PHI in BB2. Recompute values + that may be affected by that change. */ + phis = phi_nodes (bb2); + phi = single_non_singleton_phi_for_edges (phis, e1, e2); + gcc_assert (phi); + arg0 = gimple_phi_arg_def (phi, e1->dest_idx); + arg1 = gimple_phi_arg_def (phi, e2->dest_idx); + gcc_assert (arg0 != NULL && arg1 != NULL); + } + /* Do the replacement of conditional if it can be done. */ if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) cfgchanged = true; @@ -410,6 +424,134 @@ replace_phi_edge_with_variable (basic_block cond_block, bb->index); } +/* PR66726: Factor conversion out of COND_EXPR. If the arguments of the PHI + stmt are CONVERT_STMT, factor out the conversion and perform the conversion + to the result of PHI stmt. */ + +static bool +factor_out_conditional_conversion (edge e0, edge e1, gphi *phi, + tree arg0, tree arg1) +{ + gimple arg0_def_stmt = NULL, arg1_def_stmt = NULL, new_stmt; + tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE; + tree temp, result; + gphi *newphi; + gimple_stmt_iterator gsi, gsi_for_def; + source_location locus = gimple_location (phi); + enum tree_code convert_code; + + /* Handle only PHI statements with two arguments. TODO: If all + other arguments to PHI are INTEGER_CST or if their defining + statement have the same unary operation, we can handle more + than two arguments too. */ + if (gimple_phi_num_args (phi) != 2) + return false; + + /* First canonicalize to simplify tests. */ + if (TREE_CODE (arg0) != SSA_NAME) + { + std::swap (arg0, arg1); + std::swap (e0, e1); + } + + if (TREE_CODE (arg0) != SSA_NAME + || (TREE_CODE (arg1) != SSA_NAME + && TREE_CODE (arg1) != INTEGER_CST)) + return false; + + /* Check if arg0 is an SSA_NAME and the stmt which defines arg0 is + a conversion. */ + arg0_def_stmt = SSA_NAME_DEF_STMT (arg0); + if (!is_gimple_assign (arg0_def_stmt) + || !gimple_assign_cast_p (arg0_def_stmt)) + return false; + + /* Use the RHS as new_arg0. */ + convert_code = gimple_assign_rhs_code (arg0_def_stmt); + new_arg0 = gimple_assign_rhs1 (arg0_def_stmt); + if (convert_code == VIEW_CONVERT_EXPR) + new_arg0 = TREE_OPERAND (new_arg0, 0); + + if (TREE_CODE (arg1) == SSA_NAME) + { + /* Check if arg1 is an SSA_NAME and the stmt which defines arg1 + is a conversion. */ + arg1_def_stmt = SSA_NAME_DEF_STMT (arg1); + if (!is_gimple_assign (arg1_def_stmt) + || gimple_assign_rhs_code (arg1_def_stmt) != convert_code) + return false; + + /* Use the RHS as new_arg1. */ + new_arg1 = gimple_assign_rhs1 (arg1_def_stmt); + if (convert_code == VIEW_CONVERT_EXPR) + new_arg1 = TREE_OPERAND (new_arg1, 0); + } + else + { + /* If arg1 is an INTEGER_CST, fold it to new type. */ + if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) + && int_fits_type_p (arg1, TREE_TYPE (new_arg0))) + { + if (gimple_assign_cast_p (arg0_def_stmt)) + new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); + else + return false; + } + else + return false; + } + + /* If arg0/arg1 have > 1 use, then this transformation actually increases + the number of expressions evaluated at runtime. */ + if (!has_single_use (arg0) + || (arg1_def_stmt && !has_single_use (arg1))) + return false; + + /* If types of new_arg0 and new_arg1 are different bailout. */ + if (TREE_TYPE (new_arg0) != TREE_TYPE (new_arg1)) + return false; + + /* Create a new PHI stmt. */ + result = PHI_RESULT (phi); + temp = make_ssa_name (TREE_TYPE (new_arg0), NULL); + newphi = create_phi_node (temp, gimple_bb (phi)); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "PHI "); + print_generic_expr (dump_file, gimple_phi_result (phi), 0); + fprintf (dump_file, + " changed to factor conversion out from COND_EXPR.\n"); + fprintf (dump_file, "New stmt with CAST that defines "); + print_generic_expr (dump_file, result, 0); + fprintf (dump_file, ".\n"); + } + + /* Remove the old cast(s) that has single use. */ + gsi_for_def = gsi_for_stmt (arg0_def_stmt); + gsi_remove (&gsi_for_def, true); + if (arg1_def_stmt) + { + gsi_for_def = gsi_for_stmt (arg1_def_stmt); + gsi_remove (&gsi_for_def, true); + } + + add_phi_arg (newphi, new_arg0, e0, locus); + add_phi_arg (newphi, new_arg1, e1, locus); + + /* Create the conversion stmt and insert it. */ + if (convert_code == VIEW_CONVERT_EXPR) + temp = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (result), temp); + new_stmt = gimple_build_assign (result, convert_code, temp); + gsi = gsi_after_labels (gimple_bb (phi)); + gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); + + /* Remove he original PHI stmt. */ + gsi = gsi_for_stmt (phi); + gsi_remove (&gsi, true); + return true; +} + /* The function conditional_replacement does the main work of doing the conditional replacement. Return true if the replacement is done. Otherwise return false. @@ -2142,6 +2284,26 @@ gate_hoist_loads (void) This pass also performs a fifth transformation of a slightly different flavor. + Factor conversion in COND_EXPR + ------------------------------ + + This transformation factors the conversion out of COND_EXPR with + factor_out_conditional_conversion. + + For example: + if (a <= CST) goto ; else goto ; + : + tmp = (int) a; + : + tmp = PHI + + Into: + if (a <= CST) goto ; else goto ; + : + : + a = PHI + tmp = (int) a; + Adjacent Load Hoisting ----------------------