annotate gcc/gimple-match-head.c @ 143:76e1cf5455ef

add cbc_gc test
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 19:24:05 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Preamble and helpers for the autogenerated gimple-match.c file.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
9 version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
14 for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 #include "config.h"
kono
parents:
diff changeset
21 #include "system.h"
kono
parents:
diff changeset
22 #include "coretypes.h"
kono
parents:
diff changeset
23 #include "backend.h"
kono
parents:
diff changeset
24 #include "target.h"
kono
parents:
diff changeset
25 #include "rtl.h"
kono
parents:
diff changeset
26 #include "tree.h"
kono
parents:
diff changeset
27 #include "gimple.h"
kono
parents:
diff changeset
28 #include "ssa.h"
kono
parents:
diff changeset
29 #include "cgraph.h"
kono
parents:
diff changeset
30 #include "fold-const.h"
kono
parents:
diff changeset
31 #include "fold-const-call.h"
kono
parents:
diff changeset
32 #include "stor-layout.h"
kono
parents:
diff changeset
33 #include "gimple-fold.h"
kono
parents:
diff changeset
34 #include "calls.h"
kono
parents:
diff changeset
35 #include "tree-dfa.h"
kono
parents:
diff changeset
36 #include "builtins.h"
kono
parents:
diff changeset
37 #include "gimple-match.h"
kono
parents:
diff changeset
38 #include "tree-pass.h"
kono
parents:
diff changeset
39 #include "internal-fn.h"
kono
parents:
diff changeset
40 #include "case-cfn-macros.h"
kono
parents:
diff changeset
41 #include "gimplify.h"
kono
parents:
diff changeset
42 #include "optabs-tree.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
43 #include "tree-eh.h"
111
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 /* Forward declarations of the private auto-generated matchers.
kono
parents:
diff changeset
47 They expect valueized operands in canonical order and do not
kono
parents:
diff changeset
48 perform simplification of all-constant operands. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
49 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
111
kono
parents:
diff changeset
50 code_helper, tree, tree);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
51 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
111
kono
parents:
diff changeset
52 code_helper, tree, tree, tree);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
53 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
111
kono
parents:
diff changeset
54 code_helper, tree, tree, tree, tree);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
55 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
56 code_helper, tree, tree, tree, tree, tree);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
57 static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
58 code_helper, tree, tree, tree, tree, tree, tree);
111
kono
parents:
diff changeset
59
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
60 const unsigned int gimple_match_op::MAX_NUM_OPS;
111
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 /* Return whether T is a constant that we'll dispatch to fold to
kono
parents:
diff changeset
63 evaluate fully constant expressions. */
kono
parents:
diff changeset
64
kono
parents:
diff changeset
65 static inline bool
kono
parents:
diff changeset
66 constant_for_folding (tree t)
kono
parents:
diff changeset
67 {
kono
parents:
diff changeset
68 return (CONSTANT_CLASS_P (t)
kono
parents:
diff changeset
69 /* The following is only interesting to string builtins. */
kono
parents:
diff changeset
70 || (TREE_CODE (t) == ADDR_EXPR
kono
parents:
diff changeset
71 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
kono
parents:
diff changeset
72 }
kono
parents:
diff changeset
73
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
74 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
75 operation. Return true on success, storing the new operation in NEW_OP. */
111
kono
parents:
diff changeset
76
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
77 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
78 convert_conditional_op (gimple_match_op *orig_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
79 gimple_match_op *new_op)
111
kono
parents:
diff changeset
80 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
81 internal_fn ifn;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
82 if (orig_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
83 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
84 else
111
kono
parents:
diff changeset
85 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
86 combined_fn cfn = orig_op->code;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
87 if (!internal_fn_p (cfn))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
88 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
89 ifn = get_conditional_internal_fn (as_internal_fn (cfn));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
90 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
91 if (ifn == IFN_LAST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
92 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
93 unsigned int num_ops = orig_op->num_ops;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
94 new_op->set_op (as_combined_fn (ifn), orig_op->type, num_ops + 2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
95 new_op->ops[0] = orig_op->cond.cond;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 for (unsigned int i = 0; i < num_ops; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
97 new_op->ops[i + 1] = orig_op->ops[i];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
98 tree else_value = orig_op->cond.else_value;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
99 if (!else_value)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
100 else_value = targetm.preferred_else_value (ifn, orig_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
101 num_ops, orig_op->ops);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
102 new_op->ops[num_ops + 1] = else_value;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
103 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
104 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
105
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
106 /* RES_OP is the result of a simplification. If it is conditional,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
107 try to replace it with the equivalent UNCOND form, such as an
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
108 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
109 result of the replacement if appropriate, adding any new statements to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
110 SEQ and using VALUEIZE as the valueization function. Return true if
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
111 this resimplification occurred and resulted in at least one change. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
112
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
113 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
114 maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
115 tree (*valueize) (tree))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
116 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 if (!res_op->cond.cond)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
118 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 if (!res_op->cond.else_value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
121 && res_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
122 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 /* The "else" value doesn't matter. If the "then" value is a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
124 gimple value, just use it unconditionally. This isn't a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
125 simplification in itself, since there was no operation to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 build in the first place. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127 if (gimple_simplified_result_is_gimple_val (res_op))
111
kono
parents:
diff changeset
128 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
129 res_op->cond.cond = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
130 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
131 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
133 /* Likewise if the operation would not trap. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
134 bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 && TYPE_OVERFLOW_TRAPS (res_op->type));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 if (!operation_could_trap_p ((tree_code) res_op->code,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 FLOAT_TYPE_P (res_op->type),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
138 honor_trapv, res_op->op_or_null (1)))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
139 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
140 res_op->cond.cond = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
141 return false;
111
kono
parents:
diff changeset
142 }
kono
parents:
diff changeset
143 }
kono
parents:
diff changeset
144
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
145 /* If the "then" value is a gimple value and the "else" value matters,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 create a VEC_COND_EXPR between them, then see if it can be further
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 simplified. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 gimple_match_op new_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 if (res_op->cond.else_value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 && VECTOR_TYPE_P (res_op->type)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
151 && gimple_simplified_result_is_gimple_val (res_op))
111
kono
parents:
diff changeset
152 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
153 new_op.set_op (VEC_COND_EXPR, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
154 res_op->cond.cond, res_op->ops[0],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
155 res_op->cond.else_value);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156 *res_op = new_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 return gimple_resimplify3 (seq, res_op, valueize);
111
kono
parents:
diff changeset
158 }
kono
parents:
diff changeset
159
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 /* Otherwise try rewriting the operation as an IFN_COND_* call.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 Again, this isn't a simplification in itself, since it's what
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 RES_OP already described. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 if (convert_conditional_op (res_op, &new_op))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 *res_op = new_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165
111
kono
parents:
diff changeset
166 return false;
kono
parents:
diff changeset
167 }
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 /* Helper that matches and simplifies the toplevel result from
kono
parents:
diff changeset
170 a gimple_simplify run (where we don't want to build
kono
parents:
diff changeset
171 a stmt in case it's used in in-place folding). Replaces
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 RES_OP with a simplified and/or canonicalized result and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 returns whether any change was made. */
111
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
111
kono
parents:
diff changeset
177 tree (*valueize)(tree))
kono
parents:
diff changeset
178 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 if (constant_for_folding (res_op->ops[0]))
111
kono
parents:
diff changeset
180 {
kono
parents:
diff changeset
181 tree tem = NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 if (res_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183 tem = const_unop (res_op->code, res_op->type, res_op->ops[0]);
111
kono
parents:
diff changeset
184 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 res_op->ops[0]);
111
kono
parents:
diff changeset
187 if (tem != NULL_TREE
kono
parents:
diff changeset
188 && CONSTANT_CLASS_P (tem))
kono
parents:
diff changeset
189 {
kono
parents:
diff changeset
190 if (TREE_OVERFLOW_P (tem))
kono
parents:
diff changeset
191 tem = drop_tree_overflow (tem);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
192 res_op->set_value (tem);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
193 maybe_resimplify_conditional_op (seq, res_op, valueize);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
194 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
196 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
197
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 /* Limit recursion, there are cases like PR80887 and others, for
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199 example when value-numbering presents us with unfolded expressions
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 that we are really not prepared to handle without eventual
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
201 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
202 itself as available expression. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
203 static unsigned depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
204 if (depth > 10)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
205 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
206 if (dump_file && (dump_flags & TDF_FOLDING))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
207 fprintf (dump_file, "Aborting expression simplification due to "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
208 "deep recursion\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
209 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
210 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
211
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
212 ++depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
213 gimple_match_op res_op2 (*res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
214 if (gimple_simplify (&res_op2, seq, valueize,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
215 res_op->code, res_op->type, res_op->ops[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
216 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
217 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
218 *res_op = res_op2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
219 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
220 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
221 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
222
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
223 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
224 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
225
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
226 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
227 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 /* Helper that matches and simplifies the toplevel result from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
230 a gimple_simplify run (where we don't want to build
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
231 a stmt in case it's used in in-place folding). Replaces
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
232 RES_OP with a simplified and/or canonicalized result and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
233 returns whether any change was made. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
234
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
235 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
236 gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
237 tree (*valueize)(tree))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
238 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
239 if (constant_for_folding (res_op->ops[0])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240 && constant_for_folding (res_op->ops[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
241 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
242 tree tem = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
243 if (res_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
244 tem = const_binop (res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
245 res_op->ops[0], res_op->ops[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
246 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
247 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
248 res_op->ops[0], res_op->ops[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
249 if (tem != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
250 && CONSTANT_CLASS_P (tem))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
251 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
252 if (TREE_OVERFLOW_P (tem))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
253 tem = drop_tree_overflow (tem);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
254 res_op->set_value (tem);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
255 maybe_resimplify_conditional_op (seq, res_op, valueize);
111
kono
parents:
diff changeset
256 return true;
kono
parents:
diff changeset
257 }
kono
parents:
diff changeset
258 }
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 /* Canonicalize operand order. */
kono
parents:
diff changeset
261 bool canonicalized = false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
262 if (res_op->code.is_tree_code ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
263 && (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
264 || commutative_tree_code (res_op->code))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
265 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
111
kono
parents:
diff changeset
266 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
267 std::swap (res_op->ops[0], res_op->ops[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
268 if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
269 res_op->code = swap_tree_comparison (res_op->code);
111
kono
parents:
diff changeset
270 canonicalized = true;
kono
parents:
diff changeset
271 }
kono
parents:
diff changeset
272
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 /* Limit recursion, see gimple_resimplify1. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 static unsigned depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 if (depth > 10)
111
kono
parents:
diff changeset
276 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
277 if (dump_file && (dump_flags & TDF_FOLDING))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 fprintf (dump_file, "Aborting expression simplification due to "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 "deep recursion\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
282
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 ++depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 gimple_match_op res_op2 (*res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 if (gimple_simplify (&res_op2, seq, valueize,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 res_op->ops[0], res_op->ops[1]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
289 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
290 *res_op = res_op2;
111
kono
parents:
diff changeset
291 return true;
kono
parents:
diff changeset
292 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
293 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
294
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
295 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
296 return true;
111
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 return canonicalized;
kono
parents:
diff changeset
299 }
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 /* Helper that matches and simplifies the toplevel result from
kono
parents:
diff changeset
302 a gimple_simplify run (where we don't want to build
kono
parents:
diff changeset
303 a stmt in case it's used in in-place folding). Replaces
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
304 RES_OP with a simplified and/or canonicalized result and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
305 returns whether any change was made. */
111
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
308 gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
111
kono
parents:
diff changeset
309 tree (*valueize)(tree))
kono
parents:
diff changeset
310 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
311 if (constant_for_folding (res_op->ops[0])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
312 && constant_for_folding (res_op->ops[1])
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
313 && constant_for_folding (res_op->ops[2]))
111
kono
parents:
diff changeset
314 {
kono
parents:
diff changeset
315 tree tem = NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
316 if (res_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
317 tem = fold_ternary/*_to_constant*/ (res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
318 res_op->ops[0], res_op->ops[1],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
319 res_op->ops[2]);
111
kono
parents:
diff changeset
320 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
321 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
322 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
111
kono
parents:
diff changeset
323 if (tem != NULL_TREE
kono
parents:
diff changeset
324 && CONSTANT_CLASS_P (tem))
kono
parents:
diff changeset
325 {
kono
parents:
diff changeset
326 if (TREE_OVERFLOW_P (tem))
kono
parents:
diff changeset
327 tem = drop_tree_overflow (tem);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
328 res_op->set_value (tem);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
329 maybe_resimplify_conditional_op (seq, res_op, valueize);
111
kono
parents:
diff changeset
330 return true;
kono
parents:
diff changeset
331 }
kono
parents:
diff changeset
332 }
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 /* Canonicalize operand order. */
kono
parents:
diff changeset
335 bool canonicalized = false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
336 if (res_op->code.is_tree_code ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
337 && commutative_ternary_tree_code (res_op->code)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
338 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
111
kono
parents:
diff changeset
339 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
340 std::swap (res_op->ops[0], res_op->ops[1]);
111
kono
parents:
diff changeset
341 canonicalized = true;
kono
parents:
diff changeset
342 }
kono
parents:
diff changeset
343
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
344 /* Limit recursion, see gimple_resimplify1. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
345 static unsigned depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
346 if (depth > 10)
111
kono
parents:
diff changeset
347 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
348 if (dump_file && (dump_flags & TDF_FOLDING))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
349 fprintf (dump_file, "Aborting expression simplification due to "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
350 "deep recursion\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
351 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
352 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
353
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
354 ++depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
355 gimple_match_op res_op2 (*res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
356 if (gimple_simplify (&res_op2, seq, valueize,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
357 res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
358 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
359 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
360 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
361 *res_op = res_op2;
111
kono
parents:
diff changeset
362 return true;
kono
parents:
diff changeset
363 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
364 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
366 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
367 return true;
111
kono
parents:
diff changeset
368
kono
parents:
diff changeset
369 return canonicalized;
kono
parents:
diff changeset
370 }
kono
parents:
diff changeset
371
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
372 /* Helper that matches and simplifies the toplevel result from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
373 a gimple_simplify run (where we don't want to build
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
374 a stmt in case it's used in in-place folding). Replaces
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
375 RES_OP with a simplified and/or canonicalized result and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
376 returns whether any change was made. */
111
kono
parents:
diff changeset
377
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
378 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
379 gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
380 tree (*valueize)(tree))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
381 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
382 /* No constant folding is defined for four-operand functions. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 /* Limit recursion, see gimple_resimplify1. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 static unsigned depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 if (depth > 10)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 if (dump_file && (dump_flags & TDF_FOLDING))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389 fprintf (dump_file, "Aborting expression simplification due to "
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 "deep recursion\n");
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
391 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
392 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
393
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
394 ++depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
395 gimple_match_op res_op2 (*res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
396 if (gimple_simplify (&res_op2, seq, valueize,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
397 res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398 res_op->ops[0], res_op->ops[1], res_op->ops[2],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 res_op->ops[3]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
400 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
402 *res_op = res_op2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
403 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
404 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
405 --depth;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
406
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
407 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
408 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
410 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
413 /* Helper that matches and simplifies the toplevel result from
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
414 a gimple_simplify run (where we don't want to build
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
415 a stmt in case it's used in in-place folding). Replaces
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
416 RES_OP with a simplified and/or canonicalized result and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
417 returns whether any change was made. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
418
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
419 bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
420 gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 tree (*valueize)(tree))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 /* No constant folding is defined for five-operand functions. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
424
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
425 gimple_match_op res_op2 (*res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
426 if (gimple_simplify (&res_op2, seq, valueize,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
427 res_op->code, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
428 res_op->ops[0], res_op->ops[1], res_op->ops[2],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
429 res_op->ops[3], res_op->ops[4]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
430 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
431 *res_op = res_op2;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
434
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
437
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
438 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
439 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
442 build a GENERIC tree for that expression and update RES_OP accordingly. */
111
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 void
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 maybe_build_generic_op (gimple_match_op *res_op)
111
kono
parents:
diff changeset
446 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
447 tree_code code = (tree_code) res_op->code;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
448 tree val;
111
kono
parents:
diff changeset
449 switch (code)
kono
parents:
diff changeset
450 {
kono
parents:
diff changeset
451 case REALPART_EXPR:
kono
parents:
diff changeset
452 case IMAGPART_EXPR:
kono
parents:
diff changeset
453 case VIEW_CONVERT_EXPR:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
454 val = build1 (code, res_op->type, res_op->ops[0]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
455 res_op->set_value (val);
111
kono
parents:
diff changeset
456 break;
kono
parents:
diff changeset
457 case BIT_FIELD_REF:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 val = build3 (code, res_op->type, res_op->ops[0], res_op->ops[1],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
459 res_op->ops[2]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460 REF_REVERSE_STORAGE_ORDER (val) = res_op->reverse;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461 res_op->set_value (val);
111
kono
parents:
diff changeset
462 break;
kono
parents:
diff changeset
463 default:;
kono
parents:
diff changeset
464 }
kono
parents:
diff changeset
465 }
kono
parents:
diff changeset
466
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
467 tree (*mprts_hook) (gimple_match_op *);
111
kono
parents:
diff changeset
468
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
469 /* Try to build RES_OP, which is known to be a call to FN. Return null
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 if the target doesn't support the function. */
111
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 static gcall *
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473 build_call_internal (internal_fn fn, gimple_match_op *res_op)
111
kono
parents:
diff changeset
474 {
kono
parents:
diff changeset
475 if (direct_internal_fn_p (fn))
kono
parents:
diff changeset
476 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
477 tree_pair types = direct_internal_fn_types (fn, res_op->type,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
478 res_op->ops);
111
kono
parents:
diff changeset
479 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
kono
parents:
diff changeset
480 return NULL;
kono
parents:
diff changeset
481 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
482 return gimple_build_call_internal (fn, res_op->num_ops,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
483 res_op->op_or_null (0),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
484 res_op->op_or_null (1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
485 res_op->op_or_null (2),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
486 res_op->op_or_null (3),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
487 res_op->op_or_null (4));
111
kono
parents:
diff changeset
488 }
kono
parents:
diff changeset
489
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
490 /* Push the exploded expression described by RES_OP as a statement to
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
491 SEQ if necessary and return a gimple value denoting the value of the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
492 expression. If RES is not NULL then the result will be always RES
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
493 and even gimple values are pushed to SEQ. */
111
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
496 maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
111
kono
parents:
diff changeset
497 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
498 tree *ops = res_op->ops;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
499 unsigned num_ops = res_op->num_ops;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
500
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
501 /* The caller should have converted conditional operations into an UNCOND
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
502 form and resimplified as appropriate. The conditional form only
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
503 survives this far if that conversion failed. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
504 if (res_op->cond.cond)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
505 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
506
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
507 if (res_op->code.is_tree_code ())
111
kono
parents:
diff changeset
508 {
kono
parents:
diff changeset
509 if (!res
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
510 && gimple_simplified_result_is_gimple_val (res_op))
111
kono
parents:
diff changeset
511 return ops[0];
kono
parents:
diff changeset
512 if (mprts_hook)
kono
parents:
diff changeset
513 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
514 tree tem = mprts_hook (res_op);
111
kono
parents:
diff changeset
515 if (tem)
kono
parents:
diff changeset
516 return tem;
kono
parents:
diff changeset
517 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
518 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
519
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
520 if (!seq)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
521 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
522
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
523 /* Play safe and do not allow abnormals to be mentioned in
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
524 newly created statements. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
525 for (unsigned int i = 0; i < num_ops; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
526 if (TREE_CODE (ops[i]) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
527 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
528 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
529
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
530 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
531 for (unsigned int i = 0; i < 2; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
532 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
533 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
111
kono
parents:
diff changeset
534 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
535
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
536 if (res_op->code.is_tree_code ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
537 {
111
kono
parents:
diff changeset
538 if (!res)
kono
parents:
diff changeset
539 {
kono
parents:
diff changeset
540 if (gimple_in_ssa_p (cfun))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
541 res = make_ssa_name (res_op->type);
111
kono
parents:
diff changeset
542 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
543 res = create_tmp_reg (res_op->type);
111
kono
parents:
diff changeset
544 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
545 maybe_build_generic_op (res_op);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
546 gimple *new_stmt = gimple_build_assign (res, res_op->code,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
547 res_op->op_or_null (0),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
548 res_op->op_or_null (1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
549 res_op->op_or_null (2));
111
kono
parents:
diff changeset
550 gimple_seq_add_stmt_without_update (seq, new_stmt);
kono
parents:
diff changeset
551 return res;
kono
parents:
diff changeset
552 }
kono
parents:
diff changeset
553 else
kono
parents:
diff changeset
554 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
555 gcc_assert (num_ops != 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
556 combined_fn fn = res_op->code;
111
kono
parents:
diff changeset
557 gcall *new_stmt = NULL;
kono
parents:
diff changeset
558 if (internal_fn_p (fn))
kono
parents:
diff changeset
559 {
kono
parents:
diff changeset
560 /* Generate the given function if we can. */
kono
parents:
diff changeset
561 internal_fn ifn = as_internal_fn (fn);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
562 new_stmt = build_call_internal (ifn, res_op);
111
kono
parents:
diff changeset
563 if (!new_stmt)
kono
parents:
diff changeset
564 return NULL_TREE;
kono
parents:
diff changeset
565 }
kono
parents:
diff changeset
566 else
kono
parents:
diff changeset
567 {
kono
parents:
diff changeset
568 /* Find the function we want to call. */
kono
parents:
diff changeset
569 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
kono
parents:
diff changeset
570 if (!decl)
kono
parents:
diff changeset
571 return NULL;
kono
parents:
diff changeset
572
kono
parents:
diff changeset
573 /* We can't and should not emit calls to non-const functions. */
kono
parents:
diff changeset
574 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
kono
parents:
diff changeset
575 return NULL;
kono
parents:
diff changeset
576
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
577 new_stmt = gimple_build_call (decl, num_ops,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
578 res_op->op_or_null (0),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
579 res_op->op_or_null (1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
580 res_op->op_or_null (2),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
581 res_op->op_or_null (3),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
582 res_op->op_or_null (4));
111
kono
parents:
diff changeset
583 }
kono
parents:
diff changeset
584 if (!res)
kono
parents:
diff changeset
585 {
kono
parents:
diff changeset
586 if (gimple_in_ssa_p (cfun))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
587 res = make_ssa_name (res_op->type);
111
kono
parents:
diff changeset
588 else
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
589 res = create_tmp_reg (res_op->type);
111
kono
parents:
diff changeset
590 }
kono
parents:
diff changeset
591 gimple_call_set_lhs (new_stmt, res);
kono
parents:
diff changeset
592 gimple_seq_add_stmt_without_update (seq, new_stmt);
kono
parents:
diff changeset
593 return res;
kono
parents:
diff changeset
594 }
kono
parents:
diff changeset
595 }
kono
parents:
diff changeset
596
kono
parents:
diff changeset
597
kono
parents:
diff changeset
598 /* Public API overloads follow for operation being tree_code or
kono
parents:
diff changeset
599 built_in_function and for one to three operands or arguments.
kono
parents:
diff changeset
600 They return NULL_TREE if nothing could be simplified or
kono
parents:
diff changeset
601 the resulting simplified value with parts pushed to SEQ.
kono
parents:
diff changeset
602 If SEQ is NULL then if the simplification needs to create
kono
parents:
diff changeset
603 new stmts it will fail. If VALUEIZE is non-NULL then all
kono
parents:
diff changeset
604 SSA names will be valueized using that hook prior to
kono
parents:
diff changeset
605 applying simplifications. */
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 /* Unary ops. */
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 tree
kono
parents:
diff changeset
610 gimple_simplify (enum tree_code code, tree type,
kono
parents:
diff changeset
611 tree op0,
kono
parents:
diff changeset
612 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
613 {
kono
parents:
diff changeset
614 if (constant_for_folding (op0))
kono
parents:
diff changeset
615 {
kono
parents:
diff changeset
616 tree res = const_unop (code, type, op0);
kono
parents:
diff changeset
617 if (res != NULL_TREE
kono
parents:
diff changeset
618 && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
619 return res;
kono
parents:
diff changeset
620 }
kono
parents:
diff changeset
621
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
622 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
623 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
111
kono
parents:
diff changeset
624 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
625 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
626 }
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 /* Binary ops. */
kono
parents:
diff changeset
629
kono
parents:
diff changeset
630 tree
kono
parents:
diff changeset
631 gimple_simplify (enum tree_code code, tree type,
kono
parents:
diff changeset
632 tree op0, tree op1,
kono
parents:
diff changeset
633 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
634 {
kono
parents:
diff changeset
635 if (constant_for_folding (op0) && constant_for_folding (op1))
kono
parents:
diff changeset
636 {
kono
parents:
diff changeset
637 tree res = const_binop (code, type, op0, op1);
kono
parents:
diff changeset
638 if (res != NULL_TREE
kono
parents:
diff changeset
639 && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
640 return res;
kono
parents:
diff changeset
641 }
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 /* Canonicalize operand order both for matching and fallback stmt
kono
parents:
diff changeset
644 generation. */
kono
parents:
diff changeset
645 if ((commutative_tree_code (code)
kono
parents:
diff changeset
646 || TREE_CODE_CLASS (code) == tcc_comparison)
kono
parents:
diff changeset
647 && tree_swap_operands_p (op0, op1))
kono
parents:
diff changeset
648 {
kono
parents:
diff changeset
649 std::swap (op0, op1);
kono
parents:
diff changeset
650 if (TREE_CODE_CLASS (code) == tcc_comparison)
kono
parents:
diff changeset
651 code = swap_tree_comparison (code);
kono
parents:
diff changeset
652 }
kono
parents:
diff changeset
653
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
654 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
655 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
111
kono
parents:
diff changeset
656 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
657 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
658 }
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 /* Ternary ops. */
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 tree
kono
parents:
diff changeset
663 gimple_simplify (enum tree_code code, tree type,
kono
parents:
diff changeset
664 tree op0, tree op1, tree op2,
kono
parents:
diff changeset
665 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
666 {
kono
parents:
diff changeset
667 if (constant_for_folding (op0) && constant_for_folding (op1)
kono
parents:
diff changeset
668 && constant_for_folding (op2))
kono
parents:
diff changeset
669 {
kono
parents:
diff changeset
670 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
kono
parents:
diff changeset
671 if (res != NULL_TREE
kono
parents:
diff changeset
672 && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
673 return res;
kono
parents:
diff changeset
674 }
kono
parents:
diff changeset
675
kono
parents:
diff changeset
676 /* Canonicalize operand order both for matching and fallback stmt
kono
parents:
diff changeset
677 generation. */
kono
parents:
diff changeset
678 if (commutative_ternary_tree_code (code)
kono
parents:
diff changeset
679 && tree_swap_operands_p (op0, op1))
kono
parents:
diff changeset
680 std::swap (op0, op1);
kono
parents:
diff changeset
681
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
682 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
683 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
111
kono
parents:
diff changeset
684 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
685 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
686 }
kono
parents:
diff changeset
687
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
688 /* Builtin or internal function with one argument. */
111
kono
parents:
diff changeset
689
kono
parents:
diff changeset
690 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
691 gimple_simplify (combined_fn fn, tree type,
111
kono
parents:
diff changeset
692 tree arg0,
kono
parents:
diff changeset
693 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
694 {
kono
parents:
diff changeset
695 if (constant_for_folding (arg0))
kono
parents:
diff changeset
696 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
697 tree res = fold_const_call (fn, type, arg0);
111
kono
parents:
diff changeset
698 if (res && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
699 return res;
kono
parents:
diff changeset
700 }
kono
parents:
diff changeset
701
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
702 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
703 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
111
kono
parents:
diff changeset
704 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
705 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
706 }
kono
parents:
diff changeset
707
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
708 /* Builtin or internal function with two arguments. */
111
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
711 gimple_simplify (combined_fn fn, tree type,
111
kono
parents:
diff changeset
712 tree arg0, tree arg1,
kono
parents:
diff changeset
713 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
714 {
kono
parents:
diff changeset
715 if (constant_for_folding (arg0)
kono
parents:
diff changeset
716 && constant_for_folding (arg1))
kono
parents:
diff changeset
717 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
718 tree res = fold_const_call (fn, type, arg0, arg1);
111
kono
parents:
diff changeset
719 if (res && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
720 return res;
kono
parents:
diff changeset
721 }
kono
parents:
diff changeset
722
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
723 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
724 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
111
kono
parents:
diff changeset
725 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
726 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
727 }
kono
parents:
diff changeset
728
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
729 /* Builtin or internal function with three arguments. */
111
kono
parents:
diff changeset
730
kono
parents:
diff changeset
731 tree
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
732 gimple_simplify (combined_fn fn, tree type,
111
kono
parents:
diff changeset
733 tree arg0, tree arg1, tree arg2,
kono
parents:
diff changeset
734 gimple_seq *seq, tree (*valueize)(tree))
kono
parents:
diff changeset
735 {
kono
parents:
diff changeset
736 if (constant_for_folding (arg0)
kono
parents:
diff changeset
737 && constant_for_folding (arg1)
kono
parents:
diff changeset
738 && constant_for_folding (arg2))
kono
parents:
diff changeset
739 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
740 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
111
kono
parents:
diff changeset
741 if (res && CONSTANT_CLASS_P (res))
kono
parents:
diff changeset
742 return res;
kono
parents:
diff changeset
743 }
kono
parents:
diff changeset
744
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
745 gimple_match_op res_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
746 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
111
kono
parents:
diff changeset
747 return NULL_TREE;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
748 return maybe_push_res_to_seq (&res_op, seq);
111
kono
parents:
diff changeset
749 }
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
kono
parents:
diff changeset
752 VALUEIZED to true if valueization changed OP. */
kono
parents:
diff changeset
753
kono
parents:
diff changeset
754 static inline tree
kono
parents:
diff changeset
755 do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
kono
parents:
diff changeset
756 {
kono
parents:
diff changeset
757 if (valueize && TREE_CODE (op) == SSA_NAME)
kono
parents:
diff changeset
758 {
kono
parents:
diff changeset
759 tree tem = valueize (op);
kono
parents:
diff changeset
760 if (tem && tem != op)
kono
parents:
diff changeset
761 {
kono
parents:
diff changeset
762 op = tem;
kono
parents:
diff changeset
763 valueized = true;
kono
parents:
diff changeset
764 }
kono
parents:
diff changeset
765 }
kono
parents:
diff changeset
766 return op;
kono
parents:
diff changeset
767 }
kono
parents:
diff changeset
768
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
769 /* If RES_OP is a call to a conditional internal function, try simplifying
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
770 the associated unconditional operation and using the result to build
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
771 a new conditional operation. For example, if RES_OP is:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
772
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
773 IFN_COND_ADD (COND, A, B, ELSE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
774
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
775 try simplifying (plus A B) and using the result to build a replacement
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
776 for the whole IFN_COND_ADD.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
777
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
778 Return true if this approach led to a simplification, otherwise leave
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
779 RES_OP unchanged (and so suitable for other simplifications). When
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
780 returning true, add any new statements to SEQ and use VALUEIZE as the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
781 valueization function.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
782
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
783 RES_OP is known to be a call to IFN. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
784
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
785 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
786 try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
787 gimple_seq *seq, tree (*valueize) (tree))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
788 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
789 code_helper op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
790 tree_code code = conditional_internal_fn_code (ifn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
791 if (code != ERROR_MARK)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
792 op = code;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
793 else
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
794 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
795 ifn = get_unconditional_internal_fn (ifn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
796 if (ifn == IFN_LAST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
797 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
798 op = as_combined_fn (ifn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
799 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
800
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 unsigned int num_ops = res_op->num_ops;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
803 res_op->ops[num_ops - 1]),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
804 op, res_op->type, num_ops - 2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
805 for (unsigned int i = 1; i < num_ops - 1; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
806 cond_op.ops[i - 1] = res_op->ops[i];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
807 switch (num_ops - 2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
808 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
809 case 2:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
810 if (!gimple_resimplify2 (seq, &cond_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
811 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
812 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
813 case 3:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
814 if (!gimple_resimplify3 (seq, &cond_op, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
815 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
816 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
817 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
818 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
819 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
820 *res_op = cond_op;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
821 maybe_resimplify_conditional_op (seq, res_op, valueize);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
822 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
823 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
824
111
kono
parents:
diff changeset
825 /* The main STMT based simplification entry. It is used by the fold_stmt
kono
parents:
diff changeset
826 and the fold_stmt_to_constant APIs. */
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829 gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
111
kono
parents:
diff changeset
830 tree (*valueize)(tree), tree (*top_valueize)(tree))
kono
parents:
diff changeset
831 {
kono
parents:
diff changeset
832 switch (gimple_code (stmt))
kono
parents:
diff changeset
833 {
kono
parents:
diff changeset
834 case GIMPLE_ASSIGN:
kono
parents:
diff changeset
835 {
kono
parents:
diff changeset
836 enum tree_code code = gimple_assign_rhs_code (stmt);
kono
parents:
diff changeset
837 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
kono
parents:
diff changeset
838 switch (gimple_assign_rhs_class (stmt))
kono
parents:
diff changeset
839 {
kono
parents:
diff changeset
840 case GIMPLE_SINGLE_RHS:
kono
parents:
diff changeset
841 if (code == REALPART_EXPR
kono
parents:
diff changeset
842 || code == IMAGPART_EXPR
kono
parents:
diff changeset
843 || code == VIEW_CONVERT_EXPR)
kono
parents:
diff changeset
844 {
kono
parents:
diff changeset
845 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
kono
parents:
diff changeset
846 bool valueized = false;
kono
parents:
diff changeset
847 op0 = do_valueize (op0, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
848 res_op->set_op (code, type, op0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
849 return (gimple_resimplify1 (seq, res_op, valueize)
111
kono
parents:
diff changeset
850 || valueized);
kono
parents:
diff changeset
851 }
kono
parents:
diff changeset
852 else if (code == BIT_FIELD_REF)
kono
parents:
diff changeset
853 {
kono
parents:
diff changeset
854 tree rhs1 = gimple_assign_rhs1 (stmt);
kono
parents:
diff changeset
855 tree op0 = TREE_OPERAND (rhs1, 0);
kono
parents:
diff changeset
856 bool valueized = false;
kono
parents:
diff changeset
857 op0 = do_valueize (op0, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
858 res_op->set_op (code, type, op0,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
859 TREE_OPERAND (rhs1, 1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
860 TREE_OPERAND (rhs1, 2),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
861 REF_REVERSE_STORAGE_ORDER (rhs1));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
862 if (res_op->reverse)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
863 return valueized;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
864 return (gimple_resimplify3 (seq, res_op, valueize)
111
kono
parents:
diff changeset
865 || valueized);
kono
parents:
diff changeset
866 }
kono
parents:
diff changeset
867 else if (code == SSA_NAME
kono
parents:
diff changeset
868 && top_valueize)
kono
parents:
diff changeset
869 {
kono
parents:
diff changeset
870 tree op0 = gimple_assign_rhs1 (stmt);
kono
parents:
diff changeset
871 tree valueized = top_valueize (op0);
kono
parents:
diff changeset
872 if (!valueized || op0 == valueized)
kono
parents:
diff changeset
873 return false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
874 res_op->set_op (TREE_CODE (op0), type, valueized);
111
kono
parents:
diff changeset
875 return true;
kono
parents:
diff changeset
876 }
kono
parents:
diff changeset
877 break;
kono
parents:
diff changeset
878 case GIMPLE_UNARY_RHS:
kono
parents:
diff changeset
879 {
kono
parents:
diff changeset
880 tree rhs1 = gimple_assign_rhs1 (stmt);
kono
parents:
diff changeset
881 bool valueized = false;
kono
parents:
diff changeset
882 rhs1 = do_valueize (rhs1, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
883 res_op->set_op (code, type, rhs1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
884 return (gimple_resimplify1 (seq, res_op, valueize)
111
kono
parents:
diff changeset
885 || valueized);
kono
parents:
diff changeset
886 }
kono
parents:
diff changeset
887 case GIMPLE_BINARY_RHS:
kono
parents:
diff changeset
888 {
kono
parents:
diff changeset
889 tree rhs1 = gimple_assign_rhs1 (stmt);
kono
parents:
diff changeset
890 tree rhs2 = gimple_assign_rhs2 (stmt);
kono
parents:
diff changeset
891 bool valueized = false;
kono
parents:
diff changeset
892 rhs1 = do_valueize (rhs1, top_valueize, valueized);
kono
parents:
diff changeset
893 rhs2 = do_valueize (rhs2, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
894 res_op->set_op (code, type, rhs1, rhs2);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
895 return (gimple_resimplify2 (seq, res_op, valueize)
111
kono
parents:
diff changeset
896 || valueized);
kono
parents:
diff changeset
897 }
kono
parents:
diff changeset
898 case GIMPLE_TERNARY_RHS:
kono
parents:
diff changeset
899 {
kono
parents:
diff changeset
900 bool valueized = false;
kono
parents:
diff changeset
901 tree rhs1 = gimple_assign_rhs1 (stmt);
kono
parents:
diff changeset
902 /* If this is a [VEC_]COND_EXPR first try to simplify an
kono
parents:
diff changeset
903 embedded GENERIC condition. */
kono
parents:
diff changeset
904 if (code == COND_EXPR
kono
parents:
diff changeset
905 || code == VEC_COND_EXPR)
kono
parents:
diff changeset
906 {
kono
parents:
diff changeset
907 if (COMPARISON_CLASS_P (rhs1))
kono
parents:
diff changeset
908 {
kono
parents:
diff changeset
909 tree lhs = TREE_OPERAND (rhs1, 0);
kono
parents:
diff changeset
910 tree rhs = TREE_OPERAND (rhs1, 1);
kono
parents:
diff changeset
911 lhs = do_valueize (lhs, top_valueize, valueized);
kono
parents:
diff changeset
912 rhs = do_valueize (rhs, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
913 gimple_match_op res_op2 (res_op->cond, TREE_CODE (rhs1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
914 TREE_TYPE (rhs1), lhs, rhs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
915 if ((gimple_resimplify2 (seq, &res_op2, valueize)
111
kono
parents:
diff changeset
916 || valueized)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
917 && res_op2.code.is_tree_code ())
111
kono
parents:
diff changeset
918 {
kono
parents:
diff changeset
919 valueized = true;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920 if (TREE_CODE_CLASS ((enum tree_code) res_op2.code)
111
kono
parents:
diff changeset
921 == tcc_comparison)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
922 rhs1 = build2 (res_op2.code, TREE_TYPE (rhs1),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
923 res_op2.ops[0], res_op2.ops[1]);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
924 else if (res_op2.code == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
925 || res_op2.code == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
926 || res_op2.code == VECTOR_CST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
927 rhs1 = res_op2.ops[0];
111
kono
parents:
diff changeset
928 else
kono
parents:
diff changeset
929 valueized = false;
kono
parents:
diff changeset
930 }
kono
parents:
diff changeset
931 }
kono
parents:
diff changeset
932 }
kono
parents:
diff changeset
933 tree rhs2 = gimple_assign_rhs2 (stmt);
kono
parents:
diff changeset
934 tree rhs3 = gimple_assign_rhs3 (stmt);
kono
parents:
diff changeset
935 rhs1 = do_valueize (rhs1, top_valueize, valueized);
kono
parents:
diff changeset
936 rhs2 = do_valueize (rhs2, top_valueize, valueized);
kono
parents:
diff changeset
937 rhs3 = do_valueize (rhs3, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
938 res_op->set_op (code, type, rhs1, rhs2, rhs3);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
939 return (gimple_resimplify3 (seq, res_op, valueize)
111
kono
parents:
diff changeset
940 || valueized);
kono
parents:
diff changeset
941 }
kono
parents:
diff changeset
942 default:
kono
parents:
diff changeset
943 gcc_unreachable ();
kono
parents:
diff changeset
944 }
kono
parents:
diff changeset
945 break;
kono
parents:
diff changeset
946 }
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 case GIMPLE_CALL:
kono
parents:
diff changeset
949 /* ??? This way we can't simplify calls with side-effects. */
kono
parents:
diff changeset
950 if (gimple_call_lhs (stmt) != NULL_TREE
kono
parents:
diff changeset
951 && gimple_call_num_args (stmt) >= 1
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
952 && gimple_call_num_args (stmt) <= 5)
111
kono
parents:
diff changeset
953 {
kono
parents:
diff changeset
954 bool valueized = false;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
955 combined_fn cfn;
111
kono
parents:
diff changeset
956 if (gimple_call_internal_p (stmt))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
957 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
111
kono
parents:
diff changeset
958 else
kono
parents:
diff changeset
959 {
kono
parents:
diff changeset
960 tree fn = gimple_call_fn (stmt);
kono
parents:
diff changeset
961 if (!fn)
kono
parents:
diff changeset
962 return false;
kono
parents:
diff changeset
963
kono
parents:
diff changeset
964 fn = do_valueize (fn, top_valueize, valueized);
kono
parents:
diff changeset
965 if (TREE_CODE (fn) != ADDR_EXPR
kono
parents:
diff changeset
966 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
kono
parents:
diff changeset
967 return false;
kono
parents:
diff changeset
968
kono
parents:
diff changeset
969 tree decl = TREE_OPERAND (fn, 0);
kono
parents:
diff changeset
970 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
kono
parents:
diff changeset
971 || !gimple_builtin_call_types_compatible_p (stmt, decl))
kono
parents:
diff changeset
972 return false;
kono
parents:
diff changeset
973
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
974 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
111
kono
parents:
diff changeset
975 }
kono
parents:
diff changeset
976
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
977 unsigned int num_args = gimple_call_num_args (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
978 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 for (unsigned i = 0; i < num_args; ++i)
111
kono
parents:
diff changeset
980 {
kono
parents:
diff changeset
981 tree arg = gimple_call_arg (stmt, i);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 res_op->ops[i] = do_valueize (arg, top_valueize, valueized);
111
kono
parents:
diff changeset
983 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 if (internal_fn_p (cfn)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 && try_conditional_simplification (as_internal_fn (cfn),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 res_op, seq, valueize))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 switch (num_args)
111
kono
parents:
diff changeset
989 {
kono
parents:
diff changeset
990 case 1:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
991 return (gimple_resimplify1 (seq, res_op, valueize)
111
kono
parents:
diff changeset
992 || valueized);
kono
parents:
diff changeset
993 case 2:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
994 return (gimple_resimplify2 (seq, res_op, valueize)
111
kono
parents:
diff changeset
995 || valueized);
kono
parents:
diff changeset
996 case 3:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
997 return (gimple_resimplify3 (seq, res_op, valueize)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
998 || valueized);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
999 case 4:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1000 return (gimple_resimplify4 (seq, res_op, valueize)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1001 || valueized);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1002 case 5:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1003 return (gimple_resimplify5 (seq, res_op, valueize)
111
kono
parents:
diff changeset
1004 || valueized);
kono
parents:
diff changeset
1005 default:
kono
parents:
diff changeset
1006 gcc_unreachable ();
kono
parents:
diff changeset
1007 }
kono
parents:
diff changeset
1008 }
kono
parents:
diff changeset
1009 break;
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 case GIMPLE_COND:
kono
parents:
diff changeset
1012 {
kono
parents:
diff changeset
1013 tree lhs = gimple_cond_lhs (stmt);
kono
parents:
diff changeset
1014 tree rhs = gimple_cond_rhs (stmt);
kono
parents:
diff changeset
1015 bool valueized = false;
kono
parents:
diff changeset
1016 lhs = do_valueize (lhs, top_valueize, valueized);
kono
parents:
diff changeset
1017 rhs = do_valueize (rhs, top_valueize, valueized);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1018 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1019 return (gimple_resimplify2 (seq, res_op, valueize)
111
kono
parents:
diff changeset
1020 || valueized);
kono
parents:
diff changeset
1021 }
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 default:
kono
parents:
diff changeset
1024 break;
kono
parents:
diff changeset
1025 }
kono
parents:
diff changeset
1026
kono
parents:
diff changeset
1027 return false;
kono
parents:
diff changeset
1028 }
kono
parents:
diff changeset
1029
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 /* Helper for the autogenerated code, valueize OP. */
kono
parents:
diff changeset
1032
kono
parents:
diff changeset
1033 inline tree
kono
parents:
diff changeset
1034 do_valueize (tree (*valueize)(tree), tree op)
kono
parents:
diff changeset
1035 {
kono
parents:
diff changeset
1036 if (valueize && TREE_CODE (op) == SSA_NAME)
kono
parents:
diff changeset
1037 {
kono
parents:
diff changeset
1038 tree tem = valueize (op);
kono
parents:
diff changeset
1039 if (tem)
kono
parents:
diff changeset
1040 return tem;
kono
parents:
diff changeset
1041 }
kono
parents:
diff changeset
1042 return op;
kono
parents:
diff changeset
1043 }
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 /* Helper for the autogenerated code, get at the definition of NAME when
kono
parents:
diff changeset
1046 VALUEIZE allows that. */
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 inline gimple *
kono
parents:
diff changeset
1049 get_def (tree (*valueize)(tree), tree name)
kono
parents:
diff changeset
1050 {
kono
parents:
diff changeset
1051 if (valueize && ! valueize (name))
kono
parents:
diff changeset
1052 return NULL;
kono
parents:
diff changeset
1053 return SSA_NAME_DEF_STMT (name);
kono
parents:
diff changeset
1054 }
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 /* Routine to determine if the types T1 and T2 are effectively
kono
parents:
diff changeset
1057 the same for GIMPLE. If T1 or T2 is not a type, the test
kono
parents:
diff changeset
1058 applies to their TREE_TYPE. */
kono
parents:
diff changeset
1059
kono
parents:
diff changeset
1060 static inline bool
kono
parents:
diff changeset
1061 types_match (tree t1, tree t2)
kono
parents:
diff changeset
1062 {
kono
parents:
diff changeset
1063 if (!TYPE_P (t1))
kono
parents:
diff changeset
1064 t1 = TREE_TYPE (t1);
kono
parents:
diff changeset
1065 if (!TYPE_P (t2))
kono
parents:
diff changeset
1066 t2 = TREE_TYPE (t2);
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 return types_compatible_p (t1, t2);
kono
parents:
diff changeset
1069 }
kono
parents:
diff changeset
1070
kono
parents:
diff changeset
1071 /* Return if T has a single use. For GIMPLE, we also allow any
kono
parents:
diff changeset
1072 non-SSA_NAME (ie constants) and zero uses to cope with uses
kono
parents:
diff changeset
1073 that aren't linked up yet. */
kono
parents:
diff changeset
1074
kono
parents:
diff changeset
1075 static inline bool
kono
parents:
diff changeset
1076 single_use (tree t)
kono
parents:
diff changeset
1077 {
kono
parents:
diff changeset
1078 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
kono
parents:
diff changeset
1079 }
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 /* Return true if math operations should be canonicalized,
kono
parents:
diff changeset
1082 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 static inline bool
kono
parents:
diff changeset
1085 canonicalize_math_p ()
kono
parents:
diff changeset
1086 {
kono
parents:
diff changeset
1087 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
kono
parents:
diff changeset
1088 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1089
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1090 /* Return true if math operations that are beneficial only after
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1091 vectorization should be canonicalized. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1092
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1093 static inline bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1094 canonicalize_math_after_vectorization_p ()
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1095 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1096 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1097 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1098
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1099 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1100 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1101 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1102 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1103 will likely be exact, while exp (log (arg0) * arg1) might be not.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1104 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1105
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1106 static bool
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1107 optimize_pow_to_exp (tree arg0, tree arg1)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1108 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1109 gcc_assert (TREE_CODE (arg0) == REAL_CST);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1110 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1111 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1112
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1113 if (TREE_CODE (arg1) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1114 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1115
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1116 gimple *def = SSA_NAME_DEF_STMT (arg1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1117 gphi *phi = dyn_cast <gphi *> (def);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1118 tree cst1 = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1119 enum tree_code code = ERROR_MARK;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1120 if (!phi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1121 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1122 if (!is_gimple_assign (def))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1123 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1124 code = gimple_assign_rhs_code (def);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1125 switch (code)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1126 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1127 case PLUS_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1128 case MINUS_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1129 break;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1130 default:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1131 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1132 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1133 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1134 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1135 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1136
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1137 cst1 = gimple_assign_rhs2 (def);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1138
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1139 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1140 if (!phi)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1141 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1142 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1143
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1144 tree cst2 = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1145 int n = gimple_phi_num_args (phi);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1146 for (int i = 0; i < n; i++)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1147 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1148 tree arg = PHI_ARG_DEF (phi, i);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1149 if (TREE_CODE (arg) != REAL_CST)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1150 continue;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1151 else if (cst2 == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1152 cst2 = arg;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1153 else if (!operand_equal_p (cst2, arg, 0))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1154 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1155 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1156
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1157 if (cst1 && cst2)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1158 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1159 if (cst2
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1160 && TREE_CODE (cst2) == REAL_CST
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1161 && real_isinteger (TREE_REAL_CST_PTR (cst2),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1162 TYPE_MODE (TREE_TYPE (cst2))))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1163 return false;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1164 return true;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1165 }