Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/11/19 2:23 PM, Richard Biener wrote: > On Wed, 11 Sep 2019, Martin Liška wrote: > >> Hello. >> >> One another updated version of the patch. >> Changes from the previous version: >> - I fixed: >> gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, >> 2)); >> into gimple_size (GIMPLE_ASSIGN, 3) >> - I simplified condition in gimple_simplified_result_is_gimple_val >> - optimize_vec_cond_expr is using build_same_sized_truth_vector_type > > Can you here instead amend ovce_extract_ops to return the type of > 'cond' which should be the type you want? Sure, updated in the tested attached patch. I'm going to install the patch after the Cauldron. Martin > > Otherwise OK. > > Richard. > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >> >> Ready to be installed? >> Thanks, >> Martin >From 8ad0d2e59350b9410543571059c0d24bcda52db3 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple-fold.c (and_comparisons_1): Add type as first argument. (and_var_with_comparison): Likewise. (and_var_with_comparison_1): Likewise. (or_comparisons_1): Likewise. (or_var_with_comparison): Likewise. (or_var_with_comparison_1): Likewise. (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Likewise. (maybe_fold_comparisons_from_match_pd): New. * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. (maybe_fold_or_comparisons): Likewise. * gimple.c (gimple_size): Make it public and add num_ops argument. (gimple_init): New function. (gimple_alloc): Call gimple_init. * gimple.h (gimple_size): New. (gimple_init): Likewise. * tree-if-conv.c (fold_or_predicates): Pass type. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. (optimize_vec_cond_expr): Likewise. (ovce_extract_ops): Return type of conditional expression. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use init_ssa_name_imm_use. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c| 170 +-- gcc/gimple-fold.h| 4 +- gcc/gimple.c | 37 + gcc/gimple.h | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-ssa-ifcombine.c | 2 +- gcc/tree-ssa-reassoc.c | 25 -- gcc/tree-ssanames.c | 21 +++-- gcc/tree-ssanames.h | 1 + 9 files changed, 189 insertions(+), 75 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..6d9ba367839 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2) /* Forward declarations for some mutually recursive functions. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert, !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) -t = or_var_with_comparison_1 (stmt, +t = or_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else -t = and_var_with_comparison_1 (stmt, code2, op2a, op2b); +t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5422,7 +5422,7 @@ and_var_with_comparis
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Wed, 11 Sep 2019, Martin Liška wrote: > Hello. > > One another updated version of the patch. > Changes from the previous version: > - I fixed: > gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, > 2)); > into gimple_size (GIMPLE_ASSIGN, 3) > - I simplified condition in gimple_simplified_result_is_gimple_val > - optimize_vec_cond_expr is using build_same_sized_truth_vector_type Can you here instead amend ovce_extract_ops to return the type of 'cond' which should be the type you want? Otherwise OK. Richard. > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? > Thanks, > Martin
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
Hello. One another updated version of the patch. Changes from the previous version: - I fixed: gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2)); into gimple_size (GIMPLE_ASSIGN, 3) - I simplified condition in gimple_simplified_result_is_gimple_val - optimize_vec_cond_expr is using build_same_sized_truth_vector_type Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin >From ee44ff1742928e3200ce6a0677e8c8a3dbe4e6d2 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple-fold.c (and_comparisons_1): Add type as first argument. (and_var_with_comparison): Likewise. (and_var_with_comparison_1): Likewise. (or_comparisons_1): Likewise. (or_var_with_comparison): Likewise. (or_var_with_comparison_1): Likewise. (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Likewise. (maybe_fold_comparisons_from_match_pd): New. * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. (maybe_fold_or_comparisons): Likewise. * gimple.c (gimple_size): Make it public and add num_ops argument. (gimple_init): New function. (gimple_alloc): Call gimple_init. * gimple.h (gimple_size): New. (gimple_init): Likewise. * tree-if-conv.c (fold_or_predicates): Pass type. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. (optimize_vec_cond_expr): Likewise. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use init_ssa_name_imm_use. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c| 170 +-- gcc/gimple-fold.h| 4 +- gcc/gimple.c | 37 + gcc/gimple.h | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-ssa-ifcombine.c | 2 +- gcc/tree-ssa-reassoc.c | 15 +++- gcc/tree-ssanames.c | 21 +++-- gcc/tree-ssanames.h | 1 + 9 files changed, 183 insertions(+), 71 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..aa2f94ace28 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2) /* Forward declarations for some mutually recursive functions. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert, !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) -t = or_var_with_comparison_1 (stmt, +t = or_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else -t = and_var_with_comparison_1 (stmt, code2, op2a, op2b); +t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b); return canonicalize_bool (t, invert); } @@ -5422,7 +5422,7 @@ and_var_with_comparison (tree var, bool invert, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b) { tree var = gimple_assign_lhs (stmt); @@ -5453,7 +5453,7 @@ and_var_with_comparison_1 (gimple *stmt, /* If the definition is a comparison, recurse on it. */ if (TREE_CODE_CLASS
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/11/19 10:22 AM, Li Jia He wrote: > Hi, > > On 2019/9/10 3:40 PM, Martin Liška wrote: >> On 9/9/19 3:55 PM, Richard Biener wrote: >>> On Mon, 9 Sep 2019, Martin Liška wrote: >>> On 9/9/19 3:42 PM, Richard Biener wrote: > There is no newly created GIMPLE? Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd can come up with new temporary expressions that need to be inserted into GIMPLE stream? But that's probably handled in ifcombine with: t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true, GSI_SAME_STMT); ? >>> >>> No, that case is done when forcing short-circuiting when there was no >>> simplification. When there was a simplification we do >>> >>> if (result_inv) >>> t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t); >>> t = canonicalize_cond_expr_cond (t); >>> if (!t) >>> return false; >>> >>> so when it is not a condition suitable for direct replacement into >>> >>> gimple_cond_set_condition_from_tree (inner_cond, t); >>> >>> we fail. >>> >>> Richard. >>> >> >> I see, so I'm sending updated tested patch. > Hello. Next time, please Reply to all ;) > Thanks for working on this. > I tested the patch. But I found that this patch will cause gcc not to > bootstrap. I found the following statement may be a question. > ' > gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2)); > ' > we may need to change it to the following > ' > gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3)); > ' > And we may also replace gimple with gassign. Good point, I'll include the changes to my patchset. > > And we may also need to make some changes to the statements in > if(op.resimplify (NULL, follow_all_ssa_edges)). Please take a look at the > attachment: @@ -5888,23 +5890,22 @@ maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code, if (gimple_simplified_result_is_gimple_val (&op)) { tree res = op.ops[0]; - switch (TREE_CODE (res)) - { - case SSA_NAME: - { - if (res == lhs1) - return build2 (code1, type, op1a, op1b); - else if (res == lhs2) - return build2 (code2, type, op2a, op2b); - else - return res; - } - case INTEGER_CST: - /* Fold expression to boolean_true_node or boolean_false_node. */ - return res; - default: - return NULL_TREE; - } + if (res == lhs1) + return build2 (code1, type, op1a, op1b); + else if (res == lhs2) + return build2 (code2, type, op2a, op2b); + else + return res; I'll include this. + } + + if (op.code.is_tree_code () + && TREE_CODE_CLASS ((enum tree_code) op.code) == tcc_comparison) + { + tree op0 = op.ops[0]; + tree op1 = op.ops[1]; + if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) + return NULL_TREE; /* not simple */ + return build2 ((enum tree_code) op.code, op.type, op0, op1); } } This is added in patch 3/5. Martin > > Thanks, > Lijia He > >> >> Martin
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/9/19 3:55 PM, Richard Biener wrote: On Mon, 9 Sep 2019, Martin Liška wrote: On 9/9/19 3:42 PM, Richard Biener wrote: There is no newly created GIMPLE? Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd can come up with new temporary expressions that need to be inserted into GIMPLE stream? But that's probably handled in ifcombine with: t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true, GSI_SAME_STMT); ? No, that case is done when forcing short-circuiting when there was no simplification. When there was a simplification we do if (result_inv) t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t); t = canonicalize_cond_expr_cond (t); if (!t) return false; so when it is not a condition suitable for direct replacement into gimple_cond_set_condition_from_tree (inner_cond, t); we fail. Richard. I see, so I'm sending updated tested patch. Martin >From f757482a57754e5c7590e0f2cadf3cc4443beab6 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple-fold.c (and_comparisons_1): Add type as first argument. (and_var_with_comparison): Likewise. (and_var_with_comparison_1): Likewise. (or_comparisons_1): Likewise. (or_var_with_comparison): Likewise. (or_var_with_comparison_1): Likewise. (maybe_fold_and_comparisons): Call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Likewise. (maybe_fold_comparisons_from_match_pd): New. * gimple-fold.h (maybe_fold_and_comparisons): Add type argument. (maybe_fold_or_comparisons): Likewise. * gimple.c (gimple_size): Make it public and add num_ops argument. (gimple_init): New function. (gimple_alloc): Call gimple_init. * gimple.h (gimple_size): New. (gimple_init): Likewise. * tree-if-conv.c (fold_or_predicates): Pass type. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * tree-ssa-reassoc.c (eliminate_redundant_comparison): Likewise. (optimize_vec_cond_expr): Likewise. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use init_ssa_name_imm_use. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c| 179 ++- gcc/gimple-fold.h| 4 +- gcc/gimple.c | 37 gcc/gimple.h | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-ssa-ifcombine.c | 2 +- gcc/tree-ssa-reassoc.c | 14 ++- gcc/tree-ssanames.c | 21 +++-- gcc/tree-ssanames.h | 1 + 9 files changed, 191 insertions(+), 71 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..fcdcb087ec4 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5371,22 +5371,22 @@ same_bool_result_p (const_tree op1, const_tree op2) /* Forward declarations for some mutually recursive functions. */ static tree -and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -and_var_with_comparison_1 (gimple *stmt, +and_var_with_comparison_1 (tree type, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); static tree -or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, +or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison (tree var, bool invert, +or_var_with_comparison (tree, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b); static tree -or_var_with_comparison_1 (gimple *stmt, +or_var_with_comparison_1 (tree, gimple *stmt, enum tree_code code2, tree op2a, tree op2b); /* Helper function for and_comparisons_1: try to simplify the AND of the @@ -5395,7 +5395,7 @@ or_var_with_comparison_1 (gimple *stmt, Return NULL_EXPR if we can't simplify this to a single expression. */ static tree -and_var_with_comparison (tree var, bool invert, +and_var_with_comparison (tree type, tree var, bool invert, enum tree_code code2, tree op2a, tree op2b) { tree t; @@ -5409,11 +5409,11 @@ and_var_with_comparison (tree var, bool invert, !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b)) Then we only have to consider the simpler non-inverted cases. */ if (invert) -t = or_var_with_comparison_1 (stmt, +t = or_var_with_comparison_1 (type, stmt, invert_tree_comparison (code2, false), op2a, op2b); else -t = and_var_with_comparison_1 (stmt, code2, op2a, op2b); +t = and_var_with_comparison_1 (type, stmt, code2,
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Mon, 9 Sep 2019, Martin Liška wrote: > On 9/9/19 3:42 PM, Richard Biener wrote: > > There is no newly created GIMPLE? > > Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd > can come up with new temporary expressions that need to be inserted into > GIMPLE stream? But that's probably handled in ifcombine with: > > t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, > true, > GSI_SAME_STMT); > ? No, that case is done when forcing short-circuiting when there was no simplification. When there was a simplification we do if (result_inv) t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t); t = canonicalize_cond_expr_cond (t); if (!t) return false; so when it is not a condition suitable for direct replacement into gimple_cond_set_condition_from_tree (inner_cond, t); we fail. Richard.
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/9/19 3:42 PM, Richard Biener wrote: > There is no newly created GIMPLE? Hm, I thought from the beginning that maybe_fold_comparisons_from_match_pd can come up with new temporary expressions that need to be inserted into GIMPLE stream? But that's probably handled in ifcombine with: t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true, GSI_SAME_STMT); ? Martin
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Mon, 9 Sep 2019, Martin Liška wrote: > On 9/9/19 3:10 PM, Richard Biener wrote: > > On Mon, 9 Sep 2019, Martin Liška wrote: > > > >> Hi. > >> > >> I'm sending slightly updated version of the patch where we > >> need to properly select type in maybe_fold_comparisons_from_match_pd > >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE > >> and so that we can't return a boolean_type_node. > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > >> > >> Ready to be installed? > > > > 2019-07-16 Li Jia He > > Martin Liska > > > > * gimple.h (gimple_init): Declare. > > (gimple_size): Likewise. > > * gimple.c (gimple_init): Remove static and inline restrictions. > > (gimple_alloc): Only allocate memory and call gimple_init. > > (gimple_size): Likewise. > > > > Likewise? > > Fixed. > > > > > * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn. > > (make_ssa_name_fn): New. > > > > You didn't touch make_ssa_name_fn. > > Likewise here. > > > > > Since we're needing another iteration: > > > > + /* Allocate gimple stmt1 on the stack. */ > > + gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size > > (GIMPLE_ASSIGN, 2)); > > > > You can use gassign *stmt1 here so all the gimple_assign_ fns below > > get cheaper. > > > > + if (op.resimplify (NULL, follow_all_ssa_edges)) > > +{ > > + if (gimple_simplified_result_is_gimple_val (&op)) > > + { > > + tree res = op.ops[0]; > > + switch (TREE_CODE (res)) > > + { > > + case SSA_NAME: > > + { > > + gimple *def = SSA_NAME_DEF_STMT (res); > > > > you shouldn't expand SSA names here unless that SSA name is > > exactly lhs1 or lhs2 from above. So > > Ah, got it. > > > > > if (res == lhs1) > >return build2 (...); > > else if (res == lhs2) > >return build2 (..); > > else > >return res; > > > > plus you miss the case where 'op' became a simplified comparison > > in itself. So, > > Yes, that part is included in part 3. I'm going to send the updated patch > 3 as well soon. > > > > > if (op.code.is_tree_code () > > && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison) > >{ > > tree op0 = op.ops[0]; > > tree op1 = op.ops[1]; > > if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) > > return NULL_TREE; /* not simple */ > > return build2 ((enum tree_code)op.code, op.type, > > op0, op1); > >} > > > > note you need not fold_ again. It's of course ugly that we > > need to build a GENERIC tree here but that's the current interface > > and thus OK at the moment. > > I see. But what I need is to insert newly created GIMPLE assignment to > the provided gimple sequence (gsi), right? There is no newly created GIMPLE? Richard.
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/9/19 3:10 PM, Richard Biener wrote: > On Mon, 9 Sep 2019, Martin Liška wrote: > >> Hi. >> >> I'm sending slightly updated version of the patch where we >> need to properly select type in maybe_fold_comparisons_from_match_pd >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE >> and so that we can't return a boolean_type_node. >> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >> >> Ready to be installed? > > 2019-07-16 Li Jia He > Martin Liska > > * gimple.h (gimple_init): Declare. > (gimple_size): Likewise. > * gimple.c (gimple_init): Remove static and inline restrictions. > (gimple_alloc): Only allocate memory and call gimple_init. > (gimple_size): Likewise. > > Likewise? Fixed. > > * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn. > (make_ssa_name_fn): New. > > You didn't touch make_ssa_name_fn. Likewise here. > > Since we're needing another iteration: > > + /* Allocate gimple stmt1 on the stack. */ > + gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size > (GIMPLE_ASSIGN, 2)); > > You can use gassign *stmt1 here so all the gimple_assign_ fns below > get cheaper. > > + if (op.resimplify (NULL, follow_all_ssa_edges)) > +{ > + if (gimple_simplified_result_is_gimple_val (&op)) > + { > + tree res = op.ops[0]; > + switch (TREE_CODE (res)) > + { > + case SSA_NAME: > + { > + gimple *def = SSA_NAME_DEF_STMT (res); > > you shouldn't expand SSA names here unless that SSA name is > exactly lhs1 or lhs2 from above. So Ah, got it. > > if (res == lhs1) >return build2 (...); > else if (res == lhs2) >return build2 (..); > else >return res; > > plus you miss the case where 'op' became a simplified comparison > in itself. So, Yes, that part is included in part 3. I'm going to send the updated patch 3 as well soon. > > if (op.code.is_tree_code () > && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison) >{ > tree op0 = op.ops[0]; > tree op1 = op.ops[1]; > if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) > return NULL_TREE; /* not simple */ > return build2 ((enum tree_code)op.code, op.type, > op0, op1); >} > > note you need not fold_ again. It's of course ugly that we > need to build a GENERIC tree here but that's the current interface > and thus OK at the moment. I see. But what I need is to insert newly created GIMPLE assignment to the provided gimple sequence (gsi), right? Thanks, Martin > > Thanks, > Richard. > >From a0b4daec604ee92ac8e76e416cd912d7d176a811 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple.h (gimple_init): Declare. (gimple_size): Likewise. * gimple.c (gimple_init): Remove static and inline restrictions. (gimple_alloc): Only allocate memory and call gimple_init. (gimple_size): Make it external and add new num_ops argument. * gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function. (maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. * tree-ssanames.c (init_ssa_name_imm_use): New. (make_ssa_name_fn): Use make_ssa_name_fn. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c | 108 gcc/gimple.c| 37 +-- gcc/gimple.h| 2 + gcc/tree-ssanames.c | 21 ++--- gcc/tree-ssanames.h | 1 + 5 files changed, 138 insertions(+), 31 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..50cb3bf7e32 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5834,6 +5834,85 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, return NULL_TREE; } +/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons + : try to simplify the AND/OR of the ssa variable VAR with the comparison + specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't + simplify this to a single expression. As we are going to lower the cost + of building SSA names / gimple stmts significantly, we need to allocate + them ont the stack. This will cause the code to be a bit ugly. */ + +static tree +maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1, + tree op1a, tree op1b, + enum tree_code code2, tree op2a, + tree op2b) +{ + tree type = TREE_TYPE (op1a); + if (TREE_CODE (type) != VECTOR_
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Mon, 9 Sep 2019, Martin Liška wrote: > On 9/9/19 3:10 PM, Marc Glisse wrote: > > On Mon, 9 Sep 2019, Martin Liška wrote: > > > >> I'm sending slightly updated version of the patch where we > >> need to properly select type in maybe_fold_comparisons_from_match_pd > >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE > >> and so that we can't return a boolean_type_node. > > > > + tree type = TREE_TYPE (op1a); > > + if (TREE_CODE (type) != VECTOR_TYPE) > > + type = boolean_type_node; > > > > Don't you need build_same_sized_truth_vector_type or something, for > > instance with AVX512? > > > > Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I > > don't know if we can end up here with both versions, but if we can, > > guessing the type could be dangerous. Would it be hard to add a type > > argument to those functions and delegate this to the caller? Any better > > idea (maybe this is already safe and I am just missing it)? > > Richi can you help us here? I'm not sure what guarantees do we have here in > GIMPLE? Oops, I missed this hunk - the caller needs to pass this down, but at least from the ifcombine use we are always coming from a if (a CMP b) context and thus a boolean_type_node result type. For the reassoc case there's indeed nothing preventing from vector typed comparisons sneaking in here, likewise recursion via or_var_with_comparison_1 might run into vectors. Thus the toplevel interface has to pass down the (common) type of the two comparisons. Richard.
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/9/19 3:10 PM, Marc Glisse wrote: > On Mon, 9 Sep 2019, Martin Liška wrote: > >> I'm sending slightly updated version of the patch where we >> need to properly select type in maybe_fold_comparisons_from_match_pd >> function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE >> and so that we can't return a boolean_type_node. > > + tree type = TREE_TYPE (op1a); > + if (TREE_CODE (type) != VECTOR_TYPE) > + type = boolean_type_node; > > Don't you need build_same_sized_truth_vector_type or something, for instance > with AVX512? > > Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I > don't know if we can end up here with both versions, but if we can, guessing > the type could be dangerous. Would it be hard to add a type argument to those > functions and delegate this to the caller? Any better idea (maybe this is > already safe and I am just missing it)? Richi can you help us here? I'm not sure what guarantees do we have here in GIMPLE? Martin >
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Mon, 9 Sep 2019, Martin Liška wrote: I'm sending slightly updated version of the patch where we need to properly select type in maybe_fold_comparisons_from_match_pd function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE and so that we can't return a boolean_type_node. + tree type = TREE_TYPE (op1a); + if (TREE_CODE (type) != VECTOR_TYPE) +type = boolean_type_node; Don't you need build_same_sized_truth_vector_type or something, for instance with AVX512? Also, IIRC EQ_EXPR for vectors can return either a vector or a boolean. I don't know if we can end up here with both versions, but if we can, guessing the type could be dangerous. Would it be hard to add a type argument to those functions and delegate this to the caller? Any better idea (maybe this is already safe and I am just missing it)? -- Marc Glisse
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On Mon, 9 Sep 2019, Martin Liška wrote: > Hi. > > I'm sending slightly updated version of the patch where we > need to properly select type in maybe_fold_comparisons_from_match_pd > function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE > and so that we can't return a boolean_type_node. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? 2019-07-16 Li Jia He Martin Liska * gimple.h (gimple_init): Declare. (gimple_size): Likewise. * gimple.c (gimple_init): Remove static and inline restrictions. (gimple_alloc): Only allocate memory and call gimple_init. (gimple_size): Likewise. Likewise? * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn. (make_ssa_name_fn): New. You didn't touch make_ssa_name_fn. Since we're needing another iteration: + /* Allocate gimple stmt1 on the stack. */ + gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2)); You can use gassign *stmt1 here so all the gimple_assign_ fns below get cheaper. + if (op.resimplify (NULL, follow_all_ssa_edges)) +{ + if (gimple_simplified_result_is_gimple_val (&op)) + { + tree res = op.ops[0]; + switch (TREE_CODE (res)) + { + case SSA_NAME: + { + gimple *def = SSA_NAME_DEF_STMT (res); you shouldn't expand SSA names here unless that SSA name is exactly lhs1 or lhs2 from above. So if (res == lhs1) return build2 (...); else if (res == lhs2) return build2 (..); else return res; plus you miss the case where 'op' became a simplified comparison in itself. So, if (op.code.is_tree_code () && TREE_CODE_CLASS ((enum tree_code)op.code) == tcc_comparison) { tree op0 = op.ops[0]; tree op1 = op.ops[1]; if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2) return NULL_TREE; /* not simple */ return build2 ((enum tree_code)op.code, op.type, op0, op1); } note you need not fold_ again. It's of course ugly that we need to build a GENERIC tree here but that's the current interface and thus OK at the moment. Thanks, Richard.
Re: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
Hi. I'm sending slightly updated version of the patch where we need to properly select type in maybe_fold_comparisons_from_match_pd function for the created SSA_NAMEs. We can be called for a VECTOR_TYPE and so that we can't return a boolean_type_node. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin >From b6165b1d4be04f47bfa2b511974f5b8e784acb41 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/5] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple.h (gimple_init): Declare. (gimple_size): Likewise. * gimple.c (gimple_init): Remove static and inline restrictions. (gimple_alloc): Only allocate memory and call gimple_init. (gimple_size): Likewise. * gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function. (maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn. (make_ssa_name_fn): New. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c | 112 gcc/gimple.c| 37 +-- gcc/gimple.h| 2 + gcc/tree-ssanames.c | 21 ++--- gcc/tree-ssanames.h | 1 + 5 files changed, 142 insertions(+), 31 deletions(-) diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index fcffb9802b7..8a9eca13b87 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5834,6 +5834,89 @@ and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b, return NULL_TREE; } +/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons + : try to simplify the AND/OR of the ssa variable VAR with the comparison + specified by (OP2A CODE2 OP2B) from match.pd. Return NULL_EXPR if we can't + simplify this to a single expression. As we are going to lower the cost + of building SSA names / gimple stmts significantly, we need to allocate + them ont the stack. This will cause the code to be a bit ugly. */ + +static tree +maybe_fold_comparisons_from_match_pd (enum tree_code code, enum tree_code code1, + tree op1a, tree op1b, + enum tree_code code2, tree op2a, + tree op2b) +{ + tree type = TREE_TYPE (op1a); + if (TREE_CODE (type) != VECTOR_TYPE) +type = boolean_type_node; + + /* Allocate gimple stmt1 on the stack. */ + gimple *stmt1 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2)); + gimple_init (stmt1, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt1, code1); + gimple_assign_set_rhs1 (stmt1, op1a); + gimple_assign_set_rhs2 (stmt1, op1b); + + /* Allocate gimple stmt2 on the stack. */ + gimple *stmt2 = (gimple *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 2)); + gimple_init (stmt2, GIMPLE_ASSIGN, 3); + gimple_assign_set_rhs_code (stmt2, code2); + gimple_assign_set_rhs1 (stmt2, op2a); + gimple_assign_set_rhs2 (stmt2, op2b); + + /* Allocate SSA names(lhs1) on the stack. */ + tree lhs1 = (tree)XALLOCA (tree_ssa_name); + memset (lhs1, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs1, SSA_NAME); + TREE_TYPE (lhs1) = type; + init_ssa_name_imm_use (lhs1); + + /* Allocate SSA names(lhs2) on the stack. */ + tree lhs2 = (tree)XALLOCA (tree_ssa_name); + memset (lhs2, 0, sizeof (tree_ssa_name)); + TREE_SET_CODE (lhs2, SSA_NAME); + TREE_TYPE (lhs2) = type; + init_ssa_name_imm_use (lhs2); + + gimple_assign_set_lhs (stmt1, lhs1); + gimple_assign_set_lhs (stmt2, lhs2); + + gimple_match_op op (gimple_match_cond::UNCOND, code, + type, gimple_assign_lhs (stmt1), + gimple_assign_lhs (stmt2)); + if (op.resimplify (NULL, follow_all_ssa_edges)) +{ + if (gimple_simplified_result_is_gimple_val (&op)) + { + tree res = op.ops[0]; + switch (TREE_CODE (res)) + { + case SSA_NAME: + { + gimple *def = SSA_NAME_DEF_STMT (res); + + if (!is_gimple_assign (def) + || TREE_CODE_CLASS (gimple_assign_rhs_code (def)) + != tcc_comparison) + return NULL_TREE; + + return fold_build2 (gimple_assign_rhs_code (def), + type, gimple_assign_rhs1 (def), + gimple_assign_rhs2 (def)); + } + case INTEGER_CST: + /* Fold expression to boolean_true_node or boolean_false_node. */ + return res; + default: + return NULL_TREE; + } + } +} + + return NULL_TREE; +} + /* Try to simplify the AND of two comparisons, specified by (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively. If this can be simplified to a single expression (without requiring @@ -5845,11 +5928,17 @@ tree maybe_fold_and_comparisons (enum tree_code code1, tree op1a, tree op1b, enum tree_code code2, tree op2a, tree op2b) { - tree t = and_comparisons_1 (code1, op
[PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd
On 9/5/19 3:01 PM, Richard Biener wrote: > On Tue, 16 Jul 2019, Li Jia He wrote: > >> Hi, >> >> I made some changes based on the recommendations. Would you like to >> help me to see it again ? Sorry, it took so long time to provide the >> patch. >> >> Note: 1. I keep the code for and_comparisons_1 and or_comparisons_1. >> The reason is that I did not found a good way to handle the >> optimization of '((x CODE1 y) AND (x CODE2 y))' in match.pd. >> Maybe I missing some important information about match.pd. >> 2. The gimple_resimplify2 function is not used. Since stmt1, >> stmt2, lhs1 and lhs2 are allocated on the stack, Is there a >> question with the value on the stack as the return value ? >> I may have misunderstood Richard's intention. > > Sorry for the delay in reviewing. > > Rather than exporting gimple_set_code and gimple_size I'd split > out a > > void > gimple_init (gimple *, enum gimple_code code, unsigned nops); > > from gimple_alloc (changing that to GC allocate not cleared > memory) doing all of the actual initialization. Then the > allocation would go like > > gimple *stmt1 = (gimple *)XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, > 3)); > gimple_init (stmt1, GIMPLE_ASSIGN, 3); > > with an overload for gimple_size to account for # of ops. > > + /* Allocate SSA names(lhs1) on the stack. */ > + tree lhs1 = XALLOCA (tree_node); > > you can use (tree) XALLOCA (tree_ssa_name) here > > + /* Call the interface function of match.pd to simplify the expression. > */ > + tree t = gimple_simplify (code, boolean_type_node, gimple_assign_lhs > (stmt1), > + gimple_assign_lhs (stmt2), NULL, > + follow_all_ssa_edges); > + > + if (t) > > As I told Martin offline the appropriate function to use is > > You'd do > > gimple_match_op op (gimple_match_cond::UNCOND, code, > boolean_type_node, gimple_assign_lhs (stmt1), > gimple_assign_lhs (stmt2)); > if (op->resimplify (NULL, follow_all_ssa_edges)) >{ > if (gimple_simplified_result_is_gimple_val (res_op)) > .. got a constant or SSA name .. > else if (res_op->code.is_tree_code () > && TREE_CODE_CLASS ((tree_code)res_op->code)) == > tcc_comparison) > ... got a comparison res_op->op[0] res_op->code res_op->op[1] ... > > so you get the outermost expression back decomposed. > > Otherwise with you passing NULL as the gimple_seq you'll miss quite > some simplification cases. > > You also have to watch out for the result containing the LHS of one > of your temporary stmts. > > + if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code1, > op1a, > +op1b, code2, op2a, > op2b)) > +return t; > + > + if (tree t = maybe_fold_comparisons_from_match_pd (BIT_AND_EXPR, code2, > op2a, > +op2b, code1, op1a, > op1b)) > +return t; > > with match.pd rules you shouldn't need to call this twice, once with > swapped operands. > > Otherwise this first patch looks like what I'd have done and we > can build upon it. > > Not sure if you or Martin wants to improve it according to my > comments. > > Thanks, > Richard. > I'm sending patch that addresses the feedback from Richard. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin >From 6f8feb5ccf46bae2c65b88a90661e23521ce9143 Mon Sep 17 00:00:00 2001 From: Li Jia He Date: Mon, 15 Jul 2019 00:30:25 -0500 Subject: [PATCH 1/2] Auto-generate maybe_fold_and/or_comparisons from match.pd gcc/ChangeLog 2019-07-16 Li Jia He Martin Liska * gimple.h (gimple_init): Declare. (gimple_size): Likewise. * gimple.c (gimple_init): Remove static and inline restrictions. (gimple_alloc): Only allocate memory and call gimple_init. (gimple_size): Likewise. * gimple-fold.c (maybe_fold_comparisons_from_match_pd): New function. (maybe_fold_and_comparisons): Modify and_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. (maybe_fold_or_comparisons): Modify or_comparisons_1 invocation and call maybe_fold_comparisons_from_match_pd. * tree-ssanames.c (init_ssa_name_imm_use): Use make_ssa_name_fn. (make_ssa_name_fn): New. * tree-ssanames.h (init_ssa_name_imm_use): New. --- gcc/gimple-fold.c | 108 gcc/gimple.c| 37 +-- gcc/gimple.h| 2 + gcc/tree-ssanames.c | 21 ++--- gcc/