From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1011) id 9DEB53858CDB; Tue, 31 Jan 2023 14:58:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9DEB53858CDB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675177080; bh=g/sULC34DWBV60YOF0q5MeLlDYPqVQiUtV6PNXHC1lM=; h=From:To:Subject:Date:From; b=F3vKbvcW+ArFe1xczex8cMM0O0PHr94jZKyjv7q/5E6+eXMRHvPVEOpH4YCAN9hrd P606GHm/dB2uyezYbU2Jj5Uer0/6xtbzgaGNDa2bHsZCdjFWRANa1/lBDdJqSFjOsQ 0Dp15kowcn23IctOyAFXbIBo/9HdFuTObs+PvWvU= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andrew Macleod To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-5577] Properly set GORI relation trios. X-Act-Checkin: gcc X-Git-Author: Andrew MacLeod X-Git-Refname: refs/heads/master X-Git-Oldrev: 7f583a335769591d016caa51490e3e5dd50354fe X-Git-Newrev: 99fda5de368d84d97eb29a9f03e0d6039068f8b9 Message-Id: <20230131145800.9DEB53858CDB@sourceware.org> Date: Tue, 31 Jan 2023 14:58:00 +0000 (GMT) List-Id: https://gcc.gnu.org/g:99fda5de368d84d97eb29a9f03e0d6039068f8b9 commit r13-5577-g99fda5de368d84d97eb29a9f03e0d6039068f8b9 Author: Andrew MacLeod Date: Wed Jan 25 16:26:39 2023 -0500 Properly set GORI relation trios. When relation trios were added to GORI, there was only one use. As they are utilized more by range-ops, it is apparent that the implelemtation was not complete. This patch fleshes it out completely so that every GORI operation has a complete relation trio. * gimple-range-gori.cc (gori_compute::compute_operand_range): Do not abort calculations if there is a valid relation available. (gori_compute::refine_using_relation): Pass correct relation trio. (gori_compute::compute_operand1_range): Create trio and use it. (gori_compute::compute_operand2_range): Ditto. * range-op.cc (operator_plus::op1_range): Use correct trio member. (operator_minus::op1_range): Use correct trio member. * value-relation.cc (value_relation::create_trio): New. * value-relation.h (value_relation::create_trio): New prototype. Diff: --- gcc/gimple-range-gori.cc | 70 +++++++++++++++++------------------------------- gcc/range-op.cc | 4 +-- gcc/value-relation.cc | 34 +++++++++++++++++++++++ gcc/value-relation.h | 1 + 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 930e2a0f0ab..3dc4576ff13 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -632,6 +632,9 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, if (op1 && op2) { relation_kind k = handler.op1_op2_relation (lhs); + // If there is no relation, and op1 == op2, create a relation. + if (!vrel_ptr && k == VREL_VARYING && op1 == op2) + k = VREL_EQ; if (k != VREL_VARYING) { vrel.set_relation (k, op1, op2); @@ -952,7 +955,9 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range, { gcc_checking_assert (TREE_CODE (op1) == SSA_NAME); gcc_checking_assert (TREE_CODE (op2) == SSA_NAME); - gcc_checking_assert (k != VREL_VARYING && k != VREL_UNDEFINED); + + if (k == VREL_VARYING || k == VREL_EQ || k == VREL_UNDEFINED) + return false; bool change = false; bool op1_def_p = in_chain_p (op2, op1); @@ -991,7 +996,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range, Value_Range new_result (type); if (!op_handler.op1_range (new_result, type, op1_def_p ? op1_range : op2_range, - other_op, relation_trio::lhs_op2 (k))) + other_op, relation_trio::lhs_op1 (k))) return false; if (op1_def_p) { @@ -1023,7 +1028,7 @@ gori_compute::refine_using_relation (tree op1, vrange &op1_range, Value_Range new_result (type); if (!op_handler.op2_range (new_result, type, op1_def_p ? op1_range : op2_range, - other_op, relation_trio::lhs_op1 (k))) + other_op, relation_trio::lhs_op2 (k))) return false; if (op1_def_p) { @@ -1062,6 +1067,10 @@ gori_compute::compute_operand1_range (vrange &r, tree op2 = handler.operand2 (); tree lhs_name = gimple_get_lhs (stmt); + relation_trio trio; + if (rel) + trio = rel->create_trio (lhs_name, op1, op2); + Value_Range op1_range (TREE_TYPE (op1)); Value_Range tmp (TREE_TYPE (op1)); Value_Range op2_range (op2 ? TREE_TYPE (op2) : TREE_TYPE (op1)); @@ -1073,27 +1082,11 @@ gori_compute::compute_operand1_range (vrange &r, if (op2) { src.get_operand (op2_range, op2); - relation_kind k = VREL_VARYING; - relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING; - if (rel) - { - if (lhs_name == rel->op1 () && op1 == rel->op2 ()) - k = rel->kind (); - else if (lhs_name == rel->op2 () && op1 == rel->op1 ()) - k = relation_swap (rel->kind ()); - else if (op1 == rel->op1 () && op2 == rel->op2 ()) - { - op_op = rel->kind (); - refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); - } - else if (op1 == rel->op2 () && op2 == rel->op1 ()) - { - op_op = relation_swap (rel->kind ()); - refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); - } - } - if (!handler.calc_op1 (tmp, lhs, op2_range, relation_trio (VREL_VARYING, - k, op_op))) + relation_kind op_op = trio.op1_op2 (); + if (op_op != VREL_VARYING) + refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); + + if (!handler.calc_op1 (tmp, lhs, op2_range, trio)) return false; } else @@ -1101,7 +1094,7 @@ gori_compute::compute_operand1_range (vrange &r, // We pass op1_range to the unary operation. Nomally it's a // hidden range_for_type parameter, but sometimes having the // actual range can result in better information. - if (!handler.calc_op1 (tmp, lhs, op1_range, TRIO_VARYING)) + if (!handler.calc_op1 (tmp, lhs, op1_range, trio)) return false; } @@ -1172,29 +1165,16 @@ gori_compute::compute_operand2_range (vrange &r, src.get_operand (op1_range, op1); src.get_operand (op2_range, op2); - relation_kind k = VREL_VARYING; - relation_kind op_op = (op1 == op2) ? VREL_EQ : VREL_VARYING; + + relation_trio trio; if (rel) - { - if (lhs_name == rel->op1 () && op2 == rel->op2 ()) - k = rel->kind (); - else if (lhs_name == rel->op2 () && op2 == rel->op1 ()) - k = relation_swap (rel->kind ()); - else if (op1 == rel->op1 () && op2 == rel->op2 ()) - { - op_op = rel->kind (); - refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); - } - else if (op1 == rel->op2 () && op2 == rel->op1 ()) - { - op_op = relation_swap (rel->kind ()); - refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); - } - } + trio = rel->create_trio (lhs_name, op1, op2); + relation_kind op_op = trio.op1_op2 (); + if (op_op != VREL_VARYING) + refine_using_relation (op1, op1_range, op2, op2_range, src, op_op); // Intersect with range for op2 based on lhs and op1. - if (!handler.calc_op2 (tmp, lhs, op1_range, relation_trio (k, VREL_VARYING, - op_op))) + if (!handler.calc_op2 (tmp, lhs, op1_range, trio)) return false; unsigned idx; diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 6e5754e9130..ed2dd1eb99c 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1460,7 +1460,7 @@ operator_plus::op1_range (irange &r, tree type, if (!minus) return false; bool res = minus.fold_range (r, type, lhs, op2); - relation_kind rel = trio.lhs_op2 (); + relation_kind rel = trio.lhs_op1 (); // Check for a relation refinement. if (res) adjust_op1_for_overflow (r, op2, rel, true /* PLUS_EXPR */); @@ -1632,7 +1632,7 @@ operator_minus::op1_range (irange &r, tree type, if (!minus) return false; bool res = minus.fold_range (r, type, lhs, op2); - relation_kind rel = trio.lhs_op2 (); + relation_kind rel = trio.lhs_op1 (); if (res) adjust_op1_for_overflow (r, op2, rel, false /* PLUS_EXPR */); return res; diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 5ca8a7eb0d9..f5b1e67e420 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -883,6 +883,40 @@ value_relation::apply_transitive (const value_relation &rel) return false; } +// Create a trio from this value relation given LHS, OP1 and OP2. + +relation_trio +value_relation::create_trio (tree lhs, tree op1, tree op2) +{ + relation_kind lhs_1; + if (lhs == name1 && op1 == name2) + lhs_1 = related; + else if (lhs == name2 && op1 == name1) + lhs_1 = relation_swap (related); + else + lhs_1 = VREL_VARYING; + + relation_kind lhs_2; + if (lhs == name1 && op2 == name2) + lhs_2 = related; + else if (lhs == name2 && op2 == name1) + lhs_2 = relation_swap (related); + else + lhs_2 = VREL_VARYING; + + relation_kind op_op; + if (op1 == name1 && op2 == name2) + op_op = related; + else if (op1 == name2 && op2 == name1) + op_op = relation_swap (related); + else if (op1 == op2) + op_op = VREL_EQ; + else + op_op = VREL_VARYING; + + return relation_trio (lhs_1, lhs_2, op_op); +} + // Dump the relation to file F. void diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 664fd71c925..340f9c42554 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -426,6 +426,7 @@ public: inline tree op1 () const { return name1; } inline tree op2 () const { return name2; } + relation_trio create_trio (tree lhs, tree op1, tree op2); bool union_ (value_relation &p); bool intersect (value_relation &p); void negate ();