annotate gcc/tree-ssa-threadedge.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* SSA Jump Threading
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 Contributed by Jeff Law <law@redhat.com>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 it under the terms of the GNU General Public License as published by
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 GNU General Public License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
111
kono
parents: 67
diff changeset
26 #include "gimple.h"
kono
parents: 67
diff changeset
27 #include "predict.h"
kono
parents: 67
diff changeset
28 #include "ssa.h"
kono
parents: 67
diff changeset
29 #include "fold-const.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 #include "cfgloop.h"
111
kono
parents: 67
diff changeset
31 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
32 #include "tree-cfg.h"
kono
parents: 67
diff changeset
33 #include "tree-ssa-threadupdate.h"
kono
parents: 67
diff changeset
34 #include "tree-ssa-scopedtables.h"
kono
parents: 67
diff changeset
35 #include "tree-ssa-threadedge.h"
kono
parents: 67
diff changeset
36 #include "tree-ssa-dom.h"
kono
parents: 67
diff changeset
37 #include "gimple-fold.h"
kono
parents: 67
diff changeset
38 #include "cfganal.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
39 #include "alloc-pool.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
40 #include "vr-values.h"
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
41 #include "gimple-ssa-evrp-analyze.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 /* To avoid code explosion due to jump threading, we limit the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 number of statements we are going to copy. This variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 holds the number of statements currently seen that we'll have
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 to copy as part of the jump threading process. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 static int stmt_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
49 /* Array to record value-handles per SSA_NAME. */
111
kono
parents: 67
diff changeset
50 vec<tree> ssa_name_values;
kono
parents: 67
diff changeset
51
kono
parents: 67
diff changeset
52 typedef tree (pfn_simplify) (gimple *, gimple *,
kono
parents: 67
diff changeset
53 class avail_exprs_stack *,
kono
parents: 67
diff changeset
54 basic_block);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
56 /* Set the value for the SSA name NAME to VALUE. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
57
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
58 void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
59 set_ssa_name_value (tree name, tree value)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
60 {
111
kono
parents: 67
diff changeset
61 if (SSA_NAME_VERSION (name) >= ssa_name_values.length ())
kono
parents: 67
diff changeset
62 ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1);
kono
parents: 67
diff changeset
63 if (value && TREE_OVERFLOW_P (value))
kono
parents: 67
diff changeset
64 value = drop_tree_overflow (value);
kono
parents: 67
diff changeset
65 ssa_name_values[SSA_NAME_VERSION (name)] = value;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
66 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
67
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
68 /* Initialize the per SSA_NAME value-handles array. Returns it. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
69 void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
70 threadedge_initialize_values (void)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
71 {
111
kono
parents: 67
diff changeset
72 gcc_assert (!ssa_name_values.exists ());
kono
parents: 67
diff changeset
73 ssa_name_values.create (num_ssa_names);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
74 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
75
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
76 /* Free the per SSA_NAME value-handle array. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
77 void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
78 threadedge_finalize_values (void)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
79 {
111
kono
parents: 67
diff changeset
80 ssa_name_values.release ();
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
81 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
82
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 /* Return TRUE if we may be able to thread an incoming edge into
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 BB to an outgoing edge from BB. Return FALSE otherwise. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 potentially_threadable_block (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
111
kono
parents: 67
diff changeset
91 /* Special case. We can get blocks that are forwarders, but are
kono
parents: 67
diff changeset
92 not optimized away because they forward from outside a loop
kono
parents: 67
diff changeset
93 to the loop header. We want to thread through them as we can
kono
parents: 67
diff changeset
94 sometimes thread to the loop exit, which is obviously profitable.
kono
parents: 67
diff changeset
95 the interesting case here is when the block has PHIs. */
kono
parents: 67
diff changeset
96 if (gsi_end_p (gsi_start_nondebug_bb (bb))
kono
parents: 67
diff changeset
97 && !gsi_end_p (gsi_start_phis (bb)))
kono
parents: 67
diff changeset
98 return true;
kono
parents: 67
diff changeset
99
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 /* If BB has a single successor or a single predecessor, then
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 there is no threading opportunity. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 if (single_succ_p (bb) || single_pred_p (bb))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 /* If BB does not end with a conditional, switch or computed goto,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 then there is no threading opportunity. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 gsi = gsi_last_bb (bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 if (gsi_end_p (gsi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 || ! gsi_stmt (gsi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 || (gimple_code (gsi_stmt (gsi)) != GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 && gimple_code (gsi_stmt (gsi)) != GIMPLE_GOTO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 && gimple_code (gsi_stmt (gsi)) != GIMPLE_SWITCH))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 /* Record temporary equivalences created by PHIs at the target of the
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
119 edge E. Record unwind information for the equivalences into
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
120 CONST_AND_COPIES and EVRP_RANGE_DATA.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 If a PHI which prevents threading is encountered, then return FALSE
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
123 indicating we should not thread this edge, else return TRUE. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 static bool
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
126 record_temporary_equivalences_from_phis (edge e,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
127 const_and_copies *const_and_copies,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
128 evrp_range_analyzer *evrp_range_analyzer)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 {
111
kono
parents: 67
diff changeset
130 gphi_iterator gsi;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 /* Each PHI creates a temporary equivalence, record them.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 These are context sensitive equivalences and will be removed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 later. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 {
111
kono
parents: 67
diff changeset
137 gphi *phi = gsi.phi ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 tree dst = gimple_phi_result (phi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
141 /* If the desired argument is not the same as this PHI's result
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
142 and it is set by a PHI in E->dest, then we cannot thread
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
143 through E->dest. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 if (src != dst
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 && TREE_CODE (src) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 && gimple_code (SSA_NAME_DEF_STMT (src)) == GIMPLE_PHI
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 && gimple_bb (SSA_NAME_DEF_STMT (src)) == e->dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
149
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 /* We consider any non-virtual PHI as a statement since it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 count result in a constant assignment or copy operation. */
111
kono
parents: 67
diff changeset
152 if (!virtual_operand_p (dst))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 stmt_count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
111
kono
parents: 67
diff changeset
155 const_and_copies->record_const_or_copy (dst, src);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
156
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
157 /* Also update the value range associated with DST, using
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
158 the range from SRC.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
159
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
160 Note that even if SRC is a constant we need to set a suitable
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
161 output range so that VR_UNDEFINED ranges do not leak through. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
162 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
163 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
164 /* Get an empty new VR we can pass to update_value_range and save
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
165 away in the VR stack. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
166 vr_values *vr_values = evrp_range_analyzer->get_vr_values ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
167 value_range_equiv *new_vr = vr_values->allocate_value_range_equiv ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
168 new (new_vr) value_range_equiv ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
169
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
170 /* There are three cases to consider:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 First if SRC is an SSA_NAME, then we can copy the value
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 range from SRC into NEW_VR.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 Second if SRC is an INTEGER_CST, then we can just wet
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 NEW_VR to a singleton range.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 Otherwise set NEW_VR to varying. This may be overly
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 conservative. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180 if (TREE_CODE (src) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 new_vr->deep_copy (vr_values->get_value_range (src));
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 else if (TREE_CODE (src) == INTEGER_CST)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
183 new_vr->set (src);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
185 new_vr->set_varying (TREE_TYPE (src));
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
187 /* This is a temporary range for DST, so push it. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
188 evrp_range_analyzer->push_value_range (dst, new_vr);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
189 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
111
kono
parents: 67
diff changeset
194 /* Valueize hook for gimple_fold_stmt_to_constant_1. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 static tree
111
kono
parents: 67
diff changeset
197 threadedge_valueize (tree t)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198 {
111
kono
parents: 67
diff changeset
199 if (TREE_CODE (t) == SSA_NAME)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 {
111
kono
parents: 67
diff changeset
201 tree tem = SSA_NAME_VALUE (t);
kono
parents: 67
diff changeset
202 if (tem)
kono
parents: 67
diff changeset
203 return tem;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
204 }
111
kono
parents: 67
diff changeset
205 return t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 /* Try to simplify each statement in E->dest, ultimately leading to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 a simplification of the COND_EXPR at the end of E->dest.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 Record unwind information for temporary equivalences onto STACK.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 Use SIMPLIFY (a pointer to a callback function) to further simplify
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
214 statements using pass specific information.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
215
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 We might consider marking just those statements which ultimately
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 feed the COND_EXPR. It's not clear if the overhead of bookkeeping
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 would be recovered by trying to simplify fewer statements.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 If we are able to simplify a statement into the form
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 SSA_NAME = (SSA_NAME | gimple invariant), then we can record
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 a context sensitive equivalence which may help us simplify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 later statements in E->dest. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224
111
kono
parents: 67
diff changeset
225 static gimple *
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
226 record_temporary_equivalences_from_stmts_at_dest (edge e,
111
kono
parents: 67
diff changeset
227 const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
228 avail_exprs_stack *avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
229 evrp_range_analyzer *evrp_range_analyzer,
111
kono
parents: 67
diff changeset
230 pfn_simplify simplify)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
231 {
111
kono
parents: 67
diff changeset
232 gimple *stmt = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 int max_stmt_count;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
236 max_stmt_count = param_max_jump_thread_duplication_stmts;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 /* Walk through each statement in the block recording equivalences
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 we discover. Note any equivalences we discover are context
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 sensitive (ie, are dependent on traversing E) and must be unwound
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 when we're finished processing E. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 for (gsi = gsi_start_bb (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 tree cached_lhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 stmt = gsi_stmt (gsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 /* Ignore empty statements and labels. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
249 if (gimple_code (stmt) == GIMPLE_NOP
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
250 || gimple_code (stmt) == GIMPLE_LABEL
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
251 || is_gimple_debug (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 /* If the statement has volatile operands, then we assume we
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
255 cannot thread through this block. This is overly
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 conservative in some ways. */
111
kono
parents: 67
diff changeset
257 if (gimple_code (stmt) == GIMPLE_ASM
kono
parents: 67
diff changeset
258 && gimple_asm_volatile_p (as_a <gasm *> (stmt)))
kono
parents: 67
diff changeset
259 return NULL;
kono
parents: 67
diff changeset
260
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
261 /* If the statement is a unique builtin, we cannot thread
111
kono
parents: 67
diff changeset
262 through here. */
kono
parents: 67
diff changeset
263 if (gimple_code (stmt) == GIMPLE_CALL
kono
parents: 67
diff changeset
264 && gimple_call_internal_p (stmt)
kono
parents: 67
diff changeset
265 && gimple_call_internal_unique_p (stmt))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266 return NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 /* If duplicating this block is going to cause too much code
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 expansion, then do not thread through this block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
270 stmt_count++;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 if (stmt_count > max_stmt_count)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
272 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
273 /* If any of the stmts in the PATH's dests are going to be
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
274 killed due to threading, grow the max count
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
275 accordingly. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
276 if (max_stmt_count
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
277 == param_max_jump_thread_duplication_stmts)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
278 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
279 max_stmt_count += estimate_threading_killed_stmts (e->dest);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
280 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
281 fprintf (dump_file, "threading bb %i up to %i stmts\n",
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
282 e->dest->index, max_stmt_count);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
283 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
284 /* If we're still past the limit, we're done. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 if (stmt_count > max_stmt_count)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 return NULL;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
287 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
288
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
289 /* These are temporary ranges, do nto reflect them back into
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
290 the global range data. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
291 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
292 evrp_range_analyzer->record_ranges_from_stmt (stmt, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
293
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 /* If this is not a statement that sets an SSA_NAME to a new
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 value, then do not try to simplify this statement as it will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
296 not simplify in any way that is helpful for jump threading. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 if ((gimple_code (stmt) != GIMPLE_ASSIGN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 && (gimple_code (stmt) != GIMPLE_CALL
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 || gimple_call_lhs (stmt) == NULL_TREE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 || TREE_CODE (gimple_call_lhs (stmt)) != SSA_NAME))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 /* The result of __builtin_object_size depends on all the arguments
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 of a phi node. Temporarily using only one edge produces invalid
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 results. For example
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 if (x < 6)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 goto l;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
311 goto l;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 l:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 r = PHI <&w[2].a[1](2), &a.a[6](3)>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 __builtin_object_size (r, 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 The result of __builtin_object_size is defined to be the maximum of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 remaining bytes. If we use only one edge on the phi, the result will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 change to be the remaining bytes for the corresponding phi argument.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 Similarly for __builtin_constant_p:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 r = PHI <1(2), 2(3)>
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 __builtin_constant_p (r)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
325
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
326 Both PHI arguments are constant, but x ? 1 : 2 is still not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 constant. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
328
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 if (is_gimple_call (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
330 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 tree fndecl = gimple_call_fndecl (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 if (fndecl
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
333 && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
337 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
338
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 /* At this point we have a statement which assigns an RHS to an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 SSA_VAR on the LHS. We want to try and simplify this statement
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
341 to expose more context sensitive equivalences which in turn may
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
342 allow us to simplify the condition at the end of the loop.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344 Handle simple copy operations as well as implied copies from
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 ASSERT_EXPRs. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 if (gimple_assign_single_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347 && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 cached_lhs = gimple_assign_rhs1 (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 else if (gimple_assign_single_p (stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350 && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 cached_lhs = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
354 /* A statement that is not a trivial copy or ASSERT_EXPR.
111
kono
parents: 67
diff changeset
355 Try to fold the new expression. Inserting the
kono
parents: 67
diff changeset
356 expression into the hash table is unlikely to help. */
kono
parents: 67
diff changeset
357 /* ??? The DOM callback below can be changed to setting
kono
parents: 67
diff changeset
358 the mprts_hook around the call to thread_across_edge,
kono
parents: 67
diff changeset
359 avoiding the use substitution. The VRP hook should be
kono
parents: 67
diff changeset
360 changed to properly valueize operands itself using
kono
parents: 67
diff changeset
361 SSA_NAME_VALUE in addition to its own lattice. */
kono
parents: 67
diff changeset
362 cached_lhs = gimple_fold_stmt_to_constant_1 (stmt,
kono
parents: 67
diff changeset
363 threadedge_valueize);
kono
parents: 67
diff changeset
364 if (NUM_SSA_OPERANDS (stmt, SSA_OP_ALL_USES) != 0
kono
parents: 67
diff changeset
365 && (!cached_lhs
kono
parents: 67
diff changeset
366 || (TREE_CODE (cached_lhs) != SSA_NAME
kono
parents: 67
diff changeset
367 && !is_gimple_min_invariant (cached_lhs))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368 {
111
kono
parents: 67
diff changeset
369 /* We're going to temporarily copy propagate the operands
kono
parents: 67
diff changeset
370 and see if that allows us to simplify this statement. */
kono
parents: 67
diff changeset
371 tree *copy;
kono
parents: 67
diff changeset
372 ssa_op_iter iter;
kono
parents: 67
diff changeset
373 use_operand_p use_p;
kono
parents: 67
diff changeset
374 unsigned int num, i = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375
111
kono
parents: 67
diff changeset
376 num = NUM_SSA_OPERANDS (stmt, SSA_OP_ALL_USES);
kono
parents: 67
diff changeset
377 copy = XALLOCAVEC (tree, num);
kono
parents: 67
diff changeset
378
kono
parents: 67
diff changeset
379 /* Make a copy of the uses & vuses into USES_COPY, then cprop into
kono
parents: 67
diff changeset
380 the operands. */
kono
parents: 67
diff changeset
381 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
kono
parents: 67
diff changeset
382 {
kono
parents: 67
diff changeset
383 tree tmp = NULL;
kono
parents: 67
diff changeset
384 tree use = USE_FROM_PTR (use_p);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385
111
kono
parents: 67
diff changeset
386 copy[i++] = use;
kono
parents: 67
diff changeset
387 if (TREE_CODE (use) == SSA_NAME)
kono
parents: 67
diff changeset
388 tmp = SSA_NAME_VALUE (use);
kono
parents: 67
diff changeset
389 if (tmp)
kono
parents: 67
diff changeset
390 SET_USE (use_p, tmp);
kono
parents: 67
diff changeset
391 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392
111
kono
parents: 67
diff changeset
393 cached_lhs = (*simplify) (stmt, stmt, avail_exprs_stack, e->src);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
394
111
kono
parents: 67
diff changeset
395 /* Restore the statement's original uses/defs. */
kono
parents: 67
diff changeset
396 i = 0;
kono
parents: 67
diff changeset
397 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
kono
parents: 67
diff changeset
398 SET_USE (use_p, copy[i++]);
kono
parents: 67
diff changeset
399 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 /* Record the context sensitive equivalence if we were able
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 to simplify this statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 if (cached_lhs
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 && (TREE_CODE (cached_lhs) == SSA_NAME
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 || is_gimple_min_invariant (cached_lhs)))
111
kono
parents: 67
diff changeset
407 const_and_copies->record_const_or_copy (gimple_get_lhs (stmt),
kono
parents: 67
diff changeset
408 cached_lhs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 return stmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412
111
kono
parents: 67
diff changeset
413 static tree simplify_control_stmt_condition_1 (edge, gimple *,
kono
parents: 67
diff changeset
414 class avail_exprs_stack *,
kono
parents: 67
diff changeset
415 tree, enum tree_code, tree,
kono
parents: 67
diff changeset
416 gcond *, pfn_simplify,
kono
parents: 67
diff changeset
417 unsigned);
kono
parents: 67
diff changeset
418
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419 /* Simplify the control statement at the end of the block E->dest.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 To avoid allocating memory unnecessarily, a scratch GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 is available to use/clobber in DUMMY_COND.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
423
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 Use SIMPLIFY (a pointer to a callback function) to further simplify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 a condition using pass specific information.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
426
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 Return the simplified condition or NULL if simplification could
111
kono
parents: 67
diff changeset
428 not be performed. When simplifying a GIMPLE_SWITCH, we may return
kono
parents: 67
diff changeset
429 the CASE_LABEL_EXPR that will be taken.
kono
parents: 67
diff changeset
430
kono
parents: 67
diff changeset
431 The available expression table is referenced via AVAIL_EXPRS_STACK. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
432
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
433 static tree
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 simplify_control_stmt_condition (edge e,
111
kono
parents: 67
diff changeset
435 gimple *stmt,
kono
parents: 67
diff changeset
436 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
437 gcond *dummy_cond,
kono
parents: 67
diff changeset
438 pfn_simplify simplify)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 tree cond, cached_lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 enum gimple_code code = gimple_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 /* For comparisons, we have to update both operands, then try
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 to simplify the comparison. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 if (code == GIMPLE_COND)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 tree op0, op1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 enum tree_code cond_code;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 op0 = gimple_cond_lhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 op1 = gimple_cond_rhs (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 cond_code = gimple_cond_code (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 /* Get the current value of both operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 if (TREE_CODE (op0) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 {
111
kono
parents: 67
diff changeset
457 for (int i = 0; i < 2; i++)
kono
parents: 67
diff changeset
458 {
kono
parents: 67
diff changeset
459 if (TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
460 && SSA_NAME_VALUE (op0))
kono
parents: 67
diff changeset
461 op0 = SSA_NAME_VALUE (op0);
kono
parents: 67
diff changeset
462 else
kono
parents: 67
diff changeset
463 break;
kono
parents: 67
diff changeset
464 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
466
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 if (TREE_CODE (op1) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 {
111
kono
parents: 67
diff changeset
469 for (int i = 0; i < 2; i++)
kono
parents: 67
diff changeset
470 {
kono
parents: 67
diff changeset
471 if (TREE_CODE (op1) == SSA_NAME
kono
parents: 67
diff changeset
472 && SSA_NAME_VALUE (op1))
kono
parents: 67
diff changeset
473 op1 = SSA_NAME_VALUE (op1);
kono
parents: 67
diff changeset
474 else
kono
parents: 67
diff changeset
475 break;
kono
parents: 67
diff changeset
476 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478
111
kono
parents: 67
diff changeset
479 const unsigned recursion_limit = 4;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480
111
kono
parents: 67
diff changeset
481 cached_lhs
kono
parents: 67
diff changeset
482 = simplify_control_stmt_condition_1 (e, stmt, avail_exprs_stack,
kono
parents: 67
diff changeset
483 op0, cond_code, op1,
kono
parents: 67
diff changeset
484 dummy_cond, simplify,
kono
parents: 67
diff changeset
485 recursion_limit);
kono
parents: 67
diff changeset
486
kono
parents: 67
diff changeset
487 /* If we were testing an integer/pointer against a constant, then
kono
parents: 67
diff changeset
488 we can use the FSM code to trace the value of the SSA_NAME. If
kono
parents: 67
diff changeset
489 a value is found, then the condition will collapse to a constant.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490
111
kono
parents: 67
diff changeset
491 Return the SSA_NAME we want to trace back rather than the full
kono
parents: 67
diff changeset
492 expression and give the FSM threader a chance to find its value. */
kono
parents: 67
diff changeset
493 if (cached_lhs == NULL)
kono
parents: 67
diff changeset
494 {
kono
parents: 67
diff changeset
495 /* Recover the original operands. They may have been simplified
kono
parents: 67
diff changeset
496 using context sensitive equivalences. Those context sensitive
kono
parents: 67
diff changeset
497 equivalences may not be valid on paths found by the FSM optimizer. */
kono
parents: 67
diff changeset
498 tree op0 = gimple_cond_lhs (stmt);
kono
parents: 67
diff changeset
499 tree op1 = gimple_cond_rhs (stmt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500
111
kono
parents: 67
diff changeset
501 if ((INTEGRAL_TYPE_P (TREE_TYPE (op0))
kono
parents: 67
diff changeset
502 || POINTER_TYPE_P (TREE_TYPE (op0)))
kono
parents: 67
diff changeset
503 && TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
504 && TREE_CODE (op1) == INTEGER_CST)
kono
parents: 67
diff changeset
505 return op0;
kono
parents: 67
diff changeset
506 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 return cached_lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 if (code == GIMPLE_SWITCH)
111
kono
parents: 67
diff changeset
512 cond = gimple_switch_index (as_a <gswitch *> (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 else if (code == GIMPLE_GOTO)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 cond = gimple_goto_dest (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 /* We can have conditionals which just test the state of a variable
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 rather than use a relational operator. These are simpler to handle. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 if (TREE_CODE (cond) == SSA_NAME)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 {
111
kono
parents: 67
diff changeset
522 tree original_lhs = cond;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 cached_lhs = cond;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525 /* Get the variable's current value from the equivalence chains.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 It is possible to get loops in the SSA_NAME_VALUE chains
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 (consider threading the backedge of a loop where we have
111
kono
parents: 67
diff changeset
529 a loop invariant SSA_NAME used in the condition). */
kono
parents: 67
diff changeset
530 if (cached_lhs)
kono
parents: 67
diff changeset
531 {
kono
parents: 67
diff changeset
532 for (int i = 0; i < 2; i++)
kono
parents: 67
diff changeset
533 {
kono
parents: 67
diff changeset
534 if (TREE_CODE (cached_lhs) == SSA_NAME
kono
parents: 67
diff changeset
535 && SSA_NAME_VALUE (cached_lhs))
kono
parents: 67
diff changeset
536 cached_lhs = SSA_NAME_VALUE (cached_lhs);
kono
parents: 67
diff changeset
537 else
kono
parents: 67
diff changeset
538 break;
kono
parents: 67
diff changeset
539 }
kono
parents: 67
diff changeset
540 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 /* If we haven't simplified to an invariant yet, then use the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 pass specific callback to try and simplify it further. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
111
kono
parents: 67
diff changeset
545 {
kono
parents: 67
diff changeset
546 if (code == GIMPLE_SWITCH)
kono
parents: 67
diff changeset
547 {
kono
parents: 67
diff changeset
548 /* Replace the index operand of the GIMPLE_SWITCH with any LHS
kono
parents: 67
diff changeset
549 we found before handing off to VRP. If simplification is
kono
parents: 67
diff changeset
550 possible, the simplified value will be a CASE_LABEL_EXPR of
kono
parents: 67
diff changeset
551 the label that is proven to be taken. */
kono
parents: 67
diff changeset
552 gswitch *dummy_switch = as_a<gswitch *> (gimple_copy (stmt));
kono
parents: 67
diff changeset
553 gimple_switch_set_index (dummy_switch, cached_lhs);
kono
parents: 67
diff changeset
554 cached_lhs = (*simplify) (dummy_switch, stmt,
kono
parents: 67
diff changeset
555 avail_exprs_stack, e->src);
kono
parents: 67
diff changeset
556 ggc_free (dummy_switch);
kono
parents: 67
diff changeset
557 }
kono
parents: 67
diff changeset
558 else
kono
parents: 67
diff changeset
559 cached_lhs = (*simplify) (stmt, stmt, avail_exprs_stack, e->src);
kono
parents: 67
diff changeset
560 }
kono
parents: 67
diff changeset
561
kono
parents: 67
diff changeset
562 /* We couldn't find an invariant. But, callers of this
kono
parents: 67
diff changeset
563 function may be able to do something useful with the
kono
parents: 67
diff changeset
564 unmodified destination. */
kono
parents: 67
diff changeset
565 if (!cached_lhs)
kono
parents: 67
diff changeset
566 cached_lhs = original_lhs;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 cached_lhs = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 return cached_lhs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
111
kono
parents: 67
diff changeset
574 /* Recursive helper for simplify_control_stmt_condition. */
kono
parents: 67
diff changeset
575
kono
parents: 67
diff changeset
576 static tree
kono
parents: 67
diff changeset
577 simplify_control_stmt_condition_1 (edge e,
kono
parents: 67
diff changeset
578 gimple *stmt,
kono
parents: 67
diff changeset
579 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
580 tree op0,
kono
parents: 67
diff changeset
581 enum tree_code cond_code,
kono
parents: 67
diff changeset
582 tree op1,
kono
parents: 67
diff changeset
583 gcond *dummy_cond,
kono
parents: 67
diff changeset
584 pfn_simplify simplify,
kono
parents: 67
diff changeset
585 unsigned limit)
kono
parents: 67
diff changeset
586 {
kono
parents: 67
diff changeset
587 if (limit == 0)
kono
parents: 67
diff changeset
588 return NULL_TREE;
kono
parents: 67
diff changeset
589
kono
parents: 67
diff changeset
590 /* We may need to canonicalize the comparison. For
kono
parents: 67
diff changeset
591 example, op0 might be a constant while op1 is an
kono
parents: 67
diff changeset
592 SSA_NAME. Failure to canonicalize will cause us to
kono
parents: 67
diff changeset
593 miss threading opportunities. */
kono
parents: 67
diff changeset
594 if (tree_swap_operands_p (op0, op1))
kono
parents: 67
diff changeset
595 {
kono
parents: 67
diff changeset
596 cond_code = swap_tree_comparison (cond_code);
kono
parents: 67
diff changeset
597 std::swap (op0, op1);
kono
parents: 67
diff changeset
598 }
kono
parents: 67
diff changeset
599
kono
parents: 67
diff changeset
600 /* If the condition has the form (A & B) CMP 0 or (A | B) CMP 0 then
kono
parents: 67
diff changeset
601 recurse into the LHS to see if there is a dominating ASSERT_EXPR
kono
parents: 67
diff changeset
602 of A or of B that makes this condition always true or always false
kono
parents: 67
diff changeset
603 along the edge E. */
kono
parents: 67
diff changeset
604 if ((cond_code == EQ_EXPR || cond_code == NE_EXPR)
kono
parents: 67
diff changeset
605 && TREE_CODE (op0) == SSA_NAME
kono
parents: 67
diff changeset
606 && integer_zerop (op1))
kono
parents: 67
diff changeset
607 {
kono
parents: 67
diff changeset
608 gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
kono
parents: 67
diff changeset
609 if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
kono
parents: 67
diff changeset
610 ;
kono
parents: 67
diff changeset
611 else if (gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR
kono
parents: 67
diff changeset
612 || gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
kono
parents: 67
diff changeset
613 {
kono
parents: 67
diff changeset
614 enum tree_code rhs_code = gimple_assign_rhs_code (def_stmt);
kono
parents: 67
diff changeset
615 const tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
616 const tree rhs2 = gimple_assign_rhs2 (def_stmt);
kono
parents: 67
diff changeset
617
kono
parents: 67
diff changeset
618 /* Is A != 0 ? */
kono
parents: 67
diff changeset
619 const tree res1
kono
parents: 67
diff changeset
620 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack,
kono
parents: 67
diff changeset
621 rhs1, NE_EXPR, op1,
kono
parents: 67
diff changeset
622 dummy_cond, simplify,
kono
parents: 67
diff changeset
623 limit - 1);
kono
parents: 67
diff changeset
624 if (res1 == NULL_TREE)
kono
parents: 67
diff changeset
625 ;
kono
parents: 67
diff changeset
626 else if (rhs_code == BIT_AND_EXPR && integer_zerop (res1))
kono
parents: 67
diff changeset
627 {
kono
parents: 67
diff changeset
628 /* If A == 0 then (A & B) != 0 is always false. */
kono
parents: 67
diff changeset
629 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
630 return boolean_false_node;
kono
parents: 67
diff changeset
631 /* If A == 0 then (A & B) == 0 is always true. */
kono
parents: 67
diff changeset
632 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
633 return boolean_true_node;
kono
parents: 67
diff changeset
634 }
kono
parents: 67
diff changeset
635 else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res1))
kono
parents: 67
diff changeset
636 {
kono
parents: 67
diff changeset
637 /* If A != 0 then (A | B) != 0 is always true. */
kono
parents: 67
diff changeset
638 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
639 return boolean_true_node;
kono
parents: 67
diff changeset
640 /* If A != 0 then (A | B) == 0 is always false. */
kono
parents: 67
diff changeset
641 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
642 return boolean_false_node;
kono
parents: 67
diff changeset
643 }
kono
parents: 67
diff changeset
644
kono
parents: 67
diff changeset
645 /* Is B != 0 ? */
kono
parents: 67
diff changeset
646 const tree res2
kono
parents: 67
diff changeset
647 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack,
kono
parents: 67
diff changeset
648 rhs2, NE_EXPR, op1,
kono
parents: 67
diff changeset
649 dummy_cond, simplify,
kono
parents: 67
diff changeset
650 limit - 1);
kono
parents: 67
diff changeset
651 if (res2 == NULL_TREE)
kono
parents: 67
diff changeset
652 ;
kono
parents: 67
diff changeset
653 else if (rhs_code == BIT_AND_EXPR && integer_zerop (res2))
kono
parents: 67
diff changeset
654 {
kono
parents: 67
diff changeset
655 /* If B == 0 then (A & B) != 0 is always false. */
kono
parents: 67
diff changeset
656 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
657 return boolean_false_node;
kono
parents: 67
diff changeset
658 /* If B == 0 then (A & B) == 0 is always true. */
kono
parents: 67
diff changeset
659 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
660 return boolean_true_node;
kono
parents: 67
diff changeset
661 }
kono
parents: 67
diff changeset
662 else if (rhs_code == BIT_IOR_EXPR && integer_nonzerop (res2))
kono
parents: 67
diff changeset
663 {
kono
parents: 67
diff changeset
664 /* If B != 0 then (A | B) != 0 is always true. */
kono
parents: 67
diff changeset
665 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
666 return boolean_true_node;
kono
parents: 67
diff changeset
667 /* If B != 0 then (A | B) == 0 is always false. */
kono
parents: 67
diff changeset
668 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
669 return boolean_false_node;
kono
parents: 67
diff changeset
670 }
kono
parents: 67
diff changeset
671
kono
parents: 67
diff changeset
672 if (res1 != NULL_TREE && res2 != NULL_TREE)
kono
parents: 67
diff changeset
673 {
kono
parents: 67
diff changeset
674 if (rhs_code == BIT_AND_EXPR
kono
parents: 67
diff changeset
675 && TYPE_PRECISION (TREE_TYPE (op0)) == 1
kono
parents: 67
diff changeset
676 && integer_nonzerop (res1)
kono
parents: 67
diff changeset
677 && integer_nonzerop (res2))
kono
parents: 67
diff changeset
678 {
kono
parents: 67
diff changeset
679 /* If A != 0 and B != 0 then (bool)(A & B) != 0 is true. */
kono
parents: 67
diff changeset
680 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
681 return boolean_true_node;
kono
parents: 67
diff changeset
682 /* If A != 0 and B != 0 then (bool)(A & B) == 0 is false. */
kono
parents: 67
diff changeset
683 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
684 return boolean_false_node;
kono
parents: 67
diff changeset
685 }
kono
parents: 67
diff changeset
686
kono
parents: 67
diff changeset
687 if (rhs_code == BIT_IOR_EXPR
kono
parents: 67
diff changeset
688 && integer_zerop (res1)
kono
parents: 67
diff changeset
689 && integer_zerop (res2))
kono
parents: 67
diff changeset
690 {
kono
parents: 67
diff changeset
691 /* If A == 0 and B == 0 then (A | B) != 0 is false. */
kono
parents: 67
diff changeset
692 if (cond_code == NE_EXPR)
kono
parents: 67
diff changeset
693 return boolean_false_node;
kono
parents: 67
diff changeset
694 /* If A == 0 and B == 0 then (A | B) == 0 is true. */
kono
parents: 67
diff changeset
695 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
696 return boolean_true_node;
kono
parents: 67
diff changeset
697 }
kono
parents: 67
diff changeset
698 }
kono
parents: 67
diff changeset
699 }
kono
parents: 67
diff changeset
700 /* Handle (A CMP B) CMP 0. */
kono
parents: 67
diff changeset
701 else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
kono
parents: 67
diff changeset
702 == tcc_comparison)
kono
parents: 67
diff changeset
703 {
kono
parents: 67
diff changeset
704 tree rhs1 = gimple_assign_rhs1 (def_stmt);
kono
parents: 67
diff changeset
705 tree rhs2 = gimple_assign_rhs2 (def_stmt);
kono
parents: 67
diff changeset
706
kono
parents: 67
diff changeset
707 tree_code new_cond = gimple_assign_rhs_code (def_stmt);
kono
parents: 67
diff changeset
708 if (cond_code == EQ_EXPR)
kono
parents: 67
diff changeset
709 new_cond = invert_tree_comparison (new_cond, false);
kono
parents: 67
diff changeset
710
kono
parents: 67
diff changeset
711 tree res
kono
parents: 67
diff changeset
712 = simplify_control_stmt_condition_1 (e, def_stmt, avail_exprs_stack,
kono
parents: 67
diff changeset
713 rhs1, new_cond, rhs2,
kono
parents: 67
diff changeset
714 dummy_cond, simplify,
kono
parents: 67
diff changeset
715 limit - 1);
kono
parents: 67
diff changeset
716 if (res != NULL_TREE && is_gimple_min_invariant (res))
kono
parents: 67
diff changeset
717 return res;
kono
parents: 67
diff changeset
718 }
kono
parents: 67
diff changeset
719 }
kono
parents: 67
diff changeset
720
kono
parents: 67
diff changeset
721 gimple_cond_set_code (dummy_cond, cond_code);
kono
parents: 67
diff changeset
722 gimple_cond_set_lhs (dummy_cond, op0);
kono
parents: 67
diff changeset
723 gimple_cond_set_rhs (dummy_cond, op1);
kono
parents: 67
diff changeset
724
kono
parents: 67
diff changeset
725 /* We absolutely do not care about any type conversions
kono
parents: 67
diff changeset
726 we only care about a zero/nonzero value. */
kono
parents: 67
diff changeset
727 fold_defer_overflow_warnings ();
kono
parents: 67
diff changeset
728
kono
parents: 67
diff changeset
729 tree res = fold_binary (cond_code, boolean_type_node, op0, op1);
kono
parents: 67
diff changeset
730 if (res)
kono
parents: 67
diff changeset
731 while (CONVERT_EXPR_P (res))
kono
parents: 67
diff changeset
732 res = TREE_OPERAND (res, 0);
kono
parents: 67
diff changeset
733
kono
parents: 67
diff changeset
734 fold_undefer_overflow_warnings ((res && is_gimple_min_invariant (res)),
kono
parents: 67
diff changeset
735 stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
kono
parents: 67
diff changeset
736
kono
parents: 67
diff changeset
737 /* If we have not simplified the condition down to an invariant,
kono
parents: 67
diff changeset
738 then use the pass specific callback to simplify the condition. */
kono
parents: 67
diff changeset
739 if (!res
kono
parents: 67
diff changeset
740 || !is_gimple_min_invariant (res))
kono
parents: 67
diff changeset
741 res = (*simplify) (dummy_cond, stmt, avail_exprs_stack, e->src);
kono
parents: 67
diff changeset
742
kono
parents: 67
diff changeset
743 return res;
kono
parents: 67
diff changeset
744 }
kono
parents: 67
diff changeset
745
kono
parents: 67
diff changeset
746 /* Copy debug stmts from DEST's chain of single predecessors up to
kono
parents: 67
diff changeset
747 SRC, so that we don't lose the bindings as PHI nodes are introduced
kono
parents: 67
diff changeset
748 when DEST gains new predecessors. */
kono
parents: 67
diff changeset
749 void
kono
parents: 67
diff changeset
750 propagate_threaded_block_debug_into (basic_block dest, basic_block src)
kono
parents: 67
diff changeset
751 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
752 if (!MAY_HAVE_DEBUG_BIND_STMTS)
111
kono
parents: 67
diff changeset
753 return;
kono
parents: 67
diff changeset
754
kono
parents: 67
diff changeset
755 if (!single_pred_p (dest))
kono
parents: 67
diff changeset
756 return;
kono
parents: 67
diff changeset
757
kono
parents: 67
diff changeset
758 gcc_checking_assert (dest != src);
kono
parents: 67
diff changeset
759
kono
parents: 67
diff changeset
760 gimple_stmt_iterator gsi = gsi_after_labels (dest);
kono
parents: 67
diff changeset
761 int i = 0;
kono
parents: 67
diff changeset
762 const int alloc_count = 16; // ?? Should this be a PARAM?
kono
parents: 67
diff changeset
763
kono
parents: 67
diff changeset
764 /* Estimate the number of debug vars overridden in the beginning of
kono
parents: 67
diff changeset
765 DEST, to tell how many we're going to need to begin with. */
kono
parents: 67
diff changeset
766 for (gimple_stmt_iterator si = gsi;
kono
parents: 67
diff changeset
767 i * 4 <= alloc_count * 3 && !gsi_end_p (si); gsi_next (&si))
kono
parents: 67
diff changeset
768 {
kono
parents: 67
diff changeset
769 gimple *stmt = gsi_stmt (si);
kono
parents: 67
diff changeset
770 if (!is_gimple_debug (stmt))
kono
parents: 67
diff changeset
771 break;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
772 if (gimple_debug_nonbind_marker_p (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
773 continue;
111
kono
parents: 67
diff changeset
774 i++;
kono
parents: 67
diff changeset
775 }
kono
parents: 67
diff changeset
776
kono
parents: 67
diff changeset
777 auto_vec<tree, alloc_count> fewvars;
kono
parents: 67
diff changeset
778 hash_set<tree> *vars = NULL;
kono
parents: 67
diff changeset
779
kono
parents: 67
diff changeset
780 /* If we're already starting with 3/4 of alloc_count, go for a
kono
parents: 67
diff changeset
781 hash_set, otherwise start with an unordered stack-allocated
kono
parents: 67
diff changeset
782 VEC. */
kono
parents: 67
diff changeset
783 if (i * 4 > alloc_count * 3)
kono
parents: 67
diff changeset
784 vars = new hash_set<tree>;
kono
parents: 67
diff changeset
785
kono
parents: 67
diff changeset
786 /* Now go through the initial debug stmts in DEST again, this time
kono
parents: 67
diff changeset
787 actually inserting in VARS or FEWVARS. Don't bother checking for
kono
parents: 67
diff changeset
788 duplicates in FEWVARS. */
kono
parents: 67
diff changeset
789 for (gimple_stmt_iterator si = gsi; !gsi_end_p (si); gsi_next (&si))
kono
parents: 67
diff changeset
790 {
kono
parents: 67
diff changeset
791 gimple *stmt = gsi_stmt (si);
kono
parents: 67
diff changeset
792 if (!is_gimple_debug (stmt))
kono
parents: 67
diff changeset
793 break;
kono
parents: 67
diff changeset
794
kono
parents: 67
diff changeset
795 tree var;
kono
parents: 67
diff changeset
796
kono
parents: 67
diff changeset
797 if (gimple_debug_bind_p (stmt))
kono
parents: 67
diff changeset
798 var = gimple_debug_bind_get_var (stmt);
kono
parents: 67
diff changeset
799 else if (gimple_debug_source_bind_p (stmt))
kono
parents: 67
diff changeset
800 var = gimple_debug_source_bind_get_var (stmt);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
801 else if (gimple_debug_nonbind_marker_p (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
802 continue;
111
kono
parents: 67
diff changeset
803 else
kono
parents: 67
diff changeset
804 gcc_unreachable ();
kono
parents: 67
diff changeset
805
kono
parents: 67
diff changeset
806 if (vars)
kono
parents: 67
diff changeset
807 vars->add (var);
kono
parents: 67
diff changeset
808 else
kono
parents: 67
diff changeset
809 fewvars.quick_push (var);
kono
parents: 67
diff changeset
810 }
kono
parents: 67
diff changeset
811
kono
parents: 67
diff changeset
812 basic_block bb = dest;
kono
parents: 67
diff changeset
813
kono
parents: 67
diff changeset
814 do
kono
parents: 67
diff changeset
815 {
kono
parents: 67
diff changeset
816 bb = single_pred (bb);
kono
parents: 67
diff changeset
817 for (gimple_stmt_iterator si = gsi_last_bb (bb);
kono
parents: 67
diff changeset
818 !gsi_end_p (si); gsi_prev (&si))
kono
parents: 67
diff changeset
819 {
kono
parents: 67
diff changeset
820 gimple *stmt = gsi_stmt (si);
kono
parents: 67
diff changeset
821 if (!is_gimple_debug (stmt))
kono
parents: 67
diff changeset
822 continue;
kono
parents: 67
diff changeset
823
kono
parents: 67
diff changeset
824 tree var;
kono
parents: 67
diff changeset
825
kono
parents: 67
diff changeset
826 if (gimple_debug_bind_p (stmt))
kono
parents: 67
diff changeset
827 var = gimple_debug_bind_get_var (stmt);
kono
parents: 67
diff changeset
828 else if (gimple_debug_source_bind_p (stmt))
kono
parents: 67
diff changeset
829 var = gimple_debug_source_bind_get_var (stmt);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 else if (gimple_debug_nonbind_marker_p (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
831 continue;
111
kono
parents: 67
diff changeset
832 else
kono
parents: 67
diff changeset
833 gcc_unreachable ();
kono
parents: 67
diff changeset
834
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
835 /* Discard debug bind overlaps. Unlike stmts from src,
111
kono
parents: 67
diff changeset
836 copied into a new block that will precede BB, debug bind
kono
parents: 67
diff changeset
837 stmts in bypassed BBs may actually be discarded if
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
838 they're overwritten by subsequent debug bind stmts. We
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
839 want to copy binds for all modified variables, so that we
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
840 retain a bind to the shared def if there is one, or to a
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
841 newly introduced PHI node if there is one. Our bind will
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
842 end up reset if the value is dead, but that implies the
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
843 variable couldn't have survived, so it's fine. We are
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
844 not actually running the code that performed the binds at
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
845 this point, we're just adding binds so that they survive
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
846 the new confluence, so markers should not be copied. */
111
kono
parents: 67
diff changeset
847 if (vars && vars->add (var))
kono
parents: 67
diff changeset
848 continue;
kono
parents: 67
diff changeset
849 else if (!vars)
kono
parents: 67
diff changeset
850 {
kono
parents: 67
diff changeset
851 int i = fewvars.length ();
kono
parents: 67
diff changeset
852 while (i--)
kono
parents: 67
diff changeset
853 if (fewvars[i] == var)
kono
parents: 67
diff changeset
854 break;
kono
parents: 67
diff changeset
855 if (i >= 0)
kono
parents: 67
diff changeset
856 continue;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
857 else if (fewvars.length () < (unsigned) alloc_count)
111
kono
parents: 67
diff changeset
858 fewvars.quick_push (var);
kono
parents: 67
diff changeset
859 else
kono
parents: 67
diff changeset
860 {
kono
parents: 67
diff changeset
861 vars = new hash_set<tree>;
kono
parents: 67
diff changeset
862 for (i = 0; i < alloc_count; i++)
kono
parents: 67
diff changeset
863 vars->add (fewvars[i]);
kono
parents: 67
diff changeset
864 fewvars.release ();
kono
parents: 67
diff changeset
865 vars->add (var);
kono
parents: 67
diff changeset
866 }
kono
parents: 67
diff changeset
867 }
kono
parents: 67
diff changeset
868
kono
parents: 67
diff changeset
869 stmt = gimple_copy (stmt);
kono
parents: 67
diff changeset
870 /* ??? Should we drop the location of the copy to denote
kono
parents: 67
diff changeset
871 they're artificial bindings? */
kono
parents: 67
diff changeset
872 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
873 }
kono
parents: 67
diff changeset
874 }
kono
parents: 67
diff changeset
875 while (bb != src && single_pred_p (bb));
kono
parents: 67
diff changeset
876
kono
parents: 67
diff changeset
877 if (vars)
kono
parents: 67
diff changeset
878 delete vars;
kono
parents: 67
diff changeset
879 else if (fewvars.exists ())
kono
parents: 67
diff changeset
880 fewvars.release ();
kono
parents: 67
diff changeset
881 }
kono
parents: 67
diff changeset
882
kono
parents: 67
diff changeset
883 /* See if TAKEN_EDGE->dest is a threadable block with no side effecs (ie, it
kono
parents: 67
diff changeset
884 need not be duplicated as part of the CFG/SSA updating process).
kono
parents: 67
diff changeset
885
kono
parents: 67
diff changeset
886 If it is threadable, add it to PATH and VISITED and recurse, ultimately
kono
parents: 67
diff changeset
887 returning TRUE from the toplevel call. Otherwise do nothing and
kono
parents: 67
diff changeset
888 return false.
kono
parents: 67
diff changeset
889
kono
parents: 67
diff changeset
890 DUMMY_COND, SIMPLIFY are used to try and simplify the condition at the
kono
parents: 67
diff changeset
891 end of TAKEN_EDGE->dest.
kono
parents: 67
diff changeset
892
kono
parents: 67
diff changeset
893 The available expression table is referenced via AVAIL_EXPRS_STACK. */
kono
parents: 67
diff changeset
894
kono
parents: 67
diff changeset
895 static bool
kono
parents: 67
diff changeset
896 thread_around_empty_blocks (edge taken_edge,
kono
parents: 67
diff changeset
897 gcond *dummy_cond,
kono
parents: 67
diff changeset
898 class avail_exprs_stack *avail_exprs_stack,
kono
parents: 67
diff changeset
899 pfn_simplify simplify,
kono
parents: 67
diff changeset
900 bitmap visited,
kono
parents: 67
diff changeset
901 vec<jump_thread_edge *> *path)
kono
parents: 67
diff changeset
902 {
kono
parents: 67
diff changeset
903 basic_block bb = taken_edge->dest;
kono
parents: 67
diff changeset
904 gimple_stmt_iterator gsi;
kono
parents: 67
diff changeset
905 gimple *stmt;
kono
parents: 67
diff changeset
906 tree cond;
kono
parents: 67
diff changeset
907
kono
parents: 67
diff changeset
908 /* The key property of these blocks is that they need not be duplicated
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
909 when threading. Thus they cannot have visible side effects such
111
kono
parents: 67
diff changeset
910 as PHI nodes. */
kono
parents: 67
diff changeset
911 if (!gsi_end_p (gsi_start_phis (bb)))
kono
parents: 67
diff changeset
912 return false;
kono
parents: 67
diff changeset
913
kono
parents: 67
diff changeset
914 /* Skip over DEBUG statements at the start of the block. */
kono
parents: 67
diff changeset
915 gsi = gsi_start_nondebug_bb (bb);
kono
parents: 67
diff changeset
916
kono
parents: 67
diff changeset
917 /* If the block has no statements, but does have a single successor, then
kono
parents: 67
diff changeset
918 it's just a forwarding block and we can thread through it trivially.
kono
parents: 67
diff changeset
919
kono
parents: 67
diff changeset
920 However, note that just threading through empty blocks with single
kono
parents: 67
diff changeset
921 successors is not inherently profitable. For the jump thread to
kono
parents: 67
diff changeset
922 be profitable, we must avoid a runtime conditional.
kono
parents: 67
diff changeset
923
kono
parents: 67
diff changeset
924 By taking the return value from the recursive call, we get the
kono
parents: 67
diff changeset
925 desired effect of returning TRUE when we found a profitable jump
kono
parents: 67
diff changeset
926 threading opportunity and FALSE otherwise.
kono
parents: 67
diff changeset
927
kono
parents: 67
diff changeset
928 This is particularly important when this routine is called after
kono
parents: 67
diff changeset
929 processing a joiner block. Returning TRUE too aggressively in
kono
parents: 67
diff changeset
930 that case results in pointless duplication of the joiner block. */
kono
parents: 67
diff changeset
931 if (gsi_end_p (gsi))
kono
parents: 67
diff changeset
932 {
kono
parents: 67
diff changeset
933 if (single_succ_p (bb))
kono
parents: 67
diff changeset
934 {
kono
parents: 67
diff changeset
935 taken_edge = single_succ_edge (bb);
kono
parents: 67
diff changeset
936
kono
parents: 67
diff changeset
937 if ((taken_edge->flags & EDGE_DFS_BACK) != 0)
kono
parents: 67
diff changeset
938 return false;
kono
parents: 67
diff changeset
939
kono
parents: 67
diff changeset
940 if (!bitmap_bit_p (visited, taken_edge->dest->index))
kono
parents: 67
diff changeset
941 {
kono
parents: 67
diff changeset
942 jump_thread_edge *x
kono
parents: 67
diff changeset
943 = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
kono
parents: 67
diff changeset
944 path->safe_push (x);
kono
parents: 67
diff changeset
945 bitmap_set_bit (visited, taken_edge->dest->index);
kono
parents: 67
diff changeset
946 return thread_around_empty_blocks (taken_edge,
kono
parents: 67
diff changeset
947 dummy_cond,
kono
parents: 67
diff changeset
948 avail_exprs_stack,
kono
parents: 67
diff changeset
949 simplify,
kono
parents: 67
diff changeset
950 visited,
kono
parents: 67
diff changeset
951 path);
kono
parents: 67
diff changeset
952 }
kono
parents: 67
diff changeset
953 }
kono
parents: 67
diff changeset
954
kono
parents: 67
diff changeset
955 /* We have a block with no statements, but multiple successors? */
kono
parents: 67
diff changeset
956 return false;
kono
parents: 67
diff changeset
957 }
kono
parents: 67
diff changeset
958
kono
parents: 67
diff changeset
959 /* The only real statements this block can have are a control
kono
parents: 67
diff changeset
960 flow altering statement. Anything else stops the thread. */
kono
parents: 67
diff changeset
961 stmt = gsi_stmt (gsi);
kono
parents: 67
diff changeset
962 if (gimple_code (stmt) != GIMPLE_COND
kono
parents: 67
diff changeset
963 && gimple_code (stmt) != GIMPLE_GOTO
kono
parents: 67
diff changeset
964 && gimple_code (stmt) != GIMPLE_SWITCH)
kono
parents: 67
diff changeset
965 return false;
kono
parents: 67
diff changeset
966
kono
parents: 67
diff changeset
967 /* Extract and simplify the condition. */
kono
parents: 67
diff changeset
968 cond = simplify_control_stmt_condition (taken_edge, stmt,
kono
parents: 67
diff changeset
969 avail_exprs_stack, dummy_cond,
kono
parents: 67
diff changeset
970 simplify);
kono
parents: 67
diff changeset
971
kono
parents: 67
diff changeset
972 /* If the condition can be statically computed and we have not already
kono
parents: 67
diff changeset
973 visited the destination edge, then add the taken edge to our thread
kono
parents: 67
diff changeset
974 path. */
kono
parents: 67
diff changeset
975 if (cond != NULL_TREE
kono
parents: 67
diff changeset
976 && (is_gimple_min_invariant (cond)
kono
parents: 67
diff changeset
977 || TREE_CODE (cond) == CASE_LABEL_EXPR))
kono
parents: 67
diff changeset
978 {
kono
parents: 67
diff changeset
979 if (TREE_CODE (cond) == CASE_LABEL_EXPR)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980 taken_edge = find_edge (bb, label_to_block (cfun, CASE_LABEL (cond)));
111
kono
parents: 67
diff changeset
981 else
kono
parents: 67
diff changeset
982 taken_edge = find_taken_edge (bb, cond);
kono
parents: 67
diff changeset
983
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 if (!taken_edge
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 || (taken_edge->flags & EDGE_DFS_BACK) != 0)
111
kono
parents: 67
diff changeset
986 return false;
kono
parents: 67
diff changeset
987
kono
parents: 67
diff changeset
988 if (bitmap_bit_p (visited, taken_edge->dest->index))
kono
parents: 67
diff changeset
989 return false;
kono
parents: 67
diff changeset
990 bitmap_set_bit (visited, taken_edge->dest->index);
kono
parents: 67
diff changeset
991
kono
parents: 67
diff changeset
992 jump_thread_edge *x
kono
parents: 67
diff changeset
993 = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
kono
parents: 67
diff changeset
994 path->safe_push (x);
kono
parents: 67
diff changeset
995
kono
parents: 67
diff changeset
996 thread_around_empty_blocks (taken_edge,
kono
parents: 67
diff changeset
997 dummy_cond,
kono
parents: 67
diff changeset
998 avail_exprs_stack,
kono
parents: 67
diff changeset
999 simplify,
kono
parents: 67
diff changeset
1000 visited,
kono
parents: 67
diff changeset
1001 path);
kono
parents: 67
diff changeset
1002 return true;
kono
parents: 67
diff changeset
1003 }
kono
parents: 67
diff changeset
1004
kono
parents: 67
diff changeset
1005 return false;
kono
parents: 67
diff changeset
1006 }
kono
parents: 67
diff changeset
1007
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1008 /* We are exiting E->src, see if E->dest ends with a conditional
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1009 jump which has a known value when reached via E.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1010
111
kono
parents: 67
diff changeset
1011 E->dest can have arbitrary side effects which, if threading is
kono
parents: 67
diff changeset
1012 successful, will be maintained.
kono
parents: 67
diff changeset
1013
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1014 Special care is necessary if E is a back edge in the CFG as we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1015 may have already recorded equivalences for E->dest into our
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1016 various tables, including the result of the conditional at
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1017 the end of E->dest. Threading opportunities are severely
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1018 limited in that case to avoid short-circuiting the loop
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1019 incorrectly.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1020
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1021 DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1022 to avoid allocating memory.
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1023
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1024 STACK is used to undo temporary equivalences created during the walk of
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1025 E->dest.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1026
111
kono
parents: 67
diff changeset
1027 SIMPLIFY is a pass-specific function used to simplify statements.
kono
parents: 67
diff changeset
1028
kono
parents: 67
diff changeset
1029 Our caller is responsible for restoring the state of the expression
kono
parents: 67
diff changeset
1030 and const_and_copies stacks.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1031
111
kono
parents: 67
diff changeset
1032 Positive return value is success. Zero return value is failure, but
kono
parents: 67
diff changeset
1033 the block can still be duplicated as a joiner in a jump thread path,
kono
parents: 67
diff changeset
1034 negative indicates the block should not be duplicated and thus is not
kono
parents: 67
diff changeset
1035 suitable for a joiner in a jump threading path. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1036
111
kono
parents: 67
diff changeset
1037 static int
kono
parents: 67
diff changeset
1038 thread_through_normal_block (edge e,
kono
parents: 67
diff changeset
1039 gcond *dummy_cond,
kono
parents: 67
diff changeset
1040 const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1041 avail_exprs_stack *avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1042 evrp_range_analyzer *evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1043 pfn_simplify simplify,
kono
parents: 67
diff changeset
1044 vec<jump_thread_edge *> *path,
kono
parents: 67
diff changeset
1045 bitmap visited)
kono
parents: 67
diff changeset
1046 {
kono
parents: 67
diff changeset
1047 /* We want to record any equivalences created by traversing E. */
kono
parents: 67
diff changeset
1048 record_temporary_equivalences (e, const_and_copies, avail_exprs_stack);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1049
111
kono
parents: 67
diff changeset
1050 /* PHIs create temporary equivalences.
kono
parents: 67
diff changeset
1051 Note that if we found a PHI that made the block non-threadable, then
kono
parents: 67
diff changeset
1052 we need to bubble that up to our caller in the same manner we do
kono
parents: 67
diff changeset
1053 when we prematurely stop processing statements below. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1054 if (!record_temporary_equivalences_from_phis (e, const_and_copies,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1055 evrp_range_analyzer))
111
kono
parents: 67
diff changeset
1056 return -1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1057
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1058 /* Now walk each statement recording any context sensitive
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1059 temporary equivalences we can detect. */
111
kono
parents: 67
diff changeset
1060 gimple *stmt
kono
parents: 67
diff changeset
1061 = record_temporary_equivalences_from_stmts_at_dest (e, const_and_copies,
kono
parents: 67
diff changeset
1062 avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1063 evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1064 simplify);
kono
parents: 67
diff changeset
1065
kono
parents: 67
diff changeset
1066 /* There's two reasons STMT might be null, and distinguishing
kono
parents: 67
diff changeset
1067 between them is important.
kono
parents: 67
diff changeset
1068
kono
parents: 67
diff changeset
1069 First the block may not have had any statements. For example, it
kono
parents: 67
diff changeset
1070 might have some PHIs and unconditionally transfer control elsewhere.
kono
parents: 67
diff changeset
1071 Such blocks are suitable for jump threading, particularly as a
kono
parents: 67
diff changeset
1072 joiner block.
kono
parents: 67
diff changeset
1073
kono
parents: 67
diff changeset
1074 The second reason would be if we did not process all the statements
kono
parents: 67
diff changeset
1075 in the block (because there were too many to make duplicating the
kono
parents: 67
diff changeset
1076 block profitable. If we did not look at all the statements, then
kono
parents: 67
diff changeset
1077 we may not have invalidated everything needing invalidation. Thus
kono
parents: 67
diff changeset
1078 we must signal to our caller that this block is not suitable for
kono
parents: 67
diff changeset
1079 use as a joiner in a threading path. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1080 if (!stmt)
111
kono
parents: 67
diff changeset
1081 {
kono
parents: 67
diff changeset
1082 /* First case. The statement simply doesn't have any instructions, but
kono
parents: 67
diff changeset
1083 does have PHIs. */
kono
parents: 67
diff changeset
1084 if (gsi_end_p (gsi_start_nondebug_bb (e->dest))
kono
parents: 67
diff changeset
1085 && !gsi_end_p (gsi_start_phis (e->dest)))
kono
parents: 67
diff changeset
1086 return 0;
kono
parents: 67
diff changeset
1087
kono
parents: 67
diff changeset
1088 /* Second case. */
kono
parents: 67
diff changeset
1089 return -1;
kono
parents: 67
diff changeset
1090 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1091
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1092 /* If we stopped at a COND_EXPR or SWITCH_EXPR, see if we know which arm
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1093 will be taken. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1094 if (gimple_code (stmt) == GIMPLE_COND
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1095 || gimple_code (stmt) == GIMPLE_GOTO
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1096 || gimple_code (stmt) == GIMPLE_SWITCH)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1097 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1098 tree cond;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1099
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1100 /* Extract and simplify the condition. */
111
kono
parents: 67
diff changeset
1101 cond = simplify_control_stmt_condition (e, stmt, avail_exprs_stack,
kono
parents: 67
diff changeset
1102 dummy_cond, simplify);
kono
parents: 67
diff changeset
1103
kono
parents: 67
diff changeset
1104 if (!cond)
kono
parents: 67
diff changeset
1105 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1106
111
kono
parents: 67
diff changeset
1107 if (is_gimple_min_invariant (cond)
kono
parents: 67
diff changeset
1108 || TREE_CODE (cond) == CASE_LABEL_EXPR)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1109 {
111
kono
parents: 67
diff changeset
1110 edge taken_edge;
kono
parents: 67
diff changeset
1111 if (TREE_CODE (cond) == CASE_LABEL_EXPR)
kono
parents: 67
diff changeset
1112 taken_edge = find_edge (e->dest,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1113 label_to_block (cfun, CASE_LABEL (cond)));
111
kono
parents: 67
diff changeset
1114 else
kono
parents: 67
diff changeset
1115 taken_edge = find_taken_edge (e->dest, cond);
kono
parents: 67
diff changeset
1116
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 basic_block dest = (taken_edge ? taken_edge->dest : NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1118
111
kono
parents: 67
diff changeset
1119 /* DEST could be NULL for a computed jump to an absolute
kono
parents: 67
diff changeset
1120 address. */
kono
parents: 67
diff changeset
1121 if (dest == NULL
kono
parents: 67
diff changeset
1122 || dest == e->dest
kono
parents: 67
diff changeset
1123 || (taken_edge->flags & EDGE_DFS_BACK) != 0
kono
parents: 67
diff changeset
1124 || bitmap_bit_p (visited, dest->index))
kono
parents: 67
diff changeset
1125 return 0;
kono
parents: 67
diff changeset
1126
kono
parents: 67
diff changeset
1127 /* Only push the EDGE_START_JUMP_THREAD marker if this is
kono
parents: 67
diff changeset
1128 first edge on the path. */
kono
parents: 67
diff changeset
1129 if (path->length () == 0)
kono
parents: 67
diff changeset
1130 {
kono
parents: 67
diff changeset
1131 jump_thread_edge *x
kono
parents: 67
diff changeset
1132 = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
kono
parents: 67
diff changeset
1133 path->safe_push (x);
kono
parents: 67
diff changeset
1134 }
kono
parents: 67
diff changeset
1135
kono
parents: 67
diff changeset
1136 jump_thread_edge *x
kono
parents: 67
diff changeset
1137 = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
kono
parents: 67
diff changeset
1138 path->safe_push (x);
kono
parents: 67
diff changeset
1139
kono
parents: 67
diff changeset
1140 /* See if we can thread through DEST as well, this helps capture
kono
parents: 67
diff changeset
1141 secondary effects of threading without having to re-run DOM or
kono
parents: 67
diff changeset
1142 VRP.
kono
parents: 67
diff changeset
1143
kono
parents: 67
diff changeset
1144 We don't want to thread back to a block we have already
kono
parents: 67
diff changeset
1145 visited. This may be overly conservative. */
kono
parents: 67
diff changeset
1146 bitmap_set_bit (visited, dest->index);
kono
parents: 67
diff changeset
1147 bitmap_set_bit (visited, e->dest->index);
kono
parents: 67
diff changeset
1148 thread_around_empty_blocks (taken_edge,
kono
parents: 67
diff changeset
1149 dummy_cond,
kono
parents: 67
diff changeset
1150 avail_exprs_stack,
kono
parents: 67
diff changeset
1151 simplify,
kono
parents: 67
diff changeset
1152 visited,
kono
parents: 67
diff changeset
1153 path);
kono
parents: 67
diff changeset
1154 return 1;
kono
parents: 67
diff changeset
1155 }
kono
parents: 67
diff changeset
1156 }
kono
parents: 67
diff changeset
1157 return 0;
kono
parents: 67
diff changeset
1158 }
kono
parents: 67
diff changeset
1159
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1160 /* There are basic blocks look like:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1161 <P0>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1162 p0 = a CMP b ; or p0 = (INT) (a CMP b)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1163 goto <X>;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1164
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1165 <P1>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1166 p1 = c CMP d
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1167 goto <X>;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1168
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1169 <X>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1170 # phi = PHI <p0 (P0), p1 (P1)>
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1171 if (phi != 0) goto <Y>; else goto <Z>;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1172
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1173 Then, edge (P0,X) or (P1,X) could be marked as EDGE_START_JUMP_THREAD
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1174 And edge (X,Y), (X,Z) is EDGE_COPY_SRC_JOINER_BLOCK
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1175
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 Return true if E is (P0,X) or (P1,X) */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1178 bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 edge_forwards_cmp_to_conditional_jump_through_empty_bb_p (edge e)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 /* See if there is only one stmt which is gcond. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1182 gcond *gs;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1183 if (!(gs = safe_dyn_cast<gcond *> (last_and_only_stmt (e->dest))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1185
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1186 /* See if gcond's cond is "(phi !=/== 0/1)" in the basic block. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1187 tree cond = gimple_cond_lhs (gs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1188 enum tree_code code = gimple_cond_code (gs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1189 tree rhs = gimple_cond_rhs (gs);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1190 if (TREE_CODE (cond) != SSA_NAME
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1191 || (code != NE_EXPR && code != EQ_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 || (!integer_onep (rhs) && !integer_zerop (rhs)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1194 gphi *phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (cond));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1195 if (phi == NULL || gimple_bb (phi) != e->dest)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1196 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1197
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1198 /* Check if phi's incoming value is CMP. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1199 gassign *def;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1200 tree value = PHI_ARG_DEF_FROM_EDGE (phi, e);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1201 if (TREE_CODE (value) != SSA_NAME
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1202 || !has_single_use (value)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1203 || !(def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (value))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1204 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1205
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1206 /* Or if it is (INT) (a CMP b). */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1207 if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1208 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 value = gimple_assign_rhs1 (def);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1210 if (TREE_CODE (value) != SSA_NAME
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1211 || !has_single_use (value)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212 || !(def = dyn_cast<gassign *> (SSA_NAME_DEF_STMT (value))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1213 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1215
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1216 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1217 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1218
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1219 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1220 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1221
111
kono
parents: 67
diff changeset
1222 /* We are exiting E->src, see if E->dest ends with a conditional
kono
parents: 67
diff changeset
1223 jump which has a known value when reached via E.
kono
parents: 67
diff changeset
1224
kono
parents: 67
diff changeset
1225 DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
kono
parents: 67
diff changeset
1226 to avoid allocating memory.
kono
parents: 67
diff changeset
1227
kono
parents: 67
diff changeset
1228 CONST_AND_COPIES is used to undo temporary equivalences created during the
kono
parents: 67
diff changeset
1229 walk of E->dest.
kono
parents: 67
diff changeset
1230
kono
parents: 67
diff changeset
1231 The available expression table is referenced vai AVAIL_EXPRS_STACK.
kono
parents: 67
diff changeset
1232
kono
parents: 67
diff changeset
1233 SIMPLIFY is a pass-specific function used to simplify statements. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1234
111
kono
parents: 67
diff changeset
1235 static void
kono
parents: 67
diff changeset
1236 thread_across_edge (gcond *dummy_cond,
kono
parents: 67
diff changeset
1237 edge e,
kono
parents: 67
diff changeset
1238 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1239 class avail_exprs_stack *avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1240 class evrp_range_analyzer *evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1241 pfn_simplify simplify)
kono
parents: 67
diff changeset
1242 {
kono
parents: 67
diff changeset
1243 bitmap visited = BITMAP_ALLOC (NULL);
kono
parents: 67
diff changeset
1244
kono
parents: 67
diff changeset
1245 const_and_copies->push_marker ();
kono
parents: 67
diff changeset
1246 avail_exprs_stack->push_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1247 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1248 evrp_range_analyzer->push_marker ();
111
kono
parents: 67
diff changeset
1249
kono
parents: 67
diff changeset
1250 stmt_count = 0;
kono
parents: 67
diff changeset
1251
kono
parents: 67
diff changeset
1252 vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> ();
kono
parents: 67
diff changeset
1253 bitmap_clear (visited);
kono
parents: 67
diff changeset
1254 bitmap_set_bit (visited, e->src->index);
kono
parents: 67
diff changeset
1255 bitmap_set_bit (visited, e->dest->index);
kono
parents: 67
diff changeset
1256
kono
parents: 67
diff changeset
1257 int threaded;
kono
parents: 67
diff changeset
1258 if ((e->flags & EDGE_DFS_BACK) == 0)
kono
parents: 67
diff changeset
1259 threaded = thread_through_normal_block (e, dummy_cond,
kono
parents: 67
diff changeset
1260 const_and_copies,
kono
parents: 67
diff changeset
1261 avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1262 evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1263 simplify, path,
kono
parents: 67
diff changeset
1264 visited);
kono
parents: 67
diff changeset
1265 else
kono
parents: 67
diff changeset
1266 threaded = 0;
kono
parents: 67
diff changeset
1267
kono
parents: 67
diff changeset
1268 if (threaded > 0)
kono
parents: 67
diff changeset
1269 {
kono
parents: 67
diff changeset
1270 propagate_threaded_block_debug_into (path->last ()->e->dest,
kono
parents: 67
diff changeset
1271 e->dest);
kono
parents: 67
diff changeset
1272 const_and_copies->pop_to_marker ();
kono
parents: 67
diff changeset
1273 avail_exprs_stack->pop_to_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1274 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1275 evrp_range_analyzer->pop_to_marker ();
111
kono
parents: 67
diff changeset
1276 BITMAP_FREE (visited);
kono
parents: 67
diff changeset
1277 register_jump_thread (path);
kono
parents: 67
diff changeset
1278 return;
kono
parents: 67
diff changeset
1279 }
kono
parents: 67
diff changeset
1280 else
kono
parents: 67
diff changeset
1281 {
kono
parents: 67
diff changeset
1282 /* Negative and zero return values indicate no threading was possible,
kono
parents: 67
diff changeset
1283 thus there should be no edges on the thread path and no need to walk
kono
parents: 67
diff changeset
1284 through the vector entries. */
kono
parents: 67
diff changeset
1285 gcc_assert (path->length () == 0);
kono
parents: 67
diff changeset
1286 path->release ();
kono
parents: 67
diff changeset
1287 delete path;
kono
parents: 67
diff changeset
1288
kono
parents: 67
diff changeset
1289 /* A negative status indicates the target block was deemed too big to
kono
parents: 67
diff changeset
1290 duplicate. Just quit now rather than trying to use the block as
kono
parents: 67
diff changeset
1291 a joiner in a jump threading path.
kono
parents: 67
diff changeset
1292
kono
parents: 67
diff changeset
1293 This prevents unnecessary code growth, but more importantly if we
kono
parents: 67
diff changeset
1294 do not look at all the statements in the block, then we may have
kono
parents: 67
diff changeset
1295 missed some invalidations if we had traversed a backedge! */
kono
parents: 67
diff changeset
1296 if (threaded < 0)
kono
parents: 67
diff changeset
1297 {
kono
parents: 67
diff changeset
1298 BITMAP_FREE (visited);
kono
parents: 67
diff changeset
1299 const_and_copies->pop_to_marker ();
kono
parents: 67
diff changeset
1300 avail_exprs_stack->pop_to_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1301 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1302 evrp_range_analyzer->pop_to_marker ();
111
kono
parents: 67
diff changeset
1303 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306
111
kono
parents: 67
diff changeset
1307 /* We were unable to determine what out edge from E->dest is taken. However,
kono
parents: 67
diff changeset
1308 we might still be able to thread through successors of E->dest. This
kono
parents: 67
diff changeset
1309 often occurs when E->dest is a joiner block which then fans back out
kono
parents: 67
diff changeset
1310 based on redundant tests.
kono
parents: 67
diff changeset
1311
kono
parents: 67
diff changeset
1312 If so, we'll copy E->dest and redirect the appropriate predecessor to
kono
parents: 67
diff changeset
1313 the copy. Within the copy of E->dest, we'll thread one or more edges
kono
parents: 67
diff changeset
1314 to points deeper in the CFG.
kono
parents: 67
diff changeset
1315
kono
parents: 67
diff changeset
1316 This is a stopgap until we have a more structured approach to path
kono
parents: 67
diff changeset
1317 isolation. */
kono
parents: 67
diff changeset
1318 {
kono
parents: 67
diff changeset
1319 edge taken_edge;
kono
parents: 67
diff changeset
1320 edge_iterator ei;
kono
parents: 67
diff changeset
1321 bool found;
kono
parents: 67
diff changeset
1322
kono
parents: 67
diff changeset
1323 /* If E->dest has abnormal outgoing edges, then there's no guarantee
kono
parents: 67
diff changeset
1324 we can safely redirect any of the edges. Just punt those cases. */
kono
parents: 67
diff changeset
1325 FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1326 if (taken_edge->flags & EDGE_COMPLEX)
111
kono
parents: 67
diff changeset
1327 {
kono
parents: 67
diff changeset
1328 const_and_copies->pop_to_marker ();
kono
parents: 67
diff changeset
1329 avail_exprs_stack->pop_to_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1330 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1331 evrp_range_analyzer->pop_to_marker ();
111
kono
parents: 67
diff changeset
1332 BITMAP_FREE (visited);
kono
parents: 67
diff changeset
1333 return;
kono
parents: 67
diff changeset
1334 }
kono
parents: 67
diff changeset
1335
kono
parents: 67
diff changeset
1336 /* Look at each successor of E->dest to see if we can thread through it. */
kono
parents: 67
diff changeset
1337 FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)
kono
parents: 67
diff changeset
1338 {
kono
parents: 67
diff changeset
1339 if ((e->flags & EDGE_DFS_BACK) != 0
kono
parents: 67
diff changeset
1340 || (taken_edge->flags & EDGE_DFS_BACK) != 0)
kono
parents: 67
diff changeset
1341 continue;
kono
parents: 67
diff changeset
1342
kono
parents: 67
diff changeset
1343 /* Push a fresh marker so we can unwind the equivalences created
kono
parents: 67
diff changeset
1344 for each of E->dest's successors. */
kono
parents: 67
diff changeset
1345 const_and_copies->push_marker ();
kono
parents: 67
diff changeset
1346 avail_exprs_stack->push_marker ();
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1347 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1348 evrp_range_analyzer->push_marker ();
111
kono
parents: 67
diff changeset
1349
kono
parents: 67
diff changeset
1350 /* Avoid threading to any block we have already visited. */
kono
parents: 67
diff changeset
1351 bitmap_clear (visited);
kono
parents: 67
diff changeset
1352 bitmap_set_bit (visited, e->src->index);
kono
parents: 67
diff changeset
1353 bitmap_set_bit (visited, e->dest->index);
kono
parents: 67
diff changeset
1354 bitmap_set_bit (visited, taken_edge->dest->index);
kono
parents: 67
diff changeset
1355 vec<jump_thread_edge *> *path = new vec<jump_thread_edge *> ();
kono
parents: 67
diff changeset
1356
kono
parents: 67
diff changeset
1357 /* Record whether or not we were able to thread through a successor
kono
parents: 67
diff changeset
1358 of E->dest. */
kono
parents: 67
diff changeset
1359 jump_thread_edge *x = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
kono
parents: 67
diff changeset
1360 path->safe_push (x);
kono
parents: 67
diff changeset
1361
kono
parents: 67
diff changeset
1362 x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
kono
parents: 67
diff changeset
1363 path->safe_push (x);
kono
parents: 67
diff changeset
1364 found = thread_around_empty_blocks (taken_edge,
kono
parents: 67
diff changeset
1365 dummy_cond,
kono
parents: 67
diff changeset
1366 avail_exprs_stack,
kono
parents: 67
diff changeset
1367 simplify,
kono
parents: 67
diff changeset
1368 visited,
kono
parents: 67
diff changeset
1369 path);
kono
parents: 67
diff changeset
1370
kono
parents: 67
diff changeset
1371 if (!found)
kono
parents: 67
diff changeset
1372 found = thread_through_normal_block (path->last ()->e, dummy_cond,
kono
parents: 67
diff changeset
1373 const_and_copies,
kono
parents: 67
diff changeset
1374 avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1375 evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1376 simplify, path,
kono
parents: 67
diff changeset
1377 visited) > 0;
kono
parents: 67
diff changeset
1378
kono
parents: 67
diff changeset
1379 /* If we were able to thread through a successor of E->dest, then
kono
parents: 67
diff changeset
1380 record the jump threading opportunity. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1381 if (found
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1382 || edge_forwards_cmp_to_conditional_jump_through_empty_bb_p (e))
111
kono
parents: 67
diff changeset
1383 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1384 if (taken_edge->dest != path->last ()->e->dest)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1385 propagate_threaded_block_debug_into (path->last ()->e->dest,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1386 taken_edge->dest);
111
kono
parents: 67
diff changeset
1387 register_jump_thread (path);
kono
parents: 67
diff changeset
1388 }
kono
parents: 67
diff changeset
1389 else
kono
parents: 67
diff changeset
1390 delete_jump_thread_path (path);
kono
parents: 67
diff changeset
1391
kono
parents: 67
diff changeset
1392 /* And unwind the equivalence table. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1393 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1394 evrp_range_analyzer->pop_to_marker ();
111
kono
parents: 67
diff changeset
1395 avail_exprs_stack->pop_to_marker ();
kono
parents: 67
diff changeset
1396 const_and_copies->pop_to_marker ();
kono
parents: 67
diff changeset
1397 }
kono
parents: 67
diff changeset
1398 BITMAP_FREE (visited);
kono
parents: 67
diff changeset
1399 }
kono
parents: 67
diff changeset
1400
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1401 if (evrp_range_analyzer)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1402 evrp_range_analyzer->pop_to_marker ();
111
kono
parents: 67
diff changeset
1403 const_and_copies->pop_to_marker ();
kono
parents: 67
diff changeset
1404 avail_exprs_stack->pop_to_marker ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1405 }
111
kono
parents: 67
diff changeset
1406
kono
parents: 67
diff changeset
1407 /* Examine the outgoing edges from BB and conditionally
kono
parents: 67
diff changeset
1408 try to thread them.
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
kono
parents: 67
diff changeset
1411 to avoid allocating memory.
kono
parents: 67
diff changeset
1412
kono
parents: 67
diff changeset
1413 CONST_AND_COPIES is used to undo temporary equivalences created during the
kono
parents: 67
diff changeset
1414 walk of E->dest.
kono
parents: 67
diff changeset
1415
kono
parents: 67
diff changeset
1416 The available expression table is referenced vai AVAIL_EXPRS_STACK.
kono
parents: 67
diff changeset
1417
kono
parents: 67
diff changeset
1418 SIMPLIFY is a pass-specific function used to simplify statements. */
kono
parents: 67
diff changeset
1419
kono
parents: 67
diff changeset
1420 void
kono
parents: 67
diff changeset
1421 thread_outgoing_edges (basic_block bb, gcond *dummy_cond,
kono
parents: 67
diff changeset
1422 class const_and_copies *const_and_copies,
kono
parents: 67
diff changeset
1423 class avail_exprs_stack *avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1424 class evrp_range_analyzer *evrp_range_analyzer,
111
kono
parents: 67
diff changeset
1425 tree (*simplify) (gimple *, gimple *,
kono
parents: 67
diff changeset
1426 class avail_exprs_stack *,
kono
parents: 67
diff changeset
1427 basic_block))
kono
parents: 67
diff changeset
1428 {
kono
parents: 67
diff changeset
1429 int flags = (EDGE_IGNORE | EDGE_COMPLEX | EDGE_ABNORMAL);
kono
parents: 67
diff changeset
1430 gimple *last;
kono
parents: 67
diff changeset
1431
kono
parents: 67
diff changeset
1432 /* If we have an outgoing edge to a block with multiple incoming and
kono
parents: 67
diff changeset
1433 outgoing edges, then we may be able to thread the edge, i.e., we
kono
parents: 67
diff changeset
1434 may be able to statically determine which of the outgoing edges
kono
parents: 67
diff changeset
1435 will be traversed when the incoming edge from BB is traversed. */
kono
parents: 67
diff changeset
1436 if (single_succ_p (bb)
kono
parents: 67
diff changeset
1437 && (single_succ_edge (bb)->flags & flags) == 0
kono
parents: 67
diff changeset
1438 && potentially_threadable_block (single_succ (bb)))
kono
parents: 67
diff changeset
1439 {
kono
parents: 67
diff changeset
1440 thread_across_edge (dummy_cond, single_succ_edge (bb),
kono
parents: 67
diff changeset
1441 const_and_copies, avail_exprs_stack,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1442 evrp_range_analyzer, simplify);
111
kono
parents: 67
diff changeset
1443 }
kono
parents: 67
diff changeset
1444 else if ((last = last_stmt (bb))
kono
parents: 67
diff changeset
1445 && gimple_code (last) == GIMPLE_COND
kono
parents: 67
diff changeset
1446 && EDGE_COUNT (bb->succs) == 2
kono
parents: 67
diff changeset
1447 && (EDGE_SUCC (bb, 0)->flags & flags) == 0
kono
parents: 67
diff changeset
1448 && (EDGE_SUCC (bb, 1)->flags & flags) == 0)
kono
parents: 67
diff changeset
1449 {
kono
parents: 67
diff changeset
1450 edge true_edge, false_edge;
kono
parents: 67
diff changeset
1451
kono
parents: 67
diff changeset
1452 extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
kono
parents: 67
diff changeset
1453
kono
parents: 67
diff changeset
1454 /* Only try to thread the edge if it reaches a target block with
kono
parents: 67
diff changeset
1455 more than one predecessor and more than one successor. */
kono
parents: 67
diff changeset
1456 if (potentially_threadable_block (true_edge->dest))
kono
parents: 67
diff changeset
1457 thread_across_edge (dummy_cond, true_edge,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1458 const_and_copies, avail_exprs_stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1459 evrp_range_analyzer, simplify);
111
kono
parents: 67
diff changeset
1460
kono
parents: 67
diff changeset
1461 /* Similarly for the ELSE arm. */
kono
parents: 67
diff changeset
1462 if (potentially_threadable_block (false_edge->dest))
kono
parents: 67
diff changeset
1463 thread_across_edge (dummy_cond, false_edge,
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1464 const_and_copies, avail_exprs_stack,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1465 evrp_range_analyzer, simplify);
111
kono
parents: 67
diff changeset
1466 }
kono
parents: 67
diff changeset
1467 }