summaryrefslogtreecommitdiff
path: root/0328-Bugfix-if-split-Added-checking-for-ssa_name.patch
blob: 840d32e95b00eba1757fc33f51d39b4f39a3fb5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
From e2896c73513cfb2dfd7c4796effef6ba06396f35 Mon Sep 17 00:00:00 2001
From: Zinin Ivan WX1305386 <zinin.ivan@huawei-partners.com>
Date: Fri, 13 Dec 2024 10:52:08 +0300
Subject: [PATCH] [Bugfix][if-split] Added checking for ssa_name

Added checking if part of OR complex condition is really an ssa
name in necessary_complex_cond_p(). Besides, made var_n_cst
structure, which replaced var_cst and cond_parts_defs structures.
---
 gcc/gimple-if-split.cc | 123 +++++++++++++++++++----------------------
 1 file changed, 56 insertions(+), 67 deletions(-)

diff --git a/gcc/gimple-if-split.cc b/gcc/gimple-if-split.cc
index 351515435..914b65d47 100644
--- a/gcc/gimple-if-split.cc
+++ b/gcc/gimple-if-split.cc
@@ -61,14 +61,14 @@ Example:
 //-------------------------------------------------------------------------
 /* Check if arg list of call got n.  */
 bool
-got_in_args_p (gimple* call, tree n)
+got_in_args_p (gimple *call, tree n)
 {
   unsigned num_args = gimple_call_num_args (call);
 
   for (int i = 0; i < num_args; i++)
     {
       if (n == gimple_call_arg (call, i))
-  return true;
+	return true;
     }
 
   return false;
@@ -142,19 +142,24 @@ bb_got_necessary_call_p (basic_block bb, tree n, unsigned nesting)
 //-------------------------------------------------------------------------
 // Complex conditions
 //-------------------------------------------------------------------------
-/* Auxiliary struct which contains var and its constant of comaprison
- * of expr: n == cst.  */
-struct var_const
+/* Auxiliary struct which contains tree nodes of such statements:
+ * var = (n == cst). Actually in some cases var field can be not an ssa
+ * name and/or it's rhs can be not "comparison with constant"
+ * expression.  However, we need to fill var field of such structures
+ * in necessary_complex_cond_p () to build/change conditions in
+ * process_complex_cond ().  */
+struct var_n_const
 {
+  tree var = NULL_TREE;
   tree n = NULL_TREE;
   tree cst = NULL_TREE;
 };
 
 /* Check if var_def stmt got this pattern:
  *    var = (n == const);
- * If it does, we need to set var_cst struct.  */
+ * If it does, we need to set n and cst in var_n_cst struct.  */
 static bool
-comp_with_const_p (gimple *var_def, var_const *var_cst)
+comp_with_const_p (gimple *var_def, var_n_const *var_n_cst)
 {
   if (gimple_expr_code (var_def) != EQ_EXPR)
     return false;
@@ -164,33 +169,24 @@ comp_with_const_p (gimple *var_def, var_const *var_cst)
   if (TREE_CODE (var_def_rhs2) != INTEGER_CST)
     return false;
 
-  var_cst->n = gimple_assign_rhs1 (var_def);
-  var_cst->cst = var_def_rhs2;
+  var_n_cst->n = gimple_assign_rhs1 (var_def);
+  var_n_cst->cst = var_def_rhs2;
 
   return true;
 }
 
-/* Auxiliary struct which contains defenition of each part of
- * complex condition, like:
- *    a = ... <- a_def
- *    b = ... <- b_def
- *    c = a | b  <- complex_cond.  */
-struct cond_parts_defs
-{
-  gimple *a_def = NULL;
-  gimple *b_def = NULL;
-};
-
 /* Check if cond got this pattern:
  *    a = ...; <- a_def
  *    b = ...; <- b_def
- *    c = a | b;
+ *    c = a | b; <- c_def
  *    if (c != 0)
- * and a_def or b_def is comparison with constant.  If it does,
- * we need to set a with a_def and b with b_def.  */
+ * and a_def or b_def is comparison with constant.
+ * If it does, we need to set a_var_n_cst and b_var_n_cst.
+ * Also set a_var_n_cst->var as gimple_assign_rhs1 (c_def),
+ * b_var_n_cst->var as gimple_assign_rhs2 (c_def).  */
 static bool
 necessary_complex_cond_p (const gimple *cond, basic_block then_bb,
-			  cond_parts_defs *defs)
+			  var_n_const *a_var_n_cst, var_n_const *b_var_n_cst)
 {
   tree lhs = gimple_cond_lhs (cond);
   tree rhs = gimple_cond_rhs (cond);
@@ -207,27 +203,25 @@ necessary_complex_cond_p (const gimple *cond, basic_block then_bb,
       || gimple_expr_code (c_def) != BIT_IOR_EXPR)
     return false;
 
-  tree a_var = gimple_assign_rhs1 (c_def);
-  tree b_var = gimple_assign_rhs2 (c_def);
-  gimple *a_def = SSA_NAME_DEF_STMT (a_var);
-  gimple *b_def = SSA_NAME_DEF_STMT (b_var);
-
-  if (!a_def || !is_gimple_assign (a_def) || !b_def
-      || !is_gimple_assign (b_def))
-    return false;
-
-  var_const var_cst;
-
-  if (!(comp_with_const_p (a_def, &var_cst)
-	&& bb_got_necessary_call_p (then_bb, var_cst.n, SCALAR_NESTING))
-      && !(comp_with_const_p (b_def, &var_cst)
-	   && bb_got_necessary_call_p (then_bb, var_cst.n, SCALAR_NESTING)))
-    return false;
-
-  defs->a_def = a_def;
-  defs->b_def = b_def;
-
-  return true;
+  bool result = false;
+
+  gimple *a_def;
+  a_var_n_cst->var = gimple_assign_rhs1 (c_def);
+  if (TREE_CODE (a_var_n_cst->var) == SSA_NAME
+      && (a_def = SSA_NAME_DEF_STMT (a_var_n_cst->var))
+      && is_gimple_assign (a_def) && comp_with_const_p (a_def, a_var_n_cst)
+      && bb_got_necessary_call_p (then_bb, a_var_n_cst->n, SCALAR_NESTING))
+    result = true;
+
+  gimple *b_def;
+  b_var_n_cst->var = gimple_assign_rhs2 (c_def);
+  if (TREE_CODE (b_var_n_cst->var) == SSA_NAME
+      && (b_def = SSA_NAME_DEF_STMT (b_var_n_cst->var))
+      && is_gimple_assign (b_def) && comp_with_const_p (b_def, b_var_n_cst)
+      && bb_got_necessary_call_p (then_bb, b_var_n_cst->n, SCALAR_NESTING))
+    result = true;
+
+  return result;
 }
 
 /* Check if our complex condition seems to be "necessary"
@@ -253,11 +247,10 @@ process_complex_cond (basic_block cond_bb, basic_block then_bb,
 		      basic_block else_bb)
 {
   gimple *cond = last_stmt (cond_bb);
-  cond_parts_defs defs;
+  var_n_const a_var_n_cst, b_var_n_cst;
 
-  if (!can_duplicate_block_p (then_bb)
-      || !single_succ_p (then_bb)
-      || !necessary_complex_cond_p (cond, then_bb, &defs))
+  if (!can_duplicate_block_p (then_bb) || !single_succ_p (then_bb)
+      || !necessary_complex_cond_p (cond, then_bb, &a_var_n_cst, &b_var_n_cst))
     return;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -267,19 +260,16 @@ process_complex_cond (basic_block cond_bb, basic_block then_bb,
       print_gimple_stmt (dump_file, cond, 0, TDF_NONE);
     }
 
-  var_const var_cst;
-
   /* Setting cond.  */
-  if (comp_with_const_p (defs.a_def, &var_cst))
-      /* Setting cond as: if (n == const).  */
-      gimple_cond_set_condition (as_a<gcond *> (cond), EQ_EXPR, var_cst.n,
-					var_cst.cst);
+  if (a_var_n_cst.n != NULL_TREE && a_var_n_cst.cst != NULL_TREE)
+    /* Setting cond as: if (n == const).  */
+    gimple_cond_set_condition (as_a<gcond *> (cond), EQ_EXPR, a_var_n_cst.n,
+			       a_var_n_cst.cst);
   else
     {
       /* Setting cond as: if (a != 0).  */
-      tree cond_lhs = gimple_assign_lhs (defs.a_def);
-      gimple_cond_set_condition (as_a<gcond *> (cond), NE_EXPR, cond_lhs,
-      					build_zero_cst (TREE_TYPE (cond_lhs)));
+      gimple_cond_set_condition (as_a<gcond *> (cond), NE_EXPR, a_var_n_cst.var,
+				 build_zero_cst (TREE_TYPE (a_var_n_cst.var)));
     }
   update_stmt (cond);
 
@@ -290,19 +280,18 @@ process_complex_cond (basic_block cond_bb, basic_block then_bb,
 
   /* Setting inner_cond.  */
   gcond *inner_cond = NULL;
-  if (comp_with_const_p (defs.b_def, &var_cst))
+  if (b_var_n_cst.n != NULL_TREE && b_var_n_cst.cst != NULL_TREE)
     {
-      /* Setting inner cond as: if (b == const).  */
-      inner_cond = gimple_build_cond (EQ_EXPR, var_cst.n, var_cst.cst,
+      /* Setting inner cond as: if (n == const).  */
+      inner_cond = gimple_build_cond (EQ_EXPR, b_var_n_cst.n, b_var_n_cst.cst,
 				      NULL_TREE, NULL_TREE);
     }
   else
     {
       /* Setting inner cond as: if (b != 0).  */
-      tree inner_cond_lhs = gimple_assign_lhs (defs.b_def);
       inner_cond = gimple_build_cond (
-	  NE_EXPR, inner_cond_lhs, build_zero_cst (TREE_TYPE (inner_cond_lhs)),
-	  NULL_TREE, NULL_TREE);
+	  NE_EXPR, b_var_n_cst.var,
+	  build_zero_cst (TREE_TYPE (b_var_n_cst.var)), NULL_TREE, NULL_TREE);
     }
   gimple_stmt_iterator gsi = gsi_last_bb (inner_cond_bb);
   gsi_insert_after (&gsi, inner_cond, GSI_NEW_STMT);
@@ -362,7 +351,7 @@ make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb,
   if (single_succ (then_bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
     {
       gcc_assert (gimple_code (last_stmt (then_bb)) == GIMPLE_RETURN);
-      ret_val = gimple_return_retval (as_a<greturn*>(last_stmt (then_bb)));
+      ret_val = gimple_return_retval (as_a<greturn *> (last_stmt (then_bb)));
 
       then_bb_succ_edge_flags = single_succ_edge (then_bb)->flags;
     }
@@ -373,7 +362,7 @@ make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb,
    * if now merge_bb is pred of EXIT_BLOCK.  */
   if (single_succ (merge_bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
     {
-      gimple* ret = gimple_build_return (ret_val);
+      gimple *ret = gimple_build_return (ret_val);
       gimple_stmt_iterator gsi = gsi_last_bb (merge_bb);
       gsi_insert_after (&gsi, ret, GSI_NEW_STMT);
 
@@ -400,7 +389,7 @@ make_two_separate_calls (basic_block outer_cond_bb, basic_block inner_cond_bb,
 			   single_succ (merge_bb));
 
   if (get_immediate_dominator (CDI_POST_DOMINATORS, outer_cond_bb) == then_bb)
-     set_immediate_dominator (CDI_POST_DOMINATORS, outer_cond_bb, merge_bb);
+    set_immediate_dominator (CDI_POST_DOMINATORS, outer_cond_bb, merge_bb);
 
   return then_bb1;
 }
-- 
2.33.0